博客地址:http://home.cnblogs.com/u/zengjianrong/

  在内核处理此流程,反而更加简单些,代码如下:

  1. #include <net/arp.h>
  2. #include <net/neighbour.h>
  3. #include "linux/ctype.h"
  4.  
  5. #define MAC_BCAST_ADDR (unsigned char *)"\xff\xff\xff\xff\xff\xff"
  6.  
  7. /******************************************************************************
  8. * nArpTblCtl - find mac from arp_tbl by ip
  9. * DESCRIPTION: -
  10. * Input:
  11. * Output:
  12. * Returns: -EAGAIN -- find nothing, but had send arp request.try again.
  13. * -ENXIO -- find nothing, and create error.
  14. * 0 -- find ok.
  15. * modification history
  16. * --------------------
  17. * 2.00, 2014-12-18 , zengjianrong written
  18. * --------------------
  19. ******************************************************************************/
  20. static int nArpTblCtl(struct net_device *dev, const __be32 s_addr_remote, const __be32 s_addr_local, const unsigned char *pucMac)
  21. {
  22. struct arpreq arpreq;
  23. struct sockaddr_in *sin = NULL;
  24. struct neighbour *neigh = NULL;
  25. unsigned char *hw_addr = NULL;
  26. int err = -ENXIO; /* NO such device or address */
  27.  
  28. if (( == s_addr_remote)
  29. || (NULL == pucMac)
  30. || (NULL == dev))
  31. {
  32. err = -EINVAL;/* INVALID ARGUMENT */
  33. return err;
  34. }
  35.  
  36. memset(&arpreq, , sizeof(struct arpreq));
  37. sin = (struct sockaddr_in *) &(arpreq.arp_pa);
  38. sin->sin_family = AF_INET;
  39. memcpy(&(sin->sin_addr.s_addr), &s_addr_remote, sizeof(__be32));
  40. strcpy(arpreq.arp_dev, dev->name);
  41.  
  42. rtnl_lock();
  43. if (neigh = neigh_lookup(&arp_tbl, &s_addr_remote, dev))
  44. {
  45. read_lock_bh(&neigh->lock);
  46. memcpy(arpreq.arp_ha.sa_data, neigh->ha, dev->addr_len);
  47. read_unlock_bh(&neigh->lock);
  48. neigh_release(neigh);
  49.  
  50. hw_addr = (unsigned char *) arpreq.arp_ha.sa_data;
  51. memcpy(pucMac, hw_addr, );
  52. if (!( == pucMac[] && == pucMac[] && == pucMac[]
  53. && == pucMac[] && == pucMac[] && == pucMac[]))
  54. {
  55. err = ;
  56. }
  57. }
  58. else
  59. {
  60. if (neigh = neigh_create(&arp_tbl, &s_addr_remote, dev))
  61. {
  62. arp_send(ARPOP_REQUEST, ETH_P_ARP, s_addr_remote, netdev_eth1, s_addr_local,
  63. MAC_BCAST_ADDR, netdev_eth1->dev_addr, NULL);
  64. err = -EAGAIN; /* try again */
  65. }
  66. }
  67. rtnl_unlock();
  68.  
  69. return err;
  70. }
  71. static int inet_aton(cp, addr)
  72. const char *cp;
  73. struct in_addr *addr;
  74. {
  75. u_long parts[];
  76. uint32_t val;
  77. const char *c;
  78. char *endptr;
  79. int gotend, n;
  80.  
  81. c = (const char *)cp;
  82. n = ;
  83. /*
  84. * Run through the string, grabbing numbers until
  85. * the end of the string, or some error
  86. */
  87. gotend = ;
  88. while (!gotend)
  89. {
  90. unsigned long l;
  91.  
  92. l = simple_strtoul(c, &endptr, );
  93.  
  94. if (l == ULONG_MAX || (l == && endptr == c))
  95. return ();
  96.  
  97. val = (uint32_t)l;
  98. /*
  99. * If the whole string is invalid, endptr will equal
  100. * c.. this way we can make sure someone hasn't
  101. * gone '.12' or something which would get past
  102. * the next check.
  103. */
  104. if (endptr == c)
  105. return ();
  106. parts[n] = val;
  107. c = endptr;
  108.  
  109. /* Check the next character past the previous number's end */
  110. switch (*c)
  111. {
  112. case '.' :
  113. /* Make sure we only do 3 dots .. */
  114. if (n == ) /* Whoops. Quit. */
  115. return ();
  116. n++;
  117. c++;
  118. break;
  119.  
  120. case '\0':
  121. gotend = ;
  122. break;
  123.  
  124. default:
  125. if (isspace((unsigned char)*c))
  126. {
  127. gotend = ;
  128. break;
  129. }
  130. else
  131. return (); /* Invalid character, so fail */
  132. }
  133.  
  134. }
  135.  
  136. /*
  137. * Concoct the address according to
  138. * the number of parts specified.
  139. */
  140.  
  141. switch (n)
  142. {
  143. case : /* a -- 32 bits */
  144. /*
  145. * Nothing is necessary here. Overflow checking was
  146. * already done in strtoul().
  147. */
  148. break;
  149. case : /* a.b -- 8.24 bits */
  150. if (val > 0xffffff || parts[] > 0xff)
  151. return ();
  152. val |= parts[] << ;
  153. break;
  154.  
  155. case : /* a.b.c -- 8.8.16 bits */
  156. if (val > 0xffff || parts[] > 0xff || parts[] > 0xff)
  157. return ();
  158. val |= (parts[] << ) | (parts[] << );
  159. break;
  160.  
  161. case : /* a.b.c.d -- 8.8.8.8 bits */
  162. if (val > 0xff || parts[] > 0xff || parts[] > 0xff ||
  163. parts[] > 0xff)
  164. return ();
  165. val |= (parts[] << ) | (parts[] << ) | (parts[] << );
  166. break;
  167. }
  168.  
  169. if (addr != NULL)
  170. addr->s_addr = htonl(val);
  171. return ();
  172. }
  173.  
  174. int nArpTestByZjr(void)
  175. {
  176. struct in_addr sin_local_addr;
  177. struct in_addr sin_remote_addr;
  178. unsigned char aucMac[];
  179. memset(aucMac, , );
  180. memset(&sin_remote_addr, , sizeof(struct in_addr));
  181. if ( == (inet_aton("200.31.96.225", &sin_remote_addr)))
  182. {
  183. printk("%s: IP address '200.31.96.225' not valid\n", __FUNCTION__);
  184. return -;
  185. }
  186. memset(&sin_local_addr, , sizeof(struct in_addr));
  187. if ( == (inet_aton("200.31.96.1", &sin_local_addr)))
  188. {
  189. printk("%s: IP address '200.31.96.1' not valid\n", __FUNCTION__);
  190. return -;
  191. }
  192.  
  193. if ( > nArpTblCtl(netdev_eth1, sin_remote_addr.s_addr, sin_local_addr.s_addr, &aucMac))
  194. {
  195. printk("func:%s,line:%d, find nothing...\n", __FUNCTION__, __LINE__);
  196. }
  197. else
  198. {
  199. printk("200.31.96.225-->%02x:%02x:%02x:%02x:%02x:%02x\n",
  200. aucMac[], aucMac[], aucMac[], aucMac[], aucMac[], aucMac[]);
  201. }
  202. }
  203. EXPORT_SYMBOL(nArpTestByZjr);

