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){
- … …
- }