Linux下PF PACKET的使用

2021-08-18 13:50:24 字數 3134 閱讀 7604

1、af_inet和af_packet區別----

2、tcp/ip協議(一)網路基礎知識----

sock_raw(注意一定要在root下使用)原始套接字程式設計可以接收到本機網絡卡上的資料幀或者資料報,對於監聽網路的流量和分析是很有作用的.一共可以有3種方式建立這種socket

1.socket(af_inet, sock_raw, ipproto_tcp|ipproto_udp|ipproto_icmp)傳送接收ip資料報,不能用ipproto_ip,因為如果是用了ipproto_ip,系統根本就不知道該用什麼協議。

2.socket(pf_packet, sock_raw, htons(eth_p_ip|eth_p_arp|eth_p_all))傳送接收乙太網資料幀

3.socket(af_inet, sock_packet, htons(eth_p_ip|eth_p_arp|eth_p_all))過時了,不要用啊

1.介紹

在linux中提供了pf_packet介面可以操作鏈路層的資料。

2.使用方法

定義乙個pf_packet = socket(pf_socket, sock_raw, htons(eth_p_rarp));

就可以利用函式sendto和recefrom來讀取和傳送鏈路層的資料報了(當然,傳送arp包,上面第三個引數要變為 htons(eth_p_arp),或者ip的包為eth_p_ip,可檢視檔案/usr/include/linux/if_ether.h檔案看到所有支援的協議)。

3.在使用sock_raw, sock_dgram和sock_packet的區別

在socket的第乙個引數使用pf_packet的時候,上述三種socket的型別都可以使用。但是有區別。

(1)使用sock_raw傳送的資料必須包含鏈路層的協議頭,接受得到的資料報,包含鏈路層協議頭。而使用sock_dgram則都不含鏈路層的協議頭。

(2)sock_packet也是可以使用的,但是已經廢棄,以後不保證還能支援,不推薦使用。

(3)在使用sock_raw或sock_dgram和sock_packet時,在sendto和recvfrom中使用的位址型別不同,前兩者使用sockaddr_ll型別的位址,而後者使用sockaddr型別的位址。

(4)如socket的第乙個引數使用pf_inet,第二個引數使用sock_raw,則可以得到原始的ip包。

4.下面的例子是乙個簡單的rarp協議的server程式和client程式

server程式一開始獲得除lo介面以外介面的mac位址,等待rarp request請求的到來,如果請求的是自己的mac位址,則向客戶端傳送 rarp reply,回送自己的ip位址。應我使用的地方,一台機器的ip位址每次dhcp以後都會變。所以該程式還是有一些用處。

注意:本程式只為演示packet socket的工作原理,所以沒有進行任何的錯誤處理,並假設工作的機器上只有ethernet介面。但是本程式有個缺點,就是兩個程式工作在同一臺機器上的時候,server無法接收到client的rarp request。請知道的朋友賜教,謝謝!

//file name : rarp_server.cpp

extern "c"

#include

struct arpmsg ;

#define mac_bcast_addr  (uint8_t *) "\xff\xff\xff\xff\xff\xff"

#define opt_code 0

#define opt_len 1

#define opt_data 2

struct inte***ce_info

;struct inte***ce_info if_info[10];

int eth_num = 0;

void print_mac(unsigned char * mac_addr)

printf("\n");

}void print_ip(unsigned char * ip_addr)

printf("\n");

}int get_iface_index(int fd, const char* inte***ce_name)

return ifr.ifr_ifindex;

}int get_inte***ces()

while(1)

else

else  }

len += 2*sizeof(struct ifreq);

free(pbuff);      

}inte***ce_num = last_len / sizeof(struct ifreq);

for (int i =0; i < inte***ce_num; ++i)

if (ioctl(sock, siocgifhwaddr, &ifreq1) < 0)

memcpy(if_info[eth_num].mac, ifreq1.ifr_hwaddr.sa_data, 6);

strcpy(if_info[eth_num].ifname, ifreq1.ifr_name);

psockaddr_in = (struct sockaddr_in*)&inte***ce_conf.ifc_req[i].ifr_addr;

memcpy(if_info[eth_num].ip, &(psockaddr_in->sin_addr.s_addr), 4);

printf("inte***ce name: %s", if_info[eth_num].ifname);

printf(" ip address: ");

print_ip(if_info[eth_num].ip);

printf(" mac address:");

print_mac(if_info[eth_num].mac);

eth_num++;

}free(pbuff);

close(sock);

}int equal_mac(unsigned char* mac1, unsigned char* mac2)

return 1;

}int main()

if (setsockopt(s, sol_socket, so_broadcast, &optval, sizeof(optval)) == -1)

{printf("could not setsocketopt on raw socket\n");

Linux下ZendOptimizer的安裝與配置

內容 在裝的好的red hat linux 9 apache 2.0.55 mysql 5.1.6 php 5.1.2後,接下來就是安裝linux下的php加速器zendoptimizer 2.6.2了。自己編譯 php 後,zend optimizer 2.6.2 需要自己設定一下,請參照以下步驟...

Linux下的命令

管理員 普通使用者 pwd 顯示當前檔案全路徑 date 顯示系統當前日期和時間 who 顯示當前已登入的所有使用者名稱 cal 顯示日曆 uname r m,i,v 顯示當前系統作業系統資訊 wc l 行數,w字數,c位元組數 統計字數 clear 清屏 檔案操作touch 新建檔案mkdir 新...

linux 下 奇怪的

最近在做乙個從hp ux移行到linux 上面的專案,遇到乙個命令 hp ux date y m d h m s read sys date sys time dev null 2 1 但是這個命令在linux 下,就達不到預期的結果 之後問了高手,才得到解決辦法 linux read sys da...