📄 pktdrive.c
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/lib/pktdrive.c,v 1.4 2003/01/15 14:04:33 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: pktdrive.c,v $ * Revision 1.4 2003/01/15 14:04:33 josh * directory structure shifting * * Revision 1.3 2001/11/08 15:56:24 tneale * Updated for newest file layout * * Revision 1.2 2001/11/06 20:11:12 josh * updating include paths to include proper path to layout directory * * Revision 1.1.1.1 2001/11/05 17:48:42 tneale * Tornado shuffle * * Revision 2.22 2001/01/19 22:23:49 paul * Update copyright. * * Revision 2.21 2000/10/20 18:32:25 paul * Properly conditionalized driver.ip_send * * Revision 2.20 2000/10/16 19:21:54 paul * Restore sockets and mempool code. * * Revision 2.19 2000/03/17 00:12:43 meister * Update copyright message * * Revision 2.18 2000/03/13 21:22:07 paul * Removed some code that we are no longer working on. * * Revision 2.17 1999/11/05 22:29:06 paul * Updated driver structs to reflect conditional backwards-compatibility * fields and new fields. * * Revision 2.16 1998/09/04 04:00:10 sar * modified some #if statements to use #ifdef as they were testing * items that might not be defined - INSTALL_on_* options. * * Revision 2.15 1998/06/11 17:35:49 sra * Use et_media_ctl() if it's installed. * * Revision 2.14 1998/02/25 15:21:48 sra * Finish moving types.h, bug.h, and bugdef.h to common/h/. * * Revision 2.13 1998/02/25 04:57:32 sra * Update copyrights. * * Revision 2.12 1998/02/20 23:07:24 sra * Add multicast and IPv6 support. * * Revision 2.11 1998/02/19 07:46:10 sra * Preliminary multicast support. * * Revision 2.10 1997/07/01 02:23:00 mrf * packet drivers still need packet types byteswapped. * * Revision 2.9 1997/05/22 03:39:16 sra * Don't depend on ancient NF_DOWN kludge in if_attach(). * * Revision 2.8 1997/05/20 02:21:47 mrf * make snark lib driver code use new ldb arp definitions * * Revision 2.7 1997/05/07 17:23:36 mrf * move ipv6_send function to end of net_if structure * * Revision 2.6 1997/03/20 06:53:07 sra * DFARS-safe copyright text. Zap! * * Revision 2.5 1997/02/25 10:58:16 sra * Update copyright notice, dust under the bed. * * Revision 2.4 1996/10/28 03:31:26 sra * More BCC warnings. * * Revision 2.3 1996/10/26 17:50:18 sra * More silliness to silence compiler warnings. * * Revision 2.2 1996/10/26 17:43:19 sra * Get rid of some compiler warnings caused by Dave's * PPP-over-SLIP-pktdrv testing hack. * * Revision 2.1 1996/03/22 10:05:39 sra * Update copyrights prior to Attache 3.2 release. * * Revision 2.0 1995/05/10 22:38:15 sra * Attache release 3.0. * * Revision 1.10 1995/04/14 21:01:18 sra * Different fix for interface name problem. * * Revision 1.9 1995/04/14 20:21:32 dab * Malloc the right amount of space for net.s_name. This isn't right * with respect to the rest of the packet driver code but it fixes * the bug for now. * * Revision 1.8 1995/03/14 17:57:29 dab * Set the speed in network interface structures. * * Revision 1.7 1995/01/06 00:52:48 sra * Update copyright notice for 2.1 release. * * Revision 1.6 1994/12/20 22:40:36 dab * Added code to run the PPP media layer over a SLIP packet driver. * * Revision 1.5 1994/09/04 06:13:38 sra * Clean up antique type names and install macros. * * Revision 1.4 1993/08/03 01:28:51 sra * Different install option for MSC. * * Revision 1.3 1993/07/31 01:43:11 sra * Include appropriate pktd_xxx.h file for current install.h settings. * * Revision 1.2 1993/07/30 22:25:35 sra * Initial working version. * * Revision 1.1 1993/07/30 02:41:24 sra * Initial revision * *//* [clearcase]modification history-------------------01a,19apr05,job update copyright notices*//* * Packet driver code for snark under DOS. * * This started life as the attache/pc/pd2/pktdrv.lib library, but it's * been mangled somewhat to make it fit the snark architecture. */#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/ppp.h>#include <wrn/wm/attache/route.h>#include <wrn/wm/attache/ip.h>#include <wrn/wm/attache/glue.h>#include <wrn/wm/util/layout/ldbglue.h>#include <wrn/wm/util/layout/arp.h>#include <wrn/wm/demo/tasks.h>#ifdef INSTALL_on_microsoft#include <wrn/wm/demo/pktd_msc.h>#endif#ifdef INSTALL_on_bcc#include <wrn/wm/demo/pktd_bcc.h>#endif#include <wrn/wm/demo/pktd.h>/* * All the packet drivers I tested did ok with their receive modes set to * either 5 (all multicast) or 6 (all packets). For most uses, we want * mode 5, but you might need to override this to mode 6 or mode 3 (normal) * for certain applications. */#ifndef SNARK_PKTD_RCV_MODE#define SNARK_PKTD_RCV_MODE PKT_RCVR_ALL_MCAST#endif/* * Monolithic structure to hold everything that we know about a particular * interface. Routines outside this module just deal with sub-structures. * * The pd_net should be the first field, so that we can cast pointers to * it to pointers to the outer structure. */struct pktdif { struct pd_net pdn; /* Interface to packet driver library */ struct net net; /* Interface to Attache */ struct task task; /* Interface to Snark tasking routines */ packet *pkt; /* Packet under construction */ packet *pkt_q_head; /* Head of input packet queue */ packet **pkt_q_tail; /* Tail of input packet queue */ void (*receiver)(packet *); /* Media receive routine */ char name[20]; /* Space for short name for interface */ bits8_t mac[6]; /* Space for MAC address */ int saved_rcv_mode; /* Saved driver receive mode */};/* * A pointer for each possible packet driver. */static struct pd_net *pd_nets[PKTDRVR_MAX_INT - PKTDRVR_MIN_INT + 1];/* * Common driver routines for all Attache interfaces using packet drivers. *//* * Initializes an Attache network interface using a packet driver. */static void pktd_init(struct net *net){ struct pktdif *pif = net->specific; bits16_t type_field; int err; if (!net || !pif) return; /* * Do class specific initialization */ switch (pif->pdn.drvr_info.class) { case IC_ETHERNET: /* * Get one handle that will receive any incoming packet type. * We used to use separate handles for IPv4 and ARP, but that * turned out not to work with a lot of packet drivers when we * tried to extend it for IPv6 and multicast. Don't really know * why it failed, but this single-handle-with-null-type is * supported by most drivers because network analyzers use it. * So we go with what works. */ if ((err = pd_access_type(&pif->pdn, &pif->pdn.handle, (unsigned char *) 0, 0)) != PDE_NO_ERROR) { printf("Can't set up access via ethernet packet driver %s: %s\n", net->s_name, pd_perror(err)); return; } /* * Save the current receive mode and put the packet driver into * the mode we want. In most cases, we want mode 5 (unicast to * our MAC address plus all broadcast and all multicast), but you * can change this by redefining SNARK_PKTD_RCV_MODE if necessary. */ if (pif->saved_rcv_mode == -1 && (err = pd_get_rcv_mode(&pif->pdn, &pif->saved_rcv_mode)) != PDE_NO_ERROR) { printf ("Can't get get receive mode of ethernet packet driver %s: %s\n", net->s_name, pd_perror(err)); } else if ((err = pd_set_rcv_mode(&pif->pdn, SNARK_PKTD_RCV_MODE)) != PDE_NO_ERROR) { printf ("Can't set receive mode of ethernet packet driver %s: %s\n", net->s_name, pd_perror(err)); } /* * Find out our ethernet address, for ARP's benefit. */ net->ha_len = 6; net->h_address = pif->mac; pd_get_address(&pif->pdn, net->h_address, 6); break; case IC_SERIAL_LINE: if ((err = pd_access_type(&pif->pdn, &pif->pdn.handle, 0, 0)) != PDE_NO_ERROR) { printf("Can't access IP protocol via serial line packet driver %s: %s\n", net->s_name, pd_perror(err)); return; } break; case IC_FPPP: type_field = 0x2100; if ((err = pd_access_type(&pif->pdn, &pif->pdn.handle, (unsigned char *) &type_field, sizeof(type_field))) != PDE_NO_ERROR) { printf("Can't access IP protocol via FPPP packet driver %s: %s\n", net->s_name, pd_perror(err)); return; } break; default: printf("Don't know packet driver class %d for packet driver %s\n", pif->pdn.drvr_info.class, net->s_name); return; } /* mark this interface as up */ net->flags &= ~NF_DRIVER_DOWN; return;}/* * Shutdown the packet driver interface */static void pktd_close(struct net *net){ int err; if ((net->flags & NF_DRIVER_DOWN) == 0) { struct pktdif *pif = net->specific; net->flags |= NF_DRIVER_DOWN; if (pif->pdn.drvr_info.class == IC_ETHERNET && pif->saved_rcv_mode != -1 && (err = pd_set_rcv_mode(&pif->pdn, pif->saved_rcv_mode)) != PDE_NO_ERROR) { printf ("Can't restore receive mode of ethernet packet driver %s: %s\n", net->s_name, pd_perror(err)); } pd_release_type(&pif->pdn, pif->pdn.handle); }}/* * Send a packet, just hand it off to the packet driver. */static void pktd_send(packet *p){ struct pktdif *pif = p->pkt_n->specific; pd_send_pkt(&pif->pdn, p->pkt_data, p->pkt_datalen); pkt_free(p);}/* * Take a packet off an interface's input queue, pass it along * to the appropriate routine. Arrange for this to happen again * if there are more packets queued. * * This is the main-program-level part of the packet receive logic. */static void pktd_handler(struct task *task, void *cookie){ struct pktdif *pif = cookie; packet *pkt = 0; int lock; /* * Pull off the next packet on the queue. We have to lock out interrupts * while we're doing this to avoid trashing the queue, so keep this short. */ lock = glue_intlock(0); if ((pkt = pif->pkt_q_head) != 0 && (pif->pkt_q_head = pkt->pkt_link) == 0) pif->pkt_q_tail = &pif->pkt_q_head; glue_intlock(lock); /* * If we didn't get a packet, we're done. */ if (!pkt) return; /* * Got a packet. If there's a receiver, hand it up, otherwise punt it. */ if (pif->receiver) (*pif->receiver)(pkt); else pkt_free(pkt); /* * Run self again to check for another packet. */ task_enq(task);}/* * Packet driver receive upcalls come together here. Each received packet * gets two upcalls, the first one gets the packet and the second delivers * the data. Since we're running at interrupt level, we don't try to give * the packet to Attache; instead we schedule a task to run at main program * level which will do it for us. */static unsigned char far *pktd_receive (struct saveregs far *r, struct pd_net *pd_net){ struct pktdif *pif = (struct pktdif *) pd_net; int extra; if (r->ax != 0) { /* * Second upcall we queue the packet buffer. * Schedule our task to run at main program level to handle the packet(s). */ pif->pkt->pkt_link = 0; *pif->pkt_q_tail = pif->pkt; pif->pkt_q_tail = &pif->pkt->pkt_link; pif->pkt = 0; task_enq(&pif->task); } else { /* * First upcall we allocate and return the packet buffer */ /* * Sanity check the requested length */ if (r->cx != 0) { /* * Leave space at the front of the packet in case this packet * is forwarded out any networks with larger headers than this one */ extra = MaxLnh - pif->net.driver->lnh; /* * Get the packet buffer */ pif->pkt = pkt_alloc(r->cx + extra); if (pif->pkt != 0) { /* * Initialize packet buffer */ pif->pkt->pkt_datalen = r->cx; pif->pkt->pkt_data = pif->pkt->pkt_buffer + extra; pif->pkt->pkt_n = &pif->net; return (unsigned char far *) (pif->pkt->pkt_data); } } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -