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

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

#include <net/arp.h>
#include <net/neighbour.h>
#include "linux/ctype.h" #define MAC_BCAST_ADDR (unsigned char *)"\xff\xff\xff\xff\xff\xff" /******************************************************************************
* nArpTblCtl - find mac from arp_tbl by ip
* DESCRIPTION: -
* Input:
* Output:
* Returns: -EAGAIN -- find nothing, but had send arp request.try again.
* -ENXIO -- find nothing, and create error.
* 0 -- find ok.
* modification history
* --------------------
* 2.00, 2014-12-18 , zengjianrong written
* --------------------
******************************************************************************/
static int nArpTblCtl(struct net_device *dev, const __be32 s_addr_remote, const __be32 s_addr_local, const unsigned char *pucMac)
{
struct arpreq arpreq;
struct sockaddr_in *sin = NULL;
struct neighbour *neigh = NULL;
unsigned char *hw_addr = NULL;
int err = -ENXIO; /* NO such device or address */ if (( == s_addr_remote)
|| (NULL == pucMac)
|| (NULL == dev))
{
err = -EINVAL;/* INVALID ARGUMENT */
return err;
} memset(&arpreq, , sizeof(struct arpreq));
sin = (struct sockaddr_in *) &(arpreq.arp_pa);
sin->sin_family = AF_INET;
memcpy(&(sin->sin_addr.s_addr), &s_addr_remote, sizeof(__be32));
strcpy(arpreq.arp_dev, dev->name); rtnl_lock();
if (neigh = neigh_lookup(&arp_tbl, &s_addr_remote, dev))
{
read_lock_bh(&neigh->lock);
memcpy(arpreq.arp_ha.sa_data, neigh->ha, dev->addr_len);
read_unlock_bh(&neigh->lock);
neigh_release(neigh); hw_addr = (unsigned char *) arpreq.arp_ha.sa_data;
memcpy(pucMac, hw_addr, );
if (!( == pucMac[] && == pucMac[] && == pucMac[]
&& == pucMac[] && == pucMac[] && == pucMac[]))
{
err = ;
}
}
else
{
if (neigh = neigh_create(&arp_tbl, &s_addr_remote, dev))
{
arp_send(ARPOP_REQUEST, ETH_P_ARP, s_addr_remote, netdev_eth1, s_addr_local,
MAC_BCAST_ADDR, netdev_eth1->dev_addr, NULL);
err = -EAGAIN; /* try again */
}
}
rtnl_unlock(); return err;
}
static int inet_aton(cp, addr)
const char *cp;
struct in_addr *addr;
{
u_long parts[];
uint32_t val;
const char *c;
char *endptr;
int gotend, n; c = (const char *)cp;
n = ;
/*
* Run through the string, grabbing numbers until
* the end of the string, or some error
*/
gotend = ;
while (!gotend)
{
unsigned long l; l = simple_strtoul(c, &endptr, ); if (l == ULONG_MAX || (l == && endptr == c))
return (); val = (uint32_t)l;
/*
* If the whole string is invalid, endptr will equal
* c.. this way we can make sure someone hasn't
* gone '.12' or something which would get past
* the next check.
*/
if (endptr == c)
return ();
parts[n] = val;
c = endptr; /* Check the next character past the previous number's end */
switch (*c)
{
case '.' :
/* Make sure we only do 3 dots .. */
if (n == ) /* Whoops. Quit. */
return ();
n++;
c++;
break; case '\0':
gotend = ;
break; default:
if (isspace((unsigned char)*c))
{
gotend = ;
break;
}
else
return (); /* Invalid character, so fail */
} } /*
* Concoct the address according to
* the number of parts specified.
*/ switch (n)
{
case : /* a -- 32 bits */
/*
* Nothing is necessary here. Overflow checking was
* already done in strtoul().
*/
break;
case : /* a.b -- 8.24 bits */
if (val > 0xffffff || parts[] > 0xff)
return ();
val |= parts[] << ;
break; case : /* a.b.c -- 8.8.16 bits */
if (val > 0xffff || parts[] > 0xff || parts[] > 0xff)
return ();
val |= (parts[] << ) | (parts[] << );
break; case : /* a.b.c.d -- 8.8.8.8 bits */
if (val > 0xff || parts[] > 0xff || parts[] > 0xff ||
parts[] > 0xff)
return ();
val |= (parts[] << ) | (parts[] << ) | (parts[] << );
break;
} if (addr != NULL)
addr->s_addr = htonl(val);
return ();
} int nArpTestByZjr(void)
{
struct in_addr sin_local_addr;
struct in_addr sin_remote_addr;
unsigned char aucMac[];
memset(aucMac, , );
memset(&sin_remote_addr, , sizeof(struct in_addr));
if ( == (inet_aton("200.31.96.225", &sin_remote_addr)))
{
printk("%s: IP address '200.31.96.225' not valid\n", __FUNCTION__);
return -;
}
memset(&sin_local_addr, , sizeof(struct in_addr));
if ( == (inet_aton("200.31.96.1", &sin_local_addr)))
{
printk("%s: IP address '200.31.96.1' not valid\n", __FUNCTION__);
return -;
} if ( > nArpTblCtl(netdev_eth1, sin_remote_addr.s_addr, sin_local_addr.s_addr, &aucMac))
{
printk("func:%s,line:%d, find nothing...\n", __FUNCTION__, __LINE__);
}
else
{
printk("200.31.96.225-->%02x:%02x:%02x:%02x:%02x:%02x\n",
aucMac[], aucMac[], aucMac[], aucMac[], aucMac[], aucMac[]);
}
}
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. mvc ajax跳转controller 的路径

    mvc Controller : url: "../phone/index",(控制器名,方法名) 一般处理程序.ashx :  url: "../bianji.ashx ...

  2. 基于Spring Cloud Netflix的TCC柔性事务和EDA事件驱动示例

    Solar Spring Cloud为开发者提供了快速构建分布式系统中的一些常见工具,如分布式配置中心,服务发现与注册中心,智能路由,服务熔断及降级,消息总线,分布式追踪的解决方案等. 本次实战以模拟 ...

  3. Spring笔记01

    spring 第一章 Spring模块规划图 核心架包 spring-beans-4.0.0.RELEASE. spring-core-4.0.0.RELEASE. spring-context-4. ...

  4. JS-21点游戏

    //21点游戏 let readline=require("readline-sync"); //清屏函数 let clear=()=>process.stdout.writ ...

  5. Eclipse 笔记

    2004年前的开发架构:(操作系统+数据库+中间件+开发工具) AIX + DB2 + WAS + WSAD  ===  皇家级 UNIX/Linux + Oracle +BEA WebLogic + ...

  6. wpf 工程生成dll

    在WPF项目里,当工程里包含窗体时候, 不可以使用类库的方式生产dll,虽然系统支持引用exe 文件,但总是觉得不如dll习惯,后来发现,新建个项目,类型选择“WPF自定义类件库”,名称和工程名称相同 ...

  7. 5.如何基于 dubbo 进行服务治理、服务降级、失败重试以及超时重试?

    作者:中华石杉 面试题 如何基于 dubbo 进行服务治理.服务降级.失败重试以及超时重试? 面试官心理分析 服务治理,这个问题如果问你,其实就是看看你有没有服务治理的思想,因为这个是做过复杂微服务的 ...

  8. Windows出现“引用账户被锁定,且暂时无法登录”解决方法

    1. 问题描述如下: i. 远程桌面登录时,出现提示必须修改密码才能登录,是因为密码过期所导致的,如下图: ii. 当我们登录Windows控制台(基于OpenStack平台的虚拟机)进行修改密码时, ...

  9. 多个python版本共存时的pip配置

    两种方法来配置pip Func1: 1.1 找到python环境的安装包,将python.exe文件重命名,如:将python2.7版本的python.exe重命名为Python2.exe,将pyth ...

  10. 5.4 RDD编程---综合案例

    一.求top值 任务描述:求出多个文件中数值的最大.最小值 二.求最大最小值 任务描述:求出多个文件中数值的最大.最小值 解题思路:通过一个人造的key,让所有的值都成为“key”的value-lis ...