original files of m241

This commit is contained in:
neelimap
2026-07-30 11:19:44 +05:30
parent 170c2b3f3a
commit afc7070c1f
12254 changed files with 7655111 additions and 0 deletions
@@ -0,0 +1,708 @@
/* $Header: /usr/cvsroot/target/src/wrn/wm/demo/lib/pppbsd.c,v 1.3 2003/01/15 14:04:33 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: pppbsd.c,v $
* Revision 1.3 2003/01/15 14:04:33 josh
* directory structure shifting
*
* Revision 1.2 2001/11/08 15:56:25 tneale
* Updated for newest file layout
*
* Revision 1.1.1.1 2001/11/05 17:48:42 tneale
* Tornado shuffle
*
* Revision 2.10 2001/01/19 22:23:49 paul
* Update copyright.
*
* Revision 2.9 2000/10/16 19:21:54 paul
* Restore sockets and mempool code.
*
* Revision 2.8 2000/03/17 00:12:43 meister
* Update copyright message
*
* Revision 2.7 2000/03/13 21:22:08 paul
* Removed some code that we are no longer working on.
*
* Revision 2.6 1999/11/05 22:29:06 paul
* Updated driver structs to reflect conditional backwards-compatibility
* fields and new fields.
*
* Revision 2.5 1999/03/01 22:05:26 wes
* Add Yet Another Way to connect attache ppp to a unix ppp: attach
* ourselves to the master side of a pty; run pppd attached to the slave
* side.
* configured via INSTALL_SNARK_BSD_PPP_OVER_PTY
*
* Revision 2.4 1998/02/25 15:21:49 sra
* Finish moving types.h, bug.h, and bugdef.h to common/h/.
*
* Revision 2.3 1998/02/25 04:57:35 sra
* Update copyrights.
*
* Revision 2.2 1997/11/18 18:05:19 sra
* Make PPP work on Purify/SunOS testbed.
*
* Revision 2.1 1997/10/28 00:51:55 sra
* Convert PPP code to use BUG() macro.
* Bang on CHAP and PAP code some more.
* Create test driver for PPP under Snark/BSD.
*
*
*/
/* [clearcase]
modification history
-------------------
01a,19apr05,job update copyright notices
*/
/*
* Point-to-Point Protocol (PPP) interface for snark under BSD-derived systems.
*
* This code has only been tested under FreeBSD 2.x. It should work on
* any BSD-derived system with minor modifications.
*
* We depend on the PPP media layer code to handle the FCS, address, and
* control fields in the framing (PPPC_FCS must be enabled). So all we
* have to worry about is the byte stuffing and the framing "flag" byte.
*/
#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/route.h>
#include <wrn/wm/attache/ip.h>
#include <wrn/wm/attache/ppp.h>
#include <wrn/wm/attache/glue.h>
#include <stdio.h>
#include <termios.h>
#include <sys/types.h>
#include <sys/time.h>
#include <errno.h>
#include <fcntl.h>
#include <sys/file.h>
#include <unistd.h>
#if INSTALL_SNARK_BSD_PPP_OVER_TCP
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#endif
#if INSTALL_SNARK_BSD_PPP_OVER_PTY
#include <util.h>
#include <termios.h>
#endif
#include <wrn/wm/demo/snarklib.h>
#include <wrn/wm/demo/bsdif.h>
#include <wrn/wm/demo/pppbsd.h>
#define PF_PPP_BOP 0x1000
#ifndef BSDPPP_COMPORT_NAME
#if INSTALL_SNARK_BSD_PPP_OVER_PTY
#define BSDPPP_COMPORT_NAME "pty"
#elif INSTALL_SNARK_BSD_PPP_OVER_TCP
#define BSDPPP_COMPORT_NAME "tcp"
#else
#define BSDPPP_COMPORT_NAME "cuaa"
#endif
#endif
/*
* PPP control structure, hangs off net->specific->private.
*/
#ifndef SNARKBSD_PPP_IBUFLEN
#define SNARKBSD_PPP_IBUFLEN 6000
#endif
#ifndef SNARKBSD_PPP_OBUFLEN
#define SNARKBSD_PPP_OBUFLEN 6000
#endif
struct ppp_driver_ctl {
struct net *net;
bits32_t snd_asynch_mask;
packet *ipkt, *opkt_head, **opkt_tail;
int ilen, olen;
unsigned char *ibp, *obp;
unsigned char ibuf[SNARKBSD_PPP_IBUFLEN], obuf[SNARKBSD_PPP_OBUFLEN];
unsigned iescaped : 1;
unsigned idiscard : 1;
unsigned oescaped : 1;
};
/*
* PPP framing and byte stuffing magic
*/
#define PPP_FLAG 0x7e
#define PPP_ESCAPE 0x7d
#define PPP_XOR 0x20
#define PPP_MASKED(_c_, _m_) ((_c_) < 32 && ((_m_) & (1 << (_c_))))
#ifndef PPP_DRIVER_RCV_ASYNCH_MASK
#define PPP_DRIVER_RCV_ASYNCH_MASK 0
#endif
static void hexdump (char *flag, unsigned char *cp, int len)
{
int i;
fprintf(stderr, "%s:", flag);
for (i=0; i<len; i++) {
fprintf(stderr, " %02x", cp[i]);
}
fprintf(stderr, "\n");
}
/*
* 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) \
do { \
if (pdc->idiscard) { \
continue; \
} else if (p->pkt_data < p->pkt_buffer + p->pkt_buflen) { \
*p->pkt_data++ = (x); \
} else { \
pdc->idiscard = 1; \
continue; \
} \
} while (0)
static packet *ppp_driver_decode
(struct net *net, unsigned char *buf, int len, int *used)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
unsigned char *bob = buf, *eob = buf + len;
packet *p;
while (buf < eob) {
if (pdc->ipkt == 0 && (pdc->ipkt = pkt_alloc(net->driver->maxlen)) == 0)
break; /* Oops, no packet buffers */
p = pdc->ipkt;
if (PPP_MASKED(*buf, PPP_DRIVER_RCV_ASYNCH_MASK)) {
++buf; /* Noise byte, just ignore it */
continue;
}
if (pdc->iescaped) { /* Was escaped? */
pdc->iescaped = 0; /* ain't no more */
if (*buf == PPP_FLAG) /* End of frame in escape sequence? */
pdc->idiscard = 1; /* yeah, abort this packet */
DOCHAR(*buf++ ^ PPP_XOR); /* Save unescaped byte */
} else { /* Not escaped */
switch (*buf++) {
case PPP_FLAG:
if (!pdc->idiscard && p->pkt_data > p->pkt_buffer) {
pdc->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 */
}
pdc->idiscard = 0; /* Bogus packet now history */
p->pkt_data = p->pkt_buffer;
continue;
case PPP_ESCAPE:
pdc->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 ppp_driver_send().
*/
#define DOCHAR(x) \
do { *buf++ = (x); if (buf == eob) return (buf - bob); } while (0)
static int ppp_driver_encode(struct net *net, unsigned char *buf, int len)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
unsigned char *bob = buf, *eob = buf + len;
packet *p;
if (buf >= eob)
return 0;
while ((p = pdc->opkt_head) != 0) {
/*
* Send framing sequence before a new packet, to flush line noise.
*/
if ((p->pkt_flags & PF_PPP_BOP) != 0) {
p->pkt_flags &= ~PF_PPP_BOP;
DOCHAR(PPP_FLAG);
}
/*
* Process data in this packet.
*/
while (p->pkt_datalen > 0) {
if (pdc->oescaped) {
pdc->oescaped = 0; /* Was escaped, ain't no more */
DOCHAR((*p->pkt_data++) ^ PPP_XOR);
} else {
switch (*p->pkt_data) {
default:
if (!PPP_MASKED(*p->pkt_data, pdc->snd_asynch_mask)) {
DOCHAR(*p->pkt_data++);
break; /* Ordinary char, just send it */
}
case PPP_FLAG: /* I need an escape */
case PPP_ESCAPE:
pdc->oescaped = 1;
DOCHAR(PPP_ESCAPE);
continue; /* Doesn't count as sent yet */
}
}
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(PPP_FLAG);
if ((pdc->opkt_head = p->pkt_link) == 0)
pdc->opkt_tail = &pdc->opkt_head;
pkt_free(p);
}
return buf - bob;
}
#undef DOCHAR
/*
* Process whatever incoming PPP data we can without blocking,
* passing zero or more Attache packets to ppp_rcv().
*/
static void ppp_driver_input(struct net *net)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
packet *p;
int n;
if (pdc->ilen <= 0) {
do {
n = read(bif->fd, (char *) pdc->ibuf, sizeof(pdc->ibuf));
} while (n < 0 && errno == EINTR);
if (n == 0 || (n < 0 && errno != EWOULDBLOCK)) {
bif->flags &= ~BSDIF_READ;
return;
}
pdc->ilen = n;
pdc->ibp = pdc->ibuf;
}
while (pdc->ilen > 0) {
if ((p = ppp_driver_decode(net, pdc->ibp, pdc->ilen, &n)) != 0) {
p->pkt_n = net;
hexdump("RX", p->pkt_data, p->pkt_datalen);
ppp_rcv(p);
}
if (n == 0) /* out of packet buffers, try again later */
break;
pdc->ibp += n; /* count what we consumed */
pdc->ilen -= n;
}
}
/*
* Process whatever outgoing Attache packets we can without blocking.
* Generates zero or more writes of encoded PPP data.
*/
static void ppp_driver_output(struct net *net)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
int n;
for (;;) {
if (pdc->olen == 0) {
if ((n = ppp_driver_encode(net, pdc->obuf, sizeof(pdc->obuf))) == 0)
break;
pdc->olen = n;
pdc->obp = pdc->obuf;
}
do {
n = write(bif->fd, pdc->obp, pdc->olen);
} while (n < 0 && errno == EINTR);
if (n <= 0)
break;
pdc->obp += n;
pdc->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 ppp_driver_handler(int fd, void *net, unsigned flags)
{
if ((flags & BSDIF_WRITE) != 0)
ppp_driver_output(net);
if ((flags & BSDIF_READ) != 0)
ppp_driver_input(net);
}
/*
* Attache device driver routines.
*/
static void ppp_driver_send(packet *p)
{
struct net *net = p->pkt_n;
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
hexdump("TX", p->pkt_data, p->pkt_datalen);
p->pkt_flags |= PF_PPP_BOP; /* Flag that this is a new packet */
p->pkt_link = 0; /* Stuff this packet into the */
*pdc->opkt_tail = p; /* output queue */
pdc->opkt_tail = &p->pkt_link;
bif->flags |= BSDIF_WRITE; /* Now interested in output events */
ppp_driver_output(net); /* Send what we can right away */
}
static void ppp_driver_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 ppp_driver_init(struct net *net)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc;
char name[64];
net->flags |= NF_DRIVER_DOWN;
if (!net->speed)
net->speed = 115200;
if ((bif->private = pdc = GLUE_ALLOC(sizeof(*pdc))) == 0) {
fprintf(stderr, "couldn't allocate ppp control structure\n");
return;
}
MEMSET(pdc, 0, sizeof(*pdc));
pdc->opkt_tail = &pdc->opkt_head;
pdc->net = net;
#if INSTALL_SNARK_BSD_PPP_OVER_PTY
{
int pty, tty;
int subpid;
char *pppd_path;
struct termios t;
int nsleep = 10;
sprintf(name, "SNARKBSDPPP_PTY%d", net->instance);
pppd_path = getenv(name);
if (!pppd_path)
return;
if (openpty(&pty, &tty, name, NULL, NULL) < 0) {
perror("can't open pty");
return;
}
tcgetattr(tty, &t);
cfmakeraw(&t);
tcsetattr(tty, TCSAFLUSH, &t);
fflush(NULL);
subpid = fork();
if (subpid < 0) {
perror("fork");
return; /* !!! cleanup? */
}
if (subpid == 0) {
/* in the child; start pppd... */
dup2(tty, 0);
dup2(tty, 1);
close(pty);
close(tty);
fprintf(stderr, "execing %s in pid %d on %s in %d seconds...\n", pppd_path, getpid(), name, nsleep);
sleep(nsleep);
fprintf(stderr, "execing now\n");
execlp(pppd_path, "pppd", name,
"file", "snark.ppprc", NULL);
_exit(1);
}
/* now in the parent.. */
close(tty);
bif->fd = pty;
sleep(nsleep+1);
}
#elif !INSTALL_SNARK_BSD_PPP_OVER_TCP
/*
* Normal /dev/ttyxxx-based PPP. This code was written for FreeBSD 2.2.1,
* it should be pretty easy to make it work on other Unix-like systems.
*/
{
struct termios termios;
sprintf(name, "/dev/%s", net->s_name + 3);
if ((bif->fd = open(name, O_RDWR, 0660)) < 0) { /* |O_NONBLOCK */
perror("couldn't open ppp device");
goto lose;
}
if (tcgetattr(bif->fd, &termios) < 0) {
perror("couldn't get ppp line state");
goto lose;
}
if (cfmakeraw(&termios), cfsetspeed(&termios, net->speed) < 0) {
perror("couldn't fiddle ppp state");
goto lose;
}
if (tcsetattr(bif->fd, TCSANOW, &termios) < 0) {
perror("couldn't set ppp line flags and speed");
goto lose;
}
}
#elif 0
/*
* PPP over TCP. This version does an active connect. In theory,
* it should work nicely with IIJ-PPP in -direct mode running under
* Juergen Nickelsen's "socket" program, but in practice the connection
* keeps getting closed before LCP ever really gets going. Sigh.
*/
{
struct sockaddr_in sin;
char host[20];
unsigned short port;
sprintf(name, "SNARKBSDPPP_%s", net->s_name + 3);
if (sscanf(getenv(name), "%16[0-9.]:%hu", host, &port) != 2) {
fprintf(stderr, "couldn't line information for PPP/TCP link\n");
goto lose;
}
MEMSET(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
sin.sin_addr.s_addr = inet_addr(host);
if ((bif->fd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("couldn't get socket for PPP/TCP link");
goto lose;
}
if (connect(bif->fd, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
perror("couldn't connect PPP/TCP link");
goto lose;
}
}
#else
/*
* PPP over TCP. This version does a passive listen, which, in theory,
* should allow IIJ-PPP to connect to it directly.
*/
{
struct sockaddr_in sin;
unsigned short port;
int s, n;
sprintf(name, "SNARKBSDPPP_%s", net->s_name + 3);
if (sscanf(getenv(name), "%hu", &port) != 1) {
fprintf(stderr, "couldn't parse line information for PPP/TCP link %s: %s\n",
name, getenv(name));
goto lose;
}
MEMSET(&sin, 0, sizeof(sin));
sin.sin_family = AF_INET;
sin.sin_port = htons(port);
if ((s = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
perror("couldn't get socket for PPP/TCP listener");
goto lose;
}
if (bind(s, (struct sockaddr *) &sin, sizeof(sin)) < 0) {
perror("couldn't bind socket for PPP/TCP listener");
goto lose;
}
if (listen(s, 1) < 0) {
perror("couldn't listen for for PPP/TCP connection");
goto lose;
}
fprintf(stderr, "[Listening for PPP/TCP connection on port %u]\n", port);
n = sizeof(sin);
if ((bif->fd = accept(s, (struct sockaddr *) &sin, &n)) < 0) {
perror("couldn't accept PPP/TCP connection");
goto lose;
}
close(s);
fprintf(stderr, "[Got PPP/TCP connection from %s:%u]\n",
inet_ntoa(sin.sin_addr), ntohs(sin.sin_port));
}
#endif
if (fcntl(bif->fd, F_SETFL, FNDELAY) < 0) {
perror("unable to set ppp line non-blocking");
goto lose;
}
bif->handler = ppp_driver_handler;
bif->flags |= BSDIF_READ;
net->flags &= ~NF_DRIVER_DOWN;
return; /* success */
lose:
ppp_driver_close(net); /* failure */
}
static int ppp_driver_device_ctl(struct net *net, int code, ptr_t cookie)
{
struct bsdif *bif = net->specific;
struct ppp_driver_ctl *pdc = bif->private;
switch (code) {
case DEVICE_CTL_SET_PPP_ASYNC_CTL_MAP:
BUG_ASSERT(cookie && bif && pdc);
pdc->snd_asynch_mask = *(bits32_t *)cookie;
return DEVICE_CTL_GOOD;
case DEVICE_CTL_GET_PPP_RCV_ASYNC_CTL_MAP:
BUG_ASSERT(cookie);
*(bits32_t *)cookie = PPP_DRIVER_RCV_ASYNCH_MASK;
return DEVICE_CTL_GOOD;
default:
return DEVICE_CTL_UNKNOWN_CODE;
}
}
static struct driver ppp_driver = {
ppp_driver_init, /* Init routine */
ppp_driver_send, /* Raw send routine */
ppp_ip_send, /* IP packet send routine */
0, /* ARP routine */
ppp_driver_device_ctl, /* Device control routine */
ppp_driver_close, /* Close routine */
"ppp", /* Driver name prefix */
"Point-to-Point Protocol", /* Driver name */
4, /* Header length (adr, ctl, prot) */
2, /* Trailer length (FCS) */
1506, /* Max packet size */
IF_PPP, /* MIB interface type */
0, /* ARP hardware type */
ppp_control, /* Media control routine */
0, /* IPv6 send */
0 /* IPv4 send */
};
void ppp_driver_find
(void (*config)(char *, struct driver *, int, bits16_t, unsigned, bits32_t))
{
char name[64];
int speed, instance;
for (instance = 0; ; instance++) {
#if INSTALL_SNARK_BSD_PPP_OVER_PTY
sprintf(name, "SNARKBSDPPP_PTY%d", instance);
if (!getenv(name))
return;
speed = 115200;
#elif INSTALL_SNARK_BSD_PPP_OVER_TCP
sprintf(name, "SNARKBSDPPP_%s%d", BSDPPP_COMPORT_NAME, instance);
if (!getenv(name))
return;
speed = 115200;
#else
struct termios termios;
int fd;
sprintf(name, "/dev/%s%d", BSDPPP_COMPORT_NAME, instance);
if ((fd = open(name, O_RDONLY | O_NONBLOCK)) < 0) {
if (errno == ENOENT)
return;
continue;
}
speed = (tcgetattr(fd, &termios) < 0 ? 0 : cfgetispeed(&termios));
(void) close(fd);
if (speed == 0)
continue;
#endif
sprintf(name, "%s%d", BSDPPP_COMPORT_NAME, instance);
config(name, &ppp_driver, instance, 0,
ppp_driver.maxlen - ppp_driver.lnh - ppp_driver.lnt, speed);
}
}