fully parse pfsense data
This commit is contained in:
parent
292645a2bc
commit
83c012367d
10
sim/sim.py
10
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])
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
256
src/pfparser.c
256
src/pfparser.c
@ -1,17 +1,15 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#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: <rule-number>,<sub-rule-number>,<anchor>,<tracker>,<real-interface>,<reason>,<action>,<direction>,<ip-version>
|
||||
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 <ip-data>*/
|
||||
/*
|
||||
- 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 <protocol-specific-data>*/
|
||||
printf("### remaining: %s\n", message);
|
||||
/*Parse optional <protocol-specific-data>
|
||||
one of <tcp-data> | <udp-data> | <icmp-data> | <carp-data>
|
||||
ICMP and CARP are ignored*/
|
||||
if((result->ipversion == 4 && result->ipv4_data.protocol == 6) ||
|
||||
(result->ipversion == 6 && result->ipv6_data.protocol == 6)) {/* tcp */
|
||||
/*<source-port>,<destination-port>,<data-length>,<tcp-flags>,<sequence-number>,<ack-number>,<tcp-window>,<urg>,<tcp-options>*/
|
||||
/*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 */
|
||||
/*<source-port>,<destination-port>,<data-length>*/
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1,3 +1,5 @@
|
||||
#include <stdlib.h>
|
||||
|
||||
#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);
|
||||
|
Loading…
Reference in New Issue
Block a user