📄 if_sl.c
字号:
/* if_sl.c - Serial Line IP (SLIP) network interface driver *//* Copyright 1989-1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/* $NetBSD: if_sl.c,v 1.33 1994/12/11 21:39:05 mycroft Exp $ *//* * Copyright (c) 1987, 1989, 1992, 1993 * The Regents of the University of California. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in the * documentation and/or other materials provided with the distribution. * 3. All advertising materials mentioning features or use of this software * must display the following acknowledgement: * This product includes software developed by the University of * California, Berkeley and its contributors. * 4. Neither the name of the University nor the names of its contributors * may be used to endorse or promote products derived from this software * without specific prior written permission. * * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * * @(#)if_sl.c 8.6 (Berkeley) 2/1/94 *//*modification history--------------------02d,06dec00,pai removed unnecessary forward declarations (SPR #62822).02c,08may97,vin switched the order of ifDstAddrSet and ifAddrSet, fixed SIOCSIFDSTADDR in slioctl, SPR 8531, added slRtRequest().02b,01aug97,jmb Reduce number of slread netJobs by a factor of two when FRAME_END character used to begin a new frame.02a,16jul97,jmb Added code to discard packets at interrupt level if the input ring buffer is full.01z,04dec96,vin replaced MFREE with m_free (..)01y,18jul96,vin upgraded to BSD4.4, removed call to in_ifaddr_remove as it is being done in if_dettach now. 01x,07mar96,gnn Added code to handle user selectable MTUs for the SLIP link. (SPR #4652)01w,14mar95,dzb make sure to flush the wrt task's queue on close (SPR #4111).01v,13mar95,dzb added call to in_ifaddr_remove when deleting if (SPR #4109).01u,13mar95,dzb changed to use free() instead of cfree() (SPR #4113).01t,24jan95,jdi doc cleanup.01s,08dec94,dzb return ENOBUFS when dropping packet in sloutput() (SPR #3844).01r,11nov94,dzb added CSLIP enhancements. decreased SLMTU size. doc tweaks. implemented buffer loaning, and removed extra data copies. replaced calls to sl_btom() with copy_to_mbufs().01q,22apr93,caf ansification: added cast to ioctl() parameter.01p,11aug93,jmm Changed ioctl.h and socket.h to sys/ioctl.h and sys/socket.h01o,19feb93,jdi documentation cleanup.01n,22sep92,gae documentation tweaks.01m,18jul92,smb Changed errno.h to errnoLib.h.01l,26may92,rrr the tree shuffle -changed includes to have absolute path from h/01k,07nov91,jpb made slipWrtTask global for task TCB "ENTRY" status.01j,04oct91,rrr passed through the ansification filter -changed functions to ansi style -changed includes to have absolute path from h/ -changed VOID to void -changed copyright notice01i,10apr91,jdi documentation cleanup; removed stray close-quote in example; doc review by elh.01h,10aug90,dnw corrected forward declarations for void functions.01g,26jun90,hjb SLBUFSIZE increased to fix a bug in ESC handling.01f,26jun90,jcf changed semaphore initialization to 5.0.01e,07may90,hjb changed MIN,MAX to min,max; de-linted.01d,19apr90,hjb deleted param.h, de-linted.01c,20mar90,jcf changed semaphores to binary.01b,18mar90,hjb minor cleanup.01a,11apr89,hjb first vxWorks version.*//*DESCRIPTIONThis module implements the VxWorks Serial Line IP (SLIP) network interface driver. Support for compressed TCP/IP headers (CSLIP) is included.The SLIP driver enables VxWorks to talk to other machines over serialconnections by encapsulating IP packets into streams of bytes suitablefor serial transmission.USER-CALLABLE ROUTINESSLIP devices are initialized using slipInit(). Its parameters specify the Internet address for both sides of the SLIP point-to-point link,the name of the tty device on the local host, and options to enable CSLIPheader compression. The slipInit() routine calls slattach() to attach theSLIP interface to the network. The slipDelete() routine deletes a specifiedSLIP interface.LINK-LEVEL PROTOCOLSLIP is a simple protocol that uses four token charactersto delimit each packet: - END (0300) - ESC (0333) - TRANS_END (0334) - TRANS_ESC (0335)The END character denotes the end of an IP packet. The ESC character is usedwith TRANS_END and TRANS_ESC to circumvent potential occurrences of END or ESCwithin a packet. If the END character is to be embedded, SLIP sends "ESC TRANS_END" to avoid confusion between a SLIP-specific END and actualdata whose value is END. If the ESC character is to be embedded, thenSLIP sends "ESC TRANS_ESC" to avoid confusion. (Note that the SLIP ESC isnot the same as the ASCII ESC.)On the receiving side of the connection, SLIP uses the opposite actions todecode the SLIP packets. Whenever an END character is received, SLIPassumes a full IP packet has been received and sends it up to the IP layer.TARGET-SPECIFIC PARAMETERSThe global flag slipLoopBack is set to 1 by default. This flag enablesthe packets to be sent to the loopback interface if they are destined toto a local slip interface address. By setting this flag, any packetssent to a local slip interface address will not be seen on the actual seriallink. Set this flag to 0 to turn off this facility. If this flag is not setany packets sent to the local slip interface address will actually be sentout on the link and it is the peer's responsibility to loop the packet back.IMPLEMENTATIONThe write side of a SLIP connection is an independent task. Each SLIPinterface has its own output task that sends SLIP packets over aparticular tty device channel. Whenever a packet is ready to be sent out,the SLIP driver activates this task by giving a semaphore. When thesemaphore is available, the output task performs packetization(as explained above) and writes the packet to the tty device.The receiving side is implemented as a "hook" into the tty driver. A ttyioctl() request, FIOPROTOHOOK, informs the tty driver to call the SLIPinterrupt routine every time a character is received from a serial port.By tracking the number of characters and watching for the END character,the number of calls to read() and context switching time have beenreduced. The SLIP interrupt routine will queue a call to the SLIP readroutine only when it knows that a packet is ready in the tty driver's ringbuffer. The SLIP read routine will read a whole SLIP packet at a time andprocess it according to the SLIP framing rules. When a full IP packet isdecoded out of a SLIP packet, it is queued to IP's input queue.CSLIP compression is implemented to decrease the size of the TCP/IPheader information, thereby improving the data to header size ratio.CSLIP manipulates header information just before apacket is sent and just after a packet is received. Only TCP/IP headers are compressed and uncompressed; other protocol types aresent and received normally. A functioning CSLIP driver is requiredon the peer (destination) end of the physical link in order to carryout a CSLIP "conversation."Multiple units are supported by this driver. Each individual unit mayhave CSLIP support disabled or enabled, independent of the state ofother units.INTERNALThe write side of a SLIP connection is an independent task. Each SLIPinterface will have its own output task that will send SLIP packets over aparticular tty device channel. Whenever a packet is ready to be sent out,sloutput() will activate this task by giving a semaphore. When thesemaphore is available, the output task will perform packetization(as explained above) and write the packet to the tty device.The receiving side is implemented as a "hook" into the tty driver. A ttyioctl() request, FIOPROTOHOOK, informs the tty driver to call slintr() everytime a character is received from a serial port. By tracking the numberof characters and watching for the END character, the number of calls toread() and context switching time have been reduced. The slintr() routinewill queue a call to slread() only when it knows that a packet is ready inthe tty driver's ring buffer. slread() will read a whole SLIP packet at atime and process it according to the SLIP framing rules. When a full IPpacket is decoded out of a SLIP packet, it is enqueued to IP's input queue.The CSLIP compressed header format is only implemented for TCP/IP packets.The slcompress.c:sl_compress_tcp routine is called from sloutput() tocompress the header while the outgoing packet is still in an mbuf chain.The slcompress.c:sl_uncompress_tcp routine is called from slRecv() touncompress the header before the packet is copied to an mbuf chain (i.e.,the incoming packet is in a contiguous buffer).The CSLIP header's first octet contains the packet type (top 3 bits), TCP'push' bit, and flags that indicate which of the 4 TCP sequencenumbers have changed (bottom 5 bits). The next octet is aconversation number that associates a saved IP/TCP header withthe compressed packet. The next two octets are the TCP checksumfrom the original datagram. The next 0 to 15 octets aresequence number changes, one change per bit set in the header(there may be no changes and there are two special cases wherethe receiver implicitly knows what changed).There are 5 numbers which can change (they are always insertedin the following order): TCP urgent pointer, window,acknowlegement, sequence number and IP ID. (The urgent pointeris different from the others in that its value is sent, not thechange in value.) Since typical use of SLIP links is biasedtoward small packets, changes use a variable length coding withone octet for numbers in the range 1 - 255 and 3 octets (0, MSB,LSB) for numbers in the range 256 - 65535 or 0. (If the changein sequence number or ack is more than 65535, an uncompressedpacket is sent.)BOARD LAYOUTNo hardware is directly associated with this driver; therefore, a jumperingdiagram is not applicable.SEE ALSOifLib, tyLib,John Romkey: RFC-1055,.I "A Nonstandard for Transmission of IP Datagrams Over Serial Lines: SLIP,"Van Jacobson: RFC-1144, entitled.I "Compressing TCP/IP Headers for Low-Speed Serial Links"ACKNOWLEDGEMENTThis program is based on original work done by Rick Adams of The Center forSeismic Studies and Chris Torek of The University of Maryland.The CSLIP enhancements are based on work done by Van Jacobson ofUniversity of California, Berkeley for the "cslip-2.7" release.INTERNAL.CS slipInit sloutput slipDelete slipBaudSet slintr slioctl /\ | | | / \ |semaphore | | / \ | | | / \ |--| | | slattach slipWrtTask <- | | slread | | | | | sl_compress_tcp | sl_uncompress_tcp | | | | | slSoftcFree <-----------------------+ ---------slRecv.CE*//* includes */#include "vxWorks.h"#include "sys/socket.h"#include "sys/ioctl.h"#include "stdio.h"#include "errnoLib.h"#include "ioLib.h"#include "semLib.h"#include "memLib.h"#include "taskLib.h"#include "tickLib.h"#include "logLib.h"#include "ifLib.h"#include "routeLib.h"#include "netLib.h"#include "etherLib.h"#include "net/if.h"#include "net/if_types.h"#include "net/if_subr.h"#include "net/route.h"#include "net/mbuf.h"#include "net/unixLib.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "netinet/sl_compress.h"#include "if_sl.h"#include "drv/netif/netifDev.h"#include "rngLib.h"#include "tyLib.h"/* defines *//* * SLMTU is now a hard limit on input packet size. SLMTU must be <= MCLBYTES * to take advantage of buffer loaning. Additionally, it has been shown * that a smaller MTU works well with SLIP, so that echo traffic does * not have to wait for larger, bulk data packets. With an MTU that is * 10 to 20 times that TCP/IP header, a reasonable line efficiency is * achieved. For SLIP, this dictates an MTU of 400 to 800 bytes. * CSLIP could do well with an MTU as low as 100 to 400 bytes. */#define SLMTU 576 /* max Tx/Rx size in bytes */#define L_POOL 6 /* Rx loaner buffer pool */#define NSLIP 20 /* max. number of SLIP interfaces */#define SLBUF_OFF (sizeof(struct ifnet *) + 128)#define SLBUF_HI ((SLMTU*2) - 1) /* Rx character threshold */#define SLBUFSIZE ((SLMTU*2) + SLBUF_OFF) /* leave room for CSLIP uncompress *//* SLIP protocol characters */#define FRAME_END 0300 /* Frame End */#define FRAME_ESCAPE 0333 /* Frame Esc */#define TRANS_FRAME_END 0334 /* transposed frame end */#define TRANS_FRAME_ESCAPE 0335 /* transposed frame esc *//* SLIP control flags */#define SL_COMPRESS 0x01 /* enable CSLIP compression */#define SL_COMPRESS_RX 0x02 /* enable compression on Rx of compress pkt */#define SL_INTR_PACKET_DISCARD 0x04 /* discard current packet at int. level */#define SIN(s) ((struct sockaddr_in *)s) /* typedefs */typedef struct /* SL_SOFTC */ { struct ifnet sc_if; /* network-visible interface */ u_char sc_flags; /* SLIP interface control flags */ short sc_ilen; /* chars in current Rx packet */ short sc_qlen; /* num of chars in tty input queue */ char * sc_buf; /* input buffer */ char * sc_orig; /* pointer to malloc'ed buffer space */ int sc_fd; /* file descriptor for slip device */ SEM_ID sc_wrtSem; /* write semaphore */ int sc_wrtTaskId; /* write task ID */ struct slcompress sc_comp; /* TCP/IP compression info */ int sc_nLoanRxBuf; /* number of Rx buffers left to loan */ char * sc_lPool[L_POOL]; /* receive buffer loaner pool */ UINT8 * sc_pRefC[L_POOL]; /* stack of reference count pointers */ UINT8 sc_refC[L_POOL]; /* actual reference count values */ } SL_SOFTC;/* globals */int slipTaskPriority = 55; /* netTask priority +5 */int slipTaskOptions = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int slipTaskStackSize = 2000;int slipLoopBack = 1;IMPORT void if_dettach (struct ifnet *ifp);IMPORT struct ifnet loif;/* locals */LOCAL SL_SOFTC *sl_softc [NSLIP];/* forward declarations */STATUS slipDelete (); /* global for user access */void slipWrtTask (SL_SOFTC *sc); /* global for "ENTRY" status */STATUS slattach (int unit, int fd, BOOL compressEnable, BOOL compressAllow, int mtu);/* static forward declarations */#ifdef __STDC__static void slSoftcFree (SL_SOFTC *sc, int unit);static void slinit (int unit);static STATUS sloutput (struct ifnet *ifp, struct mbuf *m, struct sockaddr* dst, struct rtentry * rtp);static BOOL slintr (int unit, int inchar);static void slread (SL_SOFTC *sc, int count);static char *slRecv (SL_SOFTC *sc, BOOL firstCluster);static int slioctl (struct ifnet *ifp, int cmd, caddr_t data);static int numCharsToMask (u_char mask1, u_char mask2, u_int size, u_char *cp);static void slLoanFree (SL_SOFTC *sc, char *pRxBuf, UINT8 *pRef);static void slRtRequest (int cmd, struct rtentry * pRtEntry, struct sockaddr * pSockAddr); #else /* __STDC__ */static void slSoftcFree ();static void slinit ();static STATUS sloutput ();static BOOL slintr ();static void slread ();static char *slRecv ();static int slioctl ();static int numCharsToMask ();static void slLoanFree ();#endif /* __STDC__ *//********************************************************************************* slipInit - initialize a SLIP interface** This routine initializes a SLIP device. Its parameters specify the name* of the tty device, the Internet addresses of both sides of the SLIP* point-to-point link (i.e., the local and remote sides of the serial line* connection), and CSLIP options.** The Internet address of the local side of the connection is specified in* <myAddr> and the name of its tty device is specified in <devName>.* The Internet address of the remote side is specified in <peerAddr>.* If <baud> is not zero, the baud rate will be the specified value;* otherwise, the default baud rate will be the rate set by the tty driver.* The <unit> parameter specifies the SLIP device unit number. Up to twenty* units may be created.** The CLSIP options parameters <compressEnable> and <compressAllow> determine* support for TCP/IP header compression. If <compressAllow> is TRUE (1), then* CSLIP will be enabled only if a CSLIP type packet is received by this* device. If <compressEnable> is TRUE (1), then CSLIP compression will be* enabled explicitly for all transmitted packets, and compressed packets* can be received.** The MTU option parameter allows the setting of the MTU for the link.* * For example, the following call initializes a SLIP device, using the* console's second port, where the Internet address of the local host is* 192.10.1.1 and the address of the remote host is 192.10.1.2.* The baud rate will be the default rate for /tyCo/1. CLSIP is enabled* if a CSLIP type packet is received. The MTU of the link is 1006.* .CS* slipInit (0, "/tyCo/1", "192.10.1.1", "192.10.1.2", 0, 0, 1, 1006);* .CE** RETURNS:* OK, or ERROR if the device cannot be opened, memory is insufficient,* or the route is invalid.*/STATUS slipInit ( int unit, /* SLIP device unit number (0 - 19) */ char *devName, /* name of the tty device to be initialized */ char *myAddr, /* address of the SLIP interface */ char *peerAddr, /* address of the remote peer SLIP interface */ int baud, /* baud rate of SLIP device: 0=don't set rate */ BOOL compressEnable, /* explicitly enable CSLIP compression */ BOOL compressAllow, /* enable CSLIP compression on Rx */ int mtu /* user set-able MTU */ ) { SL_SOFTC *sc; int slipFd; char slipName [10]; char slipWrtName [10]; /* check and see of unit is in valid range */ if (unit < 0 || unit >= NSLIP) { (void)errnoSet (S_if_sl_INVALID_UNIT_NUMBER); return (ERROR); } if ((slipFd = open (devName, O_RDWR, 0)) == ERROR) return (ERROR); /* set the baud rate only if the 'baud' is not equal to zero */ if (baud != 0 && ioctl (slipFd, FIOBAUDRATE, baud) == ERROR) { (void) close (slipFd); return (ERROR); } if (mtu <= 0 || mtu > 2048) mtu = SLMTU; /* * Re-allocate big enough ring buffers for this tty device since * the default ring buffer size of tty devices is 512 bytes, which * may be smaller than SLMTU. The ring buffers are 4 times * the size of a maximum SLIP packet, for insurance. */ if (ioctl (slipFd, FIORBUFSET, 4 * mtu) == ERROR || ioctl (slipFd, FIOWBUFSET, 4 * mtu) == ERROR) { (void) close (slipFd); return (ERROR); } if (slattach (unit, slipFd, compressEnable, compressAllow, mtu) == ERROR) { (void) close (slipFd); return (ERROR); } sc = sl_softc [unit]; (void) sprintf (slipName, "sl%d", sc->sc_if.if_unit); (void) sprintf (slipWrtName, "tSl%dWrt", sc->sc_if.if_unit); /* Set own and peer's internet address. * Add a routing table entry to tell how to loopback over SLIP. * Point to point loopback routing table entry is required to * properly talk to myself using the SLIP interface address.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -