/* $Id: output.c,v 1.10 2006/03/03 17:27:38 bhockney Exp $ */ /* (C) 2004-2006 by Bob Hockney * * Based on fwlogwatch written by * * Boris Wesslowski * * * * output function for wfwl_syslog * * * * This code is distributed under the terms of GNU GPL */ #include #include #include #include #include #include #include "main.h" #include "output.h" #include "utils.h" #include "database.h" extern struct options opt; extern struct conn_data *first; extern struct field_order *fields; extern struct select_sum select_sum; /* prints difference between first and last logged packets for line */ void output_timediff(time_t start, time_t end, char *td) { time_t diff; int part; char tmp[4]; diff = end - start; if (diff <= 0) { snprintf(td, 2, "-"); return; } part = diff / 86400; /* days */ snprintf(td, TIMESIZE, "%02d:", part); diff = diff % 86400; part = diff / 3600; /* hours */ snprintf(tmp, 4, "%02d:", part); strncat(td, tmp, 4); diff = diff % 3600; part = diff / 60; /* minutes */ snprintf(tmp, 4, "%02d:", part); strncat(td, tmp, 4); part = diff % 60; /* seconds */ snprintf(tmp, 3, "%02d", part); strncat(td, tmp, 3); } void output_tcp_opts(struct conn_data *input, char *buf) { if (input->protocol == 6 ) { if ((input->flags & (TCP_ACK|TCP_FIN|TCP_RST|TCP_PSH|TCP_URG)) != 0) { if (input->flags & TCP_SYN) { strcpy(buf, "s"); } else { strcpy (buf, "-"); } if (input->flags & TCP_ACK) { strcat(buf, "a"); } else { strcat (buf, "-"); } if (input->flags & TCP_FIN) { strcat(buf, "f"); } else { strcat (buf, "-"); } if (input->flags & TCP_RST) { strcat(buf, "r"); } else { strcat (buf, "-"); } if (input->flags & TCP_PSH) { strcat(buf, "p"); } else { strcat (buf, "-"); } if (input->flags & TCP_URG) { strcat(buf, "u"); } else { strcat (buf, "-"); } } else { if (input->flags & TCP_SYN) { strcpy(buf, "SYN"); } else { strcpy(buf, "-"); } } } else { strcpy(buf, ""); } } /* output one report line, tab delimited */ void output_wfwl(struct conn_data *input, FILE *fd) { char *proto, buf[SHORTLEN]; char hostname[SHORTLEN], service[SHORTLEN]; struct field_order *flds; flds = fields; while (flds != NULL) { switch (flds->field) { case COL_ID: fprintf(fd, "%s %lu", input->filename, input->linenum); break; case COL_COUNT: fprintf(fd, "%lu", input->count); break; case COL_IP_PROTO: proto = resolve_protocol(input->protocol); fprintf(fd, "%s", proto); break; case COL_IN_IF: fprintf(fd, "%s", input->inif); break; case COL_OUT_IF: fprintf(fd, "%s", input->outif); break; case COL_TCP_SEQ: fprintf(fd, "%lu", input->tcp_seq); break; case COL_TCP_ACKSEQ: fprintf(fd, "%lu", input->tcp_ack_seq); break; case COL_ICMP_TYPE: if (input->icmp_type >= 0) fprintf(fd, "%i", input->icmp_type); break; case COL_ICMP_CODE: if (input->icmp_code >= 0) fprintf(fd, "%i", input->icmp_code); break; case COL_FWMARK: fprintf(fd, "%i", input->fwmark); break; case COL_MAC: fprintf(fd, "%s", input->raw_mac); break; case COL_START_TIME: /* Earliest */ fprintf(fd, "%li", (long int)input->start_time); break; case COL_END_TIME: /* Latest */ fprintf(fd, "%li", (long int)input->end_time); break; case COL_LOCAL_HOST: fprintf(fd, "%s", input->hostname); break; case COL_IP_LEN: fprintf(fd, "%u", input->datalen); break; case COL_IP_IHL: fprintf(fd, "%i", input->ihl); break; case COL_SOURCEHOST: fprintf(fd, "%s", inet_ntoa(input->shost)); break; case COL_DESTHOST: fprintf(fd, "%s", inet_ntoa(input->dhost)); break; case COL_SOURCEHOST_NAME: if (strlen(input->shostname)) { fprintf(fd, (char *)&input->shostname); } else { get_hostname(&input->shost, hostname); fprintf(fd, hostname); } break; case COL_DESTHOST_NAME: if (strlen(input->dhostname)) { fprintf(fd, (char *)&input->dhostname); } else { get_hostname(&input->dhost, hostname); fprintf(fd, hostname); } break; case COL_SOURCE_SERVICE: if (strlen(input->sservice)) { fprintf(fd, (char *)&input->sservice); } else { get_service_name(input->protocol, input->sport, service); fprintf(fd, service); } break; case COL_DEST_SERVICE: if (strlen(input->dservice)) { fprintf(fd, (char *)&input->dservice); } else { get_service_name(input->protocol, input->dport, service); fprintf(fd, service); } break; case COL_SOURCEPORT: if (input->protocol == 6 || input->protocol == 17) fprintf(fd, "%u", input->sport); break; case COL_DESTPORT: if (input->protocol == 6 || input->protocol == 17) fprintf(fd, "%u", input->dport); break; case COL_LOG_PREFIX: fprintf(fd, "%s", input->log_label); break; case COL_IP_TOS: fprintf(fd, "%i", input->tos); break; case COL_IP_TTL: fprintf(fd, "%i", input->ttl); break; case COL_IP_CSUM: fprintf(fd, "%i", input->csum); break; case COL_IP_ID: fprintf(fd, "%i", input->ipid); break; case COL_IP_FRAGOFF: fprintf(fd, "%i", input->fragoff); break; case COL_TCP_WINDOW: fprintf(fd, "%u", input->tcp_window); break; case COL_TCP_URGP: fprintf(fd, "%i", input->tcp_urgp); break; case COL_UDP_LEN: fprintf(fd, "%u", input->udp_len); break; case COL_ICMP_ECHOID: fprintf(fd, "%i", input->icmp_echoid); break; case COL_ICMP_ECHOSEQ: fprintf(fd, "%i", input->icmp_echoseq); break; case COL_ICMP_GATEWAY: fprintf(fd, "%s", inet_ntoa(input->icmp_gw)); break; case COL_ICMP_MTU: fprintf(fd, "%i", input->icmp_mtu); break; case COL_AHESP_SPI: fprintf(fd, "%lu", input->ahesp_spi); break; case COL_LOCAL_TIME: fprintf(fd, "%li", (long int)input->local_time); break; case COL_TCP_OPTIONS: output_tcp_opts(input, buf); fprintf(fd, "%s", buf); break; default: break; } /* end switch */ if (flds->next != NULL) { fprintf(fd, "\t"); } flds = flds->next; } /* end while (flds != NULL) */ fprintf(fd, "\n"); } /* output all report lines in raw format, semi-colon delimited */ void output_raw_data(struct conn_data *input) { struct conn_data *this; this = input; while (this != NULL) { #ifndef __OpenBSD__ #ifndef __FreeBSD__ /* not BSD */ printf("%lu;%ld;%ld;" "%s;%s;%s;" "%s;%d;" "%lu;%d;" "%lu;%d;" "%d;" "NEWSTUFF;" "%s;" "0x%x;" "%d;" "%s;" "%s;" "%d;" "%d;" "%d;" "%u;" "%u;" "%d;" "%lu;" "%lu;" "%d;" "%d;" "%d;" "%d;" "%d;" "%d;" "%u;" "%lu;" "%d;" "\n", this->count, this->start_time, this->end_time, this->hostname, this->log_label, this->branchname, this->interface, this->protocol, (unsigned long)ntohl(this->shost.s_addr), this->sport, (unsigned long)ntohl(this->dhost.s_addr), this->dport, this->flags, this->raw_mac, this->fwmark, this->datalen, this->inif, this->outif, this->tos, this->ttl, this->ihl, this->csum, this->ipid, this->fragoff, this->tcp_seq, this->tcp_ack_seq, this->tcp_window, this->tcp_urgp, this->udp_len, this->icmp_type, this->icmp_code, this->icmp_echoid, this->icmp_echoseq, (unsigned long)ntohl(this->icmp_gw.s_addr), this->icmp_mtu); #else printf("%lu;%ld;%ld;" "%s;%s;%s;" "%s;%d;" "%ld;%d;" "%ld;%d;" "%d\n", this->count, this->start_time, this->end_time, this->hostname, this->log_label, this->branchname, this->interface, this->protocol, ntohl(this->shost.s_addr), this->sport, ntohl(this->dhost.s_addr), this->dport, this->flags); #endif #else printf("%lu;%d;%d;" "%s;%s;%s;" "%s;%d;" "%u;%d;" "%u;%d;" "%d\n", this->count, this->start_time, this->end_time, this->hostname, this->log_label, this->branchname, this->interface, this->protocol, ntohl(this->shost.s_addr), this->sport, ntohl(this->dhost.s_addr), this->dport, this->flags); #endif this = this->next; } } /* determines output mode and calls function to output report */ void show_list(FILE *fd) { struct conn_data *this; int max = 0, skip; this = first; if(opt.raw) { output_raw_data(this); return; } for (skip = opt.begin; this != NULL && skip > 0; skip-- ) { this = this->next; } while ((this != NULL) && (opt.max == 0 || max < opt.max)) { output_wfwl(this, fd); if (opt.max != 0) max++; this = this->next; } }