简体   繁体   中英

Parsing a binary packet (from C) in Go

Im writing a go application that listens for UDP packets over a network and parses them.

the udp packets are written in C and the struct definition (according to their docs) is something like the below. (Please understand that new to C and networking in general)

typedef struct foo 
{
  int code;
  char seg[10];
  char sym[25];
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

A sample network packet is something like the below

[233 3 0 0 99 100 101 95 102 111 0 0 0 0 55 52 51 57 0 69 69 68 49 48 50 48 74 65 78 50 48 50 49 0 0 58 254 127 0 0 1 0 166 58 254 127 0 0 255 255 255 255 255 255 255 255 32 232 141 0 0 0 0 0 0 135 166 58 254 127 0 0 ... etc]

in short, im having trouble getting the right values after the sym field.

i read up a bit about struct alignment in C and guessing that im ignoring the padded values. But im a bit confused as to where the padding occurs

is it this

typedef struct foo 
{
  int code;
  char seg[10];
  **char pad[6];**
  char sym[25];
  **char pad[7];**
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

ie padding is added after each char field

or is it more like this

typedef struct foo 
{
  int code;
  char seg[10];
  char sym[25];
  **char pad[1];**
  short type;
  long amtToday;
  long price;
  ...etc
} foo;

the problem is that there is no way for me to determine if either of these are right at my end. I need to parse the entire struct before confirming - but unable to do so because of the padding issue

or am i heading in the wrong direction parsing this packet?

The best way to convince yourself of how it works is probably to write C-code that computes the offsets:

#include <stdio.h>

typedef struct foo
{
    int code;
    char seg[10];
    char sym[25];
    short type;
    long amtToday;
    long price;
} foo;

int main() {
    // What are the memory offsets between individual struct members?
    foo x;
    printf(
        "code: %ld, seg: %ld, sym: %ld, type: %ld, amtToday: %ld, price: %ld\n",
        (long)&x.code - (long)&x,
        (long)&x.seg - (long)&x,
        (long)&x.sym - (long)&x,
        (long)&x.type - (long)&x,
        (long)&x.amtToday - (long)&x,
        (long)&x.price - (long)&x
    );

    // How much space does the struct take up if we create an array for it?
    foo y[2];
    printf("offset: %ld\n", (long)&y[1] - (long)&y[0]);
    return 0;
}

Output:

code: 0, seg: 4, sym: 14, type: 40, amtToday: 48, price: 56
offset: 64

The offsets can depend on architecture and the compiler being used. If you are able to edit the C-program, adding explicit padding to the struct might be the best way to guarantee the same offsets on 32-bit and 64-bit systems.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM