2011-10-14 35 views
4

我寫的代碼使用PACKET_TX_RING環發送一個UDP包,我不明白這裏所描述的示例代碼: http://wiki.ipxwarzone.com/index.php5?title=Linux_packet_mmap#Kernel_PatchPACKET_MMAP數據偏移

在/ usr/src/linux目錄/文件/網絡/ packet_mmap.txt 說,框架結構是這樣的:

/* 幀結構:

  • 開始。幀必須對齊到TPACKET_ALIGNMENT = 16
  • 結構tpacket_hdr
  • 墊TPACKET_ALIGNMENT = 16
  • 結構sockaddr_ll
  • 峽,選擇爲使得分組數據(START + tp_net)對齊到 TPACKET_ALIGNMENT = 16
  • 開始+ tp_mac:[可選MAC頭]
  • 開始+ tp_net:數據包數據,與TPACKET_ALIGNMENT = 16對齊。
  • 墊。如果數據開始於開始+ tp_net,對準TPACKET_ALIGNMENT = 16

    */

然後爲什麼在示例substracts的sizeof代碼(結構sockaddr_ll)代替求和它,這是行:

/* get data offset */ 
     data_offset = TPACKET_HDRLEN - sizeof(struct sockaddr_ll); 
printf("data offset = %d bytes\n", data_offset); 

計算指針的分組數據後,將數據複製:

// fill data 
    off = ((void *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll)); 
    memcpy(off, pkt, pktlen); 

Tis看起來像是我的數據損壞,套接字地址和可選的mac地址將被要覆蓋的數據傳輸。在我的情況下,如果我使用這個代碼,UDP數據包頭將被覆蓋,這是正確的嗎?

在此先感謝

回答

3

對不起,我有點晚。 我有一個非常相同的問題,不幸的是使用PACKET_TX_RING沒有很好的記錄。但幸運的是,使用鏈接的示例程序很容易。

首先,您需要tshark(或wireshark)和您發佈的鏈接中的packet_mm源。示例源用0到150填充緩衝區,然後直接將其發送到給定設備。使用tshark我們會讀出發送的內容。

在一個殼運行tshark的(攻絲迴環設備):

$ tshark -V -i lo 

和運行packet_mm在另一個殼:

$ packet_mm lo 

退房一個幀:

Frame 1 (150 bytes on wire, 150 bytes captured) 
    Arrival Time: Nov 12, 2011 13:07:02.636424000 
    [Time delta from previous captured frame: 0.000005000 seconds] [Time delta from previous displayed frame: 0.000005000 seconds] 
    [Time since reference or first frame: 337.280499000 seconds] 
    Frame Number: 1001 
    Frame Length: 150 bytes 
    Capture Length: 150 bytes 
    [Frame is marked: False] 
    [Protocols in frame: eth:data] 
Ethernet II, Src: 06:07:08:09:0a:0b (06:07:08:09:0a:0b), Dst: 3com_03:04:05 (00:01:02:03:04:05) 
    Destination: 3com_03:04:05 (00:01:02:03:04:05) 
     Address: 3com_03:04:05 (00:01:02:03:04:05) 
     .... ...0 .... .... .... .... = IG bit: Individual address (unicast) 
     .... ..0. .... .... .... .... = LG bit: Globally unique address (factory default) 
    Source: 06:07:08:09:0a:0b (06:07:08:09:0a:0b) 
     Address: 06:07:08:09:0a:0b (06:07:08:09:0a:0b) 
     .... ...0 .... .... .... .... = IG bit: Individual address (unicast) 
     .... ..1. .... .... .... .... = LG bit: Locally administered address (this is NOT the factory default) 
    Type: Unknown (0x0c0d) 
Data (136 bytes) 

0000 0e 0f 10 11 12 13 14 15 16 17 18 19 1a 1b 1c 1d ................ 
0010 1e 1f 20 21 22 23 24 25 26 27 28 29 2a 2b 2c 2d .. !"#$%&'()*+,- 
0020 2e 2f 30 31 32 33 34 35 36 37 38 39 3a 3b 3c 3d ./:;<= 
0030 3e 3f 40 41 42 43 44 45 46 47 48 49 4a 4b 4c 4d >[email protected] 
0040 4e 4f 50 51 52 53 54 55 56 57 58 59 5a 5b 5c 5d NOPQRSTUVWXYZ[\] 
0050 5e 5f 60 61 62 63 64 65 66 67 68 69 6a 6b 6c 6d ^_`abcdefghijklm 
0060 6e 6f 70 71 72 73 74 75 76 77 78 79 7a 7b 7c 7d nopqrstuvwxyz{|} 
0070 7e 7f 80 81 82 83 84 85 86 87 88 89 8a 8b 8c 8d ~............... 
0080 8e 8f 90 91 92 93 94 95       ........ 
    Data: 0E0F101112131415161718191A1B1C1D1E1F202122232425... 
    [Length: 136] 

的目標MAC地址爲00:01:02:03:04:05和源MAC地址爲06:07:08:09:0a:0b。 和0x0e(14)數據開始(在以太網報頭之後)。

因此,示例程序的數據偏移量是要發送的(以太網)數據包的開始。

所以這確實是正確的方法來填充緩衝區發送(確保PKTLEN是不是比你的幀大小):

// fill data 
off = ((uint8_t *) header) + (TPACKET_HDRLEN - sizeof(struct sockaddr_ll)); 
memcpy(off, pkt, pktlen); 

,沒有數據將被覆蓋。但是你必須自己提供以太網,IP和UDP頭。

編輯: 對於TX_Ring,框架結構似乎是:

  • 開始。幀必須對齊到TPACKET_ALIGNMENT = 16
  • 結構tpacket_hdr(大小= 32個字節)
  • 墊TPACKET_ALIGNMENT = 16(因此有效地填充大小爲0)
  • 分組數據
  • 墊對齊到TPACKET_ALIGNMENT = 16 (所以下一幀是16Bit對齊的)