diff options
author | Michael I. Bushnell <mib@gnu.org> | 1995-09-21 15:09:18 +0000 |
---|---|---|
committer | Michael I. Bushnell <mib@gnu.org> | 1995-09-21 15:09:18 +0000 |
commit | b554935fb5f5a499c62950c1dd571a54170eb8a0 (patch) | |
tree | 776e705bf690581580f7f1a3eb9a0f5a6b596bf6 | |
parent | ee99f84aa75edac00cce6daf409089c01c65533b (diff) |
Formerly ethernet.c.~6~
-rw-r--r-- | pfinet/ethernet.c | 86 |
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 (ðer_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), |