summaryrefslogtreecommitdiff
path: root/pfinet/ethernet.c
diff options
context:
space:
mode:
authorMichael I. Bushnell <mib@gnu.org>1995-09-21 15:09:18 +0000
committerMichael I. Bushnell <mib@gnu.org>1995-09-21 15:09:18 +0000
commitb554935fb5f5a499c62950c1dd571a54170eb8a0 (patch)
tree776e705bf690581580f7f1a3eb9a0f5a6b596bf6 /pfinet/ethernet.c
parentee99f84aa75edac00cce6daf409089c01c65533b (diff)
Formerly ethernet.c.~6~
Diffstat (limited to 'pfinet/ethernet.c')
-rw-r--r--pfinet/ethernet.c86
1 files changed, 78 insertions, 8 deletions
diff --git a/pfinet/ethernet.c b/pfinet/ethernet.c
index b43fb12c..e0841072 100644
--- a/pfinet/ethernet.c
+++ b/pfinet/ethernet.c
@@ -24,20 +24,23 @@
#define ethername "el1"
device_t ether_port;
-struct device *ether_dev;
struct port_class *etherreadclass;
struct port_info *readpt;
mach_port_t readptname;
+struct device ether_dev;
+
int
ethernet_demuxer (struct mach_msg_header_t *inp,
struct mach_msg_header_t *outp)
{
struct net_rcv_msg *msg = (struct net_rcv_msg *) inp;
- struct packet_header *pkthdr = (struct packet_header *) msg->header;
-
- if (inp->msgh_id != 2999)
+ struct packet_header *pkthdr = (struct packet_header *) msg->packet;
+ struct sk_buff *skb;
+ int datalen;
+
+ if (inp->msgh_id != NET_RCV_MSG_ID)
return 0;
if (inp->msgh_local_port != readptname)
@@ -49,13 +52,32 @@ ethernet_demuxer (struct mach_msg_header_t *inp,
if (ntohs (pkthdr->type) != HDR_ETHERNET)
return 1;
+
+ /* The total size is the size of the ethernet header (which had
+ better equal sizeof (struct ethhdr) and the data portion of the
+ frame. So compute it. */
+ if (msg->header_type.msgt_number != ETH_HLEN)
+ return 1;
+ datalen = ETH_HLEN
+ + msg->packet_type.msgt_number - sizeof (struct packet_header);
+
mutex_lock (&global_lock);
- skb = alloc_skb (msg->net_rcv_msg_packet_count, GFP_ATOMIC);
- skb->len = msg->net_rcv_msg_packet_count;
+ skb = alloc_skb (datalen, GFP_ATOMIC);
+ skb->len = datalen;
sbx->dev = ether_dev;
- bcopy (msg->packet, skb->data, msg->net_rcv_msg_packet_count);
+
+ /* Copy the two parts of the frame into the buffer. */
+ bcopy (msg->header, skb->data, ETH_HLEN);
+ bcopy (msg->packet + sizeof (struct packet_header),
+ skb->data + ETH_HLEN,
+ datalen - ETH_HLEN);
+
+ /* Drop it on the queue. */
+ netif_rx (skb);
mutex_unlock (&global_lock);
+
+ return 1;
}
static short ether_filter[] =
@@ -67,8 +89,56 @@ static short ether_filter[] =
static int ether_filter_len = 3;
+/* Much of this is taken from Linux drivers/net/net_init.c: ether_setup */
+void
+setup_ethernet_device (void)
+{
+ int i;
+
+ /* Interface buffers. */
+ ether_dev->name = ethername;
+ for (i = 0; i < DEV_NUMBUFFS; i++)
+ skb_queue_head_init (&ether_dev->buffs[i]);
+
+ /* Functions */
+ ether_dev->open = ethernet_open;
+ ether_dev->stop = ethernet_stop;
+ ether_dev->hard_start_xmit = ethernet_xmit;
+ ether_dev->hard_header = eth_header;
+ ether_dev->rebuild_header = eth_rebuild_header;
+ ether_dev->type_trans = eth_type_trans;
+ ether_dev->get_stats = ethernet_get_stats;
+ ether_dev->set_multicast_list = ethernet_set_multi;
+
+ /* Some more fields */
+ ether_dev->type = ARPHRD_ETHER;
+ ether_dev->hard_header_len = sizeof (struct ethhdr);
+ ether_dev->mtu = 1500;
+ ether_dev->addr_len = 6;
+ for (i = 0; i < 6; i++)
+ ether_dev->broadcast[i] = 0xff;
+ ether_dev->flags = IFF_BROADCAST | IFF_MULTICAST;
+ ether_dev->family = AF_INET; /* hmm. */
+ ether_dev->pa_addr = ether_dev->pa_brdaddr = ether_dev->pa_mask = 0;
+ ether_dev->pa_alen = sizeof (unsigned_long);
+
+ /* That should be enough. */
+}
+
+struct enet_statistics retbuf;
+
+/* Mach doesn't provide this. DAMN. */
+struct enet_statistics *
+get_stats (struct device *dev)
+{
+ return &retbuf;
+}
+
+
+
+
void
-start_ethernet (void)
+ethernet_open (void)
{
etherreadclass = ports_create_class (0, 0);
readpt = ports_allocate_port (pfinet_bucket, sizeof (struct port_info),