From 25d614aa11e52370c200e677099746a619ea76db Mon Sep 17 00:00:00 2001 From: Zheng Da Date: Wed, 2 Nov 2016 18:06:53 +0100 Subject: eth-multiplexer: Merge the eth-multiplexer. * Makefile (prog-subdirs): Add the new program. * NEWS: Update. * eth-multiplexer/ChangeLog: New file. * eth-multiplexer/Makefile: Likewise. * eth-multiplexer/README: Likewise. * eth-multiplexer/demuxer.c: Likewise. * eth-multiplexer/dev_stat.c: Likewise. * eth-multiplexer/device_impl.c: Likewise. * eth-multiplexer/ethernet.c: Likewise. * eth-multiplexer/ethernet.h: Likewise. * eth-multiplexer/mig-decls.h: Likewise. * eth-multiplexer/mig-mutate.h: Likewise. * eth-multiplexer/multiplexer.c: Likewise. * eth-multiplexer/netfs_impl.c: Likewise. * eth-multiplexer/netfs_impl.h: Likewise. * eth-multiplexer/notify_impl.c: Likewise. * eth-multiplexer/test.c: Likewise. * eth-multiplexer/util.h: Likewise. * eth-multiplexer/vdev.c: Likewise. * eth-multiplexer/vdev.h: Likewise. The eth-multiplexer has been written by Zheng Da. This merges his work into the main repository. --- eth-multiplexer/ethernet.c | 143 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 143 insertions(+) create mode 100644 eth-multiplexer/ethernet.c (limited to 'eth-multiplexer/ethernet.c') diff --git a/eth-multiplexer/ethernet.c b/eth-multiplexer/ethernet.c new file mode 100644 index 00000000..002f30c2 --- /dev/null +++ b/eth-multiplexer/ethernet.c @@ -0,0 +1,143 @@ +/* + Copyright (C) 1995, 1996, 1998, 1999, 2000, 2002, 2007, 2008 + Free Software Foundation, Inc. + + Written by Zheng Da + + Based on pfinet/ethernet.c, written by Michael I. Bushnell, p/BSG. + + This file is part of the GNU Hurd. + + The GNU Hurd is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License as + published by the Free Software Foundation; either version 2, or (at + your option) any later version. + + The GNU Hurd is distributed in the hope that it will be useful, but + WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111, USA. */ + +#include +#include +#include +#include +#include + +#include +#include +#include + +#include "ethernet.h" +#include "vdev.h" +#include "util.h" + +#define ETH_HLEN 14 + +static struct port_info *readpt; + +/* Port for writing message to the real network interface. */ +mach_port_t ether_port; +/* Port for receiving messages from the interface. */ +static mach_port_t readptname; + +/* The BPF instruction allows IP and ARP packets */ +static struct bpf_insn ether_filter[] = +{ + {NETF_IN|NETF_BPF, /* Header. */ 0, 0, 0}, + {40, 0, 0, 12}, + {21, 1, 0, 2054}, + {21, 0, 1, 2048}, + {6, 0, 0, 1500}, + {6, 0, 0, 0} +}; +static int ether_filter_len = sizeof (ether_filter) / sizeof (short); + +int ethernet_demuxer (mach_msg_header_t *inp, + mach_msg_header_t *outp) +{ + struct net_rcv_msg *msg = (struct net_rcv_msg *) inp; + + if (inp->msgh_id != NET_RCV_MSG_ID) + return 0; + + broadcast_msg (msg); + /* The data from the underlying network is inside the message, + * so we don't need to deallocate the data. */ + return 1; +} + +int set_promisc (char *dev_name, mach_port_t ether_port, int is_promisc) +{ +#ifndef NET_FLAGS +#define NET_FLAGS (('n'<<16) + 4) +#endif + int flags; + int ret; + size_t count; + + debug ("set_promisc is called, is_promisc: %d\n", is_promisc); + count = 1; + ret = device_get_status (ether_port, NET_FLAGS, (dev_status_t) &flags, + &count); + if (ret) + { + error (0, ret, "device_get_status"); + return -1; + } + if (is_promisc) + flags |= IFF_PROMISC; + else + flags &= ~IFF_PROMISC; + ret = device_set_status(ether_port, NET_FLAGS, (dev_status_t) &flags, 1); + if (ret) + { + error (0, ret, "device_set_status"); + return -1; + } + return 0; +} + +int ethernet_open (char *dev_name, device_t master_device, + struct port_bucket *etherport_bucket, + struct port_class *etherreadclass) +{ + error_t err; + + assert (ether_port == MACH_PORT_NULL); + + err = ports_create_port (etherreadclass, etherport_bucket, + sizeof (struct port_info), &readpt); + if (err) + error (2, err, "ports_create_port"); + readptname = ports_get_right (readpt); + mach_port_insert_right (mach_task_self (), readptname, readptname, + MACH_MSG_TYPE_MAKE_SEND); + + mach_port_set_qlimit (mach_task_self (), readptname, MACH_PORT_QLIMIT_MAX); + + err = device_open (master_device, D_WRITE | D_READ, "eth", ðer_port); + mach_port_deallocate (mach_task_self (), master_device); + if (err) + error (2, err, "device_open: %s", dev_name); + + err = device_set_filter (ether_port, ports_get_right (readpt), + MACH_MSG_TYPE_MAKE_SEND, 0, + (unsigned short *)ether_filter, ether_filter_len); + if (err) + error (2, err, "device_set_filter: %s", dev_name); + + set_promisc (dev_name, ether_port, 1); + return 0; +} + +int ethernet_close (char *dev_name) +{ + set_promisc (dev_name, ether_port, 0); + return 0; +} + -- cgit v1.2.3