예제 #1
0
static void
show_dlts_and_exit(pcap_t *pd)
{
	int n_dlts;
	int *dlts = 0;
	const char *dlt_name;

	n_dlts = pcap_list_datalinks(pd, &dlts);
	if (n_dlts < 0)
		error("%s", pcap_geterr(pd));
	else if (n_dlts == 0 || !dlts)
		error("No data link types.");

	(void) fprintf(stderr, "Data link types (use option -y to set):\n");

	while (--n_dlts >= 0) {
		dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
		if (dlt_name != NULL) {
			(void) fprintf(stderr, "  %s (%s)", dlt_name,
			    pcap_datalink_val_to_description(dlts[n_dlts]));

			/*
			 * OK, does tcpdump handle that type?
			 */
			if (lookup_printer(dlts[n_dlts]) == NULL)
				(void) fprintf(stderr, " (not supported)");
			putchar('\n');
		} else {
			(void) fprintf(stderr, "  DLT %d (not supported)\n",
			    dlts[n_dlts]);
		}
	}
	free(dlts);
	exit(0);
}
예제 #2
0
static u_int
ppi_print(netdissect_options *ndo,
               const struct pcap_pkthdr *h, const u_char *p)
{
	if_printer printer;
	const ppi_header_t *hdr;
	u_int caplen = h->caplen;
	u_int length = h->len;
	uint16_t len;
	uint32_t dlt;
	uint32_t hdrlen;
	struct pcap_pkthdr nhdr;

	if (caplen < sizeof(ppi_header_t)) {
		ND_PRINT((ndo, "[|ppi]"));
		return (caplen);
	}

	hdr = (const ppi_header_t *)p;
	len = EXTRACT_LE_16BITS(&hdr->ppi_len);
	if (caplen < len) {
		/*
		 * If we don't have the entire PPI header, don't
		 * bother.
		 */
		ND_PRINT((ndo, "[|ppi]"));
		return (caplen);
	}
	if (len < sizeof(ppi_header_t)) {
		ND_PRINT((ndo, "[|ppi]"));
		return (len);
	}
	dlt = EXTRACT_LE_32BITS(&hdr->ppi_dlt);

	if (ndo->ndo_eflag)
		ppi_header_print(ndo, p, length);

	length -= len;
	caplen -= len;
	p += len;

	if ((printer = lookup_printer(dlt)) != NULL) {
		nhdr = *h;
		nhdr.caplen = caplen;
		nhdr.len = length;
		hdrlen = printer(ndo, &nhdr, p);
	} else {
		if (!ndo->ndo_eflag)
			ppi_header_print(ndo, (const u_char *)hdr, length + len);

		if (!ndo->ndo_suppress_default_print)
			ND_DEFAULTPRINT(p, caplen);
		hdrlen = 0;
	}
	return (len + hdrlen);
}
예제 #3
0
static void
show_dlts_and_exit(const char *device, pcap_t *pd)
{
	int n_dlts;
	int *dlts = 0;
	const char *dlt_name;

	n_dlts = pcap_list_datalinks(pd, &dlts);
	if (n_dlts < 0)
		error("%s", pcap_geterr(pd));
	else if (n_dlts == 0 || !dlts)
		error("No data link types.");

	/*
	 * If the interface is known to support monitor mode, indicate
	 * whether these are the data link types available when not in
	 * monitor mode, if -I wasn't specified, or when in monitor mode,
	 * when -I was specified (the link-layer types available in
	 * monitor mode might be different from the ones available when
	 * not in monitor mode).
	 */
	if (supports_monitor_mode)
		(void) fprintf(stderr, "Data link types for %s %s (use option -y to set):\n",
		    device,
		    Iflag ? "when in monitor mode" : "when not in monitor mode");
	else
		(void) fprintf(stderr, "Data link types for %s (use option -y to set):\n",
		    device);

	while (--n_dlts >= 0) {
		dlt_name = pcap_datalink_val_to_name(dlts[n_dlts]);
		if (dlt_name != NULL) {
			(void) fprintf(stderr, "  %s (%s)", dlt_name,
			    pcap_datalink_val_to_description(dlts[n_dlts]));

			/*
			 * OK, does tcpdump handle that type?
			 */
			if (lookup_printer(dlts[n_dlts]) == NULL
                            && lookup_ndo_printer(dlts[n_dlts]) == NULL)
				(void) fprintf(stderr, " (printing not supported)");
			putchar('\n');
		} else {
			(void) fprintf(stderr, "  DLT %d (printing not supported)\n",
			    dlts[n_dlts]);
		}
	}
	free(dlts);
	exit(0);
}
예제 #4
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ether header of the packet, 'h->ts' is the timestamp,
 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
