计网_C语言编程获取本机的mac地址以及mac下pcap编程报错Undefined symbols for architecture x86_64-"_pcap_*****"...的解决办法
2017-10-16 12:43
465 查看
本文包含以下两部分:
## C语言编程获取本机的mac地址
## mac下pcap编程报错Undefined symbols for architecture x86_64:”__pcap_*****”, referenced from: _main in…的解决方法
关键词:计算机网络; pcap; libpcap; mac; mac地址;
本学期计网lab老师要求我实现用C语言获取本机的mac地址。但像我这么懒的人眼珠一转就想直接调shell,但问过了老师,直接调shell的命令不行,也就意味着system(“ipconfig”)这样的代码不允许出现。不让用就算了吧,那就自己搞。当然,老师明确说了不会就问度娘,那我就问问。。。
上网查了一下,网上相关的实现有很多,比如有调用API的、通过访问网卡获取的,等等。但我这么懒,肯定不想访问网卡什么的(其实也挺容易的),那么应该怎么办呢?
受到ping命令的启发,我的想法是通过一次网络连接请求,获取本机mac地址。在构思结束后我上网查相关资料,才发现我的想法对应的是一个叫ARP协议的东西。好高兴自己居然独立想出来了一个高级的东西~(并不,只是你的思路别人已经造好了轮子而已。。)
ARP的C语言实现网络上有:传送门,但这个太长,我感觉很多功能并不需要。
要使用PCAP可能你需要在自己的电脑上安装libpcap这个函数库(是叫函数库嘛?问号脸。。。。)
mac我并没有安装libpcap,好像是自带pcap库了?(便利性赞一个)。其他系统要安装可以百度一下。
以上错误是由于没有告诉gcc要链接造成的。是的,不要以为include了pcap.h就够了,在编译的时候还需要:(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
看到
然后,成功编译。(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
note:有时候会由于权限不够,需要
回车,等待一会儿,得到完美输出:
与终端命令
至此本文结束!
[2] https://stackoverflow.com/questions/25583379/libpcap-not-linking-netbeans
[3] http://blog.csdn.net/wypblog/article/details/7456829
[4] http://blog.csdn.net/cheng_fangang/article/details/8608126
(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
visitor tracker
## C语言编程获取本机的mac地址
## mac下pcap编程报错Undefined symbols for architecture x86_64:”__pcap_*****”, referenced from: _main in…的解决方法
关键词:计算机网络; pcap; libpcap; mac; mac地址;
本学期计网lab老师要求我实现用C语言获取本机的mac地址。但像我这么懒的人眼珠一转就想直接调shell,但问过了老师,直接调shell的命令不行,也就意味着system(“ipconfig”)这样的代码不允许出现。不让用就算了吧,那就自己搞。当然,老师明确说了不会就问度娘,那我就问问。。。
上网查了一下,网上相关的实现有很多,比如有调用API的、通过访问网卡获取的,等等。但我这么懒,肯定不想访问网卡什么的(其实也挺容易的),那么应该怎么办呢?
受到ping命令的启发,我的想法是通过一次网络连接请求,获取本机mac地址。在构思结束后我上网查相关资料,才发现我的想法对应的是一个叫ARP协议的东西。好高兴自己居然独立想出来了一个高级的东西~(并不,只是你的思路别人已经造好了轮子而已。。)
ARP的C语言实现网络上有:传送门,但这个太长,我感觉很多功能并不需要。
我利用ARP协议获取本机的mac地址的思路是:模拟接收到一个数据包,并且发送数据包回应(此部分类似ping命令),然后捕获我们回应的数据包进行解析,得到本机的mac地址并不是完全基于ARP,更正为抓取ping命令发送的ICMP包
既然是捕获数据包,那就要用到我们”大名鼎鼎“的数据包捕获函数库PCAP了。要使用PCAP可能你需要在自己的电脑上安装libpcap这个函数库(是叫函数库嘛?问号脸。。。。)
mac我并没有安装libpcap,好像是自带pcap库了?(便利性赞一个)。其他系统要安装可以百度一下。
好了废话不多说,直接上代码:
/**************************myMacAddress.c************************************* * Copyright (C) 2017 by guoayng (Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)* * 实现了C语言获取本机的mac地址 * 备注: * 网上相关的实现有很多,比如有调用API的、通过访问网卡获取的,等等。并且问过了老师,直接调shell的命令不行,也就意味着system(“ipconfig”)这样的代码不允许出现 * 但我不想访问网卡什么的,那么应该怎么办呢? * 受到ping命令的启发,我的想法是通过一次网络连接请求,获取本机mac地址 * 在构思结束后我上网查相关资料,才发现我的想法对应的是一个叫ARP协议的东西 * ARP的C语言实现网络上有:http://blog.csdn.net/wangpengqi/article/details/46240505,但这个太长,我感觉很多功能并不需要 * 我利用ARP协议获取本机的mac地址的思路是:模拟接收到一个数据包,并且发送数据包回应(此部分类似ping命令),然后截取我们回应的数据包进行解析,得到本机的mac地址 * 参考了http://blog.csdn.net/wypblog/article/details/7456829 的资料后,我写出了以下代码。 ****************************************************************************/ #include <stdio.h> #include <pcap/pcap.h> #include <netinet/if_ether.h> int main(){ pcap_t *sniffer_des; char errbuf[PCAP_ERRBUF_SIZE];// PCAP_ERRBUF_SIZE is in {/usr/include/pcap/pcap.h} // the Defination is {#define PCAP_ERRBUF_SIZE 256} char *net_dev; bpf_u_int32 net, mask; struct bpf_program fp; // 可理解为结构体实例化(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved) const u_char *packet; struct pcap_pkthdr hdr; // 可理解为结构体实例化 struct ether_header *eth_header;// 可理解为结构体实例化 u_char *ptr; net_dev = "en7";//此处为我的网卡编号,一般的机子此处应为eth0 if(pcap_lookupnet(net_dev, &net, &mask, errbuf) == -1){ printf("get net error:%s\n", errbuf); return 1; } sniffer_des = pcap_open_live(net_dev, 1024, 1, 5000, errbuf);// 调用PCAP_API中的pcap_open_live // sniffer_des = pcap_open_live(net_dev, 65535, 1, 5000, errbuf);// 调用PCAP_API中的pcap_open_live // 参考http://blog.csdn.net/cheng_fangang/article/details/8608126 :发现在pcap_t* handle = pcap_open_live(sDevice, 65535, 1, 0, errbuf);这个函数时有问题了,当设置到1024的时候一点都不丢包,但是65535的时候就丢包了,(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved) // 看了pcap的pcap_open_live函数也没有看明白什么原因,我怀疑时内部处理分配内存的时候,每一个包分配65535大小肯定比分配处理1024包大小的内存耗时,所以导致丢包。 // 请各位用pcap的时候牢记这个东东吧,我可吃过苦了。。。。 if(sniffer_des == NULL){ printf("pcap_open_live%s\n", errbuf); return 1; } if(pcap_setfilter(sniffer_des, &fp) == -1){ printf("pcap_setfilter() error\n"); return 1; } packet = pcap_next(sniffer_des, &hdr); if(packet == NULL){ printf("pacap_next() failed\n"); return 1; } eth_header = (struct ether_header*)packet; if(ntohs(eth_header->ether_type) != ETHERTYPE_IP){// ETHERTYPE_IP is in {/usr/include/net/ethernet.h}, // the Defination is {#define ETHERTYPE_IP 0x0800}==>IP数据报的以太网帧类型也是0x0800(IPv4: 0x0800) printf("not ethernet packet\n"); // 若ether_type(类型)不是ip数据报,则报错(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved) return 1; } ptr = eth_header->ether_shost; int i = 0; printf("\nMy Physical Adress(MAC):"); while(i < ETHER_ADDR_LEN){ // The number of bytes in an ethernet (MAC) address. // #define ETHER_ADDR_LEN 6 printf(" %x:", *ptr++); i++; } printf("\n"); return 0; }
好了进入下一部分,gcc编译时报错如下信息:(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
Undefined symbols for architecture x86_64: "_pcap_lookupnet", referenced from: _main in xxxx.o
以上错误是由于没有告诉gcc要链接造成的。是的,不要以为include了pcap.h就够了,在编译的时候还需要:(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
~$ gcc myMacAddress.c -l pcap -o sgyMac
看到
-l pcap了吗,这是告诉gcc还要动态链接pcap库
然后,成功编译。(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
调用
调用很简单,另一个终端ping本机地址如192.168.1.10,然后新开一个终端,输入:note:有时候会由于权限不够,需要
sudo
~$ sudo ./sgyMac
回车,等待一会儿,得到完美输出:
~$ sudo ./sgyMac Password: My Physical Adress(MAC): xx: xx: xx: xx: xx: xx://我的mac地址不在这里贴出来了
与终端命令
ifconfig的结果对比后,完全正确。
文中所用C代码运行时并没有返回mac地址,而是报“not ethernet packet”
因为代码基于抓包,所以我自己在测试的时候也发生过这种情况,没有返回MAC地址。经过测试我发现,在有线连接和手机热点下的无线连接,程序都可以正常运行,但大局域网(比如商场的公共Wi-Fi)下很小几率会报这个错,我猜测是丢包?不是很清楚为什么。我可以确定的是只要是固定连接(网线那种或者开手机热点只给自己用那种),程序都可以获得MAC地址,但其他情况下就很迷。这个如果各位有想法可以在评论里与我交流。至此本文结束!
References
[1] https://ubuntuforums.org/showthread.php?t=125444[2] https://stackoverflow.com/questions/25583379/libpcap-not-linking-netbeans
[3] http://blog.csdn.net/wypblog/article/details/7456829
[4] http://blog.csdn.net/cheng_fangang/article/details/8608126
(Copyright © http://blog.csdn.net/s_gy_zetrov. All Rights Reserved)
visitor tracker
![](http://clustrmaps.com/map_v2.png?cl=0e1633&w=a&t=n&d=5Dq0hF6G3WoDZtrpxkeOQ404RoBOWSzDpckKPBFRCnk&co=0b4975&ct=cdd4d9)
相关文章推荐
- 在ubuntu x86_64 GCC4.6上ics编译错误以及解决办法
- 在ubuntu x86_64 GCC4.6上ics编译错误以及解决办法
- ashx页面中context.Session["xxx"]获取不到值的解决办法
- 编程中出现的错误,以及解决办法(持续更新)
- mac上使用g++编译出错“Undefined symbols for architecture x86_64:” 错误解决办法
- 嵌入式 获取网卡设备以及IP和MAC地址示例以及网络编程之ioctl小结
- LIBVIRT报告qemu-system-x86_64: CPU feature cmt not found的解决办法
- 【转】在ashx页面中context.Session["xxx"]获取不到值的解决办法
- Android 使用GPRS获取手机地理位置 以及 Location 获取为空的解决办法
- 用xcode6.3编译早期工程时出现Undefined symbols for architecture x86_64错误的解决办法(转)
- PHP date("Y-m-d H:i:s");获取当前时间 差8小时解决办法
- windows64 装PIL时遇到的问题以及解决办法
- 红帽子Linux6.5 X86_64 自动重启解决办法
- C++与C函数的相互调用方法以及error C2732:链接规范与"f"的早期规范冲突的解决办法
- $("#").attr("checked")获取的值是undefined的解决办法
- 解决从服务器获取的数组是 __NSCFConstantString以及""没有空格字符串的问题
- VirtualBox 安装 Linux时 报错This kernel requires an X86-64 CPU,but only detected an i686 CPU错误的解决办法
- openssl——从内存中读取RSA公钥并加密 以及 "PRNG not seeded" error message 的解决办法
- Maven构建项目速度太慢的解决办法,以及报错"Retrieving archetypes:". Java heap space
- VirtualBox 安装 Linux时 报错This kernel requires an X86-64 CPU,but only detected an i686 CPU错误的解决办法