diff options
| author | Mosder <xmosder12@gmail.com> | 2026-07-06 10:06:10 +0200 |
|---|---|---|
| committer | Mosder <xmosder12@gmail.com> | 2026-07-06 10:06:10 +0200 |
| commit | f57066460f7c914b07a612d037eb5e57f617d5b2 (patch) | |
| tree | 703a7b21c24fa1ab002349a6979da53158d161b2 /analyzer | |
| parent | f1d1feabec428bf9ffc2c786d28ce7cc95725d48 (diff) | |
feat: added basic structures for fight results parsing and base functionallity of finding only the necessary data. Still need to do tcp stream reassembly and the actual parsing of the data.
Diffstat (limited to 'analyzer')
| -rw-r--r-- | analyzer/analyzer.c | 16 | ||||
| -rw-r--r-- | analyzer/parser/fight_results.c | 18 | ||||
| -rw-r--r-- | analyzer/parser/fight_results.h | 102 | ||||
| -rw-r--r-- | analyzer/parser/parser.c | 15 | ||||
| -rw-r--r-- | analyzer/parser/parser.h | 21 | ||||
| -rw-r--r-- | analyzer/utils/pcap.c | 5 | ||||
| -rw-r--r-- | analyzer/utils/pcap.h | 3 |
7 files changed, 168 insertions, 12 deletions
diff --git a/analyzer/analyzer.c b/analyzer/analyzer.c index 7790f41..acbd5de 100644 --- a/analyzer/analyzer.c +++ b/analyzer/analyzer.c @@ -1,7 +1,6 @@ #include "analyzer.h" -#include <unistd.h> - +#include "parser/parser.h" #include "utils/pcap.h" void analyze_file(char *path) { @@ -22,14 +21,11 @@ void analyze_file(char *path) { // read packets from the file while (pcap_next_ex(handle, &packet_data, &packet) == 1) { int payload_len; - payload = get_payload_from_packet(packet, packet_data, &payload_len); - if (payload_len > 0) { - printf("\n----------------\n"); - printf("Payload length: %d\n", payload_len); - printf("Payload:\n"); - fflush(stdout); - write(STDOUT_FILENO, payload, payload_len); - } + uint32_t tcp_seq; + payload = get_payload_from_packet(packet, packet_data, &payload_len, &tcp_seq); + // TODO: Stream reassembly using TCP sequence number + int parsed_len; + parse_stream((char *)payload, payload_len, &parsed_len); } pcap_close(handle); diff --git a/analyzer/parser/fight_results.c b/analyzer/parser/fight_results.c new file mode 100644 index 0000000..c6ad7cc --- /dev/null +++ b/analyzer/parser/fight_results.c @@ -0,0 +1,18 @@ +#include "fight_results.h" + +#include <stdio.h> +#include <string.h> + +char *find_fight_results(char *stream, int stream_len, int *length) { + char *start = memmem(stream, stream_len, FIGHT_RESULTS_START, strlen(FIGHT_RESULTS_START)); + char *end = memmem(stream, stream_len, FIGHT_RESULTS_END, strlen(FIGHT_RESULTS_END)); + *length = start != NULL && end != NULL ? end - start + strlen(FIGHT_RESULTS_END) : -1; + return start; +} + +FightResults parse_fight_results(char *data, int length) { + // TODO: actually parse that data + printf("len=%d\n%.*s\n----------------\n", length, length, data); + FightResults tmp; + return tmp; +} diff --git a/analyzer/parser/fight_results.h b/analyzer/parser/fight_results.h new file mode 100644 index 0000000..270aba8 --- /dev/null +++ b/analyzer/parser/fight_results.h @@ -0,0 +1,102 @@ +// parser/fight_results.h +// utilities for parsing the fight results data + +// Payload structure: +// FIGHT_RESULTS_START EntityResults (SEPARATOR_ENTITY EntityResults)* FIGHT_RESULTS_END +// +// EntityResults structure: +// field (SEPARATOR_RESULT field)* +// fields are defined in order in the EntityResults struct + +#define FIGHT_RESULTS_START "3;19;" +#define FIGHT_RESULTS_END "[--];" +#define SEPARATOR_ENTITY "[--]" +#define SEPARATOR_RESULT "&" + +typedef struct { + int team; // friend or enemy + char *name; + int exp; + float field4; + int gold; + float field6; + char *field7; + char *gear; // rares, sets, syngs, orbs + int field9; + char *items; // regular items + int field11; + int field12; + float field13; + float field14; // some multiplier most likely exp/gold/psycho/something else idk + float field15; + int level; + double field17; + float field18; + int field19; + int field20; + float field21; + float field22; + int field23; + int field24; + int psycho; + char *drifs; + int splinters; + int field28; + char *field29; + int field30; + int field31; // possibly information who is the player - 1 for current player, 0 for others (need to double check) + int field32; + int field33; + char *field34; + char *saturation; +} EntityResults; + +// values of field "team" +#define TEAM_FRIEND 1 +#define TEAM_ENEMY 2 + +// fight results data for friendly +typedef struct { + char *name; + int exp; + int gold; + char *gear; + char *items; + int level; + int psycho; + char *drifs; + int splinters; + char *saturation_type; + int saturation; +} FriendlyResults; + +// fight results data for enemy +typedef struct { + char *name; + int level; +} EnemyResults; + +// entire fight resutls +typedef struct { + int num_friendly; + FriendlyResults *friendly_results; + int num_enemy; + EnemyResults *enemy_results; +} FightResults; + +// find the first fight results data in stream +// params: +// - stream - stream to find the fight results in +// - stream_len - length of the stream +// - length - length of the fight results data or -1 if there's no end yet +// returns: +// pointer to the beggining of fight results data or NULL if there's none +extern char *find_fight_results(char *stream, int stream_len, int *length); + +// parse given fight results +// params: +// - data - fight results data to parse +// - length - length of fight results data +// returns: +// FightResults struct containing parsed data +extern FightResults parse_fight_results(char *data, int length); diff --git a/analyzer/parser/parser.c b/analyzer/parser/parser.c new file mode 100644 index 0000000..b551d8e --- /dev/null +++ b/analyzer/parser/parser.c @@ -0,0 +1,15 @@ +#include "parser.h" + +#include <stdlib.h> + +ParsedData *parse_stream(char *stream, int stream_len, int *parsed_len) { + // TODO: Need to do parsing of the entire thing (loop) and return all of the parsed data + if (stream_len > 0) { + int length; + char *start = find_fight_results(stream, stream_len, &length); + if (start != NULL) { + parse_fight_results(start, length); + } + } + return NULL; +} diff --git a/analyzer/parser/parser.h b/analyzer/parser/parser.h new file mode 100644 index 0000000..18b4b83 --- /dev/null +++ b/analyzer/parser/parser.h @@ -0,0 +1,21 @@ +// parser/parser.h +// main parser file + +#include "fight_results.h" + +// "generic" type for parsed data +typedef struct { + enum { FIGHT_RESULTS } data_type; + union { + FightResults fight_results; + } data; +} ParsedData; + +// parse a stream of TCP data +// params: +// - stream - the stream to parse +// - stream_len - length of the stream to parse +// - parsed_len - pointer to inform how much of the stream was parsed (not all if e.g. start of data is there, but the end isn't yet) +// returns: +// pointer to the array of parsed data +extern ParsedData *parse_stream(char *stream, int stream_len, int *parsed_len); diff --git a/analyzer/utils/pcap.c b/analyzer/utils/pcap.c index cdefba7..5e9b611 100644 --- a/analyzer/utils/pcap.c +++ b/analyzer/utils/pcap.c @@ -4,7 +4,7 @@ #include <netinet/ip.h> #include <netinet/tcp.h> -const unsigned char *get_payload_from_packet(const unsigned char *packet, const struct pcap_pkthdr *packet_data, int *payload_len) { +const unsigned char *get_payload_from_packet(const unsigned char *packet, const struct pcap_pkthdr *packet_data, int *payload_len, uint32_t *tcp_seq) { // get Ethernet header const struct ether_header *eth_header = (const struct ether_header *)packet; int eth_header_len = sizeof(struct ether_header); @@ -29,6 +29,9 @@ const unsigned char *get_payload_from_packet(const unsigned char *packet, const const struct tcphdr *tcp_header = (const struct tcphdr *)(packet + eth_header_len + ip_header_len); int tcp_header_len = tcp_header->th_off * 4; + // get TCP sequence number + *tcp_seq = ntohl(tcp_header->seq); + // get payload int total_header_len = eth_header_len + ip_header_len + tcp_header_len; *payload_len = packet_data->caplen - total_header_len; diff --git a/analyzer/utils/pcap.h b/analyzer/utils/pcap.h index d31b961..16da7cd 100644 --- a/analyzer/utils/pcap.h +++ b/analyzer/utils/pcap.h @@ -8,6 +8,7 @@ // - packet - captured packet // - packet_data - metadata about packet // - payload_len - pointer to save the payload length to or -1 if not a correct packet +// - tcp_seq - pointer to save the TCP sequence number // returns: // pointer to the payload or NULL if not a correct packet -extern const unsigned char *get_payload_from_packet(const unsigned char *packet, const struct pcap_pkthdr *packet_data, int *payload_len); +extern const unsigned char *get_payload_from_packet(const unsigned char *packet, const struct pcap_pkthdr *packet_data, int *payload_len, uint32_t *tcp_seq); |
