Start parsing pf data csv

This commit is contained in:
dave 2018-05-15 23:30:46 -07:00
parent 3de1a8372a
commit 6162cf6676
4 changed files with 121 additions and 13 deletions

View File

@ -1,10 +1,14 @@
CC=gcc -Wall
CFLAGS=-g -I.
DEPS=
OBJ=main.o
OBJ=main.o pfparser.o
%.o: %.c $(DEPS)
$(CC) -c -o $@ $< $(CFLAGS)
csyslog: $(OBJ)
gcc -o $@ $^ $(CFLAGS)
clean:
rm -vf *.o csyslog

View File

@ -10,6 +10,8 @@
#include <netdb.h>
#include <limits.h>
#include "helpers.h"
#include "pfparser.h"
// UDP server-related mostly lifted from https://cs.nyu.edu/~mwalfish/classes/16sp/classnotes/handout01.pdf
@ -31,6 +33,7 @@ struct Message {
int priority;
char application[MSG_APP_LEN];
struct Datefields date;
pf_message data;
};
@ -134,8 +137,18 @@ int parse_message(struct Message* result, char* message) {
memcpy(result->application, application, sizeof(application));
position += 1; // pass over the space
printf("remaining: '%s'\n", message + position);
return 0;
// printf("remaining: '%s'\n", message + position);
// trim original message to only the CSV portion
int msglen = strlen(message);
int datalen = msglen - position;
memmove(message, &message[position], datalen);
// zero the rest of the message
memset(&message[datalen], 0, msglen - datalen);
// pf_message result_msg;
if(pfparse_message(message, &(result->data)) != 0) return 1;
// char msg_remaining[4096];
// memset(&msg_remaining, '\0', sizeof(msg_remaining));
@ -145,6 +158,7 @@ int parse_message(struct Message* result, char* message) {
// memmove(message, &message[position], strlen(message) - position);
// printf("'%s'\n", message);
return 0;
}
@ -178,7 +192,7 @@ int main(int argc, char** argv) {
memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_port = htons(port);
my_addr.sin_port = htons(port); // host to network short - converts a *s*hort from the *h*ost's to *n*etwork's endianness
if (bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr_in)) < 0)
panic("bind failed");
@ -186,17 +200,17 @@ int main(int argc, char** argv) {
while (1) {
int size_recvd;
if ((size_recvd = recvfrom(sock_fd, /* socket */
msg, /* buffer */
sizeof(msg), /* size of buffer */
0, /* flags = 0 */
(struct sockaddr*)&my_peer_addr, /* whos sending */
&addrlen /* length of buffer to receive peer info */
)) < 0)
msg, /* buffer */
sizeof(msg), /* size of buffer */
0, /* flags = 0 */
(struct sockaddr*)&my_peer_addr, /* whos sending */
&addrlen /* length of buffer to receive peer info */
)) < 0)
panic("recvfrom");
assert(size_recvd < sizeof(msg)); // messages can't be longer than our buffer
assert(addrlen == sizeof(struct sockaddr_in));
printf("Got message: %s\n", msg);
printf("\nGot message: %s\n", msg);
// TODO should we check that msg[size_recvd] == \0 ?
// printf("From host %s src port %d got message %.*s\n",
@ -206,9 +220,10 @@ int main(int argc, char** argv) {
//printf("msg[size_recvd] is: %d", msg[size_recvd]);
msg[size_recvd] = '\0'; // We receive 1 full string at a time
if(parse_message(&result, msg) != 1) {
printf("message is valid:\n\tpriority: %d\n\tapplication: %s\n\tDate: %s %d %02d:%02d:%02d\n",
printf("message is valid:\n\tpriority: %d\n\tapplication: %s\n\tDate: %s %d %02d:%02d:%02d\n"
"\tInterface: %s\n\tIP version: %d\n",
result.priority, result.application, result.date.month, result.date.day, result.date.hour,
result.date.minute, result.date.second);
result.date.minute, result.date.second, result.data.iface, result.data.ipversion);
}
}

58
src/pfparser.c Normal file
View File

@ -0,0 +1,58 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "pfparser.h"
int pfparse_message(char* message, pf_message* result) {
printf("pfparse: '%s'\n", message);
char* token;
int field = 0;
// Parse the first X 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) {
printf("%02d: %s\n", field, token);
switch (field) {
case 0: // Rule number
{
char* rnend;
long int rulenum = strtol(token, &rnend, 10);
if(rnend == NULL) return 1;
result->rulenum = (int)rulenum;
}
// if(result->rulenum == NULL) return 1;
break;
case 4: // iface
if(strlen(token) > IFACE_LEN) return 1;
memcpy(result->iface, token, strlen(token));
break;
case 5: // reason
result->reason = strcmp(token, "match") ? pf_hit_other : pf_hit_match;
break;
case 6: // action
result->action = strcmp(token, "block") ? pf_hit_block : pf_hit_pass;
break;
case 7: // direction
result->direction = strcmp(token, "in") ? pf_dir_in : pf_dir_out;
break;
case 8: // ip-version
{
char* ipvend;
long int ip_ver = strtol(token, &ipvend, 10);
if(ipvend == NULL) return 1;
result->ipversion = (int)ip_ver;
}
break;
}
field++;
}
return 0;
}

31
src/pfparser.h Normal file
View File

@ -0,0 +1,31 @@
#define IFACE_LEN 8
typedef enum pf_hit_reason {
pf_hit_match,
pf_hit_other
} pf_hit_reason;
typedef enum pf_hit_action {
pf_hit_block,
pf_hit_pass
} pf_hit_action;
typedef enum pf_direction {
pf_dir_in,
pf_dir_out
} pf_direction;
typedef struct pf_message {
int rulenum;
char iface[IFACE_LEN];
pf_hit_reason reason;
pf_hit_action action;
pf_direction direction;
int ipversion;
} pf_message;
int pfparse_message(char* message, pf_message* result);