tcpdump.c
来自「TCPDUMP的C语言源代码,是在数据链路层的应用」· C语言 代码 · 共 1,726 行 · 第 1/3 页
C
1,726 行
else { for (i = 0; devpointer != 0; i++) { printf("%d.%s", i+1, devpointer->name); if (devpointer->description != NULL) printf(" (%s)", devpointer->description); printf("\n"); devpointer = devpointer->next; } } return 0;#endif /* HAVE_PCAP_FINDALLDEVS */ case 'L': Lflag++; break; case 'e': ++eflag; break; case 'E':#ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in");#endif gndo->ndo_espsecret = optarg; break; case 'f': ++fflag; break; case 'F': infile = optarg; break; case 'G': Gflag = atoi(optarg); if (Gflag < 0) error("invalid number of seconds %s", optarg); /* We will create one file initially. */ Gflag_count = 0; /* Grab the current time for rotation use. */ if ((Gflag_time = time(NULL)) == (time_t)-1) { error("main: can't get current time: %s", pcap_strerror(errno)); } break; case 'i': if (optarg[0] == '0' && optarg[1] == 0) error("Invalid adapter index"); #ifdef HAVE_PCAP_FINDALLDEVS /* * If the argument is a number, treat it as * an index into the list of adapters, as * printed by "tcpdump -D". * * This should be OK on UNIX systems, as interfaces * shouldn't have names that begin with digits. * It can be useful on Windows, where more than * one interface can have the same name. */ if ((devnum = atoi(optarg)) != 0) { if (devnum < 0) error("Invalid adapter index"); if (pcap_findalldevs(&devpointer, ebuf) < 0) error("%s", ebuf); else { for (i = 0; i < devnum-1; i++){ devpointer = devpointer->next; if (devpointer == NULL) error("Invalid adapter index"); } } device = devpointer->name; break; }#endif /* HAVE_PCAP_FINDALLDEVS */ device = optarg; break;#ifdef HAVE_PCAP_CREATE case 'I': ++Iflag; break;#endif /* HAVE_PCAP_CREATE */ case 'l':#ifdef WIN32 /* * _IOLBF is the same as _IOFBF in Microsoft's C * libraries; the only alternative they offer * is _IONBF. * * XXX - this should really be checking for MSVC++, * not WIN32, if, for example, MinGW has its own * C library that is more UNIX-compatible. */ setvbuf(stdout, NULL, _IONBF, 0);#else /* WIN32 */#ifdef HAVE_SETLINEBUF setlinebuf(stdout);#else setvbuf(stdout, NULL, _IOLBF, 0);#endif#endif /* WIN32 */ break; case 'K': ++Kflag; break; case 'm':#ifdef LIBSMI if (smiLoadModule(optarg) == 0) { error("could not load MIB module %s", optarg); } sflag = 1;#else (void)fprintf(stderr, "%s: ignoring option `-m %s' ", program_name, optarg); (void)fprintf(stderr, "(no libsmi support)\n");#endif break; case 'M': /* TCP-MD5 shared secret */#ifndef HAVE_LIBCRYPTO warning("crypto code not compiled in");#endif tcpmd5secret = optarg; break; case 'n': ++nflag; break; case 'N': ++Nflag; break; case 'O': Oflag = 0; break; case 'p': ++pflag; break; case 'q': ++qflag; ++suppress_default_print; break; case 'r': RFileName = optarg; break; case 'R': Rflag = 0; break; case 's': { char *end; snaplen = strtol(optarg, &end, 0); if (optarg == end || *end != '\0' || snaplen < 0 || snaplen > 65535) error("invalid snaplen %s", optarg); else if (snaplen == 0) snaplen = 65535; break; } case 'S': ++Sflag; break; case 't': ++tflag; break; case 'T': if (strcasecmp(optarg, "vat") == 0) packettype = PT_VAT; else if (strcasecmp(optarg, "wb") == 0) packettype = PT_WB; else if (strcasecmp(optarg, "rpc") == 0) packettype = PT_RPC; else if (strcasecmp(optarg, "rtp") == 0) packettype = PT_RTP; else if (strcasecmp(optarg, "rtcp") == 0) packettype = PT_RTCP; else if (strcasecmp(optarg, "snmp") == 0) packettype = PT_SNMP; else if (strcasecmp(optarg, "cnfp") == 0) packettype = PT_CNFP; else if (strcasecmp(optarg, "tftp") == 0) packettype = PT_TFTP; else if (strcasecmp(optarg, "aodv") == 0) packettype = PT_AODV; else error("unknown packet type `%s'", optarg); break; case 'u': ++uflag; break;#ifdef HAVE_PCAP_DUMP_FLUSH case 'U': ++Uflag; break;#endif case 'v': ++vflag; break; case 'w': WFileName = optarg; break; case 'W': Wflag = atoi(optarg); if (Wflag < 0) error("invalid number of output files %s", optarg); WflagChars = getWflagChars(Wflag); break; case 'x': ++xflag; ++suppress_default_print; break; case 'X': ++Xflag; ++suppress_default_print; break; case 'y': gndo->ndo_dltname = optarg; gndo->ndo_dlt = pcap_datalink_name_to_val(gndo->ndo_dltname); if (gndo->ndo_dlt < 0) error("invalid data link type %s", gndo->ndo_dltname); break;#if defined(HAVE_PCAP_DEBUG) || defined(HAVE_YYDEBUG) case 'Y': { /* Undocumented flag */#ifdef HAVE_PCAP_DEBUG extern int pcap_debug; pcap_debug = 1;#else extern int yydebug; yydebug = 1;#endif } break;#endif case 'z': if (optarg) { zflag = strdup(optarg); } else { usage(); /* NOTREACHED */ } break; case 'Z': if (optarg) { username = strdup(optarg); } else { usage(); /* NOTREACHED */ } break; default: usage(); /* NOTREACHED */ } switch (tflag) { case 0: /* Default */ case 4: /* Default + Date*/ thiszone = gmt2local(0); break; case 1: /* No time stamp */ case 2: /* Unix timeval style */ case 3: /* Microseconds since previous packet */ case 5: /* Microseconds since first packet */ break; default: /* Not supported */ error("only -t, -tt, -ttt, -tttt and -ttttt are supported"); break; }#ifdef WITH_CHROOT /* if run as root, prepare for chrooting */ if (getuid() == 0 || geteuid() == 0) { /* future extensibility for cmd-line arguments */ if (!chroot_dir) chroot_dir = WITH_CHROOT; }#endif#ifdef WITH_USER /* if run as root, prepare for dropping root privileges */ if (getuid() == 0 || geteuid() == 0) { /* Run with '-Z root' to restore old behaviour */ if (!username) username = WITH_USER; }#endif if (RFileName != NULL) { int dlt; const char *dlt_name;#ifndef WIN32 /* * We don't need network access, so relinquish any set-UID * or set-GID privileges we have (if any). * * We do *not* want set-UID privileges when opening a * trace file, as that might let the user read other * people's trace files (especially if we're set-UID * root). */ if (setgid(getgid()) != 0 || setuid(getuid()) != 0 ) fprintf(stderr, "Warning: setgid/setuid failed !\n");#endif /* WIN32 */ pd = pcap_open_offline(RFileName, ebuf); if (pd == NULL) error("%s", ebuf); dlt = pcap_datalink(pd); dlt_name = pcap_datalink_val_to_name(dlt); if (dlt_name == NULL) { fprintf(stderr, "reading from file %s, link-type %u\n", RFileName, dlt); } else { fprintf(stderr, "reading from file %s, link-type %s (%s)\n", RFileName, dlt_name, pcap_datalink_val_to_description(dlt)); } localnet = 0; netmask = 0; if (fflag != 0) error("-f and -r options are incompatible"); } else { if (device == NULL) { device = pcap_lookupdev(ebuf); if (device == NULL) error("%s", ebuf); }#ifdef WIN32 if(strlen(device) == 1) //we assume that an ASCII string is always longer than 1 char { //a Unicode string has a \0 as second byte (so strlen() is 1) fprintf(stderr, "%s: listening on %ws\n", program_name, device); } else { fprintf(stderr, "%s: listening on %s\n", program_name, device); } fflush(stderr); #endif /* WIN32 */#ifdef HAVE_PCAP_CREATE pd = pcap_create(device, ebuf); if (pd == NULL) error("%s", ebuf); status = pcap_set_snaplen(pd, snaplen); if (status != 0) error("%s: pcap_set_snaplen failed: %s", device, pcap_statustostr(status)); status = pcap_set_promisc(pd, !pflag); if (status != 0) error("%s: pcap_set_promisc failed: %s", device, pcap_statustostr(status)); if (Iflag) { status = pcap_set_rfmon(pd, 1); if (status != 0) error("%s: pcap_set_rfmon failed: %s", device, pcap_statustostr(status)); } status = pcap_set_timeout(pd, 1000); if (status != 0) error("%s: pcap_set_timeout failed: %s", device, pcap_statustostr(status)); if (Bflag != 0) { status = pcap_set_buffer_size(pd, Bflag); if (status != 0) error("%s: pcap_set_buffer_size failed: %s", device, pcap_statustostr(status)); } status = pcap_activate(pd); if (status < 0) { /* * pcap_activate() failed. */ cp = pcap_geterr(pd); if (status == PCAP_ERROR) error("%s", cp); else if ((status == PCAP_ERROR_NO_SUCH_DEVICE || status == PCAP_ERROR_PERM_DENIED) && *cp != '\0') error("%s: %s\n(%s)", device, pcap_statustostr(status), cp); else error("%s: %s", device, pcap_statustostr(status)); } else if (status > 0) { /* * pcap_activate() succeeded, but it's warning us * of a problem it had. */ cp = pcap_geterr(pd); if (status == PCAP_WARNING) warning("%s", cp); else if (status == PCAP_WARNING_PROMISC_NOTSUP && *cp != '\0') warning("%s: %s\n(%s)", device, pcap_statustostr(status), cp); else warning("%s: %s", device, pcap_statustostr(status)); }#else *ebuf = '\0'; pd = pcap_open_live(device, snaplen, !pflag, 1000, ebuf); if (pd == NULL) error("%s", ebuf); else if (*ebuf) warning("%s", ebuf);#endif /* HAVE_PCAP_CREATE */ /* * Let user own process after socket has been opened. */#ifndef WIN32 if (setgid(getgid()) != 0 || setuid(getuid()) != 0) fprintf(stderr, "Warning: setgid/setuid failed !\n");#endif /* WIN32 */#if !defined(HAVE_PCAP_CREATE) && defined(WIN32) if(Bflag != 0) if(pcap_setbuff(pd, Bflag)==-1){ error("%s", pcap_geterr(pd)); }#endif /* !defined(HAVE_PCAP_CREATE) && defined(WIN32) */ if (Lflag) show_dlts_and_exit(pd); if (gndo->ndo_dlt >= 0) {#ifdef HAVE_PCAP_SET_DATALINK if (pcap_set_datalink(pd, gndo->ndo_dlt) < 0) error("%s", pcap_geterr(pd));#else /* * We don't actually support changing the * data link type, so we only let them * set it to what it already is. */ if (gndo->ndo_dlt != pcap_datalink(pd)) { error("%s is not one of the DLTs supported by this device\n", gndo->ndo_dltname); }#endif (void)fprintf(stderr, "%s: data link type %s\n", program_name, gndo->ndo_dltname); (void)fflush(stderr); } 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); } } if (infile) cmdbuf = read_infile(infile); else cmdbuf = copy_argv(&argv[optind]); if (pcap_compile(pd, &fcode, cmdbuf, Oflag, netmask) < 0) error("%s", pcap_geterr(pd)); if (dflag) { bpf_dump(&fcode, dflag); pcap_close(pd); exit(0); } init_addrtoname(localnet, netmask); init_checksum();#ifndef WIN32 (void)setsignal(SIGPIPE, cleanup); (void)setsignal(SIGTERM, cleanup); (void)setsignal(SIGINT, cleanup); (void)setsignal(SIGCHLD, child_cleanup);#endif /* WIN32 */ /* Cooperate with nohup(1) */#ifndef WIN32 if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL) (void)setsignal(SIGHUP, oldhandler);#endif /* WIN32 */ if (pcap_setfilter(pd, &fcode) < 0) error("%s", pcap_geterr(pd)); if (WFileName) { pcap_dumper_t *p; /* Do not exceed the default NAME_MAX for files. */ dumpinfo.CurrentFileName = (char *)malloc(NAME_MAX + 1); if (dumpinfo.CurrentFileName == NULL) error("malloc of dumpinfo.CurrentFileName"); /* We do not need numbering for dumpfiles if Cflag isn't set. */ if (Cflag != 0) MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, WflagChars); else MakeFilename(dumpinfo.CurrentFileName, WFileName, 0, 0); p = pcap_dump_open(pd, dumpinfo.CurrentFileName); if (p == NULL) error("%s", pcap_geterr(pd)); if (Cflag != 0 || Gflag != 0) { callback = dump_packet_and_trunc; dumpinfo.WFileName = WFileName; dumpinfo.pd = pd; dumpinfo.p = p; pcap_userdata = (u_char *)&dumpinfo; } else { callback = dump_packet; pcap_userdata = (u_char *)p; } } else { type = pcap_datalink(pd); printinfo.printer = lookup_printer(type); if (printinfo.printer == NULL) { gndo->ndo_dltname = pcap_datalink_val_to_name(type); if (gndo->ndo_dltname != NULL) error("unsupported data link type %s", gndo->ndo_dltname); else error("unsupported data link type %d", type); } callback = print_packet; pcap_userdata = (u_char *)&printinfo; }#ifndef WIN32 /* * We cannot do this earlier, because we want to be able to open * the file (if done) for writing before giving up permissions. */ if (getuid() == 0 || geteuid() == 0) { if (username || chroot_dir) droproot(username, chroot_dir); }#endif /* WIN32 */#ifdef SIGINFO /* * We can't get statistics when reading from a file rather * than capturing from a device.
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?