⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 slipbsd.c

📁 wm PNE 3.3 source code, running at more than vxworks6.x version.
💻 C
字号:
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/lib/slipbsd.c,v 1.3 2003/01/15 14:04:34 josh Exp $ *//* * Copyright (C) 1999-2005 Wind River Systems, Inc. * All rights reserved.  Provided under license only. * Distribution or other use of this software is only * permitted pursuant to the terms of a license agreement * from Wind River Systems (and is otherwise prohibited). * Refer to that license agreement for terms of use. *//**************************************************************************** *  Copyright 1993-1997 Epilogue Technology Corporation. *  Copyright 1998 Integrated Systems, Inc. *  All rights reserved. ****************************************************************************//* * $Log: slipbsd.c,v $ * Revision 1.3  2003/01/15 14:04:34  josh * directory structure shifting * * Revision 1.2  2001/11/08 15:56:26  tneale * Updated for newest file layout * * Revision 1.1.1.1  2001/11/05 17:48:43  tneale * Tornado shuffle * * Revision 2.14  2001/01/19 22:23:51  paul * Update copyright. * * Revision 2.13  2000/10/16 19:21:54  paul * Restore sockets and mempool code. * * Revision 2.12  2000/03/17 00:12:44  meister * Update copyright message * * Revision 2.11  2000/03/13 21:22:08  paul * Removed some code that we are no longer working on. * * Revision 2.10  1999/11/05 22:29:07  paul * Updated driver structs to reflect conditional backwards-compatibility * fields and new fields. * * Revision 2.9  1999/04/07 14:57:00  sra * Update COM_DEV_NAME to something sane. * * Revision 2.8  1998/02/25 15:21:50  sra * Finish moving types.h, bug.h, and bugdef.h to common/h/. * * Revision 2.7  1998/02/25 04:57:37  sra * Update copyrights. * * Revision 2.6  1997/03/20 06:53:10  sra * DFARS-safe copyright text.  Zap! * * Revision 2.5  1997/02/25 10:58:16  sra * Update copyright notice, dust under the bed. * * Revision 2.4  1997/02/19 08:10:29  sra * More fun merging snmptalk into snark, general snark cleanup. * * Revision 2.3  1996/11/13 15:09:16  mrf * Changes necessary to make snoop support work on Irix 5.x include * addition of snoop driver code and port to somewhat wacky Irix * curses implementation. * * Revision 2.2  1996/03/22  10:05:39  sra * Update copyrights prior to Attache 3.2 release. * * Revision 2.1  1995/11/16  00:33:13  sra * Fix a format string to make gcc -paranoid happier. * Rearrange file header per current conventions. * * Revision 2.0  1995/05/10  22:38:15  sra * Attache release 3.0. * * Revision 1.4  1995/01/06  00:52:48  sra * Update copyright notice for 2.1 release. * * Revision 1.3  1994/09/04  06:13:38  sra * Clean up antique type names and install macros. * * Revision 1.2  1994/01/09  23:57:29  sra * Add support for NIT under SunOS 4.1.2. * * Revision 1.1  1993/07/05  21:53:30  sra * Initial revision * *//* [clearcase]modification history-------------------01a,19apr05,job  update copyright notices*//* * Serial Line IP (SLIP) interface for snark under BSD-derived systems. * * This code has only been tested under NetBSD 0.8.  It should work on * any BSD-derived system with minor modifications. */#include <wrn/wm/attache/config.h>#include <wrn/wm/common/types.h>#include <wrn/wm/attache/mib.h>#include <wrn/wm/attache/timer.h>#include <wrn/wm/attache/packet.h>#include <wrn/wm/attache/net.h>#include <wrn/wm/attache/glue.h>#include <wrn/wm/attache/route.h>#include <wrn/wm/attache/ip.h>#include <wrn/wm/attache/loop.h>#include <stdio.h>#include <sgtty.h>#include <sys/types.h>#include <sys/time.h>#include <errno.h>#include <fcntl.h>#include <sys/file.h>#include <unistd.h>#include <wrn/wm/demo/bsdif.h>#include <wrn/wm/demo/slipbsd.h>#define	PF_SLIP_BOP	0x1000#ifndef COM_DEV_NAME#define	COM_DEV_NAME	"/dev/cuaa"#endif/* * SLIP control structure, hangs off net->specific->private. */#ifndef	SNARKBSD_SLIP_IBUFLEN#define	SNARKBSD_SLIP_IBUFLEN	1000#endif#ifndef	SNARKBSD_SLIP_OBUFLEN#define	SNARKBSD_SLIP_OBUFLEN	6000#endifstruct slipctl {  struct net *net;  unsigned iescaped : 1;  unsigned idiscard : 1;  unsigned oescaped : 1;  packet *ipkt, *opkt_head, **opkt_tail;  int ilen, olen;  unsigned char *ibp, *obp;  unsigned char ibuf[SNARKBSD_SLIP_IBUFLEN], obuf[SNARKBSD_SLIP_OBUFLEN];};/* * SLIP framing characters */#define	SLIP_END	0300#define	SLIP_ESC	0333#define	SLIP_ENC_END	0334#define	SLIP_ENC_ESC	0335/* * Decode a buffer of data into zero or more Attache packet buffers. * Most of the hair is just checking for weird boundary conditions. */#define	DOCHAR(x) \  if (sp->idiscard) { \    continue; \  } else if (p->pkt_data < p->pkt_buffer + p->pkt_buflen) { \    *p->pkt_data++ = (x); \  } else { \    sp->idiscard = 1; \    continue; \  }static packet *slip_decode  (struct net *net, unsigned char *buf, int len, int *used){  struct bsdif *bif =  net->specific;  struct slipctl *sp = bif->private;  unsigned char *bob = buf, *eob = buf + len;  packet *p;  while (buf < eob) {    if (sp->ipkt == 0 && (sp->ipkt = pkt_alloc(net->driver->maxlen)) == 0)      break;			/* Oops, no packet buffers */    p = sp->ipkt;    if (sp->iescaped) {		/* Was escaped */      sp->iescaped = 0;		/* ain't no more */      switch (*buf++) {       case SLIP_ENC_END:	DOCHAR(SLIP_END);	/* Escaped END character */	continue;       case SLIP_ENC_ESC:	DOCHAR(SLIP_ESC);	/* Escaped ESC character */	continue;       default:	sp->idiscard = 1;	/* Escaped garbage, packet be bogus */	continue;      }    } else {      switch (*buf++) {       case SLIP_END:	if (!sp->idiscard && p->pkt_data > p->pkt_buffer) {	  sp->ipkt = 0;	  p->pkt_datalen = p->pkt_data - p->pkt_buffer;	  p->pkt_data = p->pkt_buffer;	  if (used)	    *used = buf - bob;	  return p;		/* Happy packet */	}	sp->idiscard = 0;	/* Bogus packet now history */	p->pkt_data = p->pkt_buffer;	continue;       case SLIP_ESC:	sp->iescaped = 1;	/* An escaping byte! */	continue;       default:	DOCHAR(*(buf-1));	/* A normal boring byte */	continue;      }    }  }  if (used)    *used = buf - bob;  return 0;			/* Yes, we have no packet today */}#undef	DOCHAR/* * Encode zero or more Attache packet buffers into a data buffer. * Packets will have been queued for us by slip_send(). */#define	DOCHAR(x) \  do { *buf++ = (x); if (buf == eob) return (buf - bob); } while (0)static int slip_encode(struct net *net, unsigned char *buf, int len){  struct bsdif *bif = net->specific;  struct slipctl *sp = bif->private;  unsigned char *bob = buf, *eob = buf + len;  packet *p;  if (len <= 0)    return 0;  while ((p = sp->opkt_head) != 0) {    /*     * Send framing sequence before a new packet, to flush line noise.     */    if ((p->pkt_flags & PF_SLIP_BOP) != 0) {      p->pkt_flags &= ~PF_SLIP_BOP;      DOCHAR(SLIP_END);    }    /*     * Process data in this packet.     */    while (p->pkt_datalen > 0) {      if (sp->oescaped) {	sp->oescaped = 0;		/* Was escaped, ain't no more */	switch (*p->pkt_data++) {	 case SLIP_END:			/* Encoding an END octet */	  DOCHAR(SLIP_ENC_END);	  break;	 case SLIP_ESC:			/* Encoding an ESC octet */	  DOCHAR(SLIP_ENC_ESC);	  break;	}      } else {	switch (*p->pkt_data) {	 case SLIP_END:			/* I need an escape */	 case SLIP_ESC:	  sp->oescaped = 1;	  DOCHAR(SLIP_ESC);	  continue;			/* Doesn't count as sent yet */	 default:	  DOCHAR(*p->pkt_data++);	/* Normal octet, send it */	}      }      p->pkt_datalen--;			/* One less octet to feed */    }    /*     * No more data in current packet, so send framing sequence     * and proceed with next packet in the output queue.     */    DOCHAR(SLIP_END);    if ((sp->opkt_head = p->pkt_link) == 0)      sp->opkt_tail = &sp->opkt_head;    pkt_free(p);  }  return buf - bob;}#undef	DOCHAR/* * Process whatever incoming SLIP data we can without blocking, * passing zero or more Attache packets to ip_rcv(). */static void slip_rcv(struct net *net){  struct bsdif *bif = net->specific;  struct slipctl *sp = bif->private;  packet *p;  int n;  if (sp->ilen <= 0) {    do {      n = read(bif->fd, (char *) sp->ibuf, sizeof(sp->ibuf));    } while (n < 0 && errno == EINTR);    if (n == 0 || (n < 0 && errno != EWOULDBLOCK)) {      bif->flags &= ~BSDIF_READ;      return;    }    sp->ilen = n;    sp->ibp = sp->ibuf;  }  while (sp->ilen > 0) {    if ((p = slip_decode(net, sp->ibp, sp->ilen, &n)) != 0) {      p->pkt_n = net;      ip_rcv(p);    }    if (n == 0)			/* out of packet buffers, try again later */      break;    sp->ibp += n;		/* count what we consumed */    sp->ilen -= n;  }}/* * Process whatever outgoing Attache packets we can without blocking. * Generates zero or more writes of encoded SLIP data. */static void slip_snd(struct net *net){  struct bsdif *bif = net->specific;  struct slipctl *sp = bif->private;  int n;  for (;;) {    if (sp->olen == 0) {      if ((n = slip_encode(net, sp->obuf, sizeof(sp->obuf))) == 0)	break;      sp->olen = n;      sp->obp = sp->obuf;    }    do {      n = write(bif->fd, sp->obp, sp->olen);    } while (n < 0 && errno == EINTR);    if (n <= 0)      break;    sp->obp += n;    sp->olen -= n;  }  if (n == 0 || (n < 0 && errno != EWOULDBLOCK))    bif->flags &= ~BSDIF_WRITE;}/* * Handle events detected by generic NetBSD I/O loop. * The flags tell us what kind of event happened, we call the * non-blocking I/O routines to do the real work. */static void slip_handler(int fd, void *net, unsigned flags){  if ((flags & BSDIF_WRITE) != 0)    slip_snd(net);  if ((flags & BSDIF_READ) != 0)    slip_rcv(net);}/* * Convert between raw line speed numbers and NetBSD line speed codes. * The second argument names the thing you want as the return value. */enum speed_index { slip_speed_number, slip_speed_symbol };static int slip_speed(int speed, enum speed_index speed_index){    int i;  static int table[][2] = {    { 1200, B1200 }, { 2400, B2400 }, { 4800, B4800 },    { 9600, B9600 }, { 19200, EXTA }, { 38400, EXTB }  };  for (i = 0; i < sizeof(table)/sizeof(*table); ++i)    if (table[i][!speed_index] == speed)      return table[i][speed_index];  return 0;}/* * Attache device driver routines. */static void slip_ip_send(struct net *net, packet *p, inaddr_t host){  p->pkt_n = net;  (*net->driver->send)(p);		/* Not much to do here, huh? */}static void slip_send(packet *p){  struct net *net = p->pkt_n;  struct bsdif *bif = net->specific;  struct slipctl *sp = bif->private;  p->pkt_flags |= PF_SLIP_BOP;		/* Flag that this is a new packet */  p->pkt_link = 0;			/* Stuff this packet into the */  *sp->opkt_tail = p;			/* output queue */  sp->opkt_tail = &p->pkt_link;  bif->flags |= BSDIF_WRITE;		/* Now interested in output events */  slip_snd(net);			/* Send what we can right away */}static void slip_close(struct net *net){  struct bsdif *bif = net->specific;  net->flags |= NF_DRIVER_DOWN;  bif->flags &= ~(BSDIF_READ | BSDIF_WRITE);  if (bif->fd >= 0) {    (void) close(bif->fd);		/* Clean up our file if we had one */    bif->fd = -1;  }  if (bif->private) {    GLUE_FREE(bif->private);		/* Release our memory if we had any */    bif->private = 0;  }}static void slip_init(struct net *net){  struct bsdif *bif = net->specific;  struct slipctl *sp;  struct sgttyb sgtty;  char name[sizeof(COM_DEV_NAME)+4];  int speed = slip_speed(net->speed, slip_speed_symbol);  net->flags |= NF_DRIVER_DOWN;  sprintf(name, "%s%d", COM_DEV_NAME, net->instance);  if (!speed) {    fprintf(stderr, "line speed %lu not supported\n", net->speed);    return;  }  if ((bif->private = sp = GLUE_ALLOC(sizeof(*sp))) == 0) {    fprintf(stderr, "couldn't allocate slip control structure\n");    return;  }  MEMSET(sp, 0, sizeof(*sp));  sp->opkt_tail = &sp->opkt_head;  sp->net = net;  sgtty.sg_flags = RAW | ANYP;  sgtty.sg_ispeed = sgtty.sg_ospeed = speed;  if ((bif->fd = open(name, O_RDWR, 0660)) < 0) { /* |O_NONBLOCK */    perror("couldn't open slip device");  } else if (ioctl(bif->fd, TIOCSETP, &sgtty) < 0) {    perror("couldn't set slip line flags and speed");  } else if (fcntl(bif->fd, F_SETFL, FNDELAY) < 0) {    perror("unable to set slip pty non-blocking");  } else {    bif->handler = slip_handler;    bif->flags |= BSDIF_READ;    net->flags &= ~NF_DRIVER_DOWN;    return;			/* success */  }  slip_close(net);		/* failure */}static struct driver slip_driver = {  slip_init,			/* Init routine */  slip_send,			/* Raw send routine */  slip_ip_send,			/* IP packet send routine */  0, 0,				/* ARP and test close routines */  slip_close,			/* Close routine */  "sl",				/* Driver name prefix */  "Serial Line IP",		/* Driver name */  0, 0,				/* Net header and trailer lengths */  296,				/* Max packet size */  IF_SLIP,			/* MIB interface type */  0,				/* ARP hardware type (none) */  0,				/* media control */  0,				/* IPv6 send */  0				/* IPv4 send */};void slip_driver_find  (void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t)){  char name[sizeof(COM_DEV_NAME)+4];  struct sgttyb sgtty;  int fd, speed, instance;  for (instance = 0; ; instance++) {    sprintf(name, "%s%d", COM_DEV_NAME, instance);    if ((fd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {      if (errno == ENOENT)	return;      continue;    }    speed = ((ioctl(fd, TIOCGETP, &sgtty) < 0)	     ? 0 : slip_speed(sgtty.sg_ispeed, slip_speed_number));    (void) close(fd);    if (speed == 0)      continue;    sprintf(name, "%d", instance);    config(name, &slip_driver, instance, 0,	   slip_driver.maxlen - slip_driver.lnh - slip_driver.lnt, speed);  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -