#define RETSIGTYPE void

#include <sys/types.h

#include <sys/time.h

#include <netinet/in.h

#include <pcap.h

#include <signal.h

#include <stdio.h

#include <stdlib.h

#include <string.h

#include <unistd.h

#ifndef setsignal_h

#define setsignal_h

RETSIGTYPE (*setsignal(int, RETSIGTYPE (*)(int)))(int);

#endif

/* Ethernet addresses are 6 bytes */

#define ETHER_ADDR_LEN 6

#define SIZE_ETHERNET 14

#define SIZE_IPHDR 20

/* Ethernet header */

struct sniff_ethernet {

u_char ether_dhost[ETHER_ADDR_LEN]; /* Destination host address */

u_char ether_shost[ETHER_ADDR_LEN]; /* Source host address */

u_short ether_type; /* IP? ARP? RARP? etc */

};

/* ARP packet */

struct sniff_arp {

u_short arp_hwtype;

u_short arp_proto;

u_char arp_addrlen;

u_char arp_protolen;

u_short arp_operation;

u_char arp_src[6];

u_char arp_src_proto_addr[4];

u_char arp_dst[6];

u_char arp_dst_proto_addr[4];

};

/* IP header */

struct sniff_ip {

u_char ip_vhl; /* version < 4 | header length > 2 */

u_char ip_tos; /* type of service */

u_short ip_len; /* total length */

u_short ip_id; /* identification */

u_short ip_off; /* fragment offset field */

#define IP_RF 0x8000 /* reserved fragment flag */

#define IP_DF 0x4000 /* dont fragment flag */

#define IP_MF 0x2000 /* more fragments flag */

#define IP_OFFMASK 0x1fff /* mask for fragmenting bits */

u_char ip_ttl; /* time to live */

u_char ip_p; /* protocol */

u_short ip_sum; /* checksum */

u_char ip_src[4]; /* source port */

u_char ip_dst[4]; /* destination port */

// struct in_addr ip_src,ip_dst; /* source and dest address */

};

/* ICMP packet */

struct sniff_icmp {

u_char icmp_type;

u_char icmp_code;

u_short icmp_sum;

};

#define IP_HL(ip) (((ip)->ip_vhl) & 0x0f)

#define IP_V(ip) (((ip)->ip_vhl) > 4)

/* TCP header */

struct sniff_tcp {

u_short srcprt; /* source port */

u_short destprt; /* destination port */

u_int seq; /* sequence number */

u_int ack; /* acknowledgement number */

u_char hdrlen; /* data offset, rsvd */

#define TH_OFF(th) (((th)->th_offx2 & 0xf0) > 4)

u_char flags;

#define TH_FIN 0x01

#define TH_SYN 0x02

#define TH_RST 0x04

#define TH_PUSH 0x08

#define TH_ACK 0x10

#define TH_URG 0x20

#define TH_ECE 0x40

#define TH_CWR 0x80

#define TH_FLAGS (TH_FIN|TH_SYN|TH_RST|TH_ACK|TH_URG|TH_ECE|TH_CWR)

u_short win; /* window */

u_short sum; /* checksum */

u_short urp; /* urgent pointer */

};

/* UDP header */

struct sniff_udp {

u_short udp_srcprt;

u_short udp_destprt;

u_short udp_len;

u_short udp_sum;

};

/* DNS header */

struct sniff_dns {

u_short id;

u_short flags;

u_short numQuestions;

u_short numAnswers;

u_short numAA;

u_short numAddRecs;

};

int nPackets = 1;

int nARP = 0;

int nIP = 0;

int nBroadcast = 0;

int nICMP = 0;

int nTCP = 0;

int nDNS = 0;

int nUDP = 0;

int nPOP = 0;

int nSMTP = 0;

int nIMAP = 0;

int nHTML = 0;

char cpre580f98[] = "netdump";

void raw_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p);

int packettype;

char *program_name;

/* Externs */

extern void bpf_dump(struct bpf_program *, int);

extern char *copy_argv(char **);

/* Forwards */

