通过IP获取MAC地址例子(内核层)
博客地址: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地址例子(内核层)的更多相关文章
- 通过IP获取MAC地址例子(应用层)
博客地址:http://home.cnblogs.com/u/zengjianrong/ 由于某种需求,需要获取某个ip的mac地址,在应用层实现例子如下代码. 流程:1. 先遍历arp表,若存在对应 ...
- java根据本地Ip获取mac地址
import java.net.InetAddress; import java.net.NetworkInterface; import java.net.SocketException; impo ...
- android获取Mac地址和IP地址
获取Mac地址实际项目中测试了如下几种方法:(1)设备开通Wifi连接,获取到网卡的MAC地址(但是不开通wifi,这种方法获取不到Mac地址,这种方法也是网络上使用的最多的方法) //根据Wifi信 ...
- Java获取本机的IP与MAC地址
有些机器有许多虚拟的网卡,获取IP地址时会出现一些意外,所以需要一些验证: // 获取mac地址 public static String getMacAddress() { try { Enumer ...
- .net获取IP和MAC地址
获取IP 解决request.UserHostAddress取不到真实IP private string GetClientIP() { string result = HttpConte ...
- 获取平台所有接口的IP和MAC地址
我们有时候会有获取网口的IP和MAC地址的需求.可以通过ioctl来获取. #include <sys/ioctl.h>#include <net/if.h>#include ...
- 获取本机IP、mac地址、计算机名
python获取本机IP.mac地址.计算机名 在python中获取ip地址和在php中有很大不同,我们先来看一下python 获得本机MAC地址: >>> import uuid ...
- Java根据ip地址获取Mac地址,Java获取Mac地址
Java根据ip地址获取Mac地址,Java获取Mac地址 >>>>>>>>>>>>>>>>>&g ...
- Linux 获取本机IP、MAC地址用法大全
getifaddrs()和struct ifaddrs的使用,获取本机IP ifaddrs结构体定义如下: struct ifaddrs { struct ifaddrs *ifa_next; /* ...
随机推荐
- Python - 标准库概况 - 第二十一天
Python 标准库概览 操作系统接口 os模块提供了不少与操作系统相关联的函数. 建议使用 "import os" 风格而非 "from os import *&quo ...
- Linux链接文件——管理链接文件的命令
Linux链接文件——管理链接文件的命令 摘要:本文主要学习了在Linux系统中创建链接文件的命令. ln命令 ln命令用于给文件创建链接,是Link的缩写. 基本语法 ln [选项] 源文件 目标文 ...
- Windows+Qt使用gRPC
上篇文章<Windows+VS2017使用gRPC>编译出了Windows下可用的gRPC静态lib库文件,在此基础上要想在Qt上使用,需要使用MSVC2017 64bit构建组件进行构建 ...
- Spring事务部分知识点整理
目录 1.数据库事务基础概念 2.Spring中注解事务的使用 3.Spring事务使用注意场景 1.数据库事务基础概念 数据库事务是对数据库一次一系列的操作组成的单元,可以包含增删改查或者只有单 ...
- Bootstrap Table列宽拖动的方法
在之前做过的一个web项目中,前端表格是基于jQuery和Bootstrap Table实现的,要求能利用拖动改变列宽,现将实现的过程记录如下: 1. Bootstrap Table可拖动,需要用到它 ...
- LearnOpenGL.PBR.工作流贴图
- AssetBundleMaster_ReadMe_CN
在开始使用之前, 建议先导入到一个空的工程里, 通过ReadMe的一步步引导使你对整个框架以及文件结构进行熟悉, 之后再考虑导入到现有工程中使用, 完整看完教程大概需要2个小时左右. 先看看文件夹结构 ...
- Rust中的函数调用
注意区别语句和表达式哟. Rust是一门基于表示式的语言,牢记!!! fn main() { println!("Hello world!"); another_function( ...
- 201871010105-曹玉中《面向对象程序设计(java)》第十一周学习总结
201871010105-曹玉中<面向对象程序设计(java)>第十一周学习总结 项目 内容 <面向对象程序设计(java)> https://www.cnblogs.com/ ...
- python27期day09:函数的初始、函数的定义、函数的调用、函数的返回值、函数的参数、作业题。
1.函数的作用:封装代码.大量的减少了重复的代码. 2.全局空间:顶行写的就是全局空间. 图解 : 3.函数的定义: def 是一个关键字.申明要定义一个函数 my_len 函数的名字.遵循变量命名的 ...