summaryrefslogtreecommitdiffstats
path: root/c/src/libnetworking/modem
diff options
context:
space:
mode:
authorJoel Sherrill <joel.sherrill@OARcorp.com>2002-01-31 21:42:11 +0000
committerJoel Sherrill <joel.sherrill@OARcorp.com>2002-01-31 21:42:11 +0000
commit0286b9f6145f9664f6b0e196e24daee8be46b538 (patch)
tree5cdf87997238653f4083fe1c1326213040183044 /c/src/libnetworking/modem
parent2002-01-31 Ralf Corsepius <corsepiu@faw.uni-ulm.de> (diff)
downloadrtems-0286b9f6145f9664f6b0e196e24daee8be46b538.tar.bz2
2001-01-31 Mike Siers <mikes@poliac.com>
* Nice Update of PPPD support which eliminates the requiremetn that drivers be in the termios TASK_DRIVEN mode. Mike did significant testing and reports that it seems to be more stable and handle larger packets better. This patch replaces the termios tasks with more general pppd network driver tasks. The functions pppinput() and pppstart() get called from the interrupt service routine. * Makefile.am, configure.ac, net/Makefile.am, net/bpf.h, net/ethernet.h, net/if.c, net/if.h, net/if_arp.h, net/if_dl.h, net/if_ethersubr.c, net/if_llc.h, net/if_loop.c, net/if_ppp.h, net/if_pppvar.h, net/if_types.h, net/netisr.h, net/ppp-comp.h, net/ppp_defs.h, net/pppcompress.h, net/radix.c, net/radix.h, net/raw_cb.c, net/raw_cb.h, net/raw_usrreq.c, net/route.c, net/route.h, net/rtsock.c, pppd/Makefile.am, pppd/README, pppd/STATUS, pppd/auth.c, pppd/cbcp.c, pppd/ccp.c, pppd/ccp.h, pppd/chap.c, pppd/chap.h, pppd/chap_ms.c, pppd/chap_ms.h, pppd/chat.c, pppd/demand.c, pppd/fsm.c, pppd/fsm.h, pppd/ipcp.c, pppd/ipcp.h, pppd/ipxcp.c, pppd/ipxcp.h, pppd/lcp.c, pppd/lcp.h, pppd/magic.c, pppd/magic.h, pppd/options.c, pppd/patchlevel.h, pppd/pathnames.h, pppd/pppd.8, pppd/pppd.h, pppd/rtemsmain.c, pppd/rtemspppd.c, pppd/rtemspppd.h, pppd/sys-rtems.c, pppd/upap.c, pppd/upap.h, pppd/utils.c, pppd/example/README, pppd/example/netconfig.h, wrapup/Makefile.am: Modified. * net/bsd-comp.c, net/if_ppp.c, net/ppp-deflate.c, net/ppp.h, net/ppp_tty.c, net/pppcompress.c, net/zlib.c, net/zlib.h: New file. * modem/, modem/.cvsignore, modem/Makefile.am, modem/ppp.c, modem/ppp.h, modem/ppp_tty.c, modem/pppcompress.c: Subdirectory removed.
Diffstat (limited to '')
-rw-r--r--c/src/exec/libnetworking/net/if_ppp.c (renamed from c/src/libnetworking/modem/ppp.c)477
-rw-r--r--c/src/exec/libnetworking/net/pppcompress.c (renamed from c/src/libnetworking/modem/pppcompress.c)0
-rw-r--r--c/src/libnetworking/modem/.cvsignore2
-rw-r--r--c/src/libnetworking/modem/Makefile.am39
-rw-r--r--c/src/libnetworking/modem/ppp.h7
-rw-r--r--c/src/libnetworking/modem/ppp_tty.c1100
6 files changed, 343 insertions, 1282 deletions
diff --git a/c/src/libnetworking/modem/ppp.c b/c/src/exec/libnetworking/net/if_ppp.c
index 4ccecc85c1..8c8b58745d 100644
--- a/c/src/libnetworking/modem/ppp.c
+++ b/c/src/exec/libnetworking/net/if_ppp.c
@@ -75,10 +75,10 @@
#include "ppp.h"
#if NPPP > 0
-/* temporarily we switch off the compression */
-
-#include <rtems/rtems_bsdnet.h> /* to get right defines */
+#include <termios.h>
+#include <rtems/termiostypes.h>
+#include <rtems/rtems_bsdnet.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/proc.h>
@@ -89,9 +89,7 @@
#include <sys/time.h>
#include <sys/malloc.h>
-#include <rtems/rtems_bsdnet.h>
#include <net/if.h>
-#include <sys/errno.h>
#include <net/if_types.h>
#include <net/netisr.h>
#include <net/route.h>
@@ -99,14 +97,14 @@
#include <net/bpf.h>
#endif
-#ifdef INET
+#if INET
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/in_var.h>
#include <netinet/ip.h>
#endif
-#include <bpfilter.h>
+#include "bpfilter.h"
#if NBPFILTER > 0
#include <net/bpf.h>
#endif
@@ -122,23 +120,18 @@
#define splsoftnet splnet
-#ifndef NETISR_PPP
-/* This definition should be moved to net/netisr.h */
-#define NETISR_PPP 26 /* PPP software interrupt */
-#endif
-
#ifdef PPP_COMPRESS
#define PACKETPTR struct mbuf *
#include <net/ppp-comp.h>
#endif
-extern struct ifqueue ipintrq;
+
static int pppsioctl __P((struct ifnet *, int, caddr_t));
static void ppp_requeue __P((struct ppp_softc *));
#ifdef PPP_COMPRESS
static void ppp_ccp __P((struct ppp_softc *, struct mbuf *m, int rcvd));
static void ppp_ccp_closed __P((struct ppp_softc *));
#endif
-static void ppp_inproc __P((struct ppp_softc *, struct mbuf *));
+static struct mbuf *ppp_inproc __P((struct ppp_softc *, struct mbuf *));
static void pppdumpm __P((struct mbuf *m0));
/*
@@ -171,7 +164,6 @@ static void pppdumpm __P((struct mbuf *m0));
extern struct compressor ppp_bsd_compress;
extern struct compressor ppp_deflate, ppp_deflate_draft;
-
struct compressor *ppp_compressors[8] = {
#if DO_BSD_COMPRESS
&ppp_bsd_compress,
@@ -183,20 +175,250 @@ struct compressor *ppp_compressors[8] = {
NULL
};
#endif /* PPP_COMPRESS */
-static struct timeval ppp_time;
-TEXT_SET(pseudo_set, pppattach);
+extern struct ifqueue ipintrq;
+static struct timeval ppp_time;
+
+TEXT_SET(pseudo_set, ppp_rxdaemon);
+
+
+static rtems_task ppp_rxdaemon(rtems_task_argument arg)
+{
+ rtems_event_set events;
+ rtems_interrupt_level level;
+ struct ppp_softc *sc = (struct ppp_softc *)arg;
+ struct mbuf *mp = (struct mbuf *)0;
+ struct mbuf *m;
+
+ /* enter processing loop */
+ while ( 1 ) {
+ /* wait for event */
+ rtems_event_receive(RX_PACKET|RX_MBUF|RX_EMPTY,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
+ if ( events & RX_EMPTY ) {
+ printf("RX: QUEUE is EMPTY\n");
+ events &= ~RX_EMPTY;
+ }
+
+ if ( events ) {
+ /* get the network semaphore */
+ rtems_bsdnet_semaphore_obtain();
+
+ /* check to see if new packet was received */
+ if ( events & RX_PACKET ) {
+ /* get received packet mbuf chain */
+ rtems_interrupt_disable(level);
+ IF_DEQUEUE(&sc->sc_rawq, m);
+ rtems_interrupt_enable(level);
+
+ /* ensure packet was retrieved */
+ if ( m != (struct mbuf *)0 ) {
+ /* process the received packet */
+ mp = ppp_inproc(sc, m);
+ }
+ }
+
+ /* allocate a new mbuf to replace one */
+ if ( mp == NULL ) {
+ pppallocmbuf(sc, &mp);
+ }
+
+ /* place mbuf on freeq */
+ rtems_interrupt_disable(level);
+ IF_ENQUEUE(&sc->sc_freeq, mp);
+ rtems_interrupt_enable(level);
+ mp = (struct mbuf *)0;
+
+ /* release the network semaphore */
+ rtems_bsdnet_semaphore_release();
+
+ /* check to see if queue is empty */
+ if ( sc->sc_rawq.ifq_head ) {
+ /* queue is not empty - post another event */
+ rtems_event_send(sc->sc_rxtask, RX_PACKET);
+ }
+ }
+ }
+}
+
+static rtems_task ppp_txdaemon(rtems_task_argument arg)
+{
+ rtems_event_set events;
+ char cFrame = (char )PPP_FLAG;
+ int iprocess = (int )0;
+ struct ppp_softc *sc = (struct ppp_softc *)arg;
+ struct mbuf *mp;
+ struct mbuf *mf;
+ struct mbuf *m;
+ struct rtems_termios_tty *tp;
+
+ /* enter processing loop */
+ while ( 1 ) {
+ /* wait for event */
+ rtems_event_receive(TX_PACKET|TX_TRANSMIT,RTEMS_WAIT|RTEMS_EVENT_ANY,RTEMS_NO_TIMEOUT,&events);
+ if ( events & TX_TRANSMIT ) {
+ /* received event from interrupt handler - free current mbuf */
+ rtems_bsdnet_semaphore_obtain();
+ m_freem(sc->sc_outm);
+ rtems_bsdnet_semaphore_release();
+
+ /* chain is done - clear the values */
+ sc->sc_outm = (struct mbuf *)0;
+ sc->sc_outmc = (struct mbuf *)0;
+
+ /* now set flag to fake receive of TX_PACKET event */
+ /* this will check to see if we have any pending packets */
+ events |= TX_PACKET;
+ }
+
+ /* received event from pppasyncstart */
+ if ( events & TX_PACKET ) {
+ /* ensure we are not busy */
+ if ( sc->sc_outm == (struct mbuf *)0 ) {
+ /* try dequeuing a packet */
+ sc->sc_outm = ppp_dequeue(sc);
+ if ( sc->sc_outm == NULL ) {
+ /* clear output flags */
+ sc->sc_outflag = 0;
+ sc->sc_if.if_flags &= ~IFF_OACTIVE;
+ }
+ else {
+ /* set flag to start process */
+ iprocess = 1;
+ sc->sc_outflag = SC_TX_BUSY;
+ sc->sc_if.if_flags |= IFF_OACTIVE;
+ }
+ }
+ }
+
+ /* check to see if there is any processing required */
+ if ( iprocess ) {
+ /* clear process flag */
+ iprocess = (int)0;
+
+ /* initialize output values */
+ sc->sc_outfcs = PPP_INITFCS;
+ sc->sc_outbuf = (u_char *)0;
+ sc->sc_outlen = (short )0;
+ sc->sc_outoff = (short )0;
+ sc->sc_outfcslen = (short )0;
+
+ /* loop over all mbufs in chain */
+ mf = NULL;
+ mp = NULL;
+ m = sc->sc_outm;
+ while (( m != (struct mbuf *)0 ) && ( m->m_len > 0 )) {
+ /* check to see if first mbuf value has been set */
+ if ( sc->sc_outmc == (struct mbuf *)0 ) {
+ /* set values to start with this mbuf */
+ sc->sc_outmc = m;
+ sc->sc_outlen = m->m_len;
+ sc->sc_outbuf = mtod(m, u_char *);
+ }
+
+ /* update the FCS value and then check next packet length */
+ sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
+
+ /* check next packet to see if it is empty */
+ while (( m->m_next != NULL ) && ( m->m_next->m_len == 0 )) {
+ /* next mbuf is zero length */
+ /* add empty mbuf to free chain */
+ if ( mp == NULL ) {
+ /* item is head of free list */
+ mf = m->m_next;
+ mp = mf;
+ }
+ else {
+ /* add item to end of the free list */
+ mp->m_next = m->m_next;
+ mp = m->m_next;
+ }
+
+ /* remove empty item from process chain */
+ m->m_next = m->m_next->m_next;
+ mp->m_next = NULL;
+ }
+
+ /* move to next packet */
+ m = m->m_next;
+ }
+
+ /* ensure there is data to be sent out */
+ tp = (struct rtems_termios_tty *)sc->sc_devp;
+ if (( tp != NULL ) && ( sc->sc_outmc != (struct mbuf *)0 )) {
+ /* place FCS value into buffer */
+ sc->sc_outfcsbuf[sc->sc_outfcslen++] = ~sc->sc_outfcs & 0xff;
+ sc->sc_outfcsbuf[sc->sc_outfcslen++] = (~sc->sc_outfcs >> 8) & 0xff;
+ microtime(&sc->sc_if.if_lastchange);
+
+ /* write out frame byte to start the transmission */
+ (*tp->device.write)(tp->minor, &cFrame, 1);
+ }
+
+ /* check to see if we need to free some empty mbufs */
+ if ( mf != (struct mbuf *)0 ) {
+ /* free empty mbufs */
+ rtems_bsdnet_semaphore_obtain();
+ m_freem(mf);
+ rtems_bsdnet_semaphore_release();
+ }
+ }
+ }
+}
+
+static void ppp_init(struct ppp_softc *sc)
+{
+ rtems_status_code status;
+ rtems_unsigned32 priority = 100;
+
+ /* determine priority value */
+ if ( rtems_bsdnet_config.network_task_priority ) {
+ priority = rtems_bsdnet_config.network_task_priority;
+ }
+
+ /* check to see if we need to start up daemons */
+ if ( sc->sc_rxtask == 0 ) {
+ /* start rx daemon task */
+ status = rtems_task_create(rtems_build_name('R','x','P','0'), priority, 2048,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &sc->sc_rxtask);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ else {
+ status = rtems_task_start(sc->sc_rxtask, ppp_rxdaemon, (rtems_task_argument)sc);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ }
+
+ /* start tx daemon task */
+ status = rtems_task_create(rtems_build_name('T','x','P','0'), priority, 2048,
+ RTEMS_PREEMPT|RTEMS_NO_TIMESLICE|RTEMS_NO_ASR|RTEMS_INTERRUPT_LEVEL(0),
+ RTEMS_NO_FLOATING_POINT|RTEMS_LOCAL,
+ &sc->sc_txtask);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ else {
+ status = rtems_task_start(sc->sc_txtask, ppp_txdaemon, (rtems_task_argument)sc);
+ if (status != RTEMS_SUCCESSFUL) {
+ rtems_fatal_error_occurred(status);
+ }
+ }
+ }
+
+ /* mark driver running and output inactive */
+ sc->sc_if.if_flags |= IFF_RUNNING;
+}
/*
* Called from boot code to establish ppp interfaces.
*/
-int rtems_ppp_driver_attach (struct rtems_bsdnet_ifconfig *config,
- int attaching)
+int rtems_ppp_driver_attach(struct rtems_bsdnet_ifconfig *config, int attaching)
{
- register struct ppp_softc *sc;
- register int i = 0;
-/* XXX unused in rtems
- extern void (*netisrs[])__P((void)); */
+ int i = (int)0;
+ struct ppp_softc *sc;
for (sc = ppp_softc; i < NPPP; sc++) {
sc->sc_if.if_name = "ppp";
@@ -211,14 +433,17 @@ int rtems_ppp_driver_attach (struct rtems_bsdnet_ifconfig *config,
sc->sc_inq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_fastq.ifq_maxlen = IFQ_MAXLEN;
sc->sc_rawq.ifq_maxlen = IFQ_MAXLEN;
+ sc->sc_freeq.ifq_maxlen = NUM_MBUFQ;
+
+ /* initialize and attach */
+ ppp_init(sc);
if_attach(&sc->sc_if);
#if NBPFILTER > 0
bpfattach(&sc->sc_bpf, &sc->sc_if, DLT_PPP, PPP_HDRLEN);
#endif
}
-/* hardcoded in rtems_glue.c
- netisrs[NETISR_PPP] = pppintr; */
- return 1;
+
+ return ( 1 );
}
/*
@@ -230,6 +455,7 @@ pppalloc(pid)
{
int nppp, i;
struct ppp_softc *sc;
+
for (nppp = 0, sc = ppp_softc; nppp < NPPP; nppp++, sc++)
if (sc->sc_xfer == pid) {
sc->sc_xfer = 0;
@@ -246,7 +472,8 @@ pppalloc(pid)
sc->sc_relinq = NULL;
bzero((char *)&sc->sc_stats, sizeof(sc->sc_stats));
#ifdef VJC
- sc->sc_comp=malloc(sizeof(struct vjcompress),M_DEVBUF, M_NOWAIT);
+ MALLOC(sc->sc_comp, struct vjcompress *, sizeof(struct vjcompress),
+ M_DEVBUF, M_NOWAIT);
if (sc->sc_comp)
vj_compress_init(sc->sc_comp, -1);
#endif
@@ -258,7 +485,7 @@ pppalloc(pid)
sc->sc_npmode[i] = NPMODE_ERROR;
sc->sc_npqueue = NULL;
sc->sc_npqtail = &sc->sc_npqueue;
- microtime(&ppp_time);
+ microtime(&ppp_time);
sc->sc_last_sent = sc->sc_last_recv = ppp_time.tv_sec;
return sc;
@@ -272,17 +499,38 @@ pppdealloc(sc)
struct ppp_softc *sc;
{
struct mbuf *m;
+ rtems_interrupt_level level;
if_down(&sc->sc_if);
sc->sc_if.if_flags &= ~(IFF_UP|IFF_RUNNING);
sc->sc_devp = NULL;
sc->sc_xfer = 0;
- for (;;) {
- IF_DEQUEUE(&sc->sc_rawq, m);
- if (m == NULL)
- break;
- m_freem(m);
+
+ rtems_interrupt_disable(level);
+ if ( sc->sc_m != NULL ) {
+ m_freem(sc->sc_m);
+ sc->sc_m = (struct mbuf *)0;
+ }
+ if ( sc->sc_outm != NULL ) {
+ m_freem(sc->sc_outm);
+ sc->sc_outm = (struct mbuf *)0;
+ sc->sc_outmc = (struct mbuf *)0;
+ sc->sc_outflag = 0;
}
+ do {
+ IF_DEQUEUE(&sc->sc_freeq, m);
+ if (m != NULL) {
+ m_freem(m);
+ }
+ } while ( m != NULL );
+ do {
+ IF_DEQUEUE(&sc->sc_rawq, m);
+ if (m != NULL) {
+ m_freem(m);
+ }
+ } while ( m != NULL );
+ rtems_interrupt_enable(level);
+
for (;;) {
IF_DEQUEUE(&sc->sc_inq, m);
if (m == NULL)
@@ -299,10 +547,6 @@ pppdealloc(sc)
sc->sc_npqueue = m->m_nextpkt;
m_freem(m);
}
- if (sc->sc_togo != NULL) {
- m_freem(sc->sc_togo);
- sc->sc_togo = NULL;
- }
#ifdef PPP_COMPRESS
ppp_ccp_closed(sc);
sc->sc_xc_state = NULL;
@@ -310,19 +554,19 @@ pppdealloc(sc)
#endif /* PPP_COMPRESS */
#ifdef PPP_FILTER
if (sc->sc_pass_filt.bf_insns != 0) {
- free(sc->sc_pass_filt.bf_insns, M_DEVBUF);
+ FREE(sc->sc_pass_filt.bf_insns, M_DEVBUF);
sc->sc_pass_filt.bf_insns = 0;
sc->sc_pass_filt.bf_len = 0;
}
if (sc->sc_active_filt.bf_insns != 0) {
- free(sc->sc_active_filt.bf_insns, M_DEVBUF);
+ FREE(sc->sc_active_filt.bf_insns, M_DEVBUF);
sc->sc_active_filt.bf_insns = 0;
sc->sc_active_filt.bf_len = 0;
}
#endif /* PPP_FILTER */
#ifdef VJC
if (sc->sc_comp != 0) {
- free(sc->sc_comp, M_DEVBUF);
+ FREE(sc->sc_comp, M_DEVBUF);
sc->sc_comp = 0;
}
#endif
@@ -339,7 +583,7 @@ pppioctl(sc, cmd, data, flag, p)
int flag;
struct proc *p;
{
- int s, flags, mru, npx;
+ int s, flags, mru, npx, taskid;
struct npioctl *npi;
time_t t;
#ifdef PPP_FILTER
@@ -360,6 +604,11 @@ pppioctl(sc, cmd, data, flag, p)
*(int *)data = sc->sc_inq.ifq_len;
break;
+ case PPPIOCSTASK:
+ taskid = *(int *)data;
+ sc->sc_pppdtask = taskid;
+ break;
+
case PPPIOCGUNIT:
*(int *)data = sc->sc_if.if_unit;
break;
@@ -382,8 +631,17 @@ pppioctl(sc, cmd, data, flag, p)
case PPPIOCSMRU:
mru = *(int *)data;
- if (mru >= PPP_MRU && mru <= PPP_MAXMRU)
- sc->sc_mru = mru;
+ if ( mru >= MCLBYTES ) {
+ /* error - currently only handle 1 culster sized MRU */
+ /* if we want to handle up to PPP_MAXMRU then we */
+ /* need to reallocate all mbufs on the freeq */
+ /* this can only be done with iterrupts disabled */
+ return ( -1 );
+ }
+ else if ( mru >= PPP_MRU ) {
+ /* update the size */
+ sc->sc_mru = mru;
+ }
break;
case PPPIOCGMRU:
@@ -488,7 +746,7 @@ pppioctl(sc, cmd, data, flag, p)
case PPPIOCGIDLE:
s = splsoftnet();
- microtime(&ppp_time);
+ microtime(&ppp_time);
t = ppp_time.tv_sec;
((struct ppp_idle *)data)->xmit_idle = t - sc->sc_last_sent;
((struct ppp_idle *)data)->recv_idle = t - sc->sc_last_recv;
@@ -503,17 +761,17 @@ pppioctl(sc, cmd, data, flag, p)
return EINVAL;
newcodelen = nbp->bf_len * sizeof(struct bpf_insn);
if (newcodelen != 0) {
- newcode=(struct bpf_insn *) malloc (newcodelen, M_DEVBUF, M_WAITOK);
+ MALLOC(newcode, struct bpf_insn *, newcodelen, M_DEVBUF, M_WAITOK);
if (newcode == 0) {
return EINVAL; /* or sumpin */
}
if ((error = copyin((caddr_t)nbp->bf_insns, (caddr_t)newcode,
newcodelen)) != 0) {
- free(newcode, M_DEVBUF);
+ FREE(newcode, M_DEVBUF);
return error;
}
if (!bpf_validate(newcode, nbp->bf_len)) {
- free(newcode, M_DEVBUF);
+ FREE(newcode, M_DEVBUF);
return EINVAL;
}
} else
@@ -525,7 +783,7 @@ pppioctl(sc, cmd, data, flag, p)
bp->bf_insns = newcode;
splx(s);
if (oldcode != 0)
- free(oldcode, M_DEVBUF);
+ FREE(oldcode, M_DEVBUF);
break;
#endif
@@ -544,7 +802,7 @@ pppsioctl(ifp, cmd, data)
int cmd;
caddr_t data;
{
-/* struct proc *p = curproc; *//* XXX */
+ /*struct proc *p = curproc;*/ /* XXX */
register struct ppp_softc *sc = &ppp_softc[ifp->if_unit];
register struct ifaddr *ifa = (struct ifaddr *)data;
register struct ifreq *ifr = (struct ifreq *)data;
@@ -594,17 +852,16 @@ pppsioctl(ifp, cmd, data)
break;
}
break;
- case SIO_RTEMS_SHOW_STATS:
- printf (" MRU:%-8lu", sc->sc_mru);
- printf (" Bytes received:%-8lu", sc->sc_stats.ppp_ibytes);
- printf (" Packets received:%-8lu", sc->sc_stats.ppp_ipackets);
- printf (" Receive errors:%-8lu\n", sc->sc_stats.ppp_ierrors);
- printf (" Bytes sent:%-8lu", sc->sc_stats.ppp_obytes);
- printf (" Packets sent:%-8lu", sc->sc_stats.ppp_opackets);
- printf (" Transmit errors:%-8lu\n", sc->sc_stats.ppp_oerrors);
-
+
+ case SIO_RTEMS_SHOW_STATS:
+ printf(" MRU:%-8u", sc->sc_mru);
+ printf(" Bytes received:%-8u", sc->sc_stats.ppp_ibytes);
+ printf(" Packets received:%-8u", sc->sc_stats.ppp_ipackets);
+ printf(" Receive errors:%-8u\n", sc->sc_stats.ppp_ierrors);
+ printf(" Bytes sent:%-8u", sc->sc_stats.ppp_obytes);
+ printf(" Packets sent:%-8u", sc->sc_stats.ppp_opackets);
+ printf(" Transmit errors:%-8u\n", sc->sc_stats.ppp_oerrors);
break;
-
case SIOCGPPPSTATS:
psp = &((struct ifpppstatsreq *) data)->stats;
@@ -662,6 +919,7 @@ pppoutput(ifp, m0, dst, rtp)
enum NPmode mode;
int len;
struct mbuf *m;
+
if (sc->sc_devp == NULL || (ifp->if_flags & IFF_RUNNING) == 0
|| ((ifp->if_flags & IFF_UP) == 0 && dst->sa_family != AF_UNSPEC)) {
error = ENETDOWN; /* sort of */
@@ -762,17 +1020,14 @@ pppoutput(ifp, m0, dst, rtp)
*/
if (sc->sc_active_filt.bf_insns == 0
|| bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m0, len, 0))
- {
- microtime(&ppp_time);
- sc->sc_last_sent = ppp_time.tv_sec;
- }
+ sc->sc_last_sent = time.tv_sec;
*mtod(m0, u_char *) = address;
#else
/*
* Update the time we sent the most recent data packet.
*/
- microtime(&ppp_time);
+ microtime(&ppp_time);
sc->sc_last_sent = ppp_time.tv_sec;
#endif /* PPP_FILTER */
}
@@ -788,6 +1043,7 @@ pppoutput(ifp, m0, dst, rtp)
/*
* Put the packet on the appropriate queue.
*/
+ s = splsoftnet();
if (mode == NPMODE_QUEUE) {
/* XXX we should limit the number of packets on this queue */
*sc->sc_npqtail = m0;
@@ -806,11 +1062,11 @@ pppoutput(ifp, m0, dst, rtp)
IF_ENQUEUE(ifq, m0);
(*sc->sc_start)(sc);
}
- microtime(&ppp_time);
ifp->if_lastchange = ppp_time;
ifp->if_opackets++;
ifp->if_obytes += len;
+ splx(s);
return (0);
bad:
@@ -871,19 +1127,6 @@ ppp_requeue(sc)
}
/*
- * Transmitter has finished outputting some stuff;
- * remember to call sc->sc_start later at splsoftnet.
- */
-void
-ppp_restart(sc)
- struct ppp_softc *sc;
-{
-
- sc->sc_flags &= ~SC_TBUSY;
-/* schednetisr(NETISR_PPP);
-*/}
-
-/*
* Get a packet to send. This procedure is intended to be called at
* splsoftnet, since it may involve time-consuming operations such as
* applying VJ compression, packet compression, address/control and/or
@@ -901,9 +1144,12 @@ ppp_dequeue(sc)
* Grab a packet to send: first try the fast queue, then the
* normal queue.
*/
+ rtems_bsdnet_semaphore_obtain();
IF_DEQUEUE(&sc->sc_fastq, m);
if (m == NULL)
IF_DEQUEUE(&sc->sc_if.if_snd, m);
+ rtems_bsdnet_semaphore_release();
+
if (m == NULL)
return NULL;
@@ -1018,28 +1264,8 @@ ppp_dequeue(sc)
* Software interrupt routine, called at splsoftnet.
*/
void
-pppintr()
+pppintr(void)
{
- struct ppp_softc *sc;
- int i, s2;
- struct mbuf *m;
-
- sc = ppp_softc;
- for (i = 0; i < NPPP; ++i, ++sc) {
- if (!(sc->sc_flags & SC_TBUSY)
- && (sc->sc_if.if_snd.ifq_head || sc->sc_fastq.ifq_head)) {
- s2 = splimp();
- sc->sc_flags |= SC_TBUSY;
- splx(s2);
- (*sc->sc_start)(sc);
- }
- for (;;) {
- IF_DEQUEUE(&sc->sc_rawq, m);
- if (m == NULL)
- break;
- ppp_inproc(sc, m);
- }
- }
}
#ifdef PPP_COMPRESS
@@ -1160,43 +1386,25 @@ ppp_ccp_closed(sc)
#endif /* PPP_COMPRESS */
/*
- * PPP packet input routine.
- * The caller has checked and removed the FCS and has inserted
- * the address/control bytes and the protocol high byte if they
- * were omitted.
- */
-void
-ppppktin(sc, m, lost)
- struct ppp_softc *sc;
- struct mbuf *m;
- int lost;
-{
-
- if (lost)
- m->m_flags |= M_ERRMARK;
- IF_ENQUEUE(&sc->sc_rawq, m);
- pppintr();
-}
-
-/*
* Process a received PPP packet, doing decompression as necessary.
* Should be called at splsoftnet.
*/
#define COMPTYPE(proto) ((proto) == PPP_VJC_COMP? TYPE_COMPRESSED_TCP: \
TYPE_UNCOMPRESSED_TCP)
-static void
+static struct mbuf *
ppp_inproc(sc, m)
struct ppp_softc *sc;
struct mbuf *m;
{
+ struct mbuf *mf = (struct mbuf *)0;
struct ifnet *ifp = &sc->sc_if;
struct ifqueue *inq;
- int s, ilen, xlen, proto, rv;
+ int s, ilen, xlen, proto, rv;
u_char *cp, adrs, ctrl;
struct mbuf *mp;
#ifdef PPP_COMPRESS
- *dmp = NULL;
+ struct mbuf *dmp = NULL;
#endif
u_char *iphdr;
u_int hlen;
@@ -1236,7 +1444,7 @@ ppp_inproc(sc, m)
m_freem(m);
if (dmp == NULL) {
/* no error, but no decompressed packet produced */
- return;
+ return mf;
}
m = dmp;
cp = mtod(m, u_char *);
@@ -1369,7 +1577,9 @@ ppp_inproc(sc, m)
MGETHDR(mp, M_DONTWAIT, MT_DATA);
if (mp != NULL) {
m_copydata(m, 0, ilen, mtod(mp, caddr_t));
- m_freem(m);
+ /* instead of freeing - return cluster mbuf so it can be reused */
+ /* m_freem(m); */
+ mf = m;
m = mp;
m->m_len = ilen;
}
@@ -1390,15 +1600,11 @@ ppp_inproc(sc, m)
ilen, 0) == 0) {
/* drop this packet */
m_freem(m);
- return;
+ return mf;
}
if (sc->sc_active_filt.bf_insns == 0
|| bpf_filter(sc->sc_active_filt.bf_insns, (u_char *) m, ilen, 0))
- {
- microtime(&ppp_time);
-
- sc->sc_last_recv = ppp_time.tv_sec;
- }
+ sc->sc_last_recv = time.tv_sec;
*mtod(m, u_char *) = adrs;
#else
@@ -1427,7 +1633,7 @@ ppp_inproc(sc, m)
|| sc->sc_npmode[NP_IP] != NPMODE_PASS) {
/* interface is down - drop the packet. */
m_freem(m);
- return;
+ return mf;
}
m->m_pkthdr.len -= PPP_HDRLEN;
m->m_data += PPP_HDRLEN;
@@ -1460,20 +1666,23 @@ ppp_inproc(sc, m)
}
IF_ENQUEUE(inq, m);
splx(s);
+
ifp->if_ipackets++;
ifp->if_ibytes += ilen;
- microtime(&ppp_time);
+ microtime(&ppp_time);
ifp->if_lastchange = ppp_time;
- if (rv)
- (*sc->sc_ctlp)(sc);
+ if (rv) {
+ (*sc->sc_ctlp)(sc);
+ }
- return;
+ return mf;
bad:
m_freem(m);
sc->sc_if.if_ierrors++;
sc->sc_stats.ppp_ierrors++;
+ return mf;
}
#define MAX_DUMP_BYTES 128
diff --git a/c/src/libnetworking/modem/pppcompress.c b/c/src/exec/libnetworking/net/pppcompress.c
index aebe441fd3..aebe441fd3 100644
--- a/c/src/libnetworking/modem/pppcompress.c
+++ b/c/src/exec/libnetworking/net/pppcompress.c
diff --git a/c/src/libnetworking/modem/.cvsignore b/c/src/libnetworking/modem/.cvsignore
deleted file mode 100644
index 282522db03..0000000000
--- a/c/src/libnetworking/modem/.cvsignore
+++ /dev/null
@@ -1,2 +0,0 @@
-Makefile
-Makefile.in
diff --git a/c/src/libnetworking/modem/Makefile.am b/c/src/libnetworking/modem/Makefile.am
deleted file mode 100644
index 86560501b4..0000000000
--- a/c/src/libnetworking/modem/Makefile.am
+++ /dev/null
@@ -1,39 +0,0 @@
-##
-## $Id $
-##
-
-AUTOMAKE_OPTIONS = foreign 1.4
-
-LIBNAME = lib.a
-LIB = $(ARCH)/$(LIBNAME)
-
-C_FILES = ppp_tty.c ppp.c pppcompress.c
-C_O_FILES = $(C_FILES:%.c=$(ARCH)/%.o)
-
-OBJS = $(C_O_FILES)
-
-include $(RTEMS_ROOT)/make/custom/@RTEMS_BSP@.cfg
-include $(top_srcdir)/../../../automake/compile.am
-include $(top_srcdir)/../../../automake/lib.am
-
-#
-# Add local stuff here using +=
-#
-
-# DEFINES += -D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC \
-# -DBOOTP_COMPAT
-
-AM_CPPFLAGS += -D__INSIDE_RTEMS_BSD_TCPIP_STACK__ \
--D_COMPILING_BSD_KERNEL_ -DKERNEL -DINET -DNFS -DDIAGNOSTIC \
--DBOOTP_COMPAT
-
-$(LIB): $(OBJS)
- $(make-library)
-
-all-local: $(ARCH) $(OBJS) $(LIB)
-
-.PRECIOUS: $(LIB)
-
-EXTRA_DIST = ppp_tty.c ppp.c ppp.h pppcompress.c
-
-include $(top_srcdir)/../../../automake/local.am
diff --git a/c/src/libnetworking/modem/ppp.h b/c/src/libnetworking/modem/ppp.h
deleted file mode 100644
index 981ca19041..0000000000
--- a/c/src/libnetworking/modem/ppp.h
+++ /dev/null
@@ -1,7 +0,0 @@
-#ifndef __PPP_H__
-#define __PPP_H__
-#define NPPP 1
-#define NBPFILER 0
-#define VJC
-/*#define PPP_COMPRESS*/
-#endif
diff --git a/c/src/libnetworking/modem/ppp_tty.c b/c/src/libnetworking/modem/ppp_tty.c
deleted file mode 100644
index e3ca3f4a41..0000000000
--- a/c/src/libnetworking/modem/ppp_tty.c
+++ /dev/null
@@ -1,1100 +0,0 @@
-/*
- * 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,
- * 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).
- *
- * Adapted to RTEMS by Thomas Doerfler
- * based on the package of Tomasz Domin delivered
- * in RTEMS snapshot rtems-19991203:
- * Splitted hardware-independent driver parts from the hardware-dependent
- * parts, integrated into termios with newly defined line-discipline support
- */
-
-/* Thomas: ppp_tty.c,v 1.3 2000/09/12 19:26:17 thomas Exp */
-/* $Id$ */
-/* from if_sl.c,v 1.11 84/10/04 12:54:47 rick Exp */
-/* from NetBSD: if_ppp.c,v 1.15.2.2 1994/07/28 05:17:58 cgd Exp */
-
-#include "ppp.h"
-#if NPPP > 0
-
-#define VJC
-#define PPP_COMPRESS
-
-#include <rtems/rtems_bsdnet.h> /* to get right defines */
-
-#include <sys/param.h>
-#include <sys/systm.h>
-#include <sys/proc.h>
-#include <sys/mbuf.h>
-#if 0
-#include <sys/dkstat.h>
-#endif
-#include <sys/socket.h>
-#include <sys/ioctl.h>
-#include <sys/file.h>
-#if 0
-#include <sys/tty.h>
-#endif
-#include <sys/kernel.h>
-#if 0
-#include <sys/conf.h>
-#include <sys/vnode.h>
-#endif
-
-#include <net/if.h>
-#include <net/if_types.h>
-
-#ifdef VJC
-#include <netinet/in.h>
-#include <netinet/in_systm.h>
-#include <netinet/ip.h>
-#include <net/pppcompress.h>
-#endif
-
-#include <rtems.h>
-#include <rtems/libio.h>
-#include <sys/ttycom.h>
-#include <termios.h>
-#include <rtems/termiostypes.h>
-
-#ifdef PPP_FILTER
-#include <net/bpf.h>
-#endif
-#include <net/ppp_defs.h>
-#include <net/if_ppp.h>
-#include <net/if_pppvar.h>
-
-void pppasyncattach __P((void));
-int pppopen __P((struct rtems_termios_tty *tty));
-int pppclose __P((struct rtems_termios_tty *tty));
-int pppread __P((struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args));
-int pppwrite __P((struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args));
-int ppptioctl __P((struct rtems_termios_tty *tty,
- rtems_libio_ioctl_args_t *args));
-int pppinput __P((int c,struct rtems_termios_tty *tty));
-int pppstart __P((struct rtems_termios_tty *tp));
-
-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 ppp_timeout __P((void *));
-static void pppgetm __P((struct ppp_softc *sc));
-static void pppdumpb __P((u_char *b, int l));
-static void ppplogchar __P((struct ppp_softc *, int));
-
-/*
- * 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.
- */
-
-/*
- * compute used space in raw buffer
- */
-#define CCOUNT(rb) (((rb).Size+(rb).Head-(rb).Tail) \
- % (rb).Size)
-/*
- * compute free space in raw buffer
- */
-#define FCOUNT(rb) ((rb).Size-CCOUNT(rb)-1)
-#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 */
-/* FIXME: make dependent on raw buffer size */
-
-/*
- * Define the PPP line discipline.
- */
-
-static struct linesw pppdisc = {
- pppopen, pppclose, pppread, pppwrite,
- pppinput, pppstart, ppptioctl, NULL
-};
-
-void
-pppasyncattach()
-{
- linesw[PPPDISC] = pppdisc;
-}
-
-TEXT_SET(pseudo_set, pppasyncattach);
-
-/*
- * 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.
- */
-/* ARGSUSED */
-/*
- * Open the PPP device
- */
-int
-pppopen(struct rtems_termios_tty *tty)
-{
- register struct ppp_softc *sc;
- rtems_status_code status;
-
- if ((tty->t_line == PPPDISC)) {
- sc = tty->t_sc;
- if (sc != NULL && sc->sc_devp == (void *) tty) {
- return (0);
- }
- }
-
- if ((sc = pppalloc(1)) == NULL) {
- return 2;
- }
-
- if (sc->sc_relinq) {
- (*sc->sc_relinq)(sc); /* get previous owner to relinquish the unit */
- }
- /*
- * create communication semaphore
- */
- status = rtems_semaphore_create (rtems_build_name ('P', 'P', 'P',
- '0'+sc->sc_if.if_unit),
- 0,
- RTEMS_COUNTING_SEMAPHORE,
- RTEMS_NO_PRIORITY_CEILING,
- &sc->sem_id);
- if (status != RTEMS_SUCCESSFUL)
- rtems_fatal_error_occurred (status);
-
- 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 = tty;
- sc->sc_start = pppasyncstart;
- sc->sc_ctlp = pppasyncctlp;
- sc->sc_relinq = pppasyncrelinq;
- sc->sc_outm = NULL;
- pppgetm(sc);
- sc->sc_if.if_flags |= IFF_RUNNING;
- sc->sc_if.if_baudrate = 9600; /* FIXME: get line speed from termios */
-
- tty->t_sc= (void *)sc;
-
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Line specific close routine, called from device close routine
- * and from ttioctl.
- * Detach the tty from the ppp unit.
- * Mimics part of ttyclose().
- */
-int
-pppclose(struct rtems_termios_tty *tty)
-{
- register struct ppp_softc *sc;
- rtems_status_code status;
-
-
- tty->t_line = 0;
- sc = tty->t_sc;
- if (sc != NULL) {
- tty->t_sc = NULL;
- if (tty == (struct rtems_termios_tty *) sc->sc_devp) {
- rtems_bsdnet_semaphore_obtain();
- pppasyncrelinq(sc);
- /*
- * delete communication semaphore
- */
- status = rtems_semaphore_delete (sc->sem_id);
- pppdealloc(sc);
- rtems_bsdnet_semaphore_release();
- }
- }
- return RTEMS_SUCCESSFUL;
-}
-
-/*
- * Relinquish the interface unit to another device.
- */
-static void
-pppasyncrelinq(sc)
- struct ppp_softc *sc;
-{
- 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) {
- untimeout(ppp_timeout, (void *) sc);
- sc->sc_flags &= ~SC_TIMEOUT;
- }
-}
-
-/*
- * Line specific (tty) read routine.
- */
-int pppread(struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args)
-{
- char *buffer;
- int count=0,maximum;
- rtems_status_code status;
-
- struct mbuf *m, *m0;
- rtems_interval ticks;
- register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
- buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- ticks=1000000/rtems_bsdnet_microseconds_per_tick;
-
- if (sc == NULL) {
- return 0;
- }
- /*
- * Loop waiting for input, checking that nothing disasterous
- * happens in the meantime.
- */
- for (;;) {
- if (sc->sc_inq.ifq_head != NULL) {
- break;
- }
- status=rtems_semaphore_obtain(sc->sem_id,RTEMS_WAIT,ticks);
- if (status==RTEMS_TIMEOUT) {
- return status;
- }
- }
- rtems_bsdnet_semaphore_obtain();
- IF_DEQUEUE(&sc->sc_inq, m0);
- rtems_bsdnet_semaphore_release();
-
- for (m = m0;
- ((m != NULL) &&
- (count+m->m_len<maximum));
- m = m->m_next) {/* check if packet will fit in buffer */
- memcpy(buffer,mtod(m, u_char *),m->m_len);
- count+=m->m_len;
- buffer+=m->m_len;
- }
- m_freem(m0);
- rw_args->bytes_moved = count;
-
- return (count >= 0) ? RTEMS_SUCCESSFUL : RTEMS_UNSATISFIED;
-}
-
-/*
- * Line specific (tty) write routine.
- */
-int
-pppwrite(struct rtems_termios_tty *tty,
- rtems_libio_rw_args_t *rw_args)
-{
- int len;
- char *out_buffer;
- int n,maximum;
-
- register struct ppp_softc *sc = (struct ppp_softc *)tty->t_sc;
- struct sockaddr dst;
- struct mbuf *m, *m0, **mp;
-
- out_buffer = rw_args->buffer;
- maximum = rw_args->count;
-
- rtems_bsdnet_semaphore_obtain();
- for (mp = &m0; maximum; mp = &m->m_next) {
- MGET(m, M_WAIT, MT_DATA);
- if ((*mp = m) == NULL) {
- rtems_bsdnet_semaphore_release();
- m_freem(m0);
- return (ENOBUFS);
- }
- m->m_len = 0;
- if (maximum>= MCLBYTES / 2) {
- MCLGET(m, M_DONTWAIT);
- }
- len = M_TRAILINGSPACE(m);
- if (len > maximum) {
- memcpy(mtod(m, u_char *),out_buffer,maximum);
- m->m_len=maximum;
- maximum=0;
- }
- else {
- memcpy(mtod(m, u_char *),out_buffer,len);
- maximum-=len;
- m->m_len=len;
- out_buffer+=len;
- }
- }
-
- dst.sa_family = AF_UNSPEC;
- bcopy(mtod(m0, u_char *), dst.sa_data, PPP_HDRLEN);
- m0->m_data += PPP_HDRLEN;
- m0->m_len -= PPP_HDRLEN;
-
- n=pppoutput(&sc->sc_if, m0, &dst, (struct rtentry *)0);
- rtems_bsdnet_semaphore_release();
- return n;
-}
-
-/*
- * Line specific (tty) ioctl routine.
- * This discipline requires that tty device drivers call
- * the line specific l_ioctl routine from their ioctl routines.
- */
-/* ARGSUSED */
-int
-ppptioctl(struct rtems_termios_tty *tty,
- rtems_libio_ioctl_args_t *args)
-{
- int error = RTEMS_SUCCESSFUL;
- struct ppp_softc *sc = tty->t_sc;
- int cmd;
- caddr_t data;
-
- cmd=args->command;
- data=args->buffer;
-
- switch (cmd) {
- case RTEMS_IO_GET_ATTRIBUTES:
- case RTEMS_IO_SET_ATTRIBUTES:
- case RTEMS_IO_TCDRAIN:
- case TIOCGETD:
- case TIOCSETD:
- case RTEMS_IO_SNDWAKEUP:
- case RTEMS_IO_RCVWAKEUP:
- error = rtems_termios_ioctl(args);
- break;
-
- case PPPIOCSASYNCMAP:
- sc->sc_asyncmap[0] = *(u_int *)data;
- break;
-
- case PPPIOCGASYNCMAP:
- *(u_int *)data = sc->sc_asyncmap[0];
- break;
-
- case PPPIOCSRASYNCMAP:
- sc->sc_rasyncmap = *(u_int *)data;
- break;
-
- case TIOCMBIS:
- break;
- case TIOCMBIC:
- break;
- case PPPIOCGRASYNCMAP:
- *(u_int *)data = sc->sc_rasyncmap;
- break;
-
- case PPPIOCSXASYNCMAP:
- bcopy(data, sc->sc_asyncmap, sizeof(sc->sc_asyncmap));
- sc->sc_asyncmap[1] = 0; /* mustn't escape 0x20 - 0x3f */
- sc->sc_asyncmap[2] &= ~0x40000000; /* mustn't escape 0x5e */
- sc->sc_asyncmap[3] |= 0x60000000; /* must escape 0x7d, 0x7e */
- break;
-
- case PPPIOCGXASYNCMAP:
- bcopy(sc->sc_asyncmap, data, sizeof(sc->sc_asyncmap));
- break;
-
- default:
- rtems_bsdnet_semaphore_obtain();
- error = pppioctl(sc, cmd, data, 0, NULL);
- if (error == 0 && cmd == PPPIOCSMRU)
- pppgetm(sc);
- rtems_bsdnet_semaphore_release();
-
- }
- return error;
-}
-
-/*
- * FCS lookup table as calculated by genfcstab.
- */
-static u_short fcstab[256] = {
- 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
- 0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
- 0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
- 0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
- 0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
- 0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
- 0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
- 0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
- 0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
- 0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
- 0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
- 0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
- 0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
- 0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
- 0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
- 0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
- 0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
- 0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
- 0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
- 0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
- 0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
- 0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
- 0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
- 0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
- 0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
- 0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
- 0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
- 0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
- 0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
- 0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
- 0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
- 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-/*
- * Calculate a new FCS given the current FCS and the new data.
- */
-static u_short
-pppfcs(fcs, cp, len)
- register u_short fcs;
- register u_char *cp;
- register int len;
-{
- while (len--)
- fcs = PPP_FCS(fcs, *cp++);
- return (fcs);
-}
-
-/*
- * This gets called at splsoftnet from if_ppp.c at various times
- * when there is data ready to be sent.
- */
-static void
-pppasyncstart(sc)
- register struct ppp_softc *sc;
-{
- /* Call pppstart to start output again if necessary. */
- pppstart(sc->sc_devp);
-
- /*
- * This timeout is needed for operation on a pseudo-tty,
- * because the pty code doesn't call pppstart after it has
- * drained the t_outq.
- */
-/* if (!idle && (sc->sc_flags & SC_TIMEOUT) == 0) {
- timeout(ppp_timeout, (void *) sc, 1);
- sc->sc_flags |= SC_TIMEOUT;
- }
-*/
-
-}
-
-
-void modem_sendpacket(struct rtems_termios_tty *tty)
-{
- register struct mbuf *m;
- register int len;
- register u_char *start, *stop, *cp;
- int n, ndone, done;
- struct mbuf *m2;
- char c;
- register struct ppp_softc *sc=tty->t_sc;
-
-
- while (CCOUNT(tty->rawOutBuf) < PPP_HIWAT) {
- /*
- * See if we have an existing packet partly sent.
- * If not, get a new packet and start sending it.
- */
- m = sc->sc_outm;
- if (m == NULL) {
- /*
- * Get another packet to be sent.
-
- */
- m = ppp_dequeue(sc);
- if (m == NULL)
- {
- break;
- }
-
- /*
- * The extra PPP_FLAG will start up a new packet, and thus
- * will flush any accumulated garbage. We do this whenever
- * the line may have been idle for some time.
- */
- if (CCOUNT(tty->rawOutBuf) == 0) {
- ++sc->sc_stats.ppp_obytes;
- c = PPP_FLAG;
- rtems_termios_puts(&c,1,tty);
- }
-
- /* Calculate the FCS for the first mbuf's worth. */
- sc->sc_outfcs = pppfcs(PPP_INITFCS, mtod(m, u_char *), m->m_len);
- microtime(&sc->sc_if.if_lastchange);
- }
-
- for (;;) {
- start = mtod(m, u_char *);
- len = m->m_len;
- stop = start + len;
- while (len > 0) {
- /*
- * Find out how many bytes in the string we can
- * handle without doing something special.
- */
- for (cp = start; cp < stop; cp++)
- if (ESCAPE_P(*cp))
- break;
- n = cp - start;
- if (n) {
- register int i;
- i = FCOUNT(tty->rawOutBuf);
- if (n < i) {
- i = n;
- }
- if (i > 0) {
- rtems_termios_puts(start,i,tty);
- }
- ndone = i;
- len -= ndone;
- start += ndone;
- sc->sc_stats.ppp_obytes += ndone;
-
- if (ndone < n)
- break; /* packet doesn't fit */
- }
- /*
- * If there are characters left in the mbuf,
- * the first one must be special.
- * Put it out in a different form.
- */
- if (len) {
- if (FCOUNT(tty->rawOutBuf) < 2) {
- break;
- }
- else {
- char str[2];
- str[0] = PPP_ESCAPE;
- str[1] = *start ^ PPP_TRANS;
- rtems_termios_puts(str,2,tty);
- }
- sc->sc_stats.ppp_obytes += 2;
- start++;
- len--;
- }
- }
-
- /*
- * If we didn't empty this mbuf, remember where we're up to.
- * If we emptied the last mbuf, try to add the FCS and closing
- * flag, and if we can't, leave sc_outm pointing to m, but with
- * m->m_len == 0, to remind us to output the FCS and flag later.
- */
- done = len == 0;
- if (done && m->m_next == NULL) {
- u_char *p;
- int c;
- u_char endseq[8];
-
- /*
- * We may have to escape the bytes in the FCS.
- */
- p = endseq;
- c = ~sc->sc_outfcs & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- c = (~sc->sc_outfcs >> 8) & 0xFF;
- if (ESCAPE_P(c)) {
- *p++ = PPP_ESCAPE;
- *p++ = c ^ PPP_TRANS;
- } else
- *p++ = c;
- *p++ = PPP_FLAG;
-
- /*
- * Try to output the FCS and flag. If the bytes
- * don't all fit, back out.
- */
- if (FCOUNT(tty->rawOutBuf) > (p-endseq)) {
- rtems_termios_puts(endseq,p-endseq,tty);
- }
- else {
- done = 0;
- }
- if (done)
- sc->sc_stats.ppp_obytes += p - endseq;
- }
-
- if (!done) {
- /* remember where we got to */
- m->m_data = start;
- m->m_len = len;
- break;
- }
-
- /* Finished with this mbuf; free it and move on. */
- MFREE(m, m2);
- m = m2;
- if (m == NULL) {
- /* Finished a packet */
- break;
- }
- sc->sc_outfcs = pppfcs(sc->sc_outfcs, mtod(m, u_char *), m->m_len);
- }
-
- /*
- * If m == NULL, we have finished a packet.
- * If m != NULL, we've either done as much work this time
- * as we need to, or else we've filled up the output queue.
- */
- sc->sc_outm = m;
- if (m)
- break;
- }
-}
-
-/*
- * This gets called when a received packet is placed on
- * the inq, at splsoftnet.
- */
-
-static void
-pppasyncctlp(sc)
- struct ppp_softc *sc;
-{
- rtems_semaphore_release(sc->sem_id);
-}
-
-/* Put data in input queue */
-int
-pppstart(struct rtems_termios_tty *tp)
-{
- register struct ppp_softc *sc = tp->t_sc;
-
- /*
- * If there is stuff in the output queue, send it now.
- * We are being called in lieu of ttstart and must do what it would.
- */
- sc->sc_if.if_flags |= IFF_OACTIVE;
-
- /*
- * If the transmit queue has drained and the tty has not hung up
- * or been disconnected from the ppp unit, then tell if_ppp.c that
- * we need more output.
- */
- if (CCOUNT(tp->rawOutBuf) < PPP_LOWAT
- /* && !((tp->t_state & TS_CARR_ON) == 0 && (tp->t_cflag & CLOCAL) == 0)*/
- && sc != NULL && tp == (struct rtems_termios_tty *) sc->sc_devp) {
- modem_sendpacket(tp);
- }
-
- return 0;
-}
-
-/*
- * Timeout routine - try to start some more output.
- */
-static void
-ppp_timeout(x)
- void *x;
-{
- struct rtems_termios_tty *tty = ((struct rtems_termios_tty *)x);
- struct ppp_softc *sc = tty->t_sc;
- struct rtems_termios_tty *tp = (struct rtems_termios_tty *) sc->sc_devp;
-
- sc->sc_flags &= ~SC_TIMEOUT;
- pppstart(tp);
-}
-
-
-/*
- * Allocate enough mbuf to handle current MRU.
- */
-static void
-pppgetm(sc)
- register struct ppp_softc *sc;
-{
- struct mbuf *m, **mp;
- int len;
-
- mp = &sc->sc_m;
- for (len = sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN; len > 0; ){
- if ((m = *mp) == NULL) {
- MGETHDR(m, M_DONTWAIT, MT_DATA);
- if (m == NULL)
- break;
- *mp = m;
- MCLGET(m, M_DONTWAIT);
- }
- len -= M_DATASIZE(m);
- mp = &m->m_next;
- }
-}
-
-/*
- * tty interface receiver interrupt.
- */
-static unsigned paritytab[8] = {
- 0x96696996, 0x69969669, 0x69969669, 0x96696996,
- 0x69969669, 0x96696996, 0x96696996, 0x69969669
-};
-
-
-int
-pppinput(int c,struct rtems_termios_tty *tty)
-
-{
- register struct ppp_softc *sc=tty->t_sc;
- struct mbuf *m;
- int ilen, s;
-
- if (sc == NULL )
- return 0;
-
- ++sc->sc_stats.ppp_ibytes;
-
-#if 0
- if (c & TTY_FE) {
- /* framing error or overrun on this char - abort packet */
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad char %x\n", sc->sc_if.if_unit, c);
- goto flush;
- }
-#endif
-
- c &= 0xff;
-
- /*
- * Handle software flow control of output.
- */
-/* if (tp->t_iflag & IXON) {
- if (c == tp->t_cc[VSTOP] ) {
- if ((tp->t_state & TS_TTSTOP) == 0) {
- tp->t_state |= TS_TTSTOP;
- sccppp_stop_transmission(tp);
- }
- return 0;
- }
- if (c == tp->t_cc[VSTART] ) {
- tp->t_state &= ~TS_TTSTOP;
- sccppp_start_transmission(tp);
- return 0;
- }
- }
-*/
-
- if (c & 0x80)
- sc->sc_flags |= SC_RCV_B7_1;
- else
- sc->sc_flags |= SC_RCV_B7_0;
- if (paritytab[c >> 5] & (1 << (c & 0x1F)))
- sc->sc_flags |= SC_RCV_ODDP;
- else
- sc->sc_flags |= SC_RCV_EVNP;
-
-
- if (sc->sc_flags & SC_LOG_RAWIN)
- ppplogchar(sc, c);
-
- if (c == PPP_FLAG) {
- ilen = sc->sc_ilen;
- sc->sc_ilen = 0;
-
- if (sc->sc_rawin_count > 0)
- ppplogchar(sc, -1);
-
- /*
- * If SC_ESCAPED is set, then we've seen the packet
- * abort sequence
- */
- if (sc->sc_flags & (SC_FLUSH | SC_ESCAPED)
- || (ilen > 0 && sc->sc_fcs != PPP_GOODFCS)) {
- sc->sc_flags |= SC_PKTLOST; /* note the dropped packet */
- if ((sc->sc_flags & (SC_FLUSH | SC_ESCAPED)) == 0){
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad fcs %x, pkt len %d\n",
- sc->sc_if.if_unit, sc->sc_fcs, ilen);
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- } else
- sc->sc_flags &= ~(SC_FLUSH | SC_ESCAPED);
- return 0;
- }
-
- if (ilen < PPP_HDRLEN + PPP_FCSLEN) {
- if (ilen) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: too short (%d)\n", sc->sc_if.if_unit, ilen);
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- sc->sc_flags |= SC_PKTLOST;
- splx(s);
- }
- return 0;
- }
-
- /*
- * Remove FCS trailer. Somewhat painful...
- */
- ilen -= 2;
- if (--sc->sc_mc->m_len == 0) {
- for (m = sc->sc_m; m->m_next != sc->sc_mc; m = m->m_next)
- ;
- sc->sc_mc = m;
- }
- sc->sc_mc->m_len--;
-
- /* excise this mbuf chain */
- m = sc->sc_m;
- sc->sc_m = sc->sc_mc->m_next;
- sc->sc_mc->m_next = NULL;
- ppppktin(sc, m, sc->sc_flags & SC_PKTLOST);
- if (sc->sc_flags & SC_PKTLOST) {
- sc->sc_flags &= ~SC_PKTLOST;
- }
-
- pppgetm(sc);
- return 0;
- }
-
- if (sc->sc_flags & SC_FLUSH) {
- if (sc->sc_flags & SC_LOG_FLUSH)
- ppplogchar(sc, c);
- return 0;
- }
-
- if (c < 0x20 && (sc->sc_rasyncmap & (1 << c)))
- return 0;
-
- if (sc->sc_flags & SC_ESCAPED) {
- sc->sc_flags &= ~SC_ESCAPED;
- c ^= PPP_TRANS;
- } else if (c == PPP_ESCAPE) {
- sc->sc_flags |= SC_ESCAPED;
- return 0;
- }
-
- /*
- * Initialize buffer on first octet received.
- * First octet could be address or protocol (when compressing
- * address/control).
- * Second octet is control.
- * Third octet is first or second (when compressing protocol)
- * octet of protocol.
- * Fourth octet is second octet of protocol.
- */
- if (sc->sc_ilen == 0) {
- /* reset the first input mbuf */
- if (sc->sc_m == NULL) {
- pppgetm(sc);
- if (sc->sc_m == NULL) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: no input mbufs!\n", sc->sc_if.if_unit);
- goto flush;
- }
- }
- m = sc->sc_m;
- m->m_len = 0;
- m->m_data = M_DATASTART(sc->sc_m);
- sc->sc_mc = m;
- sc->sc_mp = mtod(m, char *);
- sc->sc_fcs = PPP_INITFCS;
- if (c != PPP_ALLSTATIONS) {
- if (sc->sc_flags & SC_REJ_COMP_AC) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: garbage received: 0x%x (need 0xFF)\n",
- sc->sc_if.if_unit, c);
- goto flush;
- }
- *sc->sc_mp++ = PPP_ALLSTATIONS;
- *sc->sc_mp++ = PPP_UI;
- sc->sc_ilen += 2;
- m->m_len += 2;
- }
- }
- if (sc->sc_ilen == 1 && c != PPP_UI) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: missing UI (0x3), got 0x%x\n",
- sc->sc_if.if_unit, c);
- goto flush;
- }
- if (sc->sc_ilen == 2 && (c & 1) == 1) {
- /* a compressed protocol */
- *sc->sc_mp++ = 0;
- sc->sc_ilen++;
- sc->sc_mc->m_len++;
- }
- if (sc->sc_ilen == 3 && (c & 1) == 0) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: bad protocol %x\n", sc->sc_if.if_unit,
- (sc->sc_mp[-1] << 8) + c);
- goto flush;
- }
-
- /* packet beyond configured mru? */
- if (++sc->sc_ilen > sc->sc_mru + PPP_HDRLEN + PPP_FCSLEN) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: packet too big\n", sc->sc_if.if_unit);
- goto flush;
- }
-
- /* is this mbuf full? */
- m = sc->sc_mc;
- if (M_TRAILINGSPACE(m) <= 0) {
- if (m->m_next == NULL) {
- pppgetm(sc);
- if (m->m_next == NULL) {
- if (sc->sc_flags & SC_DEBUG)
- printf("ppp%d: too few input mbufs!\n", sc->sc_if.if_unit);
- goto flush;
- }
- }
- sc->sc_mc = m = m->m_next;
- m->m_len = 0;
- m->m_data = M_DATASTART(m);
- sc->sc_mp = mtod(m, char *);
- }
-
- ++m->m_len;
- *sc->sc_mp++ = c;
- sc->sc_fcs = PPP_FCS(sc->sc_fcs, c);
- return 0;
-
- flush:
- if (!(sc->sc_flags & SC_FLUSH)) {
- sc->sc_if.if_ierrors++;
- sc->sc_stats.ppp_ierrors++;
- sc->sc_flags |= SC_FLUSH;
- if (sc->sc_flags & SC_LOG_FLUSH)
- ppplogchar(sc, c);
- }
- return 0;
-}
-
-
-#define MAX_DUMP_BYTES 128
-
-static void
-ppplogchar(sc, c)
- struct ppp_softc *sc;
- int c;
-{
- if (c >= 0)
- sc->sc_rawin[sc->sc_rawin_count++] = c;
- if (sc->sc_rawin_count >= sizeof(sc->sc_rawin)
- || (c < 0 && sc->sc_rawin_count > 0)) {
- printf("ppp%d input: ", sc->sc_if.if_unit);
- pppdumpb(sc->sc_rawin, sc->sc_rawin_count);
- sc->sc_rawin_count = 0;
- }
-}
-
-static void
-pppdumpb(b, l)
- u_char *b;
- int l;
-{
- char buf[3*MAX_DUMP_BYTES+4];
- char *bp = buf;
- static char digits[] = "0123456789abcdef";
-
- while (l--) {
- if (bp >= buf + sizeof(buf) - 3) {
- *bp++ = '>';
- break;
- }
- *bp++ = digits[*b >> 4]; /* convert byte to ascii hex */
- *bp++ = digits[*b++ & 0xf];
- *bp++ = ' ';
- }
-
- *bp = 0;
- printf("%s\n", buf);
-}
-
-#endif /* NPPP > 0 */