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

📄 bpf.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 2 页
字号:
#ifdef DEC_FDDI	/* See if this is an FDDI interface, flag it for later. */	if (ioctl(info -> rfdesc, BIOCGDLT, &link_layer) >= 0 &&	    link_layer == DLT_FDDI) {		if (!bpf_fddi_filter) {			bpf_fddi_filter = dmalloc (sizeof bpf_fddi_filter,						    MDL);			if (!bpf_fddi_filter)				log_fatal ("No memory for FDDI filter.");			memcpy (bpf_fddi_filter,				dhcp_bpf_filter, sizeof dhcp_bpf_filter);			/* Patch the BPF program to account for the difference			   in length between ethernet headers (14), FDDI and			   802.2 headers (16 +8=24, +10).			   XXX changes to filter program may require changes to			   XXX the insn number(s) used below! */			bpf_fddi_filter[0].k += 10;			bpf_fddi_filter[2].k += 10;			bpf_fddi_filter[4].k += 10;			bpf_fddi_filter[6].k += 10;			bpf_fddi_filter[7].k += 10;		}		p.bf_insns = bpf_fddi_filter;	} else#endif /* DEC_FDDI */	p.bf_insns = dhcp_bpf_filter;        /* Patch the server port into the BPF  program...	   XXX changes to filter program may require changes	   to the insn number(s) used below! XXX */	dhcp_bpf_filter [8].k = ntohs (local_port);	if (ioctl (info -> rfdesc, BIOCSETF, &p) < 0)		log_fatal ("Can't install packet filter program: %m");	if (!quiet_interface_discovery)		log_info ("Listening 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_receive (info)	struct interface_info *info;{	close (info -> rfdesc);	info -> rfdesc = -1;	if (!quiet_interface_discovery)		log_info ("Disabling input 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_RECEIVE */#ifdef USE_BPF_SENDssize_t send_packet (interface, packet, raw, len, from, to, hto)	struct interface_info *interface;	struct packet *packet;	struct dhcp_packet *raw;	size_t len;	struct in_addr from;	struct sockaddr_in *to;	struct hardware *hto;{	unsigned hbufp = 0, ibufp = 0;	double hw [4];	double ip [32];	struct iovec iov [3];	int result;	int fudge;	if (!strcmp (interface -> name, "fallback"))		return send_fallback (interface, packet, raw,				      len, from, to, hto);	/* Assemble the headers... */	assemble_hw_header (interface, (unsigned char *)hw, &hbufp, hto);	assemble_udp_ip_header (interface,				(unsigned char *)ip, &ibufp, from.s_addr,				to -> sin_addr.s_addr, to -> sin_port,				(unsigned char *)raw, len);	/* Fire it off */	iov [0].iov_base = ((char *)hw);	iov [0].iov_len = hbufp;	iov [1].iov_base = ((char *)ip);	iov [1].iov_len = ibufp;	iov [2].iov_base = (char *)raw;	iov [2].iov_len = len;	result = writev(interface -> wfdesc, iov, 3);	if (result < 0)		log_error ("send_packet: %m");	return result;}#endif /* USE_BPF_SEND */#ifdef USE_BPF_RECEIVEssize_t receive_packet (interface, buf, len, from, hfrom)	struct interface_info *interface;	unsigned char *buf;	size_t len;	struct sockaddr_in *from;	struct hardware *hfrom;{	int length = 0;	int offset = 0;	struct bpf_hdr hdr;	/* All this complexity is because BPF doesn't guarantee	   that only one packet will be returned at a time.   We're	   getting what we deserve, though - this is a terrible abuse	   of the BPF interface.   Sigh. */	/* Process packets until we get one we can return or until we've	   done a read and gotten nothing we can return... */	do {		/* If the buffer is empty, fill it. */		if (interface -> rbuf_offset == interface -> rbuf_len) {			length = read (interface -> rfdesc,				       interface -> rbuf,				       (size_t)interface -> rbuf_max);			if (length <= 0) {#ifdef __FreeBSD__				if (errno == ENXIO) {#else				if (errno == EIO) {#endif					dhcp_interface_remove						((omapi_object_t *)interface,						 (omapi_object_t *)0);				}				return length;			}			interface -> rbuf_offset = 0;			interface -> rbuf_len = BPF_WORDALIGN (length);		}		/* If there isn't room for a whole bpf header, something went		   wrong, but we'll ignore it and hope it goes away... XXX */		if (interface -> rbuf_len -		    interface -> rbuf_offset < sizeof hdr) {			interface -> rbuf_offset = interface -> rbuf_len;			continue;		}		/* Copy out a bpf header... */		memcpy (&hdr, &interface -> rbuf [interface -> rbuf_offset],			sizeof hdr);		/* If the bpf header plus data doesn't fit in what's left		   of the buffer, stick head in sand yet again... */		if (interface -> rbuf_offset +		    hdr.bh_hdrlen + hdr.bh_caplen > interface -> rbuf_len) {			interface -> rbuf_offset = interface -> rbuf_len;			continue;		}		/* If the captured data wasn't the whole packet, or if		   the packet won't fit in the input buffer, all we		   can do is drop it. */		if (hdr.bh_caplen != hdr.bh_datalen) {			interface -> rbuf_offset =				BPF_WORDALIGN (interface -> rbuf_offset +					       hdr.bh_hdrlen + hdr.bh_caplen);			continue;		}		/* Skip over the BPF header... */		interface -> rbuf_offset += hdr.bh_hdrlen;		/* Decode the physical header... */		offset = decode_hw_header (interface,					   interface -> rbuf,					   interface -> rbuf_offset,					   hfrom);		/* If a physical layer checksum failed (dunno of any		   physical layer that supports this, but WTH), skip this		   packet. */		if (offset < 0) {			interface -> rbuf_offset = 				BPF_WORDALIGN (interface -> rbuf_offset +					       hdr.bh_caplen);			continue;		}		interface -> rbuf_offset += offset;		hdr.bh_caplen -= offset;		/* Decode the IP and UDP headers... */		offset = decode_udp_ip_header (interface,					       interface -> rbuf,					       interface -> rbuf_offset,					       from,					       (unsigned char *)0,					       hdr.bh_caplen);		/* If the IP or UDP checksum was bad, skip the packet... */		if (offset < 0) {			interface -> rbuf_offset = 				BPF_WORDALIGN (interface -> rbuf_offset +					       hdr.bh_caplen);			continue;		}		interface -> rbuf_offset = interface -> rbuf_offset + offset;		hdr.bh_caplen -= offset;		/* If there's not enough room to stash the packet data,		   we have to skip it (this shouldn't happen in real		   life, though). */		if (hdr.bh_caplen > len) {			interface -> rbuf_offset =				BPF_WORDALIGN (interface -> rbuf_offset +					       hdr.bh_caplen);			continue;		}		/* Copy out the data in the packet... */		memcpy (buf, interface -> rbuf + interface -> rbuf_offset,			hdr.bh_caplen);		interface -> rbuf_offset =			BPF_WORDALIGN (interface -> rbuf_offset +				       hdr.bh_caplen);		return hdr.bh_caplen;	} while (!length);	return 0;}int can_unicast_without_arp (ip)	struct interface_info *ip;{	return 1;}int can_receive_unicast_unconfigured (ip)	struct interface_info *ip;{	return 1;}int supports_multiple_interfaces (ip)	struct interface_info *ip;{	return 1;}void maybe_setup_fallback (){	isc_result_t status;	struct interface_info *fbi = (struct interface_info *)0;	if (setup_fallback (&fbi, MDL)) {		if_register_fallback (fbi);		status = omapi_register_io_object ((omapi_object_t *)fbi,						   if_readsocket, 0,						   fallback_discard, 0, 0);		if (status != ISC_R_SUCCESS)			log_fatal ("Can't register I/O handle for %s: %s",				   fbi -> name, isc_result_totext (status));		interface_dereference (&fbi, MDL);	}}#endif

⌨️ 快捷键说明

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