Android 的 PF_PACKET 限制
来源:互联网 发布:ipad绘画漫画软件 编辑:程序博客网 时间:2024/06/08 02:10
Android 的 PF_PACKET 限制
执行:(pcap-linux.c)
sock_fd = device ? socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL))
device不为0吗?
不是》sock_fd = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_ALL));
报错:socket: Operation not permitted
原因:
建立PF_PACKET一族的socket需要root权限。
sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP))
上面这种socket
,
必须在root权限执行才能成功。
自从内核2.2开始Linux引进了capabilities的概念,
在建立PF_PACKET族的socket时会调用packet_create,
在packet_create中会检查用户是否有CAP_NET_RAW的capability:(内核检查)
if (!capable(CAP_NET_RAW))
return -EPERM;
root拥有所有的capability,
非root也可能有CAP_NET_RAW的capability。
Porting WiFi drivers to Android
http://blog.csdn.net/hongjiujing/article/details/5565431
===============================================================================================
链路层套接字PF_PACKET简介(转)
在linux环境中要从链路层(MAC)直接收发数据帧,可以通过libpcap与libnet两个动态库来分别完成收与发的工作。虽然它已被广泛使用,但在要求进行跨平台移植的软件中使用仍然有很多弊端。
这里介绍一种更为直接地、无须安装其它库的从MAC层收发数据帧的方式,即通过定义链路层的套接字来完成。
Packet套接字用于在MAC层上收发原始数据帧,这样就允许用户在用户空间完成MAC之上各个层次的实现。给无论是进行开发还是测试的人们带来了极大的便利性。
Packet套接字的定义方式与传送层的套接字定义类似,如下:
packet_socket=socket(PF_PACKET,int socket_type,int protocol);
(这个套接字的打开需要用户有root权限)
其中socket_type有两种类型,一种为SOCK_RAW,它是包含了MAC层头部信息的原始分组,当然这种类型的套接字在发送的时候需要自己加上一个MAC头部(其类型定义在linux/if_ether.h中,ethhdr),另一种是SOCK_DGRAM类型,它是已经进行了MAC层头部处理的,即收上的帧已经去掉了头部,而发送时也无须用户添加头部字段。
Protocol是指其送交的上层的协议号,如IP为0x0800,当其为htons(ETH_P_ALL) (其宏定义为0)时表示收发所有的协议。
创建好套接字后,就可以通过与UDP一样的recvfrom与sendto函数进行数据的收发,其目的地址结构为sockaddr_ll,这与传送层的地址结构定义是不一样的,其长度为20字节(在TCP/IP的链路层地址中使用了18字节),而传送层的地址结构长度为16字节。
Sockaddr_ll结构如下:
struct sockaddr_ll
{
unsigned short sll_family;
unsigned short sll_protocol;
int sll_ifindex;
unsigned short sll_hatype;
unsigned char sll_pkttype;
unsigned char sll_halen;
unsigned char sll_addr[8];
};
sll_protocol 是在 linux/if_ether.h 头文件中定义的按网络层排序的标准的以太桢协议类型。sll_ifindex 是接口的索引号(参见netdevice(2));0 匹配所有的接口(当然只有合法的才用于绑定)。 sll_hatype 是在 linux/if_arp.h 中定义的 ARP 硬件地址类型。 sll_pkttype 包含分组类型。有效的分组类型是:目标地址是本地主机的分组用的 PACKET_HOST,物理层广播分组用的 PACKET_BROADCAST ,发送到一个物理层多路广播地址的分组用的 PACKET_MULTICAST,在混杂(promiscuous)模式下的设备驱动器发向其他主机的分组用的 PACKET_OTHERHOST,本源于本地主机的分组被环回到分组套接口用的 PACKET_OUTGOING。这些类型只对接收到的分组有意义。sll_addr 和 sll_halen 包括物理层(例如 IEEE 802.3)地址和地址长度。精确的解释依赖于设备。(本段引于packet的用户手册)
当在多个网络接口的主机上使用这个套接字时,若要指定接收或发送的接口时可以使用bind进行绑定,这与TCP套接字的操作一样,但其内涵并不相同。绑定时将根据地址结构中的sll_protocal和sll_ifindex分别绑定收发的协议号和接口索引号,接口索引号sll_ifindex为0时表示使用有效的所有接口。接口的sll_ifindex值可以通过ioctl获得,如下面是获得名字为“eth0”的接口的索引号
取得的值保存在ifr结构体的ifr_ifindex中,ifr结构类型为“struct ifreq”
BTW,要获得接口的物理地址同样使用ioctl可以得到
ioctl(fd_packet,SIOCGIFHWADDR,&ifr);
以数据形式保存在ifr的ifr_hwaddr.sa_data中。
另外需要注意的是,在调用recvfrom函数时返回的地址长度信息为18字节,原因是在sockaddr_ll结构中的sll_addr[8]为8字节,MAC地址只使用了其中的前6字节。在用sendto发送时需要将目的地址结构体强制转换为struct sockaddr 类型,而且指定的长度必须为20字节,而不能是18或其它值。
我在使用中当指定了协议类型后可以准备接收该类型的数据帧,但有个问题一直困扰着我,就是无法过滤掉广播帧,必须要收到帧后判断目的地址是否为自己,然后如果用SOCK_DGRAM的时候又如何判断呢?本人正在探索中,一旦有新进展将第一时间与大家分享。
- Android 的 PF_PACKET 限制
- PF_PACKET和AF_PACKET的不同
- kernel中 PF_PACKET 的流程
- Android 模拟器的限制
- Android的多线程限制
- PF_PACKET介绍
- PF_PACKET笔记
- Android 解决65535的限制
- Android 解决65535的限制
- Android 限制EditText只能输入数字、限制输入类型、限制输入长度的小技巧
- Android 限制EditText只能输入数字、限制输入类型、限制输入长度的小技巧
- Android 限制EditText只能输入数字、限制输入类型、限制输入长度的小技巧
- Android 限制EditText只能输入数字、限制输入类型、限制输入长度的小技巧
- Linux下PF_PACKET的使用,RARP的server和client程序 (转)
- Linux下Sniffer程序的实现(PF_PACKET,SOCK_RAW,recvfrom,htons(ETH_P_IP),setsockopt(filter))
- linux中提供了PF_PACKET接口可以操作链路层的数据
- android中使用jar库的限制
- Android Broadcast 和 BroadcastReceiver的权限限制
- NSValue的使用
- 原生二维码和条形码扫描代码
- Swift - 网络请求报错App Transport Security has blocked a cleartext
- 网站更新对收录、排名的影响与解决方法
- MVC4 razor与aspx的区别以及用法1,2
- Android 的 PF_PACKET 限制
- MFC使用多字节字符集后界面变成老式风格(WIN95风格)
- 贪心算法 Problem E 1004
- SQL Server 系统数据库恢复
- SQL Server 深入解析索引存储(上)
- SQL Server 深入解析索引存储(中)
- SQL Server 深入解析索引存储(下)
- SQL Server 重新组织生成索引
- SQL Server 变更数据捕获(CDC)