Linux ARP請求組包工具 C語言socket

2021-10-19 12:38:16 字數 4227 閱讀 9893

本文是將linux socket傳送arp請求包 c語言中的功能模組進一步編寫成為了工具

使得可以修改arp請求包中的源ip位址、目標ip位址以及源mac位址

測試平台是kali

程式有兩種引數輸入模式,一種是包含源ip、目標ip、源mac以及網絡卡裝置名;另一種省略源amc,即預設使用網絡卡真實mac位址。

#include #include #include #include #include #include #include #include #include #include #include #define buffer_len 60   //arp請求包大小為60b,,抓包時會抓到一些42b的包,這是抓包軟體沒有顯示18b的padding欄位,padding全0填充在包的末尾

/*arp包結構*/

/*字段順序不可更改,發包時是直接將buffer發出*/

struct arp_head

;int main(int argc, char* ar**)

/*解析輸入的target_ip*/

num_str = strtok(ar**[2],".");

num = atoi(num_str);

arp_req->target_ip[0] = num;

for(int i=1;i<4;i++)

/*解析輸入的mac位址*/

if(argc == 5)

}/*如字串中a1,二進位制為0000 1010 0000 0001,合併到乙個位元組中,為1010 0001(0xa1)*/

unsigned char num_char_byte = ((num_char[0]<<4)&0xf0)+num_char[1];

arp_req->sender_mac[0] = num_char_byte;

eth_req->h_source[0] = num_char_byte;

sock_addr.sll_addr[0] = num_char_byte;

/*重複上述過程*/

for(int i=1;i<6;i++)

}

unsigned char num_char_byte = ((num_char[0]<<4)&0xf0)+num_char[1];

arp_req->sender_mac[i] = num_char_byte;

eth_req->h_source[i] = num_char_byte;

sock_addr.sll_addr[i] = num_char_byte; }}

/*解析網絡卡名*/

/*網絡卡名是輸入的最後乙個引數*/

strcpy(dev_name, ar**[argc-1]);

}/*輸入引數指引*/

else

//建立socket

/***int socket(int __domain, int __type, int __protocol)

*** __domain

* pf_packet指示為二層協議簇

* 使用af_packet也可,socket.h中有#define af_packet pf_packet

*** __type

* 使用pf_packet的後,__type只能選擇sock_raw或者sock_dgram

* 其中sock_raw可以自己構造幀頭,sock_dgram不行

* 幀頭使用sockaddr_ll結構體構建,這個結構體在if_packet.h中

* 有一些資料這裡選擇的是sock_packet,這個型別目前已經被建議棄用

*** __protocol

* eth_p_arp意味著我們僅僅接受arp型別

* 如果是eth_p_all就意味著我們接受所有型別幀

* 更多選項參看if_ether.h中定義

*/int sock_fd = socket(af_packet, sock_raw, htons(eth_p_arp));

if(sock_fd == -1)

/**獲取網絡卡等需要的資訊

* ifreq結構體可以用於設定或者獲取網絡卡等相關資訊,定義在if.h中

* 配合ioctl()一起使用

* ioctl()的具體引數用法和系統實現相關,不是通用的,具體參見ioctls.h

* 以下獲取的資訊都會儲存在ifreq不同字段之中

*/ struct ifreq ifr;

/*根據網絡卡裝置名獲取index*/

printf("選擇網絡卡為:%s\n",dev_name);

strcpy(ifr.ifr_name, dev_name);

if(ioctl(sock_fd, siocgifindex, &ifr) == -1)

int ifindex = ifr.ifr_ifindex;

printf("網絡卡索引為:%d\n",ifindex);

/*獲取網絡卡裝置mac位址*/

if(ioctl(sock_fd, siocgifhwaddr, &ifr) == -1)

/*將mac位址寫入所需結構*/

for(int i=0;i<6;i++)

}/*列印mac位址*/

eth_req->h_source[0],

eth_req->h_source[1],

eth_req->h_source[2],

eth_req->h_source[3],

eth_req->h_source[4],

eth_req->h_source[5]);

/*列印sender_ip*/

arp_req->sender_ip[0],

arp_req->sender_ip[1],

arp_req->sender_ip[2],

arp_req->sender_ip[3]);

/*列印target_ip*/

arp_req->target_ip[0],

arp_req->target_ip[1],

arp_req->target_ip[2],

arp_req->target_ip[3]);

/*完善sockaddr_ll結構體*/

/*注釋掉的為非必要*/

sock_addr.sll_family = pf_packet;

// sock_addr.sll_protocol = htons(eth_p_arp);

sock_addr.sll_ifindex = ifindex;

// sock_addr.sll_hatype = htons(arphrd_ether);

// sock_addr.sll_halen = eth_alen;

/*完善乙太網幀頭*/

eth_req->h_proto = htons(eth_p_arp);

/*完善arp包頭*/

arp_req->hardware_type = htons(0x01);

arp_req->protocol_type = htons(eth_p_ip);

arp_req->hardware_size = eth_alen;

arp_req->protocol_size = 0x04;

arp_req->opcode = htons(arpop_request);

/*傳送arp請求*/

if(sendto(sock_fd, buffer, 60, 0, (struct sockaddr*)&sock_addr, sizeof(sock_addr)) == -1)

printf("傳送arp請求包:");

for(int i=0;i<60;i++)

close(sock_fd);

return 0;

}

用抓包工具Fidder檢視請求資料

有的時候做開發會遇到需要檢視請求引數和返回的資料是否有問題的情景,但是debug來看又會很麻煩,前幾天在網上查到了乙個神器就是fidder 在這裡記錄一下使用方法和設定 2.設定fiddler 開啟fiddler,tools fiddler options 配置完後記得要重啟fiddler 選中 d...

charles 批量重複請求 重複發包工具

本文參考 charles 批量請求 重 包工具 repeat charles 讓你選擇乙個請求並重複,在測試後端介面的時候非常有用 charles將請求重新傳送到伺服器,並將響應顯示為新請求。如果您進行後端更改並希望測試它們,用了charles後,你就沒必要在瀏覽器 或其他客戶端 中重複該請求,ch...

模仿Wireshark網路抓包工具實現 c

其實叫抓包工具,其實就是抓取流經自己網絡卡的所有ip包,我們能夠按照ip包的協議解析不就行了。實現的核心在這裡 1 建立socket 2 sock socket af inet,sock raw,ipproto ip 3if sock invalid socket 4 8 獲取本機位址 9char ...