Вы должны проанализировать заголовок пакета, чтобы узнать, сколько данных нужно прочитать из сокета. сначала используйте кольцевой буфер (круговой!), например, BSD sys/queue.h
, чтобы упорядочить полученные данные из потока.
В приведенном ниже коде показано, как извлечь header_length
, total_length
, адрес источника и назначения пакета IPv4 на уровне 3. См. Схема пакета IPv4 , чтобы понять смещения:
typedef struct {
unsigned char version;
unsigned char header_length;
unsigned short total_length;
struct in_addr src;
struct in_addr dst;
} Packet;
int rb_packet_write_out(RingBuffer *b, int fd, int count) {
int i;
for (i = 0; i < count; i++) {
if (b->level < 20) {
return i;
}
Packet p;
unsigned char *start = b->blob + b->read_cursor;
unsigned char b1 = start[0];
p.version = b1 >> 4;
p.header_length = b1 & 0xf;
p.total_length = bigendian_deserialize_uint16(start + 2);
if (b->level < p.total_length) {
return i;
}
memcpy(&(p.src), start + 12, 4);
memcpy(&(p.dst), start + 16, 4);
char s[5], d[5];
inet_ntop(AF_INET, &(p.src), s, INET_ADDRSTRLEN);
inet_ntop(AF_INET, &(p.dst), d, INET_ADDRSTRLEN);
L_DEBUG("Packet: v%u %s -> %s (%u)", p.version, s, d, p.total_length);
}
return i;
}