2012-03-29 34 views
0

我有一個通過網絡接收數據包的應用程序。我能夠解釋除負載(數據)部分之外的所有字段值。複製通過網絡接收的數據(數據包有效載荷)

考慮數據包結構: src addr | src port | dest addr | dest端口|數據|校驗和

數據包本身存儲爲char *,並且我可以獲取所有值src/des addr,port。但有效載荷部分讓我困惑。我能夠以十六進制格式打印它,但是在char中打印時會得到非ascii值。當我將有效載荷部分複製到一個新的字符串並打印新的字符串時,我什麼也得不到,即它會打印任何東西,其長度爲0.我不會收到任何錯誤或警告。有人能告訴我哪裏出錯了嗎?我想我在這裏錯過了一些東西。

下面是一段代碼:

typedef struct pcap_802_15_4_s{ 
    guint16 fcf; 
    unsigned char seqno; 
    guint16 dpan; 
    guint16 daddr; 
    guint16 saddr; 
    char *payload_data; 
    } pcap_802_15_4_t; 


char *packet = read_serial_packet(src, &len); 


     if (!packet) 
    exit(0); 
     else if (packet[0] != TOS_SERIAL_802_15_4_ID) { 
    printf("bad packet (serial type is %02x, not %02x)\n", packet[0], TOS_SERIAL_802_15_4_ID); 
     } 

     plen = packet[1]; 
     printf("Received packet of length %i: \n", plen); 
     if (plen != len) { 
    printf("Packet format error: read packet length (%hhx) is different than expected from frame (%hhx).\n", plen, len); 
     } 

     struct timeval tv;  
     gettimeofday(&tv, NULL); 


     i = 2; 
     // Read in FCF and i+=2 
     fcf = packet[i+1] << 8 | packet[i]; 
     packet_802_15_4.fcf = fcf; 
     i += 2; 


     { 
    if ((fcf & 0x7) == 0x01) { 
     printf(" Frame type: data\n"); 
    } 
    else if ((fcf & 0x7) == 0x02) { 
     printf(" Frame type: acknowledgement\n"); 
    } 
    else { 
     printf(" Frame type: other\n"); 
    } 

    printf(" Security: %s\n", (fcf & (1 << 3)) ? "enabled":"disabled"); 
    printf(" Frame pending: %s\n", (fcf & (1 << 4)) ? "yes":"no"); 
    printf(" Ack request: %s\n", (fcf & (1 << 5)) ? "yes":"no"); 
    printf(" Intra-PAN: %s\n", (fcf & (1 << 6)) ? "yes":"no"); 
    intraPan = (fcf & (1 << 6)); 
     } 


     { 
    unsigned char seqno = packet[i++]; 
    packet_802_15_4.seqno = seqno; 
    printf(" Sequence number: 0x%hhx\n", seqno); 
    printf(" Sequence number(dump): 0x%hhx\n", packet_802_15_4.seqno); 

     } 

     { 
    char addrLen = (fcf >> 10) & 0x3; 
    short saddr = 0; 
    long long laddr = 0; 

    // 16- and 64-bit destinations have a PAN ID 
    if (addrLen == 2 || addrLen == 3) { 
     short destPan = packet[i++] << 8 | packet[i++]; 
     packet_802_15_4.dpan = destPan; 
     printf(" Destination PAN: 0x%02hx\n", destPan); 
     printf(" Destination PAN (dump): 0x%02hx\n", packet_802_15_4.dpan); 
    } 

    switch (addrLen) { 
    case 0: 
     printf(" Destination address: none\n"); 
     break; 
    case 1: 
     printf(" Destination address: invalid? (0x01)\n"); 
     break; 
    case 2: 
     saddr = (packet[i] << 8 | packet[i+1]); 
     i += 2; 
     packet_802_15_4.daddr = saddr; 
     printf(" Destination address: 0x%04hx\n", saddr); 
     printf(" case 2: Destination address(dump): 0x%04hx\n", packet_802_15_4.daddr); 
     break; 
    case 3: { 
     int j; 
     for (j = 0; j < 8; j++) { 
     laddr = laddr << 8; 
     laddr |= packet[i++]; 
     } 
     packet_802_15_4.daddr = saddr; 
     printf(" Destination address: 0x%016llx\n", laddr); 
     printf(" case 3: Destination address(dump): 0x%016llx\n", (long long unsigned int)packet_802_15_4.daddr); 
     break; 
    } 
    default: 
     printf(" Destination address: parse serror\n"); 
    } 
     } 


     { 
    char addrLen = (fcf >> 14) & 0x3; 
    short saddr = 0; 
    long long laddr = 0; 

    if (!intraPan) { // Intra-PAN packet 
     short srcPan = packet[i] << 8 | packet[i+1]; 
     //packet_802_15_4.span = srcPan; 
     i += 2; 
     printf(" Source PAN: 0x%02hx\n", srcPan); 
    } 

    switch (addrLen) { 
    case 0: 
     printf(" Source address: none\n"); 
     break; 
    case 1: 
     printf(" Source address: invalid? (0x01)\n"); 
     break; 
    case 2: 
     saddr = (packet[i] << 8 | packet[i + 1]); 
     packet_802_15_4.saddr = saddr; 
     i += 2; 
     printf(" case(2): Source address: 0x%04hx\n", saddr); 
     break; 
    case 3: { 
     int j; 
     for (j = 0; j < 8; j++) { 
     laddr = laddr << 8; 
     laddr |= packet[i++]; 
     } 
     printf(" case(3): Source address: 0x%016llx\n", laddr); 
     packet_802_15_4.saddr = saddr; 
     break; 
    } 
    default: 
     printf(" Source address: parse serror\n"); 
    } 
     } 

     if (iframes) { 
    printf(" I-Frame: %s\n", (packet[i++] == 0x3f)? "yes":"no"); 
     } 

     printf(" AM type: 0x%02hhx\n", packet[i++]); 

     if (i >= plen) { 
    printf("Packet format error: read packet is shorter than expected.\n"); 
     } 
     else { 
     int j=0; 
    packet_802_15_4.payload_data = (char *)malloc(sizeof(char) * (plen - i)); 
    for (; i < plen; i++) { 
     printf("Payload byte %d: 0x%02hhx \n",i,packet[i]); 
     printf("Payload byte %d: %c \n",i,packet[i]); 
     packet_802_15_4.payload_data[j] = (char) packet[i]; 
     j++; 
    } 

有效載荷的十六進制輸出: 爲0x00 0×01 0x10的 0xdd

+0

聽起來就像你試圖把有效負載看作一個字符串,當它可能是二進制數據。你的有效載荷的十六進制版本是什麼樣的? – John3136 2012-03-29 03:21:05

+0

以十六進制表示的有效負載:0x00 0x01 0x10 0xdd – broun 2012-03-29 03:25:23

+0

您認爲有效負載是什麼? – John3136 2012-03-29 04:07:21

回答

0

1)如果你有一個Wireshark的,捕獲多個數據包,並檢查有效載荷表示。如果Wireshark正確顯示你的有效載荷,那麼代碼的接收部分必須有問題。

2)你確定沒有任何IP頭或TCP頭嗎?你在傳輸原始以太網嗎?

3)你確定有效載荷只是字符嗎?

+0

這不是一個IP數據包。這是IEEE 802.15.4和數據包結構是一個粗略的。我改變了一些領域,以保持簡單。 – broun 2012-03-29 03:24:01

+0

你可以有一個場景,你總是傳遞相同的字符串+全0填充?所以,也許如果你在解析數據包時有錯誤,你可以通過匹配ascii來解決索引+偏移問題?假設你正在發送所有字符'AAAAA'+零填充,那麼你必須看到0x41 0x41 0x41 0x41 .... – tartar 2012-03-29 03:30:35

+0

此外,Wireshark沒有剖析TinyOS 802.15.4幀中的Am抽象層。所以無法檢查它。 – broun 2012-03-29 03:30:57

相關問題