I'm required to write a packet sniffer in the C programming language and Identify the Packet as IP, ARP, or Broadcast and count how many packets of each. I'm able to get IP packets identified and counted, but don't seem to be seeing any ARP or Broadcasts correctly or count them.
I also get this warning when I compile my code:
/netdump.c: In function 'raw_print':
./netdump.c:284: warning: cast to pointer from integer of different size
./netdump.c:285: warning: comparison between pointer and integer
Any help is appreciated!!! I'm more concerned with why I'm not getting any ARP or Broadcast packets being identified and counted.
Thanks Again,
JW
#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
#define ETHER_ADDR_LEN 6
#define SIZE_ETHERNET 14
#define SIZE_IPHDR 20
struct sniff_ethernet {
u_char ether_dhost[ETHER_ADDR_LEN];
u_char ether_shost[ETHER_ADDR_LEN];
u_short ether_type;
};
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];
};
struct sniff_ip {
u_char ip_vhl;
u_char ip_tos;
u_short ip_len;
u_short ip_id;
u_short ip_off;
#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;
u_char ip_p;
u_short ip_sum;
u_char ip_src[4];
u_char ip_dst[4];
};
int nPackets = 1;
int nARP = 0;
int nIP = 0;
int nBroadcast = 0;
char cpre580f98[] = "netdump";
void raw_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p);
int packettype;
char *program_name;
extern void bpf_dump(struct bpf_program *, int);
extern char *copy_argv(char **);
void program_ending(int);
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);
}
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);
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);
}
void program_ending(int signo)
{
struct pcap_stat 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("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);
}
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);
}
}
void
default_print(register const u_char *bp, register u_int length)
{
register const u_short *sp;
register u_int i;
register int nshorts;
if ((long)bp & 1) {
default_print_unaligned(bp, length);
return;
}
sp = (u_short *)bp;
nshorts = (u_int) length / sizeof(u_short);
i = 0;
while (--nshorts >= 0) {
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);
}
}
void raw_print(u_char *user, const struct pcap_pkthdr *h, const u_char *p)
{
const struct sniff_ethernet *ethernet;
const struct sniff_arp *arp;
const struct sniff_ip *ip;
char *payload;
char data[1480];
int shoPayload = 0;
ethernet = (struct sniff_ethernet*)(p);
u_short type;
int i=0, bcst=1;
u_char test;
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("\nType: 0x%x \n", type);
switch (type) {
case 0x806:
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);
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]);
nARP++;
break;
case 0x800:
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("\tLength: %d\n", ntohs(ip->ip_len));
nIP++;
break;
}
u_int length = h->len;
u_int caplen = h->caplen;
default_print(p, caplen);
putchar('\n');
}