void program_ending(int);

/* Length of saved portion of packet. */

int snaplen = 1500;;

static pcap_t *pd;

extern int optind;

extern int opterr;

extern char *optarg;

int pflag = 0, aflag = 0;

int

main(int argc, char **argv)

{

int cnt, op, i, done = 0;

bpf_u_int32 localnet, netmask;

char *cp, *cmdbuf, *device;

struct bpf_program fcode;

void (*oldhandler)(int);

u_char *pcap_userdata;

char ebuf[PCAP_ERRBUF_SIZE];

cnt = -1;

device = NULL;

if ((cp = strrchr(argv[0], '/')) != NULL)

program_name = cp + 1;

else

program_name = argv[0];

opterr = 0;

while ((i = getopt(argc, argv, "pa")) != -1)

{

switch (i)

{

case 'p':

pflag = 1;

break;

case 'a':

aflag = 1;

break;

case '?':

default:

done = 1;

break;

}

if (done) break;

}

if (argc > (optind)) cmdbuf = copy_argv(&argv[optind]);

else cmdbuf = "";

if (device == NULL) {

device = pcap_lookupdev(ebuf);

if (device == NULL)

error("%s", ebuf);

}

pd = pcap_open_live(device, snaplen, 1, 1000, ebuf);

if (pd == NULL)

error("%s", ebuf);

i = pcap_snapshot(pd);

if (snaplen < i) {

warning("snaplen raised from %d to %d", snaplen, i);

snaplen = i;

}

if (pcap_lookupnet(device, &localnet, &netmask, ebuf) < 0) {

localnet = 0;

netmask = 0;

warning("%s", ebuf);

}

/*

* Let user own process after socket has been opened.

*/

setuid(getuid());

if (pcap_compile(pd, &fcode, cmdbuf, 1, netmask) < 0)

error("%s", pcap_geterr(pd));

(void)setsignal(SIGTERM, program_ending);

(void)setsignal(SIGINT, program_ending);

/* Cooperate with nohup(1) */

if ((oldhandler = setsignal(SIGHUP, program_ending)) != SIG_DFL)

(void)setsignal(SIGHUP, oldhandler);

if (pcap_setfilter(pd, &fcode) < 0)

error("%s", pcap_geterr(pd));

pcap_userdata = 0;

(void)fprintf(stderr, "%s: listening on %s\n", program_name, device);

if (pcap_loop(pd, cnt, raw_print, pcap_userdata) < 0) {

(void)fprintf(stderr, "%s: pcap_loop: %s\n",

program_name, pcap_geterr(pd));

exit(1);

}

pcap_close(pd);

exit(0);

}

/* routine is executed on exit */

void program_ending(int signo)

{

struct pcap_stats stat;

if (pd != NULL & pcap_file(pd) == NULL) {

(void)fflush(stdout);

putc('\n', stderr);

if (pcap_stats(pd, &stat) < 0)

(void)fprintf(stderr, "pcap_stats: %s\n",

pcap_geterr(pd));

else {

printf("Statistics:\n______\n");

printf("Packet Counts:\n");

printf("ARP...... %d\n",nARP);

printf("IP...... %d\n",nIP);

printf("\tICMP...... %d\n",nICMP);

printf("\tTCP...... %d\n",nTCP);

printf("\t\tPOP...... %d\n",nPOP);

printf("\t\tSMTP...... %d\n",nSMTP);

printf("\t\tIMAP...... %d\n",nIMAP);

printf("\t\tHTML...... %d\n",nHTML);

printf("\tUDP...... %d\n",nUDP);

printf("\t\tDNS...... %d\n",nDNS);

//printf("BRDCST...%d\n\n",nBroadcast);

printf("\n\n");

(void)fprintf(stderr, "%d packets received by filter\n",stat.ps_recv);

(void)fprintf(stderr, "%d packets dropped by kernel\n",stat.ps_drop);

}

}

exit(0);

}

/* Like default_print() but data need not be aligned */

void

default_print_unaligned(register const u_char *cp, register u_int length)

