⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 bpf.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* bpf.c   BPF socket interface code, originally contributed by Archie Cobbs. *//* * Copyright (c) 2004 by Internet Systems Consortium, Inc. ("ISC") * Copyright (c) 1996-2003 by Internet Software Consortium * * Permission to use, copy, modify, and distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS.  IN NO EVENT SHALL ISC BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT * OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. * *   Internet Systems Consortium, Inc. *   950 Charter Street *   Redwood City, CA 94063 *   <info@isc.org> *   http://www.isc.org/ * * This software was contributed to Internet Systems Consortium * by Archie Cobbs. * * Patches for FDDI support on Digital Unix were written by Bill * Stapleton, and maintained for a while by Mike Meredith before he * managed to get me to integrate them. */#ifndef lintstatic char copyright[] ="$Id: bpf.c,v 1.48.2.6 2004/06/17 20:54:38 dhankins Exp $ Copyright (c) 2004 Internet Systems Consortium.  All rights reserved.\n";#endif /* not lint */#include "dhcpd.h"#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)	\				|| defined (USE_LPF_RECEIVE)# if defined (USE_LPF_RECEIVE)#  include <asm/types.h>#  include <linux/filter.h>#  define bpf_insn sock_filter /* Linux: dare to be gratuitously different. */# else#  include <sys/ioctl.h>#  include <sys/uio.h>#  include <net/bpf.h>#  if defined (NEED_OSF_PFILT_HACKS)#   include <net/pfilt.h>#  endif# endif#include <netinet/in_systm.h>#include "includes/netinet/ip.h"#include "includes/netinet/udp.h"#include "includes/netinet/if_ether.h"#endif/* Reinitializes the specified interface after an address change.   This   is not required for packet-filter APIs. */#ifdef USE_BPF_SENDvoid if_reinitialize_send (info)	struct interface_info *info;{}#endif#ifdef USE_BPF_RECEIVEvoid if_reinitialize_receive (info)	struct interface_info *info;{}#endif/* Called by get_interface_list for each interface that's discovered.   Opens a packet filter for each interface and adds it to the select   mask. */#if defined (USE_BPF_SEND) || defined (USE_BPF_RECEIVE)int if_register_bpf (info)	struct interface_info *info;{	int sock;	char filename[50];	int b;	/* Open a BPF device */	for (b = 0; 1; b++) {		/* %Audit% 31 bytes max. %2004.06.17,Safe% */		sprintf(filename, BPF_FORMAT, b);		sock = open (filename, O_RDWR, 0);		if (sock < 0) {			if (errno == EBUSY) {				continue;			} else {				if (!b)					log_fatal ("No bpf devices.%s%s%s",					       "   Please read the README",					       " section for your operating",					       " system.");				log_fatal ("Can't find free bpf: %m");			}		} else {			break;		}	}	/* Set the BPF device to point at this interface. */	if (ioctl (sock, BIOCSETIF, info -> ifp) < 0)		log_fatal ("Can't attach interface %s to bpf device %s: %m",		       info -> name, filename);	return sock;}#endif /* USE_BPF_SEND || USE_BPF_RECEIVE */#ifdef USE_BPF_SENDvoid if_register_send (info)	struct interface_info *info;{	/* If we're using the bpf API for sending and receiving,	   we don't need to register this interface twice. */#ifndef USE_BPF_RECEIVE	info -> wfdesc = if_register_bpf (info, interface);#else	info -> wfdesc = info -> rfdesc;#endif	if (!quiet_interface_discovery)		log_info ("Sending on   BPF/%s/%s%s%s",		      info -> name,		      print_hw_addr (info -> hw_address.hbuf [0],				     info -> hw_address.hlen - 1,				     &info -> hw_address.hbuf [1]),		      (info -> shared_network ? "/" : ""),		      (info -> shared_network ?		       info -> shared_network -> name : ""));}void if_deregister_send (info)	struct interface_info *info;{	/* If we're using the bpf API for sending and receiving,	   we don't need to register this interface twice. */#ifndef USE_BPF_RECEIVE	close (info -> wfdesc);#endif	info -> wfdesc = -1;	if (!quiet_interface_discovery)		log_info ("Disabling output on BPF/%s/%s%s%s",		      info -> name,		      print_hw_addr (info -> hw_address.hbuf [0],				     info -> hw_address.hlen - 1,				     &info -> hw_address.hbuf [1]),		      (info -> shared_network ? "/" : ""),		      (info -> shared_network ?		       info -> shared_network -> name : ""));}#endif /* USE_BPF_SEND */#if defined (USE_BPF_RECEIVE) || defined (USE_LPF_RECEIVE)/* Packet filter program...   XXX Changes to the filter program may require changes to the constant   offsets used in if_register_send to patch the BPF program! XXX */struct bpf_insn dhcp_bpf_filter [] = {	/* Make sure this is an IP packet... */	BPF_STMT (BPF_LD + BPF_H + BPF_ABS, 12),	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, ETHERTYPE_IP, 0, 8),	/* Make sure it's a UDP packet... */	BPF_STMT (BPF_LD + BPF_B + BPF_ABS, 23),	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, IPPROTO_UDP, 0, 6),	/* Make sure this isn't a fragment... */	BPF_STMT(BPF_LD + BPF_H + BPF_ABS, 20),	BPF_JUMP(BPF_JMP + BPF_JSET + BPF_K, 0x1fff, 4, 0),	/* Get the IP header length... */	BPF_STMT (BPF_LDX + BPF_B + BPF_MSH, 14),	/* Make sure it's to the right port... */	BPF_STMT (BPF_LD + BPF_H + BPF_IND, 16),	BPF_JUMP (BPF_JMP + BPF_JEQ + BPF_K, 67, 0, 1),             /* patch */	/* If we passed all the tests, ask for the whole packet. */	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),	/* Otherwise, drop it. */	BPF_STMT(BPF_RET+BPF_K, 0),};#if defined (DEC_FDDI)struct bpf_insn *bpf_fddi_filter;#endifint dhcp_bpf_filter_len = sizeof dhcp_bpf_filter / sizeof (struct bpf_insn);#if defined (HAVE_TR_SUPPORT)struct bpf_insn dhcp_bpf_tr_filter [] = {        /* accept all token ring packets due to variable length header */        /* if we want to get clever, insert the program here */	/* If we passed all the tests, ask for the whole packet. */	BPF_STMT(BPF_RET+BPF_K, (u_int)-1),	/* Otherwise, drop it. */	BPF_STMT(BPF_RET+BPF_K, 0),};int dhcp_bpf_tr_filter_len = (sizeof dhcp_bpf_tr_filter /			      sizeof (struct bpf_insn));#endif /* HAVE_TR_SUPPORT */#endif /* USE_LPF_RECEIVE || USE_BPF_RECEIVE */#if defined (USE_BPF_RECEIVE)void if_register_receive (info)	struct interface_info *info;{	int flag = 1;	struct bpf_version v;	u_int32_t addr;	struct bpf_program p;	u_int32_t bits;#ifdef DEC_FDDI	int link_layer;#endif /* DEC_FDDI */	/* Open a BPF device and hang it on this interface... */	info -> rfdesc = if_register_bpf (info);	/* Make sure the BPF version is in range... */	if (ioctl (info -> rfdesc, BIOCVERSION, &v) < 0)		log_fatal ("Can't get BPF version: %m");	if (v.bv_major != BPF_MAJOR_VERSION ||	    v.bv_minor < BPF_MINOR_VERSION)		log_fatal ("BPF version mismatch - recompile DHCP!");	/* Set immediate mode so that reads return as soon as a packet	   comes in, rather than waiting for the input buffer to fill with	   packets. */	if (ioctl (info -> rfdesc, BIOCIMMEDIATE, &flag) < 0)		log_fatal ("Can't set immediate mode on bpf device: %m");#ifdef NEED_OSF_PFILT_HACKS	/* Allow the copyall flag to be set... */	if (ioctl(info -> rfdesc, EIOCALLOWCOPYALL, &flag) < 0)		log_fatal ("Can't set ALLOWCOPYALL: %m");	/* Clear all the packet filter mode bits first... */	bits = 0;	if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)		log_fatal ("Can't clear pfilt bits: %m");	/* Set the ENBATCH, ENCOPYALL, ENBPFHDR bits... */	bits = ENBATCH | ENCOPYALL | ENBPFHDR;	if (ioctl (info -> rfdesc, EIOCMBIS, &bits) < 0)		log_fatal ("Can't set ENBATCH|ENCOPYALL|ENBPFHDR: %m");#endif	/* Get the required BPF buffer length from the kernel. */	if (ioctl (info -> rfdesc, BIOCGBLEN, &info -> rbuf_max) < 0)		log_fatal ("Can't get bpf buffer length: %m");	info -> rbuf = dmalloc (info -> rbuf_max, MDL);	if (!info -> rbuf)		log_fatal ("Can't allocate %ld bytes for bpf input buffer.",			   (long)(info -> rbuf_max));	info -> rbuf_offset = 0;	info -> rbuf_len = 0;	/* Set up the bpf filter program structure. */	p.bf_len = dhcp_bpf_filter_len;

⌨️ 快捷键说明

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