#include "usniff.h" typedef struct ether_header eth_hdr; /* Ethernet header */ typedef struct ip ip_hdr; /* IP header */ typedef struct tcphdr tcp_hdr; /* TCP header */ char *pcap_dev; /* Pcap device file descriptor */ char *copy_argv (char **); void pwcall (u_char *, const struct pcap_pkthdr *, const u_char *); void usage (void); int main(int argc, char *argv[]) { struct bpf_program program; /* BPF filter program */ register int c; /* Temporary variable */ char errbuf[PCAP_ERRBUF_SIZE]; /* pcap error buffer */ char *filter = NULL; /* pcap filter */ pcap_t *handle; /* pcap handle */ bpf_u_int32 mask; /* our netmask */ bpf_u_int32 net; /* our IP adx */ uint32_t npolls = -1; /* Number of pcap polls */ while ((c = getopt(argc, argv, "i:p:u")) != -1) { switch (c) { case 'i': pcap_dev = optarg; break; case 'p': if (optarg != NULL && isdigit(*optarg)) { npolls = atol(optarg); if (npolls < 0) { fprintf(stderr, "Packets must be > than 0\n"); exit(1); } } else { fprintf(stderr, "Invalid packet number\n"); exit(1); } break; case 'u': usage(); exit(0); break; default: usage(); exit(1); break; } } /* Got root? */ if (getuid()) { fprintf(stderr, "Must be root user.\n"); exit(1); } /* Strip off any none getopt arguments for pcap filter */ if (!filter) filter = copy_argv(&argv[optind]); /* Initialize the interface to listen on */ if ((!pcap_dev) && ((pcap_dev = pcap_lookupdev(errbuf)) == NULL)) { fprintf(stderr, "%s\n", errbuf); exit(-1); } if ((handle = pcap_open_live(pcap_dev, 68, 0, 0, errbuf)) == NULL) { fprintf(stderr, "%s\n", errbuf); exit(-1); } pcap_lookupnet(pcap_dev, &net, &mask, errbuf); /* Get netinfo */ if (filter) { if (pcap_compile(handle, &program, filter, 0, net) == -1) { fprintf(stderr, "Error - `pcap_compile()'\n"); return 1; } if (pcap_setfilter(handle, &program) == -1) { fprintf(stderr, "Error - `pcap_setfilter()'\n"); return 1; } pcap_freecode(&program); } /* Main loop */ printf("Starting capturing engine on %s...\n", pcap_dev); pcap_loop(handle, npolls, pwcall, NULL); /* Exit program */ printf("Closing capturing engine...\n"); pcap_close(handle); } /* * copy_argv: copy out any unprocessed arguments off of argv and return * requires: argument vector */ char *copy_argv(char **argv) { char **p; u_int len = 0; char *buf; char *src, *dst; p = argv; if (*p == 0) return 0; while (*p) len += strlen(*p++) + 1; buf = (char *) malloc(len); if (buf == NULL) { fprintf(stdout, "copy_argv: malloc"); exit(1); } p = argv; dst = buf; while ((src = *p++) != NULL) { while ((*dst++ = *src++) != '\0'); dst[-1] = ' '; } dst[-1] = '\0'; return buf; } /* * pwcall: This is the pcap looper. It is like most pcap callbacks * except it does a lot of printing. * requires: all of the standard pcap_loop data */ void pwcall(u_char * args, const struct pcap_pkthdr *header, const u_char * packet) { eth_hdr *ethernet; /* The ethernet header */ ip_hdr *ip; /* The IP header */ u_int id; /* Host id */ u_int i; /* Counter */ const struct tcphdr *tcp; /* TCP Header */ int len; /* real length */ u_int off, version; /* offset, version */ u_int length=header->len; /* True header len */ char *t; /* Timestamp intermediary */ time_t result; /* Time result (as read) */ t = ""; /* empty */ /* Extract ethernet, ip and tcp headers */ ethernet = (eth_hdr *) (packet); /* Pointer to ethernet header */ ip = (ip_hdr *) (packet + sizeof(eth_hdr)); tcp = (struct tcphdr *) (packet + sizeof(struct ether_header) + sizeof(struct ip)); len = ntohs(ip->ip_len); off = ntohs(ip->ip_off); /* Setup the timestamp */ result = time(NULL); t = asctime(localtime(&result)); t[strlen(t) - 1] = ' '; t[strlen(t)] = 0; /* this is just real fun - inet_ntoa mixed with fprintf screws up */ /* so the WAR is to mix up the print types. */ printf("%s: %s:", t, inet_ntoa(ip->ip_src)); fprintf(stdout,"%u ", tcp->th_sport); printf("-> %s:", inet_ntoa(ip->ip_dst)); fprintf(stdout,"%u ", tcp->th_dport); fprintf(stdout, "tos %u len %u off %u ttl %u prot %u cksum %u seq %u ack %u win %u\n", ip->ip_tos, len, off, ip->ip_ttl, ip->ip_p, ip->ip_sum, tcp->th_seq, tcp->th_ack, tcp->th_win); } /* * usage - Simple usage message */ void usage() { printf(PACKAGE " [option][arguments]\n" PACKAGE " " "[-i ][-p ][-u]\n" "Options:\n" " -i Specify the interface to watch\n" " -p Exit after analyzing int polls\n" " -u Display help\n"); }