u_int
pktap_if_print(netdissect_options *ndo,
               const struct pcap_pkthdr *h, const u_char *p)
{
	uint32_t dlt, hdrlen, rectype;
	u_int caplen = h->caplen;
	u_int length = h->len;
	if_printer printer;
	const pktap_header_t *hdr;
	struct pcap_pkthdr nhdr;

	ndo->ndo_protocol = "pktap_if";
	if (caplen < sizeof(pktap_header_t)) {
		nd_print_trunc(ndo);
		return (caplen);
	}
	hdr = (const pktap_header_t *)p;
	dlt = EXTRACT_LE_U_4(hdr->pkt_dlt);
	hdrlen = EXTRACT_LE_U_4(hdr->pkt_len);
	if (hdrlen < sizeof(pktap_header_t)) {
		/*
		 * Claimed header length < structure length.
		 * XXX - does this just mean some fields aren't
		 * being supplied, or is it truly an error (i.e.,
		 * is the length supplied so that the header can
		 * be expanded in the future)?
		 */
		nd_print_trunc(ndo);
		return (caplen);
	}
	if (caplen < hdrlen) {
		nd_print_trunc(ndo);
		return (caplen);
	}

	if (ndo->ndo_eflag)
		pktap_header_print(ndo, p, length);

	length -= hdrlen;
	caplen -= hdrlen;
	p += hdrlen;

	rectype = EXTRACT_LE_U_4(hdr->pkt_rectype);
	switch (rectype) {

	case PKT_REC_NONE:
		ND_PRINT("no data");
		break;

	case PKT_REC_PACKET:
		if ((printer = lookup_printer(dlt)) != NULL) {
			nhdr = *h;
			nhdr.caplen = caplen;
			nhdr.len = length;
			hdrlen += printer(ndo, &nhdr, p);
		} else {
			if (!ndo->ndo_eflag)
				pktap_header_print(ndo, (const u_char *)hdr,
						length + hdrlen);

			if (!ndo->ndo_suppress_default_print)
				ND_DEFAULTPRINT(p, caplen);
		}
		break;
	}

	return (hdrlen);
}
예제 #5
0
int main(int argc, char *argv[])
{
	struct bpf_program fcode;
	pcap_handler printer;
	char ebuf[PCAP_ERRBUF_SIZE];
	int c,i,snaplen=512,size,packetcnt;
	bpf_u_int32 myself, localnet, netmask;
	unsigned char *pcap_userdata;

	filter_rule = argv[1];
	signal(SIGINT,sig_int);

	opterr =0;
	if(argc-1 <1)
	{
		usage();
		exit(1);
	}

	while( (c=getopt(argc,argv,"i:c:pher")) != -1) {
		switch(c) {
			case 'i' :
				device = optarg;
				break;
			case 'p' :
				pflag = 1;
				break;
			case 'c':
				cflag = 1;
				packetcnt = atoi(optarg);
				if(packetcnt <=0) {
					fprintf(stderr, "invalid pacet number %s",optarg);
					exit(1);
				}
				break;
			case 'e':
				eflag =1;
				break;
			case 'r':
				rflag =1;
				break;
			case 'h':
				usage();
				exit(1);
		}
	}

	if(device == NULL) {
		if( (device = pcap_lookupdev(ebuf) ) ==NULL)
		{
			perror(ebuf);
			exit(-1);
		}
	}
	fprintf(stdout,"device = %s\n", device);

	pd = pcap_open_live(device , snaplen, PROMISCOUS, 1000, ebuf);
	if(pd == NULL) {
		perror(ebuf);
		exit(-1);
	}

	i = pcap_snapshot(pd);
	if(snaplen <i) {
		perror(ebuf);
		exit(-1);
		}
	if(pcap_lookupnet(device, &localnet, &netmask, ebuf) <0) {
		perror(ebuf);
		exit(-1);
	}

	setuid(getuid());

	if(pcap_compile(pd, &fcode, filter_rule , 0, netmask)<0) {
		perror(ebuf);
		exit(-1);
	}

	if(pcap_setfilter(pd, &fcode) <0) {
		perror(ebuf);
		exit(-1);
	}

	fflush(stderr);

	printer = lookup_printer(pcap_datalink(pd));
	pcap_userdata = 0;
	if(pcap_loop(pd,packetcnt, printer, pcap_userdata) <0) {
		perror("pcap_loop error");
		exit(-1);
	}
	
	pcap_close(pd);
	exit(0);
}
예제 #6
0
/*
 * This is the top level routine of the printer.  'p' points
 * to the ether header of the packet, 'h->ts' is the timestamp,
 * 'h->len' is the length of the packet off the wire, and 'h->caplen'
 * is the number of bytes actually captured.
 */
