pcap-bpf.c
来自「<B>Digital的Unix操作系统VAX 4.2源码</B>」· C语言 代码 · 共 190 行
C
190 行
/* * Copyright (c) 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-bpf.c 4.1 ULTRIX 1/25/91 * Based on: * rcsid[] = "@(#)$Header: pcap-bpf.c,v 1.15 90/12/17 13:15:04 mccanne Exp $ (LBL)" */#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/bpf.h>#include <net/if.h>#include <string.h>#include "interface.h"extern int errno;static voidbpf_stats(fd) int fd;{ struct bpf_stat s; if (ioctl(fd, BIOCGSTATS, &s) < 0) return; (void)fflush(stdout); (void)fprintf(stderr, "\n%d packets received by filter\n", s.bs_recv); (void)fprintf(stderr, "%d packets dropped by kernel\n", s.bs_drop);}voidreadloop(cnt, if_fd, fp, printit) int cnt; int if_fd; struct bpf_program *fp; void (*printit)();{ u_char *buf; u_int bufsize; int cc; if (ioctl(if_fd, BIOCGBLEN, (caddr_t)&bufsize) < 0) { perror("getting buffer length"); exit(1); } buf = (u_char *)malloc(bufsize); if (ioctl(if_fd, BIOCSETF, (caddr_t)fp) < 0) { perror("setting filter"); exit(1); } while (1) { register u_char *bp, *ep; if ((cc = read(if_fd, (char *)buf, (int)bufsize)) < 0) {#ifdef sun /* * Due to a SunOS bug, after 2^31 bytes, the kernel * file offset overflows and read fails with EINVAL. * The lseek() to 0 will fix things. */ if (errno == EINVAL && (long)(tell(if_fd) + bufsize) < 0) { (void)lseek(if_fd, 0, 0); continue; }#endif perror("read"); exit(1); } /* * Loop through each packet. */#define bhp ((struct bpf_hdr *)bp) bp = buf; ep = bp + cc; while (bp < ep) { register int caplen, hdrlen; (*printit)(bp + (hdrlen = bhp->bh_hdrlen), &bhp->bh_tstamp, bhp->bh_datalen, caplen = bhp->bh_caplen); if (cflag && --cnt == 0) goto out; bp += BPF_WORDALIGN(caplen + hdrlen); }#undef bhp } out: wrapup(if_fd);}wrapup(fd) int fd;{ bpf_stats(fd); close(fd);}static inline intbpf_open(){ int fd; int n = 0; char device[sizeof "/dev/bpf000"]; /* * Go through all the minors and find one that isn't in use. */ do { (void)sprintf(device, "/dev/bpf%d", n++); fd = open(device, O_RDONLY); } while (fd < 0 && errno == EBUSY); if (fd < 0) { perror(device); exit(-1); } return fd;}intinitdevice(device, pflag, linktype) char *device; int pflag; int *linktype;{ struct timeval timeout; int if_fd; struct ifreq ifr; struct bpf_devp devp; if_fd = bpf_open(); (void)strncpy(ifr.ifr_name, device, sizeof(ifr.ifr_name)); if (ioctl(if_fd, BIOCSETIF, (caddr_t)&ifr) < 0) { perror(device); exit(-1); } /* Get the data link layer type. */ if (ioctl(if_fd, BIOCDEVP, (caddr_t)&devp) < 0) { perror(device); exit(-1); } *linktype = devp.bdev_type; /* set timeout */ timeout.tv_sec = 1; timeout.tv_usec = 0; if (ioctl(if_fd, BIOCSRTIMEOUT, (caddr_t)&timeout) < 0) { perror(device); exit(-1); } /* set promiscuous mode if requested, but not for SLIP */ if (pflag == 0 && devp.bdev_type != DLT_SLIP) { if (ioctl(if_fd, BIOCPROMISC, (void *)0) < 0) { perror(device); exit(-1); } } return(if_fd);}
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?