2011-10-14 3 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 는 프레임 구조는이 것을 말한다. 프레임 = 16
  • 구조체 tpacket_hdr
  • 패드 TPACKET_ALIGNMENT 행 = 16
  • 구조체 sockaddr_ll
  • 갭, 즉 패킷 데이터 이동제 (+ tp_net 시작) TPACKET_ALIGNMENT에 정렬 = 16
  • TPACKET_ALIGNMENT 정렬되어야 시작 + 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를 (루프백 디바이스를 태핑) :

$ 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] 

다른 쉘에서

$ tshark -V -i lo 

및 실행 packet_mm 목적지 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를 들어 는 프레임 구조체가 될 것으로 보인다. 프레임 = 16
  • 구조체 tpacket_hdr (크기 = 32 바이트) TPACKET_ALIGNMENT = 16 행
  • 패드 (따라서 효과적으로 패딩 크기 0)
  • 패킷 데이터 TPACKET_ALIGNMENT = 16 정렬
  • 패드 TPACKET_ALIGNMENT 정렬되어야 (따라서 다음 프레임은 16Bit 정렬 됨)