2013-07-31 37 views
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中提取標題信息,這看起來有點毫無意義,因爲它已經在那裏,準備好了。一定會有更好的辦法?封裝,解封裝,重新封裝,發送似乎有太多不必要的步驟。我正在爲一些預先存在的代碼編寫底層接口,因此我不能將輸入調整爲不包含數據鏈接層頭。

+0

看看這裏。 http://austinmarton.wordpress.com/2011/09/14/sending-raw-ethernet-packets-from-a-specific-interface-in-c-on-linux/ –

+0

我認爲這很接近,但我該怎麼辦在sll_addr中填入目標MAC地址?如果可能的話,我想避免必須從我的輸入數據中提取這個數據(因爲數據包已經構建好了,所以我不明白爲什麼我必須將它拆開)。我想我明白如果這是不可能的,但? – Froskoy

+0

Ahem。 http://stackoverflow.com/questions/1519585/how-to-get-mac-address-for-an-interface-in-linux-using-ac-program –

回答