/* passlogd - passive syslog capture daemon copyright (c) 2005 - christian void 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); } } }