0
我正在嘗試編寫一個接收字節流的函數(包括以太網數據包以及封裝在以太網數據包中的上層協議),並將其發送到網絡上在特定的界面上。在C(Linux)中將原始數據包注入到網絡中
這裏是我的代碼摘要:
// create socket
int s = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
if (s < 0) {
// error handling
}
// set up to just receive/send packets on one interface (stored in the variable iface_name e.g. eth0)
struct ifreq ifr;
bzero(&ifr, sizeof(struct ifreq));
strncpy(ifr.ifr_ifrn.ifrn_name, iface_name, IFNAMSIZ);
if (ioctl(s, SIOCGIFINDEX, &ifr) < 0) {
// error handling
}
// set up socaddr for write
struct sockaddr sa;
sa.sa_family = PF_PACKET;
sa.sa_data = htons(ETH_P_ALL);
// write to wire
// buf has type char* and len has type int
// buf contains ethernet header, followed by payload (e.g. ARP packet or IP packet)
if (sendto(s, buf, len, 0, &sa, sizeof(struct sockaddr)) < 0) {
perror("sendto");
// more error handling
}
我得到的錯誤
sendto: Invalid argument
如何解決這個問題?
我最初的猜測是,這是由sa
論點引起的,因爲所有其他人都是相當標準的,並且沒有太多錯誤。我可以用sockaddr_ll
類型的參數代替它,如this example,但這意味着從buf
中提取標題信息,這看起來有點毫無意義,因爲它已經在那裏,準備好了。一定會有更好的辦法?封裝,解封裝,重新封裝,發送似乎有太多不必要的步驟。我正在爲一些預先存在的代碼編寫底層接口,因此我不能將輸入調整爲不包含數據鏈接層頭。
看看這裏。 http://austinmarton.wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/ –
我認爲這很接近,但我該怎麼辦在sll_addr中填入目標MAC地址?如果可能的話,我想避免必須從我的輸入數據中提取這個數據(因爲數據包已經構建好了,所以我不明白爲什麼我必須將它拆開)。我想我明白如果這是不可能的,但? – Froskoy
Ahem。 http://stackoverflow.com/questions/1519585/how-to-get-mac-address-for-an-interface-in-linux-using-ac-program –