{

register u_int i, s;

register int nshorts;

nshorts = (u_int) length / sizeof(u_short);

i = 0;

while (--nshorts >= 0) {

if ((i++ % 8) == 0)

(void)printf("\n\t\t\t");

s = *cp++;

(void)printf(" %02x%02x", s, *cp++);

}

if (length & 1) {

if ((i % 8) == 0)

(void)printf("\n\t\t\t");

(void)printf(" %02x", *cp);

}

}

/*

* By default, print the packet out in hex.

*/

void

default_print(register const u_char *bp, register u_int length)

{

/*"u_" designates a variable as unsigned*/

register const u_short *sp;

register u_int i;

register int nshorts;

u_short packet[length/2];

if ((long)bp & 1) {

default_print_unaligned(bp, length);

return;

}

sp = (u_short *)bp; /*set pointer sp equal to (u_short *)bp*/

nshorts = (u_int) length / sizeof(u_short);

i = 0;

while (--nshorts >= 0) {

packet[i] = *sp;

if ((i++ % 8) == 0)

(void)printf("\n\t");

(void)printf(" %04x", ntohs(*sp++));

}

if (length & 1) {

if ((i % 8) == 0)

(void)printf("\n\t");

(void)printf(" %02x", *(u_char *)sp);

}

putchar('\n');

}

/*

insert your code in this routine

*/

void raw_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)

