2010-08-05 81 views
0

我有以下代碼來打開原始套接字並將其發送。在發送功能我有一個顯示我,我的包的長度爲21。然而,當我使用數據包嗅探器查看接收端的數據包,我看到一絲聲明:在Linux中使用原始套接字時,802.3標頭長度始終爲256

  1. 數據包的實際長度60.
  2. (如在802.3首部給出)的長度爲256

這些數字也不是21,並且我與不喜歡的差異的嵌入式設備通信。我谷歌搜索,但我不知道如何使sendto()報告正確的長度。

bool EthernetSocket::_open(const char *ifname) { 
    _sd = socket(AF_PACKET, SOCK_DGRAM, htons(ETH_P_802_2)); 
    _ifname = ifname; 
    _ifidx = Ethernet::GetInterface(ifname); 
    if(_sd < 0) { 
    perror("Failed to open socket"); 
    _bOpened = false; 
    } 
    else { 
    _bOpened = true; 
    } 
    return _bOpened; 
} 


bool EthernetSocket::_send(const Buffer& txbuff, Address& addr) { 
    if(txbuff.Length() == 0) 
    return false; 

    if(_ifidx != -1) 
    addr.SetInterface(_ifidx); 

printf("SEND: Length: %d\n", txbuff.Length()); 
    if(sendto(_sd, txbuff.Data(), txbuff.Length(), 0, (struct sockaddr *) addr.Component(), (socklen_t) addr.Size()) == -1) { 
    perror("Failed broadcast"); 
    return false; 
    } 
    return true; 
} 

編輯:我發現,那場被設置爲sll_protocol場在我sockaddr_ll結構。但爲什麼?將它設置爲htons(ETH_P_802_2),它應該是沒有幫助的。

回答

0

我有一個部分答案。

將sll_protocol設置爲htons(ETH_P_802_3)可以解決問題。我不確定這是爲什麼,因爲ETH_P_802_2和ETH_P_802_3應該表現得基本相同 - 而且我可以找到的所有相關內核源代碼都支持我。

我通過協議爲ETH_P_802_2的recvfrom()接收數據包,因此返回的地址將其sll_protocol字段設置爲ETH_P_802_2。這意味着要回覆,我必須在接收數據後手動將字段設置爲ETH_P_802_3。這是一個可怕的混亂。

這是怎麼回事?