u_int
pktap_if_print(struct netdissect_options *ndo,
               const struct pcap_pkthdr *h, const u_char *p)
{
	uint32_t dlt, hdrlen, rectype;
	u_int caplen = h->caplen;
	u_int length = h->len;
	if_ndo_printer ndo_printer;
        if_printer printer;
	pktap_header_t *hdr;

	if (caplen < sizeof(pktap_header_t) || length < sizeof(pktap_header_t)) {
		ND_PRINT((ndo, "[|pktap]"));
		return (0);
	}
	hdr = (pktap_header_t *)p;
	dlt = EXTRACT_LE_32BITS(&hdr->pkt_dlt);
	hdrlen = EXTRACT_LE_32BITS(&hdr->pkt_len);
	if (hdrlen < sizeof(pktap_header_t)) {
		/*
		 * Claimed header length < structure length.
		 * XXX - does this just mean some fields aren't
		 * being supplied, or is it truly an error (i.e.,
		 * is the length supplied so that the header can
		 * be expanded in the future)?
		 */
		ND_PRINT((ndo, "[|pktap]"));
		return (0);
	}
	if (caplen < hdrlen || length < hdrlen) {
		ND_PRINT((ndo, "[|pktap]"));
		return (hdrlen);
	}

	if (ndo->ndo_eflag)
		pktap_header_print(ndo, p, length);

	length -= hdrlen;
	caplen -= hdrlen;
	p += hdrlen;

	rectype = EXTRACT_LE_32BITS(&hdr->pkt_rectype);
	switch (rectype) {

	case PKT_REC_NONE:
		ND_PRINT((ndo, "no data"));
		break;

	case PKT_REC_PACKET:
		if ((printer = lookup_printer(dlt)) != NULL) {
			printer(h, p);
		} else if ((ndo_printer = lookup_ndo_printer(dlt)) != NULL) {
			ndo_printer(ndo, h, p);
		} else {
			if (!ndo->ndo_eflag)
				pktap_header_print(ndo, (u_char *)hdr,
						length + hdrlen);

			if (!ndo->ndo_suppress_default_print)
				ND_DEFAULTPRINT(p, caplen);
		}
		break;
	}

	return (hdrlen);
}
예제 #7
0
파일: pcap_parse.c 프로젝트: necoma/aguri2
void
pcap_read(const char *dumpfile, const char *interface, 
	const char *filter_cmd, int snaplen)
{
	int fd;
	const char *device = NULL;
	struct bpf_program bprog;

	if (dumpfile != NULL) {
		/* read from a saved pcap file */
		pd = pcap_open_offline(dumpfile, errbuf);
		if (pd == NULL)
			err(1, "%s", errbuf);
	} else {
		if (interface != NULL) {
			device = interface;
		} else {
			device = pcap_lookupdev(errbuf);
			if (device == NULL)
				errx(1, "%s", errbuf);
		}
		if (snaplen == 0)
			snaplen = DEFAULT_SNAPLEN;
		fprintf(stderr, "pcap_read: reading from %s with snaplen:%d\n", 
			device, snaplen);
		pd = pcap_open_live(device, snaplen, 1, 0, errbuf);
		if (pd == NULL)
			errx(1, "%s", errbuf);
	}

	if (pcap_compile(pd, &bprog, filter_cmd, 0, 0) < 0)
		err(1, "pcap_compile: %s", pcap_geterr(pd));
	else if (pcap_setfilter(pd, &bprog) < 0)
		err(1, "pcap_setfilter: %s", pcap_geterr(pd));

	net_reader = lookup_printer(pcap_datalink(pd));

	fd = fileno(pcap_file(pd));

	if (device != NULL) {
		/* let user own process after interface has been opened */
		setuid(getuid());
#if defined(BSD) && defined(BPF_MAXBUFSIZE)
		{
			/* check the buffer size */
			u_int bufsize;

			if (ioctl(fd, BIOCGBLEN, (caddr_t)&bufsize) < 0)
				perror("BIOCGBLEN");
			else
				fprintf(stderr, "bpf buffer size is %d\n", bufsize);
		}
#endif /* BSD */
	}

	while (1) {
		int cnt;

		cnt = pcap_dispatch(pd, 1, dump_reader, 0);
		if (cnt < 0)
			break;
		if (dumpfile != NULL && cnt == 0)
			/* EOF */
			break;
	}

	pcap_close(pd);
}
예제 #8
0
int
main(int argc, char **argv)
{
	register int cnt, op, i;
	bpf_u_int32 localnet, netmask;
	register char *cp, *infile, *cmdbuf, *device, *RFileName, *WFileName;
	pcap_handler printer;
	struct bpf_program fcode;
	RETSIGTYPE (*oldhandler)(int);
	u_char *pcap_userdata;
	char ebuf[PCAP_ERRBUF_SIZE];

	cnt = -1;
	device = NULL;
	infile = NULL;
	RFileName = NULL;
	WFileName = NULL;
	if ((cp = strrchr(argv[0], '/')) != NULL)
		program_name = cp + 1;
	else
		program_name = argv[0];

	if (abort_on_misalignment(ebuf) < 0)
		error("%s", ebuf);

	opterr = 0;
	while (
	    (op = getopt(argc, argv, "ac:defF:i:lnNOpqr:s:StT:vw:xY")) != EOF)
		switch (op) {

		case 'a':
			++aflag;
			break;

		case 'c':
			cnt = atoi(optarg);
			if (cnt <= 0)
				error("invalid packet count %s", optarg);
			break;

		case 'd':
			++dflag;
			break;

		case 'e':
			++eflag;
			break;

		case 'f':
			++fflag;
			break;

		case 'F':
			infile = optarg;
			break;

		case 'i':
			device = optarg;
			break;

		case 'l':
#ifdef HAVE_SETLINEBUF
			setlinebuf(stdout);
#else
			setvbuf(stdout, NULL, _IOLBF, 0);
#endif
			break;

		case 'n':
			++nflag;
			break;

		case 'N':
			++Nflag;
			break;

		case 'O':
			Oflag = 0;
			break;

		case 'p':
			++pflag;
			break;

		case 'q':
			++qflag;
			break;

		case 'r':
			RFileName = optarg;
			break;

		case 's':
			snaplen = atoi(optarg);
			if (snaplen <= 0)
				error("invalid snaplen %s", optarg);
			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
				error("unknown packet type `%s'", optarg);
			break;

		case 'v':
			++vflag;
			break;

		case 'w':
			WFileName = optarg;
			break;
#ifdef YYDEBUG
		case 'Y':
			{
			/* Undocumented flag */
			extern int yydebug;
			yydebug = 1;
			}
			break;
#endif
		case 'x':
			++xflag;
			break;

		default:
			usage();
			/* NOTREACHED */
		}

	if (aflag && nflag)
		error("-a and -n options are incompatible");

	if (tflag > 0)
		thiszone = gmt2local(0);

	if (RFileName != NULL) {
		/*
		 * We don't need network access, so set it back to the user id.
		 * Also, this prevents the user from reading anyone's
		 * trace file.
		 */
		setuid(getuid());

		pd = pcap_open_offline(RFileName, ebuf);
		if (pd == NULL)
			error("%s", ebuf);
		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);
		}
		pd = pcap_open_live(device, snaplen, !pflag, 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 (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);
		exit(0);
	}
	init_addrtoname(localnet, netmask);

	(void)setsignal(SIGTERM, cleanup);
	(void)setsignal(SIGINT, cleanup);
	/* Cooperate with nohup(1) */
	if ((oldhandler = setsignal(SIGHUP, cleanup)) != SIG_DFL)
		(void)setsignal(SIGHUP, oldhandler);

	if (pcap_setfilter(pd, &fcode) < 0)
		error("%s", pcap_geterr(pd));
	if (WFileName) {
		pcap_dumper_t *p = pcap_dump_open(pd, WFileName);
		if (p == NULL)
			error("%s", pcap_geterr(pd));
		printer = pcap_dump;
		pcap_userdata = (u_char *)p;
	} else {
		printer = lookup_printer(pcap_datalink(pd));
		pcap_userdata = 0;
	}
	if (RFileName == NULL) {
		(void)fprintf(stderr, "%s: listening on %s\n",
		    program_name, device);
		(void)fflush(stderr);
	}
	if (pcap_loop(pd, cnt, printer, pcap_userdata) < 0) {
		(void)fprintf(stderr, "%s: pcap_loop: %s\n",
		    program_name, pcap_geterr(pd));
		exit(1);
	}
	pcap_close(pd);
	exit(0);
}