You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

171 lines
7.9 KiB

#include "packet_dump.h"
#include "../lib/debug_config.h"
#include <stdio.h>
#include <string.h>
static const char* tcp_flags_to_str(uint8_t flags) {
static char buf[32];
int pos = 0;
buf[0] = '\0';
if (flags & 0x01) { pos += snprintf(buf + pos, sizeof(buf) - pos, "FIN,"); }
if (flags & 0x02) { pos += snprintf(buf + pos, sizeof(buf) - pos, "SYN,"); }
if (flags & 0x04) { pos += snprintf(buf + pos, sizeof(buf) - pos, "RST,"); }
if (flags & 0x08) { pos += snprintf(buf + pos, sizeof(buf) - pos, "PSH,"); }
if (flags & 0x10) { pos += snprintf(buf + pos, sizeof(buf) - pos, "ACK,"); }
if (flags & 0x20) { pos += snprintf(buf + pos, sizeof(buf) - pos, "URG,"); }
if (flags & 0x40) { pos += snprintf(buf + pos, sizeof(buf) - pos, "ECE,"); }
if (flags & 0x80) { pos += snprintf(buf + pos, sizeof(buf) - pos, "CWR,"); }
if (pos > 0 && buf[pos - 1] == ',') {
buf[pos - 1] = '\0';
}
if (buf[0] == '\0') {
return "none";
}
return buf;
}
char* dump_ip_packet_to_buffer(const uint8_t* data, size_t len) {
static char buffer[1024];
buffer[0] = '\0';
if (len < 20) {
snprintf(buffer, sizeof(buffer), "Packet too small: %zd bytes", len);
return buffer;
}
uint8_t version = (data[0] >> 4) & 0x0F;
if (version != 4) {
snprintf(buffer, sizeof(buffer), "Non-IPv4 packet: %zd bytes", len);
return buffer;
}
uint8_t ihl = (data[0] & 0x0F) * 4;
if (len < ihl) {
snprintf(buffer, sizeof(buffer), "Truncated IP header: %zd bytes", len);
return buffer;
}
uint8_t protocol = data[9];
uint32_t src_ip = *(uint32_t*)&data[12];
uint32_t dst_ip = *(uint32_t*)&data[16];
char src_str[16], dst_str[16];
snprintf(src_str, sizeof(src_str), "%u.%u.%u.%u",
(src_ip) & 0xFF, (src_ip >> 8) & 0xFF,
(src_ip >> 16) & 0xFF, (src_ip >> 24) & 0xFF);
snprintf(dst_str, sizeof(dst_str), "%u.%u.%u.%u",
(dst_ip) & 0xFF, (dst_ip >> 8) & 0xFF,
(dst_ip >> 16) & 0xFF, (dst_ip >> 24) & 0xFF);
const char* proto_name = "UNKNOWN";
uint16_t src_port = 0, dst_port = 0;
char proto_info[128] = {'\0'};
int is_special_proto = 0;
if (protocol == 6 && len >= ihl + 20) {
proto_name = "TCP";
src_port = (data[ihl] << 8) | data[ihl + 1];
dst_port = (data[ihl + 2] << 8) | data[ihl + 3];
uint32_t seq_num = ((uint32_t)data[ihl + 4] << 24) |
((uint32_t)data[ihl + 5] << 16) |
((uint32_t)data[ihl + 6] << 8) |
((uint32_t)data[ihl + 7]);
uint32_t ack_num = ((uint32_t)data[ihl + 8] << 24) |
((uint32_t)data[ihl + 9] << 16) |
((uint32_t)data[ihl + 10] << 8) |
((uint32_t)data[ihl + 11]);
uint8_t flags = data[ihl + 13];
uint16_t window = (data[ihl + 14] << 8) | data[ihl + 15];
snprintf(proto_info, sizeof(proto_info), "[%s] seq=%u ack=%u win=%u",
tcp_flags_to_str(flags), seq_num, ack_num, window);
is_special_proto = 1;
} else if (protocol == 17 && len >= ihl + 8) {
proto_name = "UDP";
src_port = (data[ihl] << 8) | data[ihl + 1];
dst_port = (data[ihl + 2] << 8) | data[ihl + 3];
uint16_t udp_len = (data[ihl + 4] << 8) | data[ihl + 5];
snprintf(proto_info, sizeof(proto_info), "len=%u", udp_len);
is_special_proto = 1;
} else if (protocol == 1 && len >= ihl + 8) {
proto_name = "ICMP";
uint8_t icmp_type = data[ihl];
uint16_t icmp_id = (data[ihl + 4] << 8) | data[ihl + 5];
uint16_t icmp_seq = (data[ihl + 6] << 8) | data[ihl + 7];
if (icmp_type == 0) {
snprintf(proto_info, sizeof(proto_info), "echo_reply seq=%u id=%u", icmp_seq, icmp_id);
} else if (icmp_type == 8) {
snprintf(proto_info, sizeof(proto_info), "echo_request seq=%u id=%u", icmp_seq, icmp_id);
} else {
snprintf(proto_info, sizeof(proto_info), "type=%u code=%u", icmp_type, data[ihl + 1]);
}
is_special_proto = 1;
}
if (is_special_proto && proto_info[0] != '\0') {
if (src_port > 0 && dst_port > 0) {
int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) %s",
proto_name, src_str, src_port, dst_str, dst_port, len, proto_info);
if (offset > 0 && offset < (int)sizeof(buffer) - 50) {
snprintf(buffer + offset, sizeof(buffer) - offset, " data: "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x",
data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3],
data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7],
data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11],
data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15],
data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19],
data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23],
data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27],
data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]);
}
} else {
int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s -> %s (%zd bytes) %s",
proto_name, src_str, dst_str, len, proto_info);
if (offset > 0 && offset < (int)sizeof(buffer) - 50) {
snprintf(buffer + offset, sizeof(buffer) - offset, " data: "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x",
data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3],
data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7],
data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11],
data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15],
data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19],
data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23],
data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27],
data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]);
}
}
} else {
int offset = snprintf(buffer, sizeof(buffer), "IPv4 %s %s:%d -> %s:%d (%zd bytes) data: "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x "
"%02x%02x%02x%02x%02x%02x%02x%02x",
proto_name, src_str, src_port, dst_str, dst_port, len,
data[ihl + 0], data[ihl + 1], data[ihl + 2], data[ihl + 3],
data[ihl + 4], data[ihl + 5], data[ihl + 6], data[ihl + 7],
data[ihl + 8], data[ihl + 9], data[ihl + 10], data[ihl + 11],
data[ihl + 12], data[ihl + 13], data[ihl + 14], data[ihl + 15],
data[ihl + 16], data[ihl + 17], data[ihl + 18], data[ihl + 19],
data[ihl + 20], data[ihl + 21], data[ihl + 22], data[ihl + 23],
data[ihl + 24], data[ihl + 25], data[ihl + 26], data[ihl + 27],
data[ihl + 28], data[ihl + 29], data[ihl + 30], data[ihl + 31]);
if (offset > 0 && offset < (int)sizeof(buffer)) {
buffer[offset] = '\0';
}
}
return buffer;
}