diff --git a/sim/sim.py b/sim/sim.py index d171d07..661ecb3 100755 --- a/sim/sim.py +++ b/sim/sim.py @@ -1,16 +1,17 @@ #!/usr/bin/env python3 +import sys import socket import os from time import sleep DEST = ("127.0.0.1", 4200) -FILE = "pflog.txt" +FNAME = 1 -def main(): - with open(os.path.join(os.path.dirname(__file__), FILE), "r") as f: +def main(fname): + with open(os.path.join(os.path.dirname(__file__), fname), "r") as f: lines = [line.rstrip().encode("UTF-8") for line in f] sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) while True: @@ -18,5 +19,6 @@ def main(): sock.sendto(line, DEST) sleep(1) + if __name__ == '__main__': - main() + main(sys.argv[FNAME]) diff --git a/src/main.c b/src/main.c index 734d02c..c8455a6 100644 --- a/src/main.c +++ b/src/main.c @@ -99,7 +99,7 @@ int main(int argc, char** argv) { if(sysmsg_parse(&result, msg) != 0) { printf("Failed to parse message: %s", msg); } else { - printf("syslog message is valid:\n\tpriority: %d\n\tapplication: %s\n\tDate: %s %d %02d:%02d:%02d\n\t\n", + printf("syslog message is valid:\n\tpriority: %d\n\tapplication: %s\n\tDate: %s %d %02d:%02d:%02d\n", result.priority, result.application, result.date.month, @@ -112,11 +112,9 @@ int main(int argc, char** argv) { pf_data fwdata = {0}; //memset(&fwdata, 0, sizeof(fwdata)); if(pfdata_parse(msg, &fwdata) != 0) { - printf("Failed to parse pfsense data: %s", msg); + printf("Failed to parse pfsense data: %s\n\n", msg); } else { - printf("IP Data:\n\tInterface: %s\n\tIP version: %d\n", - fwdata.iface, - fwdata.ipversion); + pfdata_print(&fwdata); } } } diff --git a/src/pfparser.c b/src/pfparser.c index 3d249bf..e7f0313 100644 --- a/src/pfparser.c +++ b/src/pfparser.c @@ -1,17 +1,15 @@ #include -#include #include #include "pfparser.h" - int pfdata_parse(char* message, pf_data* result) { printf("pfparse: '%s'\n", message); char* token; int field = 0; - /* Parse the first X fields + /* Parse the first 9 fields They are: ,,,,,,,, We only collect rule-number, real-interface, reason, action, direction, ip-version */ while ( (token = strsep(&message, ",")) != NULL) { @@ -53,43 +51,249 @@ int pfdata_parse(char* message, pf_data* result) { } break; } + if(field == 8) { + break; + } field++; } if(result->ipversion == 4) { /*parse ipv4 fields*/ - /* - - TOS, hex as a string field starting with "0x" or empty - - "Explicit Congestion Notification" - or empty, we will ignore - - TTL, int - - packet ID, int (seemingly useless?) - - fragment offset, int (???) - - flags ("none" or some string, each flag is an uppercase(?) character) - - protocol id, int - - protocol name, string - */ + field = 0; + while ( (token = strsep(&message, ",")) != NULL) { + printf("%02d: %s\n", field, token); + switch (field) { + case 0: /*TOS, hex as a string field starting with "0x" or empty*/ + { + char* rnend; + int tos = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->ipv4_data.tos = tos; + } + break; + case 1: /*"Explicit Congestion Notification" - or empty, we will ignore*/ + break; + case 2: /*TTL, int*/ + { + char* rnend; + int ttl = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->ipv4_data.ttl = ttl; + } + break; + case 3: /*packet ID, int (seemingly useless?)*/ + break; + case 4: /*fragment offset, int (???)*/ + break; + case 5: /*flags ("none" or some string, DF or MF - see https://en.wikipedia.org/wiki/IPv4#Flags)*/ + break; + case 6: /*protocol id, int*/ + { + char* rnend; + int proto_id = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->ipv4_data.protocol = proto_id; + } + break; + case 7: /*protocol name, string*/ + break; + } + if(field == 7) { + break; + } + field++; + } } else if(result->ipversion == 6) { /*parse ipv6 fields*/ - /* - - class, hex as a string field starting with "0x" - - flow label, "data" ??? - - hop-limit, int (like ttl) - - protocol name, string - - protocol id, int - */ + field = 0; + while ( (token = strsep(&message, ",")) != NULL) { + printf("%02d: %s\n", field, token); + switch (field) { + case 0: /*class, hex as a string field starting with "0x"*/ + break; + case 1: /*flow label, "data" ???*/ + break; + case 2: /*hop-limit, int (like ttl)*/ + { + char* rnend; + int ttl = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->ipv6_data.hoplimit = ttl; + } + break; + case 3: /*protocol name, string*/ + break; + case 4: /*protocol id, int*/ + { + char* rnend; + int proto_id = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->ipv6_data.protocol = proto_id; + } + break; + } + if(field == 4) { + break; + } + field++; + } } else { return 1; /*unknown ip version*/ } /*Parse */ - /* - - packet length, int - - source addr, string (ipv4 OR ipv6!) - - dest addr, string (ipv4 OR ipv6!) - */ + /*parse ipv6 fields*/ + field = 0; + while ( (token = strsep(&message, ",")) != NULL) { + printf("%02d: %s\n", field, token); + switch (field) { + case 0: /*packet length, int*/ + { + char* rnend; + int pack_len = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->packet_length = pack_len; + } + break; + case 1: /*source addr, string (ipv4 OR ipv6!)*/ + if(strlen(token) > IP_STR_LEN) return 1; /*too long ip string*/ + memcpy(result->src_addr, token, strlen(token)); + break; + case 2: /*dest addr, string (ipv4 OR ipv6!)*/ + if(strlen(token) > IP_STR_LEN) return 1; /*too long ip string*/ + memcpy(result->dest_addr, token, strlen(token)); + break; + } + if(field == 2) { + break; + } + field++; + } - /*Parse optional */ + printf("### remaining: %s\n", message); + /*Parse optional + one of | | | + ICMP and CARP are ignored*/ + if((result->ipversion == 4 && result->ipv4_data.protocol == 6) || + (result->ipversion == 6 && result->ipv6_data.protocol == 6)) {/* tcp */ + /*,,,,,,,,*/ + /*printf("rest: %s\n", message);*/ + /*parse ipv6 fields*/ + field = 0; + while ( (token = strsep(&message, ",")) != NULL) { + printf("%02d: %s\n", field, token); + switch (field) { + case 0: /*src port, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->tcp_data.srcport = num; + } + break; + case 1: /*dest port, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->tcp_data.destport = num; + } + break; + case 2: /*packet length, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->tcp_data.length = num; + } + break; + } + if(field == 8) { + break; + } + field++; + } + } else if((result->ipversion == 4 && result->ipv4_data.protocol == 11) || + (result->ipversion == 6 && result->ipv6_data.protocol == 11)) {/* udp */ + /*,,*/ + field = 0; + while ( (token = strsep(&message, ",")) != NULL) { + printf("%02d: %s\n", field, token); + switch (field) { + case 0: /*src port, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->udp_data.srcport = num; + } + break; + case 1: /*dest port, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->udp_data.destport = num; + } + break; + case 2: /*packet length, int*/ + { + char* rnend; + int num = strtol(token, &rnend, 0); + if(rnend == NULL) return 1; + result->udp_data.length = num; + } + break; + } + if(field == 2) { + break; + } + field++; + } + } else if(result->ipversion == 4 && result->ipv4_data.protocol == 1){/* icmp-v4 */ + + } else if(result->ipversion == 6 && result->ipv6_data.protocol == 58){/* icmp-v6 */ + + } return 0; } + + +void pfdata_print(pf_data* data) { + printf("Action: %s\n", pfhastr[data->action]); + printf("IP Data:\n\tInterface: %s\n\tIP version: %d\n", + data->iface, + data->ipversion); + if(data->ipversion == 4) { + printf("IPV4 Data:\n\tTTL: %d\n\tProtocol ID: %d\n", + data->ipv4_data.ttl, + data->ipv4_data.protocol); + } else if(data->ipversion == 6) { + printf("IPV6 Data:\n\tHop Limit: %d\n\tProtocol ID: %d\n", + data->ipv6_data.hoplimit, + data->ipv6_data.protocol); + } + printf("Endpoints:\n\tsrc: %s\n\tdest: %s\n", + data->src_addr, + data->dest_addr); + + if (data->ipversion == 4) { + if (data->ipv4_data.protocol == 6) { + printf("Protocol: tcp4\n\tsrcport: %d\n\tdestport: %d\n\tsize: %d\n", + data->tcp_data.srcport, data->tcp_data.destport, data->tcp_data.length); + } else if (data->ipv4_data.protocol == 11) { + printf("Protocol: udp4\n\tsrcport: %d\n\tdestport: %d\n\tsize: %d\n", + data->udp_data.srcport, data->udp_data.destport, data->udp_data.length); + } + } else if (data->ipversion == 6) { + if (data->ipv6_data.protocol == 6) { + printf("Protocol: tcp6\n\tsrcport: %d\n\tdestport: %d\n\tsize: %d\n", + data->tcp_data.srcport, data->tcp_data.destport, data->tcp_data.length); + } else if (data->ipv6_data.protocol == 11) { + printf("Protocol: udp6\n\tsrcport: %d\n\tdestport: %d\n\tsize: %d\n", + data->udp_data.srcport, data->udp_data.destport, data->udp_data.length); + } + } +} diff --git a/src/pfparser.h b/src/pfparser.h index d56e582..01c72e9 100644 --- a/src/pfparser.h +++ b/src/pfparser.h @@ -1,3 +1,5 @@ +#include + #define IFACE_LEN 8 @@ -32,14 +34,41 @@ const static char* pfdirstr[] __attribute__ ((unused)) = typedef struct pf_data_ipv4 { - int derp; + int ttl; + int tos; + int protocol; } pf_data_ipv4; typedef struct pf_data_ipv6 { - int derp; - int derp2; + int hoplimit; + int protocol; } pf_data_ipv6; +/*typedef struct ipv4_addr { + u_int32_t addr; +} ipv4_addr; + +typedef struct ipv6_addr { + u_int32_t addr1; + u_int32_t addr2; + u_int32_t addr3; + u_int32_t addr4; +} ipv6_addr;*/ + +typedef struct pf_data_tcp { + int srcport; + int destport; + int length; +} pf_data_tcp; + +typedef struct pf_data_udp { + int srcport; + int destport; + int length; +} pf_data_udp; + +#define IP_STR_LEN 41 /*40 char ipv6 address + null term*/ + typedef struct pf_data { int rulenum; @@ -52,7 +81,24 @@ typedef struct pf_data { pf_data_ipv4 ipv4_data; pf_data_ipv6 ipv6_data; }; + /*union { + ipv4_addr ipv4_src; + ipv6_addr ipv6_src; + }; + union { + ipv4_addr ipv4_dest; + ipv6_addr ipv6_dest; + };*/ + int packet_length; + char src_addr[IP_STR_LEN]; + char dest_addr[IP_STR_LEN]; + union { + pf_data_tcp tcp_data; + pf_data_udp udp_data; + }; } pf_data; int pfdata_parse(char* message, pf_data* result); + +void pfdata_print(pf_data* data);