📄 tcpdump.c
字号:
if (!pcap_device)
PERROR ((ebuf));
}
pd = pcap_open_live (pcap_device, snaplen, !pflag, 0, ebuf);
if (!pd)
PERROR ((ebuf));
if (!pd)
WARNING ((ebuf));
if (Lflag)
show_dlts_and_exit (pd);
if (dlt >= 0)
{
if (pcap_set_datalink(pd, dlt) < 0)
PERROR (("%s", pcap_geterr(pd)));
fprintf (stderr, "%s: data link type %s\n", program_name, dlt_name);
}
i = pcap_snapshot (pd);
if (snaplen < i)
{
WARNING (("snaplen raised from %d to %d", snaplen, i));
snaplen = i;
}
if (pcap_lookupnet (pcap_device, (bpf_u_int32*)&localnet,
(bpf_u_int32*)&netmask, ebuf) < 0)
{
localnet = 0;
netmask = 0;
WARNING ((ebuf));
}
}
/* Hook handlers for SIGINT, SIGBREAK and SIGQUIT
*/
init_handlers();
if (infile)
cmdbuf = read_infile (infile);
else cmdbuf = copy_argv (&argv[optind]);
if (pcap_compile (pd, &fcode, cmdbuf, Oflag, netmask) < 0)
{
program_end (0);
PERROR ((pcap_geterr(pd)));
}
if (snaplen < 102 && fcode.bf_insns[3].k == 36)
WARNING (("snaplen < 102, XTP headers will be truncated"));
if (dflag)
{
program_end (1);
bpf_dump (&fcode, dflag);
return (0);
}
init_addrtoname (nflag, localnet, netmask);
if (pcap_setfilter(pd,&fcode) < 0)
{
program_end (0);
PERROR ((pcap_geterr(pd)));
}
if (WFileName)
{
pcap_dumper_t *p = pcap_dump_open (pd, WFileName);
if (!p)
{
program_end (0);
PERROR ((pcap_geterr(pd)));
}
printer = pcap_dump;
pcap_userdata = (u_char*)p;
if (vflag)
pcap_verbose (1);
}
else
{
printer = lookup_printer (pcap_datalink(pd));
pcap_userdata = 0;
}
if (use_conio)
{
#ifdef USE_CONIO
set_conio();
#else
program_end (1);
PERROR (("`-C' option not supported in this version."));
#endif
}
if (!RFileName)
{
char buf[50];
sprintf (buf, "%s: listening on %s\n",
program_name, pcap_device ? pcap_device : "all devices");
#ifdef USE_CONIO
if (use_conio)
PRINTF (buf);
else fprintf (stderr, buf);
#else
fprintf (stderr, buf);
#endif
}
if (pcap_loop(pd,count,printer,pcap_userdata) < 0)
{
fprintf (stderr, "%s: pcap_loop: %s\n", program_name, pcap_geterr(pd));
rc = 1;
}
dump_stats();
program_end (1);
if (Hflag && !RFileName)
dump_hostnames();
return (rc);
}
static void program_end (int free_mem)
{
static int done = 0;
if (!done)
{
pcap_close (pd);
if (free_mem)
{
free (pd);
pd = NULL;
}
done = 1;
}
}
/*
* Can't print the summary if reading from a savefile
*/
static void dump_stats (void)
{
struct pcap_stat stat;
struct pcap_stat_ex stat_ex;
if (!pd || pcap_file(pd))
return;
if (pcap_stats(pd,&stat) < 0)
fprintf (stderr, "pcap_stats: %s\n", pcap_geterr(pd));
else
{
fprintf (stderr, "packets received by filter: %-6lu\n", stat.ps_recv);
fprintf (stderr, "packets passed thru filter: %-6lu\n", pcap_filter_packets());
if (stat.ps_recv)
{
fprintf (stderr, "packets dropped by kernel/pcap: %-6lu (%.1f%%)\n",
stat.ps_drop,
100.0 * (double)stat.ps_drop / (double)stat.ps_recv);
fprintf (stderr, "packets dropped by driver/hw: %-6lu (%.1f%%)\n",
stat.ps_ifdrop,
100.0 * (double)stat.ps_ifdrop / (double)stat.ps_recv);
}
}
if (pcap_stats_ex (pd,&stat_ex) >= 0) /* extended statistics */
{
fprintf (stderr,
"details: packets %lu, bytes %lu, dropped %lu, errors %lu, collisions %lu\n"
" FIFO err %lu, overruns %lu, framing %lu, len err %lu, CRC err %lu\n",
stat_ex.rx_packets, stat_ex.rx_bytes, stat_ex.rx_dropped,
stat_ex.rx_errors, stat_ex.collisions, stat_ex.rx_fifo_errors,
stat_ex.rx_over_errors, stat_ex.rx_frame_errors,
stat_ex.rx_length_errors, stat_ex.rx_crc_errors);
}
}
/*
* Like default_print() but data need not be aligned
*/
void default_print_unaligned (const u_char *cp, u_int length)
{
int nshorts = length / sizeof(u_short);
u_int s, i = 0;
if (xaflag)
{
dump_hex_ascii (cp,length);
return;
}
if (Aflag)
{
dump_ascii (cp,length);
return;
}
while (--nshorts >= 0)
{
if ((i++ % 8) == 0)
PUTS ("\n\t\t\t");
s = *cp++;
PRINTF (" %02x%02x", s, *cp++);
}
if (length & 1)
{
if ((i % 8) == 0)
PUTS ("\n\t\t\t");
PRINTF (" %02x", *cp);
}
}
void default_print (const u_char *bp, u_int length)
{
const u_short *sp;
u_int i;
int nshorts;
if (xaflag)
{
dump_hex_ascii (bp,length);
return;
}
if (Aflag)
{
dump_ascii (bp,length);
return;
}
#if 0
if (!xflag)
{
PUTCHAR ('\n');
print_data (bp, length);
return;
}
#endif
if ((unsigned)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)
PUTS ("\n\t\t\t");
PRINTF (" %04x", ntohs (*sp++));
}
if (length & 1)
{
if ((i % 8) == 0)
PUTS ("\n\t\t\t");
PRINTF (" %02x", *(u_char*)sp);
}
}
static void dump_ascii (const u_char *bp, u_int length)
{
char buf [5000];
char *ptr = buf;
*ptr++ = '\n';
while ((int)length-- > 0)
{
if (*bp > 0x7E || isprint(*bp))
*ptr++ = *bp++;
else
{
/* Convert control characters, e.g. 13 -> "\r", 0 -> "^@"
*/
switch (*bp)
{
case '\r':
strcpy (ptr,"\\r");
break;
case '\n':
strcpy (ptr,"\\n\n");
ptr++;
break;
case '\t':
strcpy (ptr,"\\t");
break;
default:
ptr[0] = '^';
ptr[1] = *bp + '@';
}
ptr += 2;
bp++;
}
}
if (ptr > buf+1)
{
*ptr = '\0';
PUTS (buf);
}
}
static void dump_hex_ascii (const u_char *bp, u_int length)
{
u_int ofs, j;
for (ofs = 0; ofs < length; ofs += 16)
{
char buf [80];
PRINTF ("\n\t%04X: ", ofs);
for (j = 0; j < 16 && j+ofs < length; j++)
PRINTF ("%02X ", (unsigned)bp[j+ofs]);
if (j < 16)
PRINTF ("%*s", 3*(16-j), "");
for (j = 0; j < 16 && j+ofs < length; j++)
{
u_char ch = bp[j+ofs];
if (ch < ' ')
ch = '.';
buf[j] = ch;
}
PRINTF ("%.*s", (int)j, buf);
}
}
/*
* Print a usage message, optionally full details
*/
static void program_usage (int details)
{
char features[80] = { '\0' };
#if defined (__HIGHC__)
static char *builder = "HighC/Pharlap";
#elif defined (__DJGPP__)
static char *builder = "GNU-C/djgpp2";
#elif defined (__WATCOMC__)
static char *builder = "Watcom-C";
#else
static char *builder = "??";
#endif
printf ("Version %s (%s). pcap v%d.%d\n"
"Usage: %s%s [-?adDeEfhLlnNOpPqRStuvxXC] [-c count] [-F file]\n"
" [-i interface] [-M type] [-r file] [-s snaplen]\n"
" [-E espkey] [m module] [-T type] [-w file] [filter-expression]\n\n",
TCPDUMP_VERSION, builder, PCAP_VERSION_MAJOR, PCAP_VERSION_MINOR,
program_path, program_name);
if (details)
{
printf (
"options: -a translate network/broadcast addresses to names\n"
" -b parse only link-layer protocol <p>\n"
" -c stop after receiving count packets\n"
" -d dump compiled filter expression and stop\n"
" -D dump info on supported devices\n"
" -e print link-level header on each line\n"
" -E secret for decrypting ESP packets\n"
" -f print foreign ip-addresses numerically\n"
" -F read filter expression from file\n"
" -h write resolved host names to `hosts.add' file\n"
" -i select interface. Use `-i?' for supported drivers\n"
" -L list available data link types and exit\n"
" -l make stdout line buffered\n"
" -M specify message type for SunRPC protocols (-M? for list)\n"
" -m load SMI MIB module definitions from file\n"
" -n print addresses numerically\n"
" -N don't print domain of host names\n"
" -O don't run packet-matching optimiser\n"
" -p don't set network driver in promiscuous mode\n"
" -P print details for some SunRPC protocols\n"
" -q quick output; prints short packet-trace\n"
" -r read packet data from file\n"
" -R print packets read from file at real pace\n"
" -s truncate the packets to snaplen (%d)\n"
" -S print absolute TCP sequence numbers\n"
" -t don't print a timestamp on each dump line\n"
" -tt print timestamp in Unix style\n"
" -ttt print times in time-deltas\n"
" -tttt print time and date (MM/DD/YYYY)\n"
" -T force interpretion to specified type (-T? for list)\n"
" -u print undecoded NFS handles\n"
" -v verbose output; prints IP-tos/ttl etc.\n"
" -w write packet data to file (see -r)\n"
" -A print packet contents in ascii (without headers)\n"
" -x print packet contents in hex\n"
" -X print packet contents in hex and ascii\n"
" -C print using direct screen write\n", DEFAULT_SNAPLEN);
#ifdef USE_INET6
strcat (features, "IPv6, ");
#endif
#ifdef PRINT_NETBIOS_DETAILS
strcat (features, "NetBIOS details, ");
#endif
#ifdef PRINT_DECNET_DETAILS
strcat (features, "DEC-Net details, ");
#endif
#ifdef USE_RSVP
strcat (features, "RSVP decoding, ");
#endif
#ifdef USE_SSL
strcat (features, "SSL decoding, ");
#endif
#ifdef LIBSMI
strcat (features, "MIB modules, ");
#endif
*strrchr (features, ',') = '.';
printf ("Built-in features: %s\n", features);
}
exit (-1);
}
#ifdef __DJGPP__
/*
* Disable wildcard expansion on command-line
*/
char **__crt0_glob_function (char *arg)
{
return (char**)0;
}
static int old_sigquit = -1;
#endif
/*
* called on a interrupt signal
*/
static void sigint_task (void)
{
#ifdef __DJGPP__
if (old_sigquit != -1)
__djgpp_set_sigquit_key (old_sigquit);
#endif
#ifdef __HIGHC__
_dx_reset_data();
#endif
#ifdef USE_CONIO
if (use_conio)
unset_conio();
else
#endif
putc ('\n', stderr);
dump_stats();
program_end (1);
if (Hflag && !RFileName)
dump_hostnames();
exit (0);
}
/*
* Signal handler for SIGINT/SIGBREAK (^C/^Break).
*/
static void sig_handler (int sig)
{
signal (sig, sig_handler);
if (sig == SIGINT)
sigint_task();
#ifdef SIGBREAK
if (sig == SIGBREAK)
sigint_task();
#endif
#ifdef SIGQUIT
if (sig == SIGQUIT)
sigint_task();
#endif
fprintf (stderr, "Illegal signal %d\n", sig);
}
/*
* Setup handlers for SIGINT,SIGBREAK and SIGQUIT.
* SIGSEGV, SIGILL and SIGFPE handlers are already installed
* in pcap_open_live(). Should maybe reset them here.
*/
static void init_handlers (void)
{
#if defined(__DJGPP__)
old_sigquit = __djgpp_set_sigquit_key (1); /* Make-code for ESC */
set_cbreak (break_mode);
#endif
#ifdef SIGBREAK
signal (SIGBREAK, sig_handler);
#endif
#ifdef SIGQUIT
signal (SIGQUIT, sig_handler);
#endif
signal (SIGINT, sig_handler);
#if defined(__HIGHC__)
InstallExcHandler (NULL);
#endif
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -