博客地址: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. word转html预览

    #region Index页面 /// <summary> /// Index页面 /// </summary> /// <paramname="url&quo ...

  2. 010.[转] maven的三大生命周期

    一.Maven的生命周期 Maven的生命周期就是对所有的构建过程进行抽象和统一.包含了项目的清理.初始化.编译.测试.打包.集成测试.验证.部署和站点生成等几乎所有的构建步骤. Maven的生命周期 ...

  3. oracle查询中会使索引无效的情况总结

    总结一下oracle中会使索引无效的情况 1 无where条件: 2 索引列进行运算时: 3 使用like,并且通配符在前的情况: 4 字符型字段为数字时在where条件里不添加引号: 5 not i ...

  4. win7 安装vb6

    1. 用setup.exe有问题,用acmsetup.exe 2.打开setupwiz.ini,把"acme=acmboot.exe"改为"=setup\acmsetup ...

  5. gradle入门

    gradle入门 简介: Gradle是一个基于Apache Ant和Apache Maven概念的项目自动化构建开源工具.它使用一种基于Groovy的特定领域语言(DSL)来声明项目设置,抛弃了基于 ...

  6. C++学习视频和资料

    我在学习c++时,比较迷茫,而且当时学完c++primer时不知道该学习什么, 犹豫了好久,最后找到了一些关于c++学习路线的视频,包含源代码,我感觉还不错,分享给大家. 下载地址 https://d ...

  7. conan使用(三)--打包只有头文件的库

    参考:https://docs.conan.io/en/latest/howtos/header_only.html?highlight=header%20only 对于只含头文件的库打包非常简单,以 ...

  8. E08【选尺码】I'm looking for size 43

    核心句型 I'm looking for size 43 我想要43号的 场景对话 A:Can I help you?您需要什么? B:Yes,can I try on those shoes,ple ...

  9. shell 字符菜单管理

    1.创建一个脚本func.sh 脚本如下func2.sh #!/bin/bash function menu(){ title="My Menu" url="www.la ...

  10. 可迭代对象,迭代器对象,for循环

    迭代器:迭代的工具.迭代是更新换代,如你爷爷生了你爹,你爹生了你,迭代也可以说成是重复,并且但每一次的重复都是基于上一次的结果来的.如计算机中的迭代开发,就是基于软件的上一个版本更新.以下代码就不是迭 ...