{

u_short type;

int i=0, bcst=1;

u_char test;

/* declare pointers to packet headers */

const struct sniff_ethernet *ethernet; /* The ethernet header */

const struct sniff_arp *arp; /* The arp packet */

const struct sniff_ip *ip; /* The IP header */

const struct sniff_icmp *icmp; /* The ICMP header */

const struct sniff_tcp *tcp; /* The TCP header */

const struct sniff_udp *udp; /* The UDP header */

const struct sniff_dns *dns; /* The DNS header */

char *payload; /* Packet payload */

char *options_ptr; /* TCP Options Ptr */

char data[1480];

int shoPayload = 0;

ethernet = (struct sniff_ethernet*)(p);

// if (size_ip < 20) {

// printf(" * Invalid IP header length: %u bytes\n", size_ip);

// return;

// }

// tcp = (struct sniff_tcp*)(packet + SIZE_ETHERNET + size_ip);

// size_tcp = TH_OFF(tcp)*4;

// if (size_tcp < 20) {

// printf(" * Invalid TCP header length: %u bytes\n", size_tcp);

// return;

// }

// payload = (u_char *)(packet + SIZE_ETHERNET + size_ip + size_tcp);

//decode ethernet packet header

printf("Ethernet Header\n------\n");

printf("Src: %02x:%02x:%02x:%02x:%02x:%02x\n", ethernet->ether_shost[0],ethernet->ether_shost[1],ethernet->ether_shost[2],ethernet->ether_shost[3],ethernet->ether_shost[4],ethernet->ether_shost[5]);

printf("Dst: %02x:%02x:%02x:%02x:%02x:%02x\n", ethernet->ether_dhost[0],ethernet->ether_dhost[1],ethernet->ether_dhost[2],ethernet->ether_dhost[3],ethernet->ether_dhost[4],ethernet->ether_dhost[5]);

// while (i < 6) {

// printf("%x:",(u_char *)ethernet->ether_dhost[i]);

// if ("ff" != ethernet->ether_dhost[i]) {

// printf("%x:",ethernet->ether_dhost[i]);

// bcst = 0;

// }

// i++;

// }

// if (bcst == 1) {

// nBroadcast++;

// printf("Broadcast\n");

// }

type = ntohs(ethernet->ether_type);

printf("Type: %x \n", type);

switch (type) {

case 0x806:

//decode ARP packet header

arp = (struct sniff_arp*)(p + SIZE_ETHERNET);

printf("Payload = ARP\n");

printf("\n\tARP Decode\n\t------\n");

printf("\tHW type: %04x\n", arp->arp_hwtype);

printf("\tProto type: %04x\n", arp->arp_proto);

printf("\tHW Addr Len: %02x\n", arp->arp_addrlen);

printf("\tProto Len: %02x\n", arp->arp_protolen);

switch (arp->arp_operation) {

case 0x100:

printf("\tOperation: ARP Request(0x100)\n");

break;

case 0x200:

printf("\tOperation: ARP Response(0x200)\n");

break;

case 0x300:

printf("\tOperation: RARP Request(0x300)\n");

break;

case 0x400:

printf("\tOperation: RARP Reply(0x400)\n");

break;

default:

printf("\tOperation: UNDEF(0x%04x)\n", arp->arp_operation);

break;

}

printf("\tSrc: %02x:%02x:%02x:%02x:%02x:%02x\n", arp->arp_src[0],arp->arp_src[1],arp->arp_src[2],arp->arp_src[3],arp->arp_src[4],arp->arp_src[5]);

printf("\tDst: %02x:%02x:%02x:%02x:%02x:%02x\n", arp->arp_dst[0],arp->arp_dst[1],arp->arp_dst[2],arp->arp_dst[3],arp->arp_dst[4],arp->arp_dst[5]);

printf("\tSrc IP: %d.%d.%d.%d\n", arp->arp_src_proto_addr[0],arp->arp_src_proto_addr[1],arp->arp_src_proto_addr[2],arp->arp_src_proto_addr[3]);

printf("\tDst IP: %d.%d.%d.%d\n", arp->arp_dst_proto_addr[0],arp->arp_dst_proto_addr[1],arp->arp_dst_proto_addr[2],arp->arp_dst_proto_addr[3]);

nARP++;

break;

case 0x800:

//decode IP packet header

ip = (struct sniff_ip*)(p + SIZE_ETHERNET);

printf("Payload = IP\n");

printf("\n\tIP Header\n\t------\n");

printf("\tSrc: %d.%d.%d.%d\n", ip->ip_src[0],ip->ip_src[1],ip->ip_src[2],ip->ip_src[3]);

printf("\tDst: %d.%d.%d.%d\n", ip->ip_dst[0],ip->ip_dst[1],ip->ip_dst[2],ip->ip_dst[3]);

printf("\tIP Version: %x\n", (ip->ip_vhl) > 4);

printf("\tHeader Len: %x\n",(ip->ip_vhl) & 0x0F);

printf("\tTOS: %x\n", ip->ip_tos);

printf("\tLength: %d\n", ntohs(ip->ip_len));

printf("\tPacket ID: %d\n", ntohs(ip->ip_id));

switch (ntohs(ip->ip_off) > 13) {

case 0:

printf("\tFlags: None\n");

break;

case 1:

printf("\tFlags: More Fragments\n");

break;

case 2:

printf("\tFlags: Do not Fragment\n");

break;

}

printf("\tOffset: %d\n", ntohs(ip->ip_off) & 0x1fff);

printf("\tTTL: %d\n", ip->ip_ttl);

printf("\tChecksum: %d\n", ntohs(ip->ip_sum));

switch (ip->ip_p) {

case 1:

//decode ICMP packet header

printf("\tProtocol: ICMP (1)\n");

icmp = (struct sniff_icmp*)(p + SIZE_ETHERNET +20);

printf("\n\t\tICMP Decode\n\t\t------\n");

switch (icmp->icmp_type) {

case 0:

printf("\t\tType: Echo Reply(%d)\n",icmp->icmp_type);

break;

case 3:

printf("\t\tType: Destination Unreachable(3)\n");

break;

case 4:

printf("\t\tType: Source Quench(4)\n");

break;

case 5:

printf("\t\tType: Redirect(5)\n");

break;

case 8:

printf("\t\tType: Echo(8)\n");

break;

default:

printf("\t\tType: UNDEF\n");

break;

}

printf("\t\tCode: %x\n", icmp->icmp_code);

printf("\t\tChecksum: %d\n", icmp->icmp_sum);

nICMP++;

break;

case 6:

//decode TCP packet header

printf("\tProtocol: TCP(6)\n");

tcp = (struct sniff_tcp*)(p + SIZE_ETHERNET + 20);

printf("\n\t\tTCP Decode\n\t\t------\n");

printf("\t\tSource Port: %d\n", ntohs(tcp->srcprt));

printf("\t\tDest Port: %d\n", ntohs(tcp->destprt));

printf("\t\tSequence #: %d\n", ntohs(tcp->seq));

printf("\t\tAck #: %d\n", ntohs(tcp->ack));

printf("\t\tHdr Len: %d\n", (tcp->hdrlen) >4);

printf("\t\t\tFIN: %d\n", tcp->flags & TH_FIN );

printf("\t\t\tSYN: %d\n", ((tcp->flags) & TH_SYN) >1);

printf("\t\t\tRST: %d\n", ((tcp->flags) & TH_RST) >2);

printf("\t\t\tPSH: %d\n", ((tcp->flags) & TH_PUSH) >3);

printf("\t\t\tACK: %d\n", ((tcp->flags) & TH_ACK) >4);

printf("\t\t\tURG: %d\n", ((tcp->flags) & TH_URG) >5);

printf("\t\tWindow: %d\n", ntohs(tcp->win));

printf("\t\tChecksum: %d\n", ntohs(tcp->sum));

printf("\t\tUrgent Pointer: %x\n", ntohs(tcp->urp));

printf("\t\tOptions:");

//set the position of the options pointer and print any TCP packet Options

options_ptr = (u_char *)(p + SIZE_ETHERNET + SIZE_IPHDR + 20);

if ((tcp->hdrlen > 4) > 5) {

for( i = 0; i < (tcp->hdrlen > 4)*4 - 20; i++) {

printf(" %02x", options_ptr[i] );

}

}

nTCP++;

//increment TCP packet counters for POP, SMTP, and IMAP

if (ntohs(tcp->srcprt) == 110 | ntohs(tcp->destprt) == 110) {

nPOP++;

shoPayload = 1;

}

if (ntohs(tcp->srcprt) == 25 | ntohs(tcp->destprt) == 25) {

nSMTP++;

shoPayload = 1;

}

if (ntohs(tcp->srcprt) == 143 | ntohs(tcp->destprt) == 143) {

nIMAP++;

shoPayload = 1;

}

if (ntohs(tcp->srcprt) == 80 | ntohs(tcp->destprt) == 80) {

nHTML++;

shoPayload = 1;

}

//if the TCP packet is a PSH packet, print out the TCP packet Payload

if (shoPayload == 1) {

if (((tcp->flags) & TH_PUSH) >3 == 1) {

printf("\n");

payload = (u_char *)(p + SIZE_ETHERNET + SIZE_IPHDR + ((tcp->hdrlen) > 4)*4 );

printf("\nTCP Payload(%d)\n------\n",ntohs(ip->ip_len)-(((tcp->hdrlen) > 4)*4) );

for( i = 0; i < ntohs(ip->ip_len)-(((tcp->hdrlen)> 4)*4); i++) {

printf("%c", payload[i] );

}

}

}

printf("\n\n");

break;

case 17:

printf("\tProtocol: UDP(17)\n");

udp = (struct sniff_udp*)(p + SIZE_ETHERNET + 20);

printf("\n\t\tUDP Decode\n\t\t------\n");

printf("\t\tSource Port: %d\n", ntohs(udp->udp_srcprt));

printf("\t\tDest Port: %d\n", ntohs(udp->udp_destprt));

printf("\t\tLenth: %d\n", ntohs(udp->udp_len));

printf("\t\tChecksum: %d\n", ntohs(udp->udp_sum));

nUDP++;

if (ntohs(udp->udp_srcprt) == 53 | ntohs(udp->udp_destprt) == 53)

nDNS++;

break;

default:

printf("\tProtocol is UNDEF(%d)\n", ip->ip_p);

break;

}

nIP++;

break;

default:

printf("\tPayload is UNDEF");

break;

}

u_int length = h->len;

u_int caplen = h->caplen;

default_print(p, caplen);

putchar('\n');

}