summaryrefslogtreecommitdiff
path: root/eth-multiplexer/bpf_impl.h
diff options
context:
space:
mode:
authorroot <root@(null).(none)>2009-05-03 17:20:00 +0200
committerroot <root@(null).(none)>2009-05-03 17:20:00 +0200
commite0faf22f31c48fb27b43c1825897d26e58feafc4 (patch)
tree65a09372b31e08a3a865bd0a88cd2718bafcd643 /eth-multiplexer/bpf_impl.h
This is my initial working version.
There is a bug in boot in this version: subhurd sometimes cannot boot.
Diffstat (limited to 'eth-multiplexer/bpf_impl.h')
-rw-r--r--eth-multiplexer/bpf_impl.h156
1 files changed, 156 insertions, 0 deletions
diff --git a/eth-multiplexer/bpf_impl.h b/eth-multiplexer/bpf_impl.h
new file mode 100644
index 00000000..82db1b8d
--- /dev/null
+++ b/eth-multiplexer/bpf_impl.h
@@ -0,0 +1,156 @@
+ /*
+ * Mach Operating System
+ * Copyright (c) 1993-1989 Carnegie Mellon University
+ * All Rights Reserved.
+ *
+ * Permission to use, copy, modify and distribute this software and its
+ * documentation is hereby granted, provided that both the copyright
+ * notice and this permission notice appear in all copies of the
+ * software, derivative works or modified versions, and any portions
+ * thereof, and that both notices appear in supporting documentation.
+ *
+ * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
+ * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
+ * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
+ *
+ * Carnegie Mellon requests users of this software to return to
+ *
+ * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU
+ * School of Computer Science
+ * Carnegie Mellon University
+ * Pittsburgh PA 15213-3890
+ *
+ * any improvements or extensions that they make and grant Carnegie Mellon
+ * the rights to redistribute these changes.
+ */
+/*
+ * Author: David B. Golub, Carnegie Mellon University
+ * Date: 3/98
+ *
+ * Network IO.
+ *
+ * Packet filter code taken from vaxif/enet.c written
+ * CMU and Stanford.
+ */
+
+/* the code copied from device/net_io.c in Mach */
+
+#ifndef BPF_IMPL_H
+#define BPF_IMPL_H
+
+#include <device/bpf.h>
+
+#include "queue.h"
+#include "vdev.h"
+
+typedef unsigned short filter_t;
+typedef filter_t *filter_array_t;
+
+#define NET_MAX_FILTER 128 /* was 64, bpf programs are big */
+
+#define NET_HASH_SIZE 256
+#define N_NET_HASH 4
+#define N_NET_HASH_KEYS 4
+
+#ifndef BPF_ALIGN
+#define EXTRACT_SHORT(p) ((u_short)ntohs(*(u_short *)p))
+#define EXTRACT_LONG(p) (ntohl(*(u_long *)p))
+#else
+#define EXTRACT_SHORT(p)\
+ ((u_short)\
+ ((u_short)*((u_char *)p+0)<<8|\
+ (u_short)*((u_char *)p+1)<<0))
+#define EXTRACT_LONG(p)\
+ ((u_long)*((u_char *)p+0)<<24|\
+ (u_long)*((u_char *)p+1)<<16|\
+ (u_long)*((u_char *)p+2)<<8|\
+ (u_long)*((u_char *)p+3)<<0)
+#endif
+
+#define HASH_ITERATE(head, elt) (elt) = (net_hash_entry_t) (head); do {
+#define HASH_ITERATE_END(head, elt) \
+ (elt) = (net_hash_entry_t) queue_next((queue_entry_t) (elt)); \
+} while ((elt) != (head));
+
+#define FILTER_ITERATE(if_port_list, fp, nextfp, chain) \
+ for ((fp) = (net_rcv_port_t) queue_first(if_port_list); \
+ !queue_end(if_port_list, (queue_entry_t)(fp)); \
+ (fp) = (nextfp)) { \
+ (nextfp) = (net_rcv_port_t) queue_next(chain);
+#define FILTER_ITERATE_END }
+
+/* entry_p must be net_rcv_port_t or net_hash_entry_t */
+#define ENQUEUE_DEAD(dead, entry_p, chain) { \
+ queue_next(&(entry_p)->chain) = (queue_entry_t) (dead); \
+ (dead) = (queue_entry_t)(entry_p); \
+}
+
+#define CSPF_BYTES(n) ((n) * sizeof (filter_t))
+
+/*
+ * Receive port for net, with packet filter.
+ * This data structure by itself represents a packet
+ * filter for a single session.
+ */
+struct net_rcv_port {
+ queue_chain_t input; /* list of input open_descriptors */
+ queue_chain_t output; /* list of output open_descriptors */
+ mach_port_t rcv_port; /* port to send packet to */
+ int rcv_count; /* number of packets received */
+ int priority; /* priority for filter */
+ filter_t *filter_end; /* pointer to end of filter */
+ filter_t filter[NET_MAX_FILTER];
+ /* filter operations */
+};
+typedef struct net_rcv_port *net_rcv_port_t;
+
+/*
+ * A single hash entry.
+ */
+struct net_hash_entry {
+ queue_chain_t chain; /* list of entries with same hval */
+#define he_next chain.next
+#define he_prev chain.prev
+ mach_port_t rcv_port; /* destination port */
+ unsigned int keys[N_NET_HASH_KEYS];
+};
+typedef struct net_hash_entry *net_hash_entry_t;
+
+/*
+ * This structure represents a packet filter with multiple sessions.
+ *
+ * For example, all application level TCP sessions might be
+ * represented by one of these structures. It looks like a
+ * net_rcv_port struct so that both types can live on the
+ * same packet filter queues.
+ */
+struct net_hash_header {
+ struct net_rcv_port rcv;
+ int n_keys; /* zero if not used */
+ int ref_count; /* reference count */
+ net_hash_entry_t table[NET_HASH_SIZE];
+} filter_hash_header[N_NET_HASH];
+
+typedef struct net_hash_header *net_hash_header_t;
+
+int bpf_do_filter(net_rcv_port_t infp, char *p, unsigned int wirelen,
+ char *header, unsigned int hlen, net_hash_entry_t **hash_headpp,
+ net_hash_entry_t *entpp);
+io_return_t net_set_filter(struct vether_device *ifp, mach_port_t rcv_port,
+ int priority, filter_t *filter, unsigned int filter_count);
+
+int bpf_validate(bpf_insn_t f, int bytes, bpf_insn_t *match);
+int bpf_eq (bpf_insn_t f1, bpf_insn_t f2, int bytes);
+unsigned int bpf_hash (int n, unsigned int *keys);
+int bpf_match (net_hash_header_t hash, int n_keys, unsigned int *keys,
+ net_hash_entry_t **hash_headpp, net_hash_entry_t *entpp);
+
+int hash_ent_remove (struct vether_device *ifp, net_hash_header_t hp, int used,
+ net_hash_entry_t *head, net_hash_entry_t entp, queue_entry_t *dead_p);
+void net_free_dead_infp (queue_entry_t dead_infp);
+void net_free_dead_entp (queue_entry_t dead_entp);
+void remove_dead_filter (struct vether_device *ifp,
+ queue_head_t *if_port_list, mach_port_t dead_port);
+void destroy_filters (struct vether_device *ifp);
+
+#endif /* _DEVICE_BPF_H_ */