通过IP获取MAC地址例子(内核层)的更多相关文章

  1. 通过IP获取MAC地址例子(应用层)

    博客地址:http://home.cnblogs.com/u/zengjianrong/ 由于某种需求,需要获取某个ip的mac地址,在应用层实现例子如下代码. 流程:1. 先遍历arp表,若存在对应 ...

  2. java根据本地Ip获取mac地址

    import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; impo ...

  3. android获取Mac地址和IP地址

    获取Mac地址实际项目中测试了如下几种方法:(1)设备开通Wifi连接,获取到网卡的MAC地址(但是不开通wifi,这种方法获取不到Mac地址,这种方法也是网络上使用的最多的方法) //根据Wifi信 ...

  4. Java获取本机的IP与MAC地址

    有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumer ...

  5. .net获取IP和MAC地址

    获取IP  解决request.UserHostAddress取不到真实IP private string GetClientIP()   {    string result = HttpConte ...

  6. 获取平台所有接口的IP和MAC地址

    我们有时候会有获取网口的IP和MAC地址的需求.可以通过ioctl来获取. #include <sys/ioctl.h>#include <net/if.h>#include ...

  7. 获取本机IP、mac地址、计算机名

    python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...

  8. Java根据ip地址获取Mac地址,Java获取Mac地址

    Java根据ip地址获取Mac地址,Java获取Mac地址 >>>>>>>>>>>>>>>>>&g ...

  9. Linux 获取本机IP、MAC地址用法大全

    getifaddrs()和struct ifaddrs的使用,获取本机IP ifaddrs结构体定义如下: struct ifaddrs { struct ifaddrs *ifa_next; /* ...

随机推荐

  1. Python - 标准库概况 - 第二十一天

    Python 标准库概览 操作系统接口 os模块提供了不少与操作系统相关联的函数. 建议使用 "import os" 风格而非 "from os import *&quo ...

  2. Linux链接文件——管理链接文件的命令

    Linux链接文件——管理链接文件的命令 摘要:本文主要学习了在Linux系统中创建链接文件的命令. ln命令 ln命令用于给文件创建链接,是Link的缩写. 基本语法 ln [选项] 源文件 目标文 ...

  3. Windows+Qt使用gRPC

    上篇文章<Windows+VS2017使用gRPC>编译出了Windows下可用的gRPC静态lib库文件,在此基础上要想在Qt上使用,需要使用MSVC2017 64bit构建组件进行构建 ...

  4. Spring事务部分知识点整理

    目录 1.数据库事务基础概念 2.Spring中注解事务的使用 3.Spring事务使用注意场景 1.数据库事务基础概念   数据库事务是对数据库一次一系列的操作组成的单元,可以包含增删改查或者只有单 ...

  5. Bootstrap Table列宽拖动的方法

    在之前做过的一个web项目中,前端表格是基于jQuery和Bootstrap Table实现的,要求能利用拖动改变列宽,现将实现的过程记录如下: 1. Bootstrap Table可拖动,需要用到它 ...

  6. LearnOpenGL.PBR.工作流贴图

  7. AssetBundleMaster_ReadMe_CN

    在开始使用之前, 建议先导入到一个空的工程里, 通过ReadMe的一步步引导使你对整个框架以及文件结构进行熟悉, 之后再考虑导入到现有工程中使用, 完整看完教程大概需要2个小时左右. 先看看文件夹结构 ...

  8. Rust中的函数调用

    注意区别语句和表达式哟. Rust是一门基于表示式的语言,牢记!!! fn main() { println!("Hello world!"); another_function( ...

  9. 201871010105-曹玉中《面向对象程序设计(java)》第十一周学习总结

    201871010105-曹玉中<面向对象程序设计(java)>第十一周学习总结 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/ ...

  10. python27期day09:函数的初始、函数的定义、函数的调用、函数的返回值、函数的参数、作业题。

    1.函数的作用:封装代码.大量的减少了重复的代码. 2.全局空间:顶行写的就是全局空间. 图解 : 3.函数的定义: def 是一个关键字.申明要定义一个函数 my_len 函数的名字.遵循变量命名的 ...