📄 ppp_io.c
字号:
//==========================================================================
//
// src/ppp_io.c
//
//==========================================================================
// This file is part of eCos, the Embedded Configurable Operating System.
// Portions created by Nick Garnett are
// Copyright (C) 2003, 2004 eCosCentric Ltd.
//####BSDCOPYRIGHTBEGIN####
//
// -------------------------------------------
//
// Portions of this software may have been derived from OpenBSD,
// FreeBSD or other sources, and are covered by the appropriate
// copyright disclaimers included herein.
//
// -------------------------------------------
//
//####BSDCOPYRIGHTEND####
//==========================================================================
/*
* ppp_tty.c - Point-to-Point Protocol (PPP) driver for asynchronous
* tty devices.
*
* 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,
* 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).
*/
/* $FreeBSD: src/sys/net/ppp_tty.c,v 1.43 2000/01/29 16:56:24 peter Exp $ */
#include <pkgconf/system.h>
#include <pkgconf/net.h>
#include <pkgconf/ppp.h>
#define _KERNEL
#define VJC /* XXX for ppp_defs.h */
#include <sys/param.h>
#define suser(x) 0
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/uio.h>
#ifdef PPP_FILTER
#include <net/bpf.h>
#endif
#include <cyg/ppp/net/if_ppp.h>
#include <cyg/ppp/net/if_pppvar.h>
//==========================================================================
#ifdef __ECOS
#include "cyg/ppp/ppp_io.h"
//#define db_printf diag_printf
#define db_printf(fmt, ... )
#define spltty(x) splsoftnet(x)
#define ENOIOCTL ENOSYS
#endif
//==========================================================================
static u_short pppfcs __P((u_short fcs, u_char *cp, int len));
static void pppasyncstart __P((struct ppp_softc *));
static void pppasyncctlp __P((struct ppp_softc *));
static void pppasyncrelinq __P((struct ppp_softc *));
static void pppasyncsetmtu __P((struct ppp_softc *));
static void pppgetm __P((struct ppp_softc *sc));
static void ppplogchar __P((struct ppp_softc *, int));
/* XXX called from if_ppp.c - layering violation */
void pppasyncattach __P((void *));
//==========================================================================
/*
* Some useful mbuf macros not in mbuf.h.
*/
#define M_IS_CLUSTER(m) ((m)->m_flags & M_EXT)
#define M_DATASTART(m) \ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_buf : \ (m)->m_flags & M_PKTHDR ? (m)->m_pktdat : (m)->m_dat)
#define M_DATASIZE(m) \ (M_IS_CLUSTER(m) ? (m)->m_ext.ext_size : \ (m)->m_flags & M_PKTHDR ? MHLEN: MLEN)
//==========================================================================
/*
* Does c need to be escaped?
*/
#define ESCAPE_P(c) (sc->sc_asyncmap[(c) >> 5] & (1 << ((c) & 0x1F)))
//==========================================================================
/*
* Procedures for using an async tty interface for PPP.
*/
/* This is a FreeBSD-2.X kernel. */
//#define CCOUNT(q) ((q)->c_cc)
//#define PPP_LOWAT 100 /* Process more output when < LOWAT on queue */
//#define PPP_HIWAT 400 /* Don't start a new packet if HIWAT on que */
//==========================================================================
/*
* Line specific open routine for async tty devices.
* Attach the given tty to the first available ppp unit.
* Called from device open routine or ttioctl() at >= splsofttty()
*/
/* ARGSUSED */
int
cyg_ppp_pppopen(tp)
struct tty *tp;
{
register struct ppp_softc *sc;
int error, s;
if ((error = suser(p)) != 0)
return (error);
s = spltty();
if ((sc = pppalloc(0)) == NULL) {
splx(s);
return ENXIO;
}
if (sc->sc_relinq)
(*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
sc->sc_ilen = 0;
sc->sc_m = NULL;
bzero(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 *) tp;
sc->sc_start = pppasyncstart;
sc->sc_ctlp = pppasyncctlp;
sc->sc_relinq = pppasyncrelinq;
sc->sc_setmtu = pppasyncsetmtu;
sc->sc_outm = NULL;
pppgetm(sc);
sc->sc_if.if_flags |= IFF_RUNNING;
getmicrotime(&sc->sc_if.if_lastchange);
tp->t_sc = (caddr_t) sc;
splx(s);
return (0);
}
//==========================================================================
/*
* Line specific close routine, called from device close routine
* and from ttioctl at >= splsofttty().
* Detach the tty from the ppp unit.
* Mimics part of ttyclose().
*/
int
cyg_ppp_pppclose(tp, flag)
struct tty *tp;
int flag;
{
register struct ppp_softc *sc;
int s;
db_printf("%s called\n", __PRETTY_FUNCTION__);
s = spltty();
sc = (struct ppp_softc *) tp->t_sc;
if (sc != NULL) {
tp->t_sc = NULL;
if (tp == (struct tty *) sc->sc_devp) {
pppasyncrelinq(sc);
pppdealloc(sc);
}
}
splx(s);
return 0;
}
//==========================================================================
/*
* Relinquish the interface unit to another device.
*/
static void
pppasyncrelinq(sc)
struct ppp_softc *sc;
{
int s;
s = spltty();
if (sc->sc_outm) {
m_freem(sc->sc_outm);
sc->sc_outm = NULL;
}
if (sc->sc_m) {
m_freem(sc->sc_m);
sc->sc_m = NULL;
}
if (sc->sc_flags & SC_TIMEOUT) {
sc->sc_flags &= ~SC_TIMEOUT;
}
splx(s);
}
//==========================================================================
/*
* This gets called from the upper layer to notify a mtu change
*/
static void
pppasyncsetmtu(sc)
register struct ppp_softc *sc;
{
db_printf("%s called\n", __PRETTY_FUNCTION__);
}
//==========================================================================
/*
* function to check if data is available
*/
int
cyg_ppp_pppcheck(tp)
register struct tty *tp;
{
register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
int status = 0;
register int s;
s = spltty();
if (tp != (struct tty *) sc->sc_devp ) {
splx(s);
return 0;
}
if (sc->sc_inq.ifq_head == NULL)
{
splx(s);
return 0;
}
// if the queue is not empty
if ( IF_IS_EMPTY(&sc->sc_inq) == false)
status = 1;
splx(s);
return(status);
}
//==========================================================================
/*
* Line specific (tty) read routine.
* called at zero spl from the device driver in the response to user-level
* reads on the tty file descriptor (ie: pppd).
*/
int
cyg_ppp_pppread(tp, uio, flag)
register struct tty *tp;
struct uio *uio;
int flag;
{
register struct ppp_softc *sc = (struct ppp_softc *)tp->t_sc;
struct mbuf *m, *m0;
register int s;
int error = 0;
db_printf("%s called\n", __PRETTY_FUNCTION__);
if (sc == NULL)
return 0;
// Look for input. If there is none return EWOULDBLOCK, otherwise
// dequeue the next packet and return it.
s = spltty();
if (tp != (struct tty *) sc->sc_devp ) {
splx(s);
return 0;
}
if (sc->sc_inq.ifq_head == NULL)
{
splx(s);
return EWOULDBLOCK;
}
/* Get the packet from the input queue */
IF_DEQUEUE(&sc->sc_inq, m0);
splx(s);
for (m = m0; m && uio->uio_resid; m = m->m_next)
{
if ((error = uiomove(mtod(m, u_char *), m->m_len, uio)) != 0)
break;
}
m_freem(m0);
return (error);
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -