📄 if_ppp.c
字号:
/* if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver *//* Copyright 1996 Wind River Systems, Inc. */#include "copyright_wrs.h"/* $NetBSD: if_ppp.c,v 1.20 1994/10/30 21:48:52 cgd Exp $ *//* * if_ppp.c - Point-to-Point Protocol (PPP) Asynchronous driver. * * Copyright (c) 1989 Carnegie Mellon University. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by Carnegie Mellon University. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Drew D. Perkins * Carnegie Mellon University * 4910 Forbes Ave. * Pittsburgh, PA 15213 * (412) 268-8576 * ddp@andrew.cmu.edu * * Based on: * @(#)if_sl.c 7.6.1.2 (Berkeley) 2/15/89 * * Copyright (c) 1987 Regents of the University of California. * All rights reserved. * * Redistribution and use in source and binary forms are permitted * provided that the above copyright notice and this paragraph are * duplicated in all such forms and that any documentation, * advertising materials, and other materials related to such * distribution and use acknowledge that the software was developed * by the University of California, Berkeley. The name of the * University may not be used to endorse or promote products derived * from this software without specific prior written permission. * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Serial Line interface * * Rick Adams * Center for Seismic Studies * 1300 N 17th Street, Suite 1450 * Arlington, Virginia 22209 * (703)276-7900 * rick@seismo.ARPA * seismo!rick * * Pounded on heavily by Chris Torek (chris@mimsy.umd.edu, umcp-cs!chris). * Converted to 4.3BSD Beta by Chris Torek. * Other changes made at Berkeley, based in part on code by Kirk Smith. * * Converted to 4.3BSD+ 386BSD by Brad Parker (brad@cayman.com) * Added VJ tcp header compression; more unified ioctls * * Extensively modified by Paul Mackerras (paulus@cs.anu.edu.au). * Cleaned up a lot of the mbuf-related code to fix bugs that * caused system crashes and packet corruption. Changed pppstart * so that it doesn't just give up with a collision if the whole * packet doesn't fit in the output ring buffer. * * Added priority queueing for interactive IP packets, following * the model of if_sl.c, plus hooks for bpf. * Paul Mackerras (paulus@cs.anu.edu.au). *//* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp *//*modification history--------------------01t,16apr99,koz Fix for 25165, communications error handling01s,17feb99,sgv Fix for spr 23702, pppintr check for NULL ppp_softc01r,17feb99,sgv Fix for spr 24459. pppalloc was not setting the correct ppp_softc structure to NULL on error condition01q.10sep98,sgv Added fix for interoperating with Windows01p,18aug97,jmb Add code to discard packets at interrupt level due to overflow of input ring buffer.01o,30dec97,sgv fixed problem in PPP output Hooks01n,26sep97,sgv Added PPP output Hooks01m,19sep97,vin changed m_ext.ext_buf to m_extBuf and m_ext.ext_size to m_extSize01l,14nov96,vin upgraded to use new buffering scheme.01k,13aug96,vin upgraded to BSD4.4, removed call in_ifaddr_remove as it is being done in if_dettach. 01j,30jul95,dzb cleanup on errors while openning serial device.01i,05jul95,dzb close out serial fd on errors in pppalloc().01h,12jun95,dzb added SNMP MIBII support (counters and ioctl). header file consolidation.01g,24apr95,dzb removed in_ifaddr_remove() because added to in.c (SPR #4109).01f,09mar95,dzb added counters for ip packets sent/received.01e,06mar95,dzb changed cfree() to free() (ANSI).01d,09feb95,dab added SIOCGIFMTU command to ppptioctl().01c,07feb95,dzb changed pppoutput() to return errno, instead of ERROR. removed redundant mbuf check from ppp_wrt_flush(). zeroed out m_len after MGET (SPR #4037).01b,16jan95,dzb warnings cleanup. moved global prototypes to if_ppp.h.01a,21dec94,dab VxWorks port - first WRS version. +dzb added: path for ppp header files, WRS copyright.*/#include "vxWorks.h"#include "net/mbuf.h"#include "sockLib.h"#include "ioctl.h"#include "stdio.h"#include "errnoLib.h"#include "ioLib.h"#include "iosLib.h"#include "semLib.h"#include "memLib.h"#include "taskLib.h"#include "signal.h"#include "sigLib.h"#include "etherLib.h"#include "netLib.h"#include "m2Lib.h"#include "private/m2LibP.h"#include "net/if.h"#include "net/unixLib.h"#include "net/route.h"#include "netinet/in.h"#include "netinet/in_systm.h"#include "netinet/in_var.h"#include "netinet/ip.h"#include "pppLib.h"#include "rngLib.h"#include "tyLib.h"#include "tickLib.h"#if NPPP > 0#ifdef VJC#define HDROFF MAX_HDR/* HDROFF should really be 128, but other parts of the system will panic on TCP+IP headers bigger than MAX_HDR = MHLEN (100). */#else#define HDROFF (0)#endif#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que *//* external variables */IMPORT void ipintr();IMPORT void if_attach();IMPORT void if_dettach();IMPORT void if_down();/* global variables */struct ppp_softc *ppp_softc[NPPP] = { 0 } ;int ppp_wrt_task_priority = 60;int ppp_wrt_task_options = VX_SUPERVISOR_MODE | VX_UNBREAKABLE;int ppp_wrt_task_stack_size = 0x4000;char *ppp_device_name = "ppp";static int pppioctl __ARGS((struct ifnet *, int , caddr_t));static int pppattach __ARGS((int));static int pppoutput __ARGS((struct ifnet *, struct mbuf *, struct sockaddr *, struct rtentry *));static void pppinput __ARGS((struct ppp_softc *, int));static int pppasyncstart __ARGS((struct ppp_softc *));static u_short pppfcs __ARGS((int, u_char *, int));static int pppgetm __ARGS((struct ppp_softc *sc));static void pppdumpm __ARGS((struct mbuf *, int));static void pppdumpb __ARGS((u_char *, int));static void ppplogchar __ARGS((struct ppp_softc *, int));static void pppdealloc __ARGS((struct ppp_softc *));static struct ppp_softc *pppalloc __ARGS((int, char *));static void ppp_wrt_flush __ARGS((struct ppp_softc *));static void pinit __ARGS((int));static int pppintr __ARGS((int, int));static void ppp_tty_read __ARGS((int, struct ppp_softc *, int));/* * Some useful mbuf macros not in mbuf.h. */#define M_DATASTART(m) (m)->m_extBuf#define M_DATASIZE(m) (m)->m_extSize#define PPPBUFSIZE (PPP_MTU * 2)/* * The following disgusting hack gets around the problem that IP TOS * can't be set yet. We want to put "interactive" traffic on a high * priority queue. To decide if traffic is interactive, we check that * a) it is TCP and b) one of its ports is telnet, rlogin or ftp control. */static u_short interactive_ports[8] = { 0, 513, 0, 0, 0, 21, 0, 23,};#define INTERACTIVE(p) (interactive_ports[(p) & 7] == (p))/* * Does c need to be escaped? */#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))/* * Called to establish ppp interfaces. */static intpppattach(unit) int unit;{ register struct ppp_softc *sc; sc = ppp_softc[unit]; sc->sc_if.if_name = "ppp"; sc->sc_if.if_unit = unit; sc->sc_if.if_mtu = PPP_MTU; sc->sc_if.if_flags = IFF_POINTOPOINT | IFF_MULTICAST ; sc->sc_if.if_type = IFT_PPP; sc->sc_if.if_hdrlen = PPP_HDRLEN; sc->sc_if.if_ioctl = pppioctl; sc->sc_if.if_output = pppoutput; sc->sc_if.if_snd.ifq_maxlen = IFQ_MAXLEN; sc->sc_inq.ifq_maxlen = IFQ_MAXLEN; sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN; sc->sc_if.if_reset = pppclose; sc->sc_if.if_init = (FUNCPTR) pinit; if_attach(&sc->sc_if); return (OK);}/* * Allocate a ppp interface unit and initialize it. */static struct ppp_softc *pppalloc(unit, device) int unit; char *device;{ struct ppp_softc *sc; if (ppp_softc[unit] != NULL) return NULL; if ((sc = (struct ppp_softc *)calloc(1, sizeof(struct ppp_softc))) == NULL) return (NULL); ppp_softc[unit] = sc; if ((sc->sc_fd = open(device, O_RDWR, 0)) == ERROR) { ppp_softc[unit] = (struct ppp_softc *)NULL; free((char *) sc); return NULL; } if (ioctl(sc->sc_fd, FIORBUFSET, 4 * PPP_MTU) == ERROR || ioctl(sc->sc_fd, FIOWBUFSET, 4 * PPP_MTU) == ERROR) { close(sc->sc_fd); ppp_softc[unit] = (struct ppp_softc *)NULL; free((char *) sc); return NULL; } if (pppattach(unit) == ERROR) { close(sc->sc_fd); ppp_softc[unit] = (struct ppp_softc *)NULL; free((char *) sc); return (NULL); } if (ioctl(sc->sc_fd, FIOPROTOHOOK, (int)pppintr) == ERROR || ioctl(sc->sc_fd, FIOPROTOARG, unit) == ERROR) { close(sc->sc_fd); pppdealloc(sc); return (NULL); } sc->sc_flags = 0; sc->sc_mru = PPP_MRU;#ifdef VJC sl_compress_init(&sc->sc_comp);#endif sc->sc_if.if_flags |= IFF_RUNNING; return sc;}/* * Deallocate a ppp unit. */static voidpppdealloc(sc) struct ppp_softc *sc;{ struct mbuf *m; if_down(&sc->sc_if); sc->sc_devp = NULL; sc->sc_xfer = 0; for (;;) { IF_DEQUEUE(&sc->sc_inq, m); if (m == NULL) break; m_freem(m); } for (;;) { IF_DEQUEUE(&sc->sc_fastq, m); if (m == NULL) break; m_freem(m); } sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); if_dettach(&sc->sc_if); ppp_softc[sc->sc_if.if_unit] = (struct ppp_softc *)NULL; free((char *) sc);}/* * pppopen - open the ppp interface. * Returns unit id. */intpppopen(unit, device) int unit; char *device;{ register struct ppp_softc *sc; char ppp_wrt_name[10]; if ((sc = pppalloc(unit, device)) == NULL) return (ERROR); if (sc->sc_outm != NULL) { m_freem(sc->sc_outm); sc->sc_outm = NULL; } if (pppgetm(sc) == 0) { sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING); return (ERROR); } sc->sc_ilen = 0; bzero((char *)sc->sc_asyncmap, sizeof(sc->sc_asyncmap)); sc->sc_asyncmap[0] = 0xffffffff; sc->sc_asyncmap[3] = 0x60000000; sc->sc_rasyncmap = 0; sc->sc_devp = (void *) NULL; sc->sc_start = pppasyncstart; sc->sc_qlen = 0; sc->sc_tid = taskIdSelf(); semBInit(&sc->sc_wrtsem, SEM_Q_PRIORITY, SEM_EMPTY); ioctl(sc->sc_fd, FIOFLUSH, 0); sprintf(ppp_wrt_name, "tPPP%dWrt", sc->sc_if.if_unit); sc->sc_wrt_task_id = taskSpawn(ppp_wrt_name, ppp_wrt_task_priority, ppp_wrt_task_options, ppp_wrt_task_stack_size, (FUNCPTR)ppp_wrt_task, (int)sc, 0, 0, 0, 0, 0, 0, 0, 0, 0); if (sc->sc_wrt_task_id == ERROR) { close(sc->sc_fd); pppdealloc(sc); return (ERROR); } return (OK);} /* * Line specific close routine. * Detach the tty from the ppp unit. * Mimics part of ttyclose(). */intpppclose(unit) int unit;{ register struct ppp_softc *sc; int s; if (unit >= 0 && unit < NPPP) sc = ppp_softc[unit]; else return (ERROR); if (sc != NULL) { ppp_wrt_flush(sc); ioctl(sc->sc_fd, FIOPROTOHOOK, NULL); taskDelete(sc->sc_wrt_task_id); s = splimp(); /* paranoid; splnet probably ok */ close(sc->sc_fd); m_freem(sc->sc_outm); sc->sc_outm = NULL; m_freem(sc->sc_m); sc->sc_m = NULL; pppdealloc(sc); splx(s); } else return (ERROR); return(OK);}/* * Line specific (tty) read routine. */intpppread(unit, buf, count) int unit; char *buf; int count;{ register struct ppp_softc *sc = ppp_softc[unit]; struct mbuf *m; register int s; s = splimp(); IF_DEQUEUE(&sc->sc_inq, m); splx(s); if (m == NULL) return 0; copy_from_mbufs(buf, m, count); return (count);}/* * Line specific (tty) write routine. */intpppwrite(unit, buf, count) int unit; char *buf; int count;{ register struct ppp_softc *sc = ppp_softc[unit]; struct mbuf *m, *m0, **mp; struct sockaddr dst; struct ppp_header *ph1, *ph2; int len; if (count > sc->sc_if.if_mtu + PPP_HDRLEN || count < PPP_HDRLEN) { errno = EMSGSIZE; return (-1); } for (mp = &m0; count; mp = &m->m_next) { m = mBufClGet(M_WAIT, MT_DATA, count, FALSE); if ((*mp = m) == NULL) { m_freem(m0); errno = ENOBUFS; return (-1); } len = min (count, m->m_extSize); /* num for copy */ bcopy(buf, mtod(m, caddr_t), len); count -= len;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -