/*
passlogd - passive syslog capture daemon
copyright (c) 2005 - christian void <cvoid@morphine.com>
file: parse.c
history:
11feb05 cvoid: fixed problem with -e crashing
11feb05 cvoid: fixed -e to allow 'all'
02apr03 cvoid: fixed 3 buffer overflow conditions in the parser.
07jun01 cvoid: added syslog-like output format.
07jun01 cvoid: added short packet syslog notification.
07jun01 cvoid: added call to sanitize_buffer() just in case.
07jun01 cvoid: miscellaneous parser fixes.
04jun01 cvoid: created.
*/
#include "passlog.h"
/* globals */
extern int debug;
extern int vflag;
extern int sflag;
extern int rflag;
extern int fflag;
extern int dflag;
extern int logfd;
extern int conflag;
/* pcap callback routine for parsing packets */
/* warning: this definately needs to be rewritten */
void sl_parse(char *user, struct pcap_pkthdr *pkthdr, u_char *pkt)
{
int i, j, wb;
char *timestr;
time_t curtime;
int err = 0;
char *errstr;
char srcip[255];
char dstip[255];
char level[5];
char message[1024];
char buffer[4096];
int syslev;
int z=0;
/* initialize our buffers - this just has to be expensive as fuck */
init_buf(srcip, sizeof(srcip));
init_buf(dstip, sizeof(dstip));
init_buf(level, sizeof(level));
init_buf(message, sizeof(message));
init_buf(buffer, sizeof(buffer));
i = 26;
if (pkthdr->caplen > 32)
{
sprintf(srcip, "%d.%d.%d.%d", pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]);
i=i+4;
sprintf(dstip, "%d.%d.%d.%d", pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]);
i=i+4;
}
else
{
if(debug)
printf("packet too short!\n");
openlog("passlogd", 0, LOG_DAEMON);
syslog(LOG_INFO, "received %d byte packet (too short)", pkthdr->caplen);
closelog();
return;
}
i=i+9;
j=0;
while(pkt[i] != '>'){
if(j==sizeof(level)-1)
{
/* not ideal - we should log this */
break;
}
level[j] = pkt[i];
i++;
j++;
}
i++;
if(debug)
printf("caplen: %d len: %d\n", pkthdr->caplen, pkthdr->len);
while(pkt[i] != '\n' && pkt[i] != '\r' && i < (pkthdr->caplen - 1)){
if(debug)
printf("at byte %d of %d\n", i, pkthdr->caplen - 1);
if(z==sizeof(message)-1)
{
/* not ideal - we should log this */
break;
}
message[z] = pkt[i];
i++;
z++;
}
if(rflag){
/* reverse lookup the ip addresses */
err = reverse_lookup(srcip);
if(debug)printf("reverse: %d\n", err);
reverse_lookup(dstip);
if(debug)printf("reverse: %d\n", err);
}
/* built the logstring */
if(dflag){
snprintf(buffer, sizeof(buffer)-1, "%s %s\n", srcip, message);
}
else {
snprintf(buffer, sizeof(buffer)-1, "%s to %s: <%s> %s\n", srcip, dstip, level, message);
}
if(debug){
wb = write(logfd, "\n\nRAW PACKET:\n", 14);
wb = write(logfd, pkt, pkthdr->caplen - 1);
wb = write(logfd, "\n\nPARSED PACKET:\n", 17);
}
/* sanitize the buffer */
sanitize_buffer(buffer, sizeof(buffer));
if(sflag){
/* log to syslog */
/* break out facility and priority */
syslev = atoi(level);
openlog("passlogd", 0, LOG_DAEMON);
syslog(syslev, "%s", buffer);
closelog();
}
/* get current time */
err = gettimeofday((void *) &curtime, NULL);
timestr = ctime(&curtime);
timestr[strlen(timestr)-1]=0x20;
/* dump to stdio */
if(conflag){
printf("%s", timestr);
printf("%s", buffer);
}
if(fflag){
/* log to logfile */
wb = write(logfd, timestr, strlen(timestr));
wb = write(logfd, buffer, strlen(buffer));
if(debug){
errstr = (char *) strerror(errno);
printf("wrote %d bytes to logfile\n", wb);
printf("write() returned: %s\n", errstr);
}
}
}
syntax highlighted by Code2HTML, v. 0.9.1