📄 bpfdrive.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/lib/bpfdrive.c,v 1.4 2003/01/15 14:04:30 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved. Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** * Copyright 1993-1997 Epilogue Technology Corporation. * Copyright 1998 Integrated Systems, Inc. * All rights reserved. ****************************************************************************//* * $Log: bpfdrive.c,v $ * Revision 1.4 2003/01/15 14:04:30 josh * directory structure shifting * * Revision 1.3 2001/11/08 15:56:20 tneale * Updated for newest file layout * * Revision 1.2 2001/11/06 20:11:11 josh * updating include paths to include proper path to layout directory * * Revision 1.1.1.1 2001/11/05 17:48:41 tneale * Tornado shuffle * * Revision 2.28 2001/01/19 22:23:39 paul * Update copyright. * * Revision 2.27 2000/12/02 20:27:16 sar * Set pkt_datalen before call et_rcv so that we know how many bytes * we actually received in upper layers * * Revision 2.26 2000/10/16 19:21:49 paul * Restore sockets and mempool code. * * Revision 2.25 2000/03/17 00:12:36 meister * Update copyright message * * Revision 2.24 2000/03/13 21:22:02 paul * Removed some code that we are no longer working on. * * Revision 2.23 1999/11/05 22:29:04 paul * Updated driver structs to reflect conditional backwards-compatibility * fields and new fields. * * Revision 2.22 1999/10/19 23:07:54 sar * Add et_ipv6_send_pkt as the ipv6 send routine * * Revision 2.21 1999/03/25 20:25:09 wes * provide install option for subinstances (on by default) * * Revision 2.20 1998/10/28 18:50:54 josh * marging in courier-sep98 branch * * Revision 2.19.8.1 1998/09/11 05:50:22 sra * Initial commit on courier-sep98 branch. * * Revision 2.19 1998/02/25 15:21:46 sra * Finish moving types.h, bug.h, and bugdef.h to common/h/. * * Revision 2.18 1998/02/25 04:57:21 sra * Update copyrights. * * Revision 2.17 1997/06/06 17:39:15 sra * Get rid of unused variable warning in bpf_driver_send(). * * Revision 2.16 1997/05/22 18:51:47 mrf * add ipv4_send routine to driver structure * * Revision 2.15 1997/05/20 20:41:00 mrf * remove reference to 'struct bb_ether' (now departed) * * Revision 2.14 1997/05/20 02:08:03 mrf * ipaddr_t, ldb macro and routing api conversion of media layer and arp code * * Revision 2.13 1997/05/07 17:23:34 mrf * move ipv6_send function to end of net_if structure * * Revision 2.11 1997/04/25 01:02:24 sra * Fix code to set explicit MAC addresses for BPF, allow non-promiscuous mode. * * Revision 2.10 1997/04/19 02:47:58 mrf * added basic ipv6 code, config ipv6 addresses, added new ipv6_send handler * to snoop and bpf driver structures, added configurable maxlnt and cleaned * up makefile.cfg formatting error * * Revision 2.9 1997/03/20 06:52:52 sra * DFARS-safe copyright text. Zap! * * Revision 2.8 1997/02/27 21:34:23 josh * changed (cookie *) to (void *) in bpf_driver_read() * * Revision 2.7 1997/02/25 10:58:16 sra * Update copyright notice, dust under the bed. * * Revision 2.6 1997/02/19 08:10:29 sra * More fun merging snmptalk into snark, general snark cleanup. * * Revision 2.5 1997/01/28 18:43:33 lowell * support for having a hardware address *before* an IP address * (what a concept) * * Revision 2.4 1996/07/09 18:54:14 lowell * go back to using IP address for part of ethernet address; * but only if if there *is* an IP address * * Revision 2.3 1996/04/23 22:05:58 lowell * added ARP-for-my-own-address on startup * (to solve problems associated with making up ethernet addresses * out of thin air) * * Revision 2.2 1996/03/22 10:05:39 sra * Update copyrights prior to Attache 3.2 release. * * Revision 2.1 1995/10/04 23:49:53 lowell * added media control routine and changed the generation of ethernet * addresses so they don't depend on already having an IP address * * Revision 2.0 1995/05/10 22:38:15 sra * Attache release 3.0. * * Revision 1.6 1995/03/03 21:02:32 sra * Add installation option for workaround for erroneous BPF byteswap of * ethernet type field on output, since this kernel bug seems to have * resurfaced in FreeBSD 2.0. * * Revision 1.5 1995/01/06 00:52:48 sra * Update copyright notice for 2.1 release. * * Revision 1.4 1994/09/04 06:13:38 sra * Clean up antique type names and install macros. * * Revision 1.3 1994/08/08 08:30:47 sra * Turn off byteswap kludge, now that FreeBSD has fixed the BPF bug. * * Revision 1.2 1994/01/09 23:57:29 sra * Add support for NIT under SunOS 4.1.2. * * Revision 1.1 1993/07/05 21:53:30 sra * Initial revision * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*//* * Berkeley Packet Filter (BPF) network interface for snark package. * * This has only been tested on NetBSD 0.8, it will probably work on other * BSD-Net2-derived systems, and may work with minor modifications on other * BSD-related systems with BPF (eg, SunOS with the BPF additions supplied * with the tcpdump program distributed by LBL). * * This file contains the Attache driver code for BPF. * * There are a couple of slightly strange things about this code. * * 1) We need a fake MAC address for each interface, not because Attache * cares but because it's the easiest way to get BPF to do the right * thing without all kinds of bizzare interactions with the unix * routing code. We cons up addresses by borrowing a disused vendor * componant (listed as "obsolete") and using pieces of snark's * process ID and the UNIX machine's host ID for the remaining * octets of the MAC address. This should generate locally unique * MAC addresses on (almost) any IP network. * * We used to use snark's IP address, but that won't work when we * don't have an IP address (as I realized when trying to test * DHCP). This approach does result in a different MAC address * every time (necessary to run multiple snark instances in * parallel), so the net-configuring code has to ARP for its own * address after installing an address. * * 2) The current BPF implementation (on NetBSD 0.8, anyway) barfs * when I attempt to write() a packet longer than 1024 octets, so * the IP MTU for this interface is 1010 octets (1024 - lnh - lnt) * rather than 1500. * */#include <stdio.h>#include <unistd.h>#include <ctype.h>#include <wrn/wm/attache/config.h>#include <wrn/wm/common/types.h>#include <wrn/wm/attache/mib.h>#include <wrn/wm/attache/timer.h>#include <wrn/wm/attache/packet.h>#include <wrn/wm/attache/net.h>#include <wrn/wm/attache/ether.h>#include <wrn/wm/attache/arp.h>#include <wrn/wm/attache/route.h>#include <wrn/wm/attache/glue.h>#include <wrn/wm/util/layout/ldbglue.h>#include <wrn/wm/util/layout/ethernet.h>#include <wrn/wm/util/layout/arp.h>#include <wrn/wm/demo/bpf.h>#include <wrn/wm/demo/bsdif.h>#include <wrn/wm/demo/bpfdrive.h>struct bpf_driver_private { bits8_t mac[6]; /* MAC address for this interface */};#define TEN_MEGABITS 10000000#ifndef IFNAMELEN#define IFNAMELEN 20#endif/* * Routines to read (struct bsdif) generic network interface. */static void bpf_driver_rcv (unsigned char *buffer, unsigned buffer_length, unsigned network_length, void *cookie){ packet *p; if (buffer_length != network_length || (p = pkt_alloc(buffer_length)) == 0) return; MEMCPY(p->pkt_buffer, buffer, buffer_length); p->pkt_datalen = buffer_length; p->pkt_n = cookie; et_rcv(p);}static void bpf_driver_read (int fd, void *cookie, unsigned flags){ struct net *net = cookie; if ((net->flags & NF_DRIVER_DOWN) == 0 && (flags & BSDIF_READ) != 0) (void) bpf_read(fd, net->driver->maxlen, bpf_driver_rcv, net);}/* * Attache device driver routines for BPF. *//*#include <wrn/wm/demo/read_ini.h>*/static void bpf_driver_init (struct net *net){ /* This prefix is from "obsolete" portion of DEC's space (see RFC-1340). */ static bits8_t bpf_driver_mac_prefix[3] = { 0xAA, 0x00, 0x00 }; struct bsdif *bif = net->specific; struct bpf_driver_private *private; char name[IFNAMELEN]; STRCPY(name, net->s_name + STRLEN(net->driver->prefix)); if (isalpha(name[STRLEN(name) - 1])) name[STRLEN(name) - 1] = '\0'; net->flags |= NF_DRIVER_DOWN; net->speed = TEN_MEGABITS; /* * Pick a MAC address to use. If there's already one specified, * use it. Otherwise, if we're in 2.x backwards compatability mode and have * an IP address, use it, otherwise try to generate something unique. */ if (!net->h_address) { if ((bif->private = private = GLUE_ALLOC(sizeof(*private))) == 0) return; net->ha_len = sizeof(private->mac); net->h_address = private->mac; MEMCPY(private->mac+0, bpf_driver_mac_prefix, 3); if (net->ip_addr) { MEMCPY(private->mac + 3, ((bits8_t *) &net->ip_addr) + 1, 3); } else { pid_t proc = getpid(); bits32_t hostid = gethostid(); private->mac[3] ^= (bits8_t) (proc & 0xff); private->mac[4] ^= (bits8_t) (proc >> 8 & 0xff); private->mac[5] ^= (bits8_t) (hostid & 0xff); } } if ((bif->fd = bpf_open(name, net->driver->maxlen, net->h_address, INSTALL_SNARK_BSD_BPF_PROMISCUOUS)) < 0) return; bif->handler = bpf_driver_read; bif->flags |= BSDIF_READ; net->flags &= ~NF_DRIVER_DOWN;}static void bpf_driver_send (struct packet *p){ struct bsdif *bif = p->pkt_n->specific;#if INSTALL_SNARK_BSD_BPF_SWAP_OUTPUT_ETHERTYPE /* * Some versions of BPF code byte swap the ethernet type field. * Enable the following two lines to kludge around this. */ { bits16_t type = SWAP16(GET_ETHERNET_HEADER_TYPE(p->pkt_data)); SET_ETHERNET_HEADER_TYPE(p->pkt_data, type); }#endif /* * Send the packet, logging any error that might occur. * If the driver is down, just drop the packet. */ if ((p->pkt_n->flags & NF_DRIVER_DOWN) == 0 && bpf_write(bif->fd, p->pkt_data, p->pkt_datalen) < 0) perror("BPF write() failure"); pkt_free(p);}static void bpf_driver_close (struct net *net){ struct bsdif *bif = net->specific; if ((net->flags & NF_DRIVER_DOWN) == 0) { bpf_close(bif->fd); net->flags |= NF_DRIVER_DOWN; } if (bif->private) { GLUE_FREE(bif->private); bif->private = 0; }}static struct driver bpf_driver = { bpf_driver_init, /* Interface initialization routine */ bpf_driver_send, /* Raw packet send routine */ 0, /* IP packet send back compat routine */ et_arp_send, /* ARP packet send encapsulation routine */ 0, /* Test routine (unused) */ bpf_driver_close, /* Interface close routine */ "bpf", /* Driver short name */ "Berkeley Packet Filter Ethernet", /* Driver long name */ 14, /* Local net header length */ 0, /* Local net trailer length */#if 0 1514, /* Real Ethernet frame size is this... */#else 1024, /* ...but this is the most BPF can handle */#endif IF_ETHERNET, /* MIB type of interfaces using this driver */ ARP_HEADER_HARDWARE_TYPE_is_ETHERNET,#if !INSTALL_ATTACHE_ETHERNET_NO_MEDIA_CTL et_media_ctl, /* Media control routine, if installed */#else 0,#endif /* !INSTALL_ATTACHE_ETHERNET_NO_MEDIA_CTL */#if INSTALL_ATTACHE_IPV6 et_ipv6_send, /* IPv6 send routine, if installed */#else 0,#endif /* INSTALL_ATTACHE_IPV6 */#if INSTALL_ATTACHE_IPV4 et_ipv4_send /* IPv4 send routine, if installed */#else 0#endif /* INSTALL_ATTACHE_IPV4 */};/* * Routines for finding BPF interface devices. * This is just a wrapper to add the Attache-specific things onto bpf_find(). */struct bpf_driver_find_state { void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t); int instance;};static void bpf_driver_find_one(char *name, void *cookie){ struct bpf_driver_find_state *state = cookie; state->config(name, &bpf_driver, state->instance++, NF_ARP, bpf_driver.maxlen - bpf_driver.lnh - bpf_driver.lnt, TEN_MEGABITS);#if INSTALL_SNARK_BSD_BPF_SUBINSTANCES { char c; for (c = 'a'; c <= 'z'; c++) { char name_[IFNAMELEN]; sprintf(name_, "%s%c", name, c); state->config(name_, &bpf_driver, state->instance++, NF_ARP, bpf_driver.maxlen - bpf_driver.lnh - bpf_driver.lnt, TEN_MEGABITS); } }#endif}void bpf_driver_find (void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t)){ struct bpf_driver_find_state state; state.config = config; state.instance = 0; bpf_find(bpf_driver_find_one, &state);}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -