protocol
|
值
|
作用
|
ETH_P_IP
|
0X0800
|
只接收发往目的MAC是本机的IP类型的数据帧
|
ETH_P_ARP
|
0X0806
|
只接收发往目的MAC是本机的ARP类型的数据帧
|
ETH_P_RARP
|
0X8035
|
只接受发往目的MAC是本机的RARP类型的数据帧
|
ETH_P_ALL
|
0X0003
|
接收发往目的MAC是本机的所有类型(ip,arp,rarp)的数据帧,同时还可以接收从本机发出去的所有数据帧。在混杂模式打开的情况下,还会接收到发往目的MAC为非本地硬件地址的数据帧。
|
- struct sockaddr_ll{
- unsigned short sll_family; /* 总是 AF_PACKET */
- unsigned short sll_protocol; /* 物理层的协议 */
- int sll_ifindex; /* 接口号 */
- unsigned short sll_hatype; /* 报头类型 */
- unsigned char sll_pkttype; /* 分组类型 */
- unsigned char sll_halen; /* 地址长度 */
- unsigned char sll_addr[8]; /* 物理层地址 */
- };
- struct
sockaddr_ll sll;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, "eth0");
- ioctl(sockfd, SIOCGIFINDEX, &ifr);
- sll.sll_ifindex = ifr.ifr_ifindex;
- struct ifreq ifr;
- strcpy(ifr.ifr_name, "eth0");
- ioctl(sockfd, SIOCGIFHWADDR, &ifr);
- #include <stdio.h>
- #include <stdlib.h>
- #include <errno.h>
- #include <unistd.h>
- #include <sys/socket.h>
- #include <sys/types.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/if_ether.h>
- int main(int argc, char **argv) {
- int sock, n;
- char buffer[2048];
- struct ethhdr *eth;
- struct iphdr *iph;
- if (0>(sock=socket(PF_PACKET, SOCK_RAW, htons(ETH_P_IP)))) {
- perror("socket");
- exit(1);
- }
- while (1) {
- printf("=====================================\n");
- //注意:在这之前我没有调用bind函数,原因是什么呢?
- n = recvfrom(sock,buffer,2048,0,NULL,NULL);
- printf("%d bytes read\n",n);
- //接收到的数据帧头6字节是目的MAC地址,紧接着6字节是源MAC地址。
- eth=(struct ethhdr*)buffer;
- printf("Dest MAC addr:%02x:%02x:%02x:%02x:%02x:%02x\n",eth->h_dest[0],eth->h_dest[1],eth->h_dest[2],eth->h_dest[3],eth->h_dest[4],eth->h_dest[5]);
- printf("Source MAC addr:%02x:%02x:%02x:%02x:%02x:%02x\n",eth->h_source[0],eth->h_source[1],eth->h_source[2],eth->h_source[3],eth->h_source[4],eth->h_source[5]);
- iph=(struct iphdr*)(buffer+sizeof(struct ethhdr));
- //我们只对IPV4且没有选项字段的IPv4报文感兴趣
- if(iph->version ==4 && iph->ihl == 5){
- printf("Source host:%s\n",inet_ntoa(iph->saddr));
- printf("Dest host:%s\n",inet_ntoa(iph->daddr));
- }
- }
- }
- struct ifreq ethreq;
- … …
- strncpy(ethreq.ifr_name,"eth0",IFNAMSIZ);
- if(-1 == ioctl(sock,SIOCGIFFLAGS,ðreq)){
- perror("ioctl");
- close(sock);
- exit(1);
- }
- ethreq.ifr_flags |=IFF_PROMISC;
- if(-1 == ioctl(sock,SIOCGIFFLAGS,ðreq)){
- perror("ioctl");
- close(sock);
- exit(1);
- }
- while(1){
- … …
- }