1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180
|
/****************************************************************************
**
** File: ipgrab.c
**
** Author: Mike Borella
**
** Comments: Sniffs all packets on the link and dumps the fields of
** the data link, IP, TCP, and UDP headers.
**
*****************************************************************************/
#include <stdio.h>
#include <unistd.h>
#include <pcap.h>
#include <malloc.h>
#include "config.h"
char *pcap_cmd; /* command string for pcap */
pcap_t *pd; /* pcap device descriptor */
int cnt; /* number of packets to read */
int datalink; /* data link layer type */
pcap_handler dev_prcsr; /* ptr to func that processes packet for a device */
struct arg_t *my_args; /* Command line arguments */
extern char version[];
/*----------------------------------------------------------------------------
*
* main()
*
*----------------------------------------------------------------------------
*/
int main(int argc, char *argv[])
{
u_char *userdata;
void ftlerr(char *,...);
void open_pcap(void);
void dump_raw(u_char *, const struct pcap_pkthdr *, const u_char *);
void dump_ethernet(u_char *, const struct pcap_pkthdr *, const u_char *);
void dump_slip(u_char *, const struct pcap_pkthdr *, const u_char *);
void init_addrtoname(void);
char *copy_argv(char **);
/*
* Clear device (interface) handle, user data and packet count
*/
userdata = NULL;
cnt = -1;
/*
* Parse command line for options
*/
my_args = parse_cl(argc, argv);
if (my_args->c)
cnt = my_args->c;
/*
* Copy filter command into a string
*/
pcap_cmd = copy_argv(&argv[my_args->optind]);
/*
* Open the pcap device for sniffing
*/
open_pcap();
/*
* Get rid of root privs
*/
setuid(getuid());
/*
* Initialize the protocol name and ID lookup tables
*/
init_addrtoname();
/*
* Print intro stuff to stderr so output files have consistent
* format
*/
fprintf(stderr, "%s %s 3Com Advanced Technologies Research Center\n",
argv[0], version);
fprintf(stderr, "Listening on device %s ", my_args->i);
/*
* Decide which processing function to use based on datalink type
*/
switch(datalink)
{
case DLT_EN10MB:
dev_prcsr = dump_ethernet;
fprintf(stderr, "(ethernet)\n");
break;
case DLT_SLIP:
dev_prcsr = dump_slip;
fprintf(stderr, "(slip)\n");
break;
#ifdef DLT_RAW /* Not supported in some arch or older pcap versions */
case DLT_RAW:
dev_prcsr = dump_raw;
fprintf(stderr, "(raw)\n");
break;
#endif
default:
ftlerr("\n%s cannot handle data link type %d", argv[0], datalink);
}
/*
* Read all packets on the device. Continue until cnt packets read
*/
if (pcap_loop(pd, cnt, dev_prcsr, userdata) < 0)
ftlerr("pcap_loop: %s", pcap_geterr(pd));
/*
* XXX Get stats here
*/
/*
* Close the pcap device
*/
pcap_close(pd);
exit(0);
}
/*----------------------------------------------------------------------------
*
* copy_argv()
*
* Copy arg vector into a new buffer, concatenating arguments with spaces.
* Lifted from tcpdump.
*
*----------------------------------------------------------------------------
*/
char *copy_argv(char **argv)
{
char **p;
u_int len = 0;
char *buf;
char *src, *dst;
void ftlerr(char *, ...);
p = argv;
if (*p == 0) return 0;
while (*p)
len += strlen(*p++) + 1;
buf = (char *) malloc (len);
if (buf == NULL) ftlerr("copy_argv: malloc() failed");
p = argv;
dst = buf;
while ((src = *p++) != NULL)
{
while ((*dst++ = *src++) != '\0');
dst[-1] = ' ';
}
dst[-1] = '\0';
return buf;
}
|