misc edits before setting laptop on fire

This commit is contained in:
dave 2018-05-21 18:56:06 -07:00
parent 6162cf6676
commit 7878165b02
5 changed files with 83 additions and 65 deletions

1
src/gdb.sh Executable file
View File

@ -0,0 +1 @@
gdb --args ./csyslog 4200

View File

@ -1,8 +1,8 @@
// Convert a defined token to a string /*Convert a defined token to a string*/
#define _STR(x) #x #define _STR(x) #x
// Usable wrapper for above /*Usable wrapper for above
// Note: #x does not work in context, 2nd layer is required ?? Note: #x does not work in context, 2nd layer is required ??
// http://www.decompile.com/cpp/faq/file_and_line_error_string.htm http://www.decompile.com/cpp/faq/file_and_line_error_string.htm*/
#define STR(x) _STR(x) #define STR(x) _STR(x)

View File

@ -13,21 +13,22 @@
#include "pfparser.h" #include "pfparser.h"
// UDP server-related mostly lifted from https://cs.nyu.edu/~mwalfish/classes/16sp/classnotes/handout01.pdf /*UDP server-related mostly lifted from https://cs.nyu.edu/~mwalfish/classes/16sp/classnotes/handout01.pdf*/
#define DF_MONTH_LEN 9 #define DF_MONTH_LEN 9
/*TODO numeric indicator for month?*/
struct Datefields { struct Datefields {
char month[DF_MONTH_LEN]; // TODO numeric indicator? char month[DF_MONTH_LEN];
int day; int day;
int hour; int hour;
int minute; int minute;
int second; int second;
}; };
/*TODO check max app name length*/
#define MSG_APP_LEN 64 // TODO check max app name length #define MSG_APP_LEN 64
struct Message { struct Message {
int priority; int priority;
@ -50,17 +51,17 @@ int parse_priority(char* message, int* priority, int* position) {
The position after the final `>` will be placed in the passed `position` int pointer The position after the final `>` will be placed in the passed `position` int pointer
Returns 0 on success or something else on failure Returns 0 on success or something else on failure
*/ */
// Must have >3 chars to form <x> priority /*Must have >3 chars to form <x> priority*/
if (strlen(message) < 3) return 1; if (strlen(message) < 3) return 1;
// Must start with < /*Must start with <*/
if (message[0] != '<') return 1; if (message[0] != '<') return 1;
char digits[4]; char digits[4];
memset(&digits, '\0', sizeof(digits)); memset(&digits, '\0', sizeof(digits));
int num_digits = 0; int num_digits = 0;
int pos = 1; int pos = 1;
//bool found_priority_end = false; // TODO /*bool found_priority_end = false; // TODO*/
while (pos < 4) { while (pos < 4) {
if(!isdigit(message[pos])) return 1; // priority must be numeric if(!isdigit(message[pos])) return 1; /*priority must be numeric*/
digits[num_digits] = message[pos]; digits[num_digits] = message[pos];
num_digits++; num_digits++;
pos++; pos++;
@ -68,8 +69,8 @@ int parse_priority(char* message, int* priority, int* position) {
break; break;
} }
} }
// TODO if escape the loop because pos >= 4, we never found '>' /*TODO if escape the loop because pos >= 4, we never found '>'*/
if (num_digits == 0) return 1; // empty priority <> ? if (num_digits == 0) return 1; /*empty priority <> ?*/
*priority = atoi(digits); *priority = atoi(digits);
*position = pos; *position = pos;
return 0; return 0;
@ -83,12 +84,12 @@ int parse_datefield(char* message, struct Datefields* date, int* position) {
Parse out the date and place the fields in the passed datefields struct pointer Parse out the date and place the fields in the passed datefields struct pointer
Position will be advanced to the character after the parsed data Position will be advanced to the character after the parsed data
*/ */
// char month[8]; /*char month[8];
// memset(&month, '\0', sizeof(month)); // makes valgrind happy as the above char contains uninitialized memory memset(&month, '\0', sizeof(month)); makes valgrind happy as the above char contains uninitialized memory*/
int date_length; int date_length;
if(sscanf(message + *position, "%"STR(DF_MONTH_LEN)"s %d %d:%d:%d%n", if(sscanf(message + *position, "%"STR(DF_MONTH_LEN)"s %d %d:%d:%d%n",
date->month, &(date->day), &(date->hour), &(date->minute), &(date->second), &date_length) != 5) { date->month, &(date->day), &(date->hour), &(date->minute), &(date->second), &date_length) != 5) {
return 1; // Failed to parse all desired fields return 1; /*Failed to parse all desired fields*/
} }
*position += date_length; *position += date_length;
return 0; return 0;
@ -97,11 +98,11 @@ int parse_datefield(char* message, struct Datefields* date, int* position) {
int parse_application(char* message, char* application, int* position) { int parse_application(char* message, char* application, int* position) {
int app_length; int app_length;
if(sscanf(message + *position, "%"STR(MSG_APP_LEN)"s%n", application, &app_length) != 1) { // %n not counted in returned field count if(sscanf(message + *position, "%"STR(MSG_APP_LEN)"s%n", application, &app_length) != 1) { /*%n not counted in returned field count*/
return 1; // Failed to parse all desired fields return 1; /*Failed to parse all desired fields*/
} }
if(strlen(application) < 2) return 1; // Expect at least chars if(strlen(application) < 2) return 1; /*Expect at least chars*/
application[app_length-1] = '\0'; // Remove the trailing : application[app_length-1] = '\0'; /*Remove the trailing :*/
*position += app_length; *position += app_length;
return 0; return 0;
} }
@ -119,44 +120,44 @@ int parse_message(struct Message* result, char* message) {
int position = 0; int position = 0;
if(parse_priority(message, &priority, &position) != 0) return 1; if(parse_priority(message, &priority, &position) != 0) return 1;
result->priority = priority; result->priority = priority;
position++; // Now sits on the first character of the ISOTIMESTAMP position++; /*Now sits on the first character of the ISOTIMESTAMP*/
// Parse ISOTIMESTAMP /*Parse ISOTIMESTAMP
// Note: does not parse a full iso timestamp, only the format above Note: does not parse a full iso timestamp, only the format above*/
struct Datefields date; struct Datefields date;
if(parse_datefield(message, &date, &position) != 0) { if(parse_datefield(message, &date, &position) != 0) {
return 1; return 1;
} }
result->date = date; result->date = date;
position++; // position now at beginning of HOSTNAME field position++; /*position now at beginning of HOSTNAME field*/
// Parse APPLICATION /*Parse APPLICATION
// filterlog: 5,,,1000000103,cpsw0,match.... filterlog: 5,,,1000000103,cpsw0,match....*/
char application[MSG_APP_LEN]; char application[MSG_APP_LEN];
if(parse_application(message, application, &position) != 0) return 1; if(parse_application(message, application, &position) != 0) return 1;
memcpy(result->application, application, sizeof(application)); memcpy(result->application, application, sizeof(application));
position += 1; // pass over the space position += 1; /*pass over the space*/
// printf("remaining: '%s'\n", message + position); /*printf("remaining: '%s'\n", message + position);*/
// trim original message to only the CSV portion /*trim original message to only the CSV portion*/
int msglen = strlen(message); int msglen = strlen(message);
int datalen = msglen - position; int datalen = msglen - position;
memmove(message, &message[position], datalen); memmove(message, &message[position], datalen);
// zero the rest of the message /*zero the rest of the message*/
memset(&message[datalen], 0, msglen - datalen); memset(&message[datalen], 0, msglen - datalen);
// pf_message result_msg; /*pf_message result_msg;*/
if(pfparse_message(message, &(result->data)) != 0) return 1; if(pfparse_message(message, &(result->data)) != 0) return 1;
// char msg_remaining[4096]; /*char msg_remaining[4096];
// memset(&msg_remaining, '\0', sizeof(msg_remaining)); memset(&msg_remaining, '\0', sizeof(msg_remaining));
// memcpy(msg_remaining, &message[position], strlen(message) - position); memcpy(msg_remaining, &message[position], strlen(message) - position);
// printf("'%s'\n", msg_remaining); printf("'%s'\n", msg_remaining);
// or or
// memmove(message, &message[position], strlen(message) - position); memmove(message, &message[position], strlen(message) - position);
// printf("'%s'\n", message); printf("'%s'\n", message);*/
return 0; return 0;
} }
@ -169,7 +170,7 @@ int main(int argc, char** argv) {
exit(1); exit(1);
} }
// Parse port number to integer /*Parse port number to integer*/
char* portend; char* portend;
unsigned int portl; unsigned int portl;
portl = strtol(argv[1], &portend, 10); portl = strtol(argv[1], &portend, 10);
@ -177,22 +178,22 @@ int main(int argc, char** argv) {
assert(portl < USHRT_MAX); assert(portl < USHRT_MAX);
unsigned short port = (unsigned short)portl; unsigned short port = (unsigned short)portl;
// Create socket /*Create socket*/
int sock_fd; int sock_fd;
char msg[4096]; char msg[4096];
if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) if ((sock_fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0)
panic("socket"); panic("socket");
// Set socket options /*Set socket options*/
int one = 1; int one = 1;
setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one)); setsockopt(sock_fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof(one));
// Bind socket /*Bind socket*/
struct sockaddr_in my_addr, my_peer_addr; struct sockaddr_in my_addr, my_peer_addr;
memset(&my_addr, 0, sizeof(my_addr)); memset(&my_addr, 0, sizeof(my_addr));
my_addr.sin_family = AF_INET; my_addr.sin_family = AF_INET;
my_addr.sin_addr.s_addr = INADDR_ANY; my_addr.sin_addr.s_addr = INADDR_ANY;
my_addr.sin_port = htons(port); // host to network short - converts a *s*hort from the *h*ost's to *n*etwork's endianness 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) if (bind(sock_fd, (struct sockaddr*)&my_addr, sizeof(struct sockaddr_in)) < 0)
panic("bind failed"); panic("bind failed");
@ -207,18 +208,18 @@ int main(int argc, char** argv) {
&addrlen /* length of buffer to receive peer info */ &addrlen /* length of buffer to receive peer info */
)) < 0) )) < 0)
panic("recvfrom"); panic("recvfrom");
assert(size_recvd < sizeof(msg)); // messages can't be longer than our buffer assert(size_recvd < sizeof(msg)); /*messages can't be longer than our buffer*/
assert(addrlen == sizeof(struct sockaddr_in)); assert(addrlen == sizeof(struct sockaddr_in));
printf("\nGot message: %s\n", msg); printf("\nGot message: %s\n", msg);
// TODO should we check that msg[size_recvd] == \0 ? /*TODO should we check that msg[size_recvd] == \0 ?
// printf("From host %s src port %d got message %.*s\n", printf("From host %s src port %d got message %.*s\n",
// inet_ntoa(my_peer_addr.sin_addr), ntohs(my_peer_addr.sin_port), size_recvd, msg); inet_ntoa(my_peer_addr.sin_addr), ntohs(my_peer_addr.sin_port), size_recvd, msg);*/
struct Message result; struct Message result;
// printf("XXXsize: %lu", sizeof(result)); // curious how big the struct gets /*printf("XXXsize: %lu", sizeof(result)); // curious how big the struct gets
//printf("msg[size_recvd] is: %d", msg[size_recvd]); printf("msg[size_recvd] is: %d", msg[size_recvd]);*/
msg[size_recvd] = '\0'; // We receive 1 full string at a time msg[size_recvd] = '\0'; /*We receive 1 full string at a time*/
if(parse_message(&result, msg) != 1) { 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", "\tInterface: %s\n\tIP version: %d\n",

View File

@ -4,46 +4,47 @@
#include "pfparser.h" #include "pfparser.h"
int pfparse_message(char* message, pf_message* result) { int pfparse_message(char* message, pf_message* result) {
printf("pfparse: '%s'\n", message); printf("pfparse: '%s'\n", message);
char* token; char* token;
int field = 0; int field = 0;
// Parse the first X fields /* Parse the first X fields
// They are: <rule-number>,<sub-rule-number>,<anchor>,<tracker>,<real-interface>,<reason>,<action>,<direction>,<ip-version> 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 We only collect rule-number, real-interface, reason, action, direction, ip-version */
while ( (token = strsep(&message, ",")) != NULL) { while ( (token = strsep(&message, ",")) != NULL) {
printf("%02d: %s\n", field, token); printf("%02d: %s\n", field, token);
switch (field) { switch (field) {
case 0: // Rule number case 0: /* Rule number*/
{ { /*language limitation, the `char*` label (or `unsigned`) is not supported after a switch case TODO look up the underlying reason again*/
char* rnend; char* rnend;
long int rulenum = strtol(token, &rnend, 10); long int rulenum = strtol(token, &rnend, 10);
if(rnend == NULL) return 1; if(rnend == NULL) return 1;
result->rulenum = (int)rulenum; result->rulenum = (int)rulenum;
} }
// if(result->rulenum == NULL) return 1; /*if(result->rulenum == NULL) return 1;*/
break; break;
case 4: // iface case 4: /*iface*/
if(strlen(token) > IFACE_LEN) return 1; if(strlen(token) > IFACE_LEN) return 1;
memcpy(result->iface, token, strlen(token)); memcpy(result->iface, token, strlen(token));
break; break;
case 5: // reason case 5: /*reason*/
result->reason = strcmp(token, "match") ? pf_hit_other : pf_hit_match; result->reason = strcmp(token, "match") ? pf_hit_other : pf_hit_match; /*TODO error on unexpected*/
break; break;
case 6: // action case 6: /*action*/
result->action = strcmp(token, "block") ? pf_hit_block : pf_hit_pass; result->action = strcmp(token, "block") ? pf_hit_block : pf_hit_pass; /*XXX*/
break; break;
case 7: // direction case 7: /*direction*/
result->direction = strcmp(token, "in") ? pf_dir_in : pf_dir_out; result->direction = strcmp(token, "in") ? pf_dir_in : pf_dir_out; /*XXX*/
break; break;
case 8: // ip-version case 8: /*ip-version*/
{ {
char* ipvend; char* ipvend;
long int ip_ver = strtol(token, &ipvend, 10); long int ip_ver = strtol(token, &ipvend, 10);
@ -54,5 +55,19 @@ int pfparse_message(char* message, pf_message* result) {
} }
field++; field++;
} }
if(result->ipversion == 4) {
/*parse ipv4 fields*/
}
else if(result->ipversion == 6) {
/*parse ipv6 fields*/
} else {
return 1;
}
/*Parse <ip-data>*/
/*Parse optional <protocol-specific-data>*/
return 0; return 0;
} }

1
src/valgrind.sh Executable file
View File

@ -0,0 +1 @@
valgrind --leak-check=full --track-origins=yes -v ./csyslog 4200