博客地址: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. Linux目录和文件——查询目录和文件的命令

    Linux目录和文件——查询目录和文件的命令 摘要:本文主要学习了在Linux系统中是如何查询目录和文件的. which命令 which命令是根据PATH环境变量设置的路径,去搜索执行文件. 基本语法 ...

  2. maven 学习---使用Maven运行单元测试

    要通过Maven运行单元测试,发出此命令: mvn test 这会在你的项目中运行整个单元测试. 案例学习 创建两个单元测试,并通过 Maven 的运行它.参见一个简单的 Java 测试类: pack ...

  3. Bootstrap Table列宽拖动的方法

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

  4. Linux强制关掉其他ssh登录的用户

    Linux强制关掉其他ssh登录的用户 首先 用who命令查看登录的iproot pts/0 162.16.16.155 14:30 0.00s 0.07s 0.05s wroot pts/1 162 ...

  5. JSP 与Javabean 的交互技术

    JSP 与Javabean 的交互技术 JavaBean的属性可以是任意类型,并且一个JavaBean可以有多个属性.每个属性通常都需要具有相应的setter. getter方法,setter方法称为 ...

  6. lvm调整卷大小

    lvreduce -L 10240M /dev/rhel/home pvchange -xn /dev/sdb1 pvmove -i /dev/sdb1 vgreduce rhel /dev/sdb1 ...

  7. Dev-C++之调试

    参考这个博客https://blog.csdn.net/qq_38737992/article/details/77621299,解决了问题

  8. JS高阶---为什么说JS是单线程执行的???

    大纲: [主体] (1)如何证明JS运行是单线程的? 上述代码执行顺序结果为:fn()→timeout →timeout 接下来对上述代码做下修改 执行结果如右图所示 接下来点击确认,关闭弹框,再往后 ...

  9. JS高阶---对象创建模式(5种)

    [前言] 函数高级部分先看到这里,接下里看下面向对象高级部分 .对象创建模式 .继承模式 [主体] (1)Object构造函数模式 案例如下: 测试结果如右图所示 (2)对象字面量形式创建 案例如下: ...

  10. Python获取帮助的3种方式(转载)

    我们可以很容易的通过Python解释器获取帮助.如果想知道一个对象(object)更多的信息,那么可以调用help(object)!另外还有一些有用的方法,dir(object)会显示该对象的大部分相 ...