cpfsyslog/src/sysparser.c

176 lines
5.6 KiB
C

#include "sysparser.h"
#include <stdio.h>
#include "helpers.h"
#include <string.h>
#include <ctype.h>
#include <stdlib.h>
int parse_priority(char* message, int* priority, int* position) {
/*
Given a string that begins with a message something like: <123>foo
Parse out the number (123) and place it in the passed `priority` 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
*/
/*Must have >3 chars to form <x> priority*/
if (strlen(message) < 3) return 1;
/*Must start with <*/
if (message[0] != '<') return 1;
char digits[4];
memset(&digits, '\0', sizeof(digits));
int num_digits = 0;
int pos = 1;
int found_end = 0;
/*bool found_priority_end = false; // TODO*/
while (pos < 4) {
if(!isdigit(message[pos])) return 1; /*priority must be numeric*/
digits[num_digits] = message[pos];
num_digits++;
pos++;
if (message[pos] == '>') {
found_end = 1;
break;
}
}
if (found_end == 0) return 1;
if (num_digits == 0) return 1; /*empty priority <> ?*/
*priority = atoi(digits);
*position = pos;
return 0;
}
int parse_datefield(char* message, struct Datefields* date, int* position) {
/*
Given a message+position pointers, where message + position in a string like:
May 10 03:09:59 filterlog: 5,,,....
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
*/
/*char month[8];
memset(&month, '\0', sizeof(month)); makes valgrind happy as the above char contains uninitialized memory*/
int date_length;
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) {
return 1; /*Failed to parse all desired fields*/
}
*position += date_length;
return 0;
}
int parse_application(char* message, char* application, int* position) {
int app_length;
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*/
}
if(app_length - 1 > MSG_APP_LEN) return 1;
if(strlen(application) < 2) return 1; /*Expect at least chars*/
application[app_length-1] = '\0'; /*Remove the trailing :*/
*position += app_length;
return 0;
}
int sysmsg_parse(struct SysMessage* result, char* message) {
/*
parse a message like:
<134>May 10 03:09:59 filterlog: 5,,,1000000103,cpsw0,match,block,in,4,0x20,,239,27547,0,none,6,tcp,40,185.216.140.37,24.4.129.164,57159,11111,0,S,3919167832,,1024,,
Format:
<priority>VERSION ISOTIMESTAMP HOSTNAME APPLICATION PID MESSAGEID STRUCTURED-DATA MSG
Assumes null termed string
Param message will be transformed to the MSG field
*/
int priority = 0;
int position = 0;
if(parse_priority(message, &priority, &position) != 0) return 1;
result->priority = priority;
position++; /*Now sits on the first character of the ISOTIMESTAMP*/
/*Parse ISOTIMESTAMP
Note: does not parse a full iso timestamp, only the format above*/
struct Datefields date;
if(parse_datefield(message, &date, &position) != 0) {
return 1;
}
result->date = date;
if(message[position] != ' ') return 1; // Something other than a space after the date
position++; /*position now at beginning of HOSTNAME field*/
/*Parse APPLICATION
filterlog: 5,,,1000000103,cpsw0,match....*/
char application[MSG_APP_LEN];
if(parse_application(message, application, &position) != 0) return 1;
memcpy(result->application, application, sizeof(application));
if(message[position] != ' ') return 1; // Something other than a space after the app name
position += 1; /*pass over the space*/
/*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;
/* put message in result */
// memcpy(&(result->message), message, strlen(message));
// result->message = message + position;
/*char msg_remaining[4096];
memset(&msg_remaining, '\0', sizeof(msg_remaining));
memcpy(msg_remaining, &message[position], strlen(message) - position);
printf("'%s'\n", msg_remaining);
or
memmove(message, &message[position], strlen(message) - position);
printf("'%s'\n", message);*/
return 0;
}
int month2num(char* month) {
for(int i=1; i<=12; i++) {
if(strcmp(month, month2nummap[i]) == 0) {
return i;
}
}
return -1;
}
#ifdef AFL
int main() {
char *buffer;
size_t bufsize = 4096;
size_t characters;
buffer = (char *)malloc(bufsize * sizeof(char));
if (buffer == NULL)
die("Unable to allocate buffer");
characters = getline(&buffer,&bufsize,stdin);
struct SysMessage data = {0};
int result = sysmsg_parse(&data, buffer);
printf("sysparser result: %d\n", result);
if(result == 0) {
pf_data fwdata = {0};
result = pfdata_parse(buffer, &fwdata);
printf("pfparser result: %d\n", result);
}
return result;
}
#endif