pcap-snit.c

来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 259 行

C
259
字号
/* * Copyright (c) 1989, 1990 The Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that: (1) source code distributions * retain the above copyright notice and this paragraph in its entirety, (2) * distributions including binary code include the above copyright notice and * this paragraph in its entirety in the documentation or other materials * provided with the distribution, and (3) all advertising materials mentioning * features or use of this software display the following acknowledgement: * ``This product includes software developed by the University of California, * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of * the University nor the names of its contributors may be used to endorse * or promote products derived from this software without specific prior * written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * SCCSID: @(#)pcap-snit.c	4.1	ULTRIX	1/25/91 * Based on: * rcsid[] = "@(#)$Header: pcap-snit.c,v 1.12 91/01/08 19:43:24 mccanne Exp $ (LBL)" *//* * Modifications made to accomodate the new SunOS4.0 NIT facility by * Micky Liu, micky@cunixc.cc.columbia.edu, Columbia University in May, 1989. * This module now handles the STREAMS based NIT. */#include <stdio.h>#include <netdb.h>#include <ctype.h>#include <signal.h>#include <errno.h>#include <sys/types.h>#include <sys/time.h>#include <sys/timeb.h>#include <sys/socket.h>#include <sys/file.h>#include <sys/ioctl.h>#include <net/nit.h>/* Sun OS 4.x includes */#include <sys/fcntlcom.h>#include <sys/dir.h>#include <net/nit_if.h>#include <net/nit_pf.h>#include <net/nit_buf.h>#include <sys/stropts.h>#include <net/if.h>#include <netinet/in.h>#include <netinet/in_systm.h>#include <netinet/ip.h>#include <netinet/if_ether.h>#include <netinet/ip_var.h>#include <netinet/udp.h>#include <netinet/udp_var.h>#include <netinet/tcp.h>#include <netinet/tcpip.h>#include <net/bpf.h>#include "interface.h"/* * The chunk size for NIT.  This is the amount of buffering * done for read calls. */#define CHUNKSIZE (2*1024)/* * The total buffer space used by NIT. */#define BUFSPACE (4*CHUNKSIZE)struct nit_stat {	int dcount;	int rcount;} nstat;static voidsnit_stats(){	fflush(stdout);	(void)fprintf(stderr, "\n%d packets received by filter\n", 		      nstat.rcount);	(void)fprintf(stderr, "%d packets dropped by kernel\n", nstat.dcount);}voidreadloop(cnt, if_fd, fp, printit)	int cnt;	int if_fd;	struct bpf_program *fp;	void (*printit)();{	u_char buf[CHUNKSIZE];	int cc, i;	int drops;	struct nit_stat *nsp = &nstat;	register struct bpf_insn *fcode = fp->bf_insns;	i = 0;	while ((cc = read(if_fd, (char*)buf, sizeof buf)) >= 0) {		register u_char *bp, *cp, *bufstop;		struct nit_bufhdr *hdrp;		struct nit_iftime *ntp;		struct nit_iflen *nlp;		struct nit_ifdrops *ndp;		int caplen;		bp = buf;		bufstop = buf + cc;		/*		* loop through each snapshot in the chunk		*/		while (bp < bufstop) {			++nsp->rcount;			cp = bp;			/* get past NIT buffer  */			hdrp = (struct nit_bufhdr *)cp;			cp += sizeof(*hdrp);			/* get past NIT timer   */			ntp = (struct nit_iftime *)cp;			cp += sizeof(*ntp);			ndp = (struct nit_ifdrops *)cp;			nsp->dcount = ndp->nh_drops;			cp += sizeof *ndp;			/* get past packet len  */			nlp = (struct nit_iflen *)cp;			cp += sizeof(*nlp);			/* next snapshot        */			bp += hdrp->nhb_totlen;			caplen = nlp->nh_pktlen;			if (caplen > snaplen)				caplen = snaplen;			if (bpf_filter(fcode, cp, nlp->nh_pktlen, caplen)) {				(*printit)(cp, &ntp->nh_timestamp,					   nlp->nh_pktlen, caplen);				if (cflag && ++i >= cnt) {					wrapup(if_fd);					return;				}			}		}	}	perror("read");	exit(-1);}wrapup(fd)	int fd;{	snit_stats();	close(fd);}intinitdevice(device, pflag, linktype)	char *device;	int pflag;	int *linktype;{	struct strioctl si;		/* struct for ioctl() */	struct timeval timeout;		/* timeout for ioctl() */	struct ifreq ifr;		/* interface request struct */	u_long if_flags;		/* modes for interface             */	int  ret;	int chunksize = CHUNKSIZE;	int if_fd;	if (snaplen < 96)		/*		 * NIT requires a snapshot length of at least 96.		 */		snaplen = 96;	if ((if_fd = open("/dev/nit",O_RDONLY)) < 0) {		perror("/dev/nit");		exit(-1);	}	/* arrange to get discrete messages from the STREAM and use NIT_BUF */	ioctl(if_fd, I_SRDOPT, (char*)RMSGD);	ioctl(if_fd, I_PUSH, "nbuf");	/* set the timeout */	si.ic_timout = INFTIM;	timeout.tv_sec = 1;	timeout.tv_usec = 0;	si.ic_cmd = NIOCSTIME;	si.ic_len = sizeof(timeout);	si.ic_dp = (char*)&timeout;	if ((ret = ioctl(if_fd, I_STR, (char*)&si)) < 0) {		perror("nit_ioctl_timeout");		exit(-1);	}	/* set the chunksize */	si.ic_cmd = NIOCSCHUNK;	si.ic_len = sizeof(chunksize);	si.ic_dp = (char*)&chunksize;	if ((ret = ioctl(if_fd, I_STR, (char*)&si)) < 0) {		perror("nit_ioctl_chunksize");		exit(-1);	}	/* request the interface */	strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name));	ifr.ifr_name[sizeof(ifr.ifr_name) - 1] = ' ';	si.ic_cmd = NIOCBIND;	si.ic_len = sizeof(ifr);	si.ic_dp = (char*)&ifr;	if ((ret = ioctl(if_fd, I_STR, (char*)&si)) < 0) {		perror(ifr.ifr_name);		exit(1);	}	/* set the snapshot length */	si.ic_cmd = NIOCSSNAP;	si.ic_len = sizeof(snaplen);	si.ic_dp = (char*)&snaplen;	if ((ret = ioctl(if_fd, I_STR, (char*)&si)) < 0) {		perror("nit_ioctl_snaplen");		exit(1);	}	/* set the interface flags */	si.ic_cmd = NIOCSFLAGS;	if_flags = NI_TIMESTAMP | NI_LEN | NI_DROPS;	if (pflag == 0)		if_flags |= NI_PROMISC;	si.ic_len = sizeof(if_flags);	si.ic_dp = (char*)&if_flags;	if ((ret = ioctl(if_fd, I_STR, (char*)&si)) < 0) {		perror("nit_ioctl_iflags");		exit(1);	}	ioctl(if_fd, I_FLUSH, (char*)FLUSHR);	/*	 * NIT supports only ethernets.	 */	*linktype = DLT_EN10MB;	return if_fd;}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?