數(shù)據(jù)鏈路層主要的功能
- 把網(wǎng)絡(luò)層的包封裝成幀
- 對(duì)幀的校驗(yàn)和確認(rèn)
- 流量的控制
數(shù)據(jù)鏈路層生成以太網(wǎng)幀,以太網(wǎng)幀的主要格式如下。
太網(wǎng)幀的傳輸大小是由傳輸媒介決定的,數(shù)據(jù)幀的大小是64—1518。幀頭14個(gè)字節(jié),分別是目標(biāo)MAC地址
(6個(gè)字節(jié))+源MAC地址(6個(gè)字節(jié))+協(xié)議類(lèi)型(2個(gè)字節(jié)),幀尾是32位的CRC冗余校驗(yàn)。對(duì)于兩個(gè)字
節(jié)協(xié)議字段,0×0800主要用于IP協(xié)議,還有一些其他的網(wǎng)絡(luò)協(xié)議,比如Novell IPX等。
這里先介紹以太網(wǎng)幀頭格式,用libcap抓出來(lái)的包最后的CRC冗余校驗(yàn)已經(jīng)在物理網(wǎng)卡上完成。下面是代碼
#include <pcap.h> #include <stdio.h> #include <stdlib.h> #include <string.h> #include <sys/socket.h> #include <arpa/inet.h> #include <net/ethernet.h> #include <netinet/ip_icmp.h> //Provides declarations for icmp header #include <netinet/udp.h> //Provides declarations for udp header #include <netinet/tcp.h> //Provides declarations for tcp header #include <netinet/ip.h> //Provides declarations for ip header #define BUFFER_SIZE 2048 #define HIGH4(a) (((a&0xf0))>>4) #define LOW4(a) (a&0x0f) int size ; void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer); void print_mac(const u_char *packet_buffer); void mac_to_str(char *szMac, unsigned char mac[6]); int main(int argc,char *argv[]) { pcap_if_t *alldevsp , *device; pcap_t *handle; //Handle of the device that shall be sniffed char errbuf[100] , *devname , devs[100][100]; int count = 1 , n; //First get the list of available devices printf("Finding available devices ... "); if( pcap_findalldevs( &alldevsp , errbuf) ) { printf("Error finding devices : %s" , errbuf); exit(1); } printf("Done"); //Print the available devices printf("\nAvailable Devices are :\n"); for(device = alldevsp ; device != NULL ; device = device->next) { printf("%d. %s - %s\n" , count , device->name , device->description); if(device->name != NULL) { strcpy(devs[count] , device->name); } count++; } //Ask user which device to sniff printf("Enter the number of the device you want to sniff : "); scanf("%d" , &n); devname = devs[n]; //Open the device for sniffing printf("Opening device %s for sniffing ... " , devname); handle = pcap_open_live(devname , 65536 , 1 , 0 , errbuf); if (handle == NULL) { fprintf(stderr, "Couldn't open device %s : %s\n" , devname , errbuf); exit(1); } printf("Done\n"); //Put the device in sniff loop pcap_loop(handle , -1 , process_packet , NULL); return 0; } void process_packet(u_char *args, const struct pcap_pkthdr *header, const u_char *buffer) { size = header->len; print_mac(buffer); } void print_mac(const u_char *packet_buffer) { struct ethhdr *ethernet_header = NULL; //ether header char sour_mac[40] = {'\0'}; //<linux/if_ether.h> char des_mac[40] = {'\0'}; //#define ETH_ALEN 6 ethernet_header = (struct ethhdr *)packet_buffer; mac_to_str(sour_mac,ethernet_header->h_source); mac_to_str(des_mac,ethernet_header->h_dest); printf("length of ethernet_head : %d \n",sizeof(struct ethhdr)); printf("des_MAC : %s\n",des_mac); printf("sour_MAC : %s\n",sour_mac); printf("Protocal : %x\n",ntohs(ethernet_header->h_proto)); } //MAC地址翻譯 void mac_to_str(char *szMac, unsigned char mac[6]) { sprintf(szMac, "%X%X:%X%X:%X%X:%X%X:%X%X:%X%X" , HIGH4(mac[0]), LOW4(mac[0]) , HIGH4(mac[1]), LOW4(mac[1]) , HIGH4(mac[2]), LOW4(mac[2]) , HIGH4(mac[3]), LOW4(mac[3]) , HIGH4(mac[4]), LOW4(mac[4]) , HIGH4(mac[5]), LOW4(mac[5]) ); }
$ gcc get_mac.c -o get_mac -lpcap
更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主
微信掃碼或搜索:z360901061

微信掃一掃加我為好友
QQ號(hào)聯(lián)系: 360901061
您的支持是博主寫(xiě)作最大的動(dòng)力,如果您喜歡我的文章,感覺(jué)我的文章對(duì)您有幫助,請(qǐng)用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長(zhǎng)非常感激您!手機(jī)微信長(zhǎng)按不能支付解決辦法:請(qǐng)將微信支付二維碼保存到相冊(cè),切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。
【本文對(duì)您有幫助就好】元
