2014-06-21 33 views
1

我知道這個問題必須被問過,但我不能找到一個很好的解決它。如何啓用卸載的原始套接字

我寫在Ubuntu 12.04 C程序使用一個原始套接字發送TCP數據包。計算校驗和非常耗時,所以我試圖將其卸載到我的NIC。

struct sockaddr intfAddr 
rawSock = socket(AF_INET,SOCK_PACKET,htons(3)); //ETH_P_ALL = 3 
if (rawSock == -1) { perror("failed to create raw socket"); exit(-1); } 
memset(&intfAddr, 0, sizeof (struct sockaddr)); 
intfAddr.sa_family = AF_INET; 
strcpy(intfAddrs.sa_data, "eth0"); 
system("ifconfig eth0 promisc); 
//sprintf(cmd, "ethtool -K %s rx off", intfName); system(cmd); 
if (bind(rawSock, (struct sockaddr *)&intfAddr, sizeof(intfAddrs[intf])) == -1) { 
    perror("failed to bind"); exit(-1); 
} 

我發從一臺PC和使用Wireshark的TCP的數據包捕獲的數據包是已連接到PC發送另一臺PC上。 Wireshark可以捕獲所有數據包,但不幸的是TCP校驗和不正確 - 發送PC的NIC沒有執行校驗和計算。如果我設置TCP校驗和爲0的數據包,Wireshark將會看到校驗和爲0的數據包。

由於發送PC上的linux命令「ethtool -k eth0」顯示tx offload已打開,所以這很混亂。

$ ethtool -k eth0 
Offload parameters for eth0: 
rx-checksumming: on 
tx-checksumming: on 
scatter-gather: off 
tcp-segmentation-offload: off 
udp-fragmentation-offload: off 
generic-segmentation-offload: off 
generic-receive-offload: on 
large-receive-offload: off 
rx-vlan-offload: on 
tx-vlan-offload: on 
ntuple-filters: off 
receive-hashing: off 

任何想法?謝謝!

回答

0

爲什麼使用ETH_P_ALL?,嘗試使用htons(8)進行ETH_P_IP,並且代碼中的另一個問題是您正在使用數據包系列,PF用於在設備驅動程序中發送/接收數據OSI第2層),如果你要使用數據包的家庭與RAW_SOCK一起,你需要自己生成每個單頭,所以嘗試創建Socket實例如下:

; IP header would be provided by the kernel 
int s = socket (AF_INET, SOCK_RAW, IPPROTO_TCP); 
; if you wanna use the Packet Family, do the following 
sd = socket(PF_INET, SOCK_RAW, IPPROTO_RAW); 

在這種情況下,你必須提供標題自己和校驗,做一個有關TCP僞頭研製,利用此功能來計算的話

unsigned short csum(unsigned short *buf, int nwords) 
{  // 
     unsigned long sum; 
     for(sum=0; nwords>0; nwords--) 
       sum += *buf++; 
     sum = (sum >> 16) + (sum &0xffff); 
     sum += (sum >> 16); 
     return (unsigned short)(~sum); 
} 

祝你好運:)