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*)𝔦 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 + -
显示快捷键?