2001-10-12 Mike Siers <mikes@poliac.com>

* Update to stable working state.  Congratulations Mike! :)
	* modem_example: Directory removed.
	* modem_example/16550.h, modem_example/README, modem_example/modem.c,
	modem_example/modem.h, modem_example/ppp.c, modem_example/ppp.h,
	modem_example/pppcompress.c: Files removed.
	* pppd/example/pppd.options: New file.
	* pppd/README, pppd/STATUS, pppd/cbcp.c, pppd/cbcp.h, pppd/chat.c,
	pppd/pppd.h, pppd/rtemsmain.c: Updated.
This commit is contained in:
Joel Sherrill
2001-10-12 13:43:05 +00:00
parent ba71076168
commit aee474b0cf
28 changed files with 1387 additions and 4308 deletions

View File

@@ -1,3 +1,14 @@
2001-10-12 Mike Siers <mikes@poliac.com>
* Update to stable working state. Congratulations Mike! :)
* modem_example: Directory removed.
* modem_example/16550.h, modem_example/README, modem_example/modem.c,
modem_example/modem.h, modem_example/ppp.c, modem_example/ppp.h,
modem_example/pppcompress.c: Files removed.
* pppd/example/pppd.options: New file.
* pppd/README, pppd/STATUS, pppd/cbcp.c, pppd/cbcp.h, pppd/chat.c,
pppd/pppd.h, pppd/rtemsmain.c: Updated.
2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add autom4te.cache for autoconf > 2.52.

View File

@@ -1,3 +1,14 @@
2001-10-12 Mike Siers <mikes@poliac.com>
* Update to stable working state. Congratulations Mike! :)
* modem_example: Directory removed.
* modem_example/16550.h, modem_example/README, modem_example/modem.c,
modem_example/modem.h, modem_example/ppp.c, modem_example/ppp.h,
modem_example/pppcompress.c: Files removed.
* pppd/example/pppd.options: New file.
* pppd/README, pppd/STATUS, pppd/cbcp.c, pppd/cbcp.h, pppd/chat.c,
pppd/pppd.h, pppd/rtemsmain.c: Updated.
2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add autom4te.cache for autoconf > 2.52.

View File

@@ -16,5 +16,9 @@ provided the modem driver as well.
The port was updated to 2.3.11 by Mike Siers <mikes@poliac.com>
who added an example test.
Updated the chat program to return the correct errors and support
the ABORT commands. Removed some dead code and did a lot of
testing on a new Coldfire BSP. Version seems to be very stable.
=================================================================

View File

@@ -2,39 +2,28 @@
# $Id$
#
The pppd application seems to very stable. It has been tested using
the example application with the i386/pc586 and m68k/sbc5206e BSPs.
The tests were executed using a null modem serial cable to connect
with a UNIX box running either the ppp or pppd application and with
an external modem to dial up a local ISP.
Notes from Mike Siers <mikes@poliac.com>
========================================
If you have problems getting your target to make consistent connections
with an ISP, the problem is most likely with the ppp options. First
try using the "novj" and "noaccomp" options. If you have questions
about what other option values are available for the rtems_pppd_set_option
function, please look at the pppd.8 man page file or the the source code.
The majority of options that are documented in man page should work
with this function call.
I know that several users have tried out this version of
pppd under RTEMS. It has been successfully used as both
a client and server. Below are the only issues that I
know of.
The pppd application requires the BSP termios driver support task
driven I/O. Below is a list of known issues that need to be resolved:
1) Large packet ping causes RTEMS box to lock up
If you ping the RTEMS box over the ppp link with a packet
size greater than 1500, the RTEMS box locks up. I think
the problem is in the pppd ethernet driver.
- pppd locks up when it receives large packet pings (> 1500 bytes)
- pppd occasionaly locks up with mbuf allocation error
(problem is rare and may be BSP related)
2) Upgrade the libnetworking/modem files
This upgrade did not modify the ppp ethernet driver files
in the libnetworking/modem directory. Would like to
upgrade these files. Hopefully, it will fix the large
packet ping problem.
3) The files cbcp.c and cbcp.h provide a callback feature
that I have not tried to compile or use. The files in
this directory are identical to the 2.3.11 versions.
for completeness.
JOEL: Are the modifications to the original pppd such that the
real maintainers will accept them?
No. The pppd 2.3.11 branch is an old branch. The current
version is 2.4.x and it contains alot of extra items that
just did not make sense to have in an embedded environment.
I could make the RTEMS changes compatible with the standard
2.3.11 release by using compilation flags. I have not
contacted the maintainers to see if they are interested.
If you find any other problems or fix some problems, please post your
changes to the RTEMS mailing list.
Good Luck

View File

@@ -0,0 +1,456 @@
/*
* cbcp - Call Back Configuration Protocol.
*
* Copyright (c) 1995 Pedro Roque Marques
* 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 Pedro Roque Marques. The name of the author 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.
*/
#define RCSID "$Id$"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "cbcp.h"
#include "fsm.h"
#include "lcp.h"
static const char rcsid[] = RCSID;
/*
* Options.
*/
static int setcbcp __P((char **));
static option_t cbcp_option_list[] = {
{ "callback", o_special, setcbcp,
"Ask for callback" },
{ NULL }
};
/*
* Protocol entry points.
*/
static void cbcp_init __P((int unit));
static void cbcp_open __P((int unit));
static void cbcp_lowerup __P((int unit));
static void cbcp_input __P((int unit, u_char *pkt, int len));
static void cbcp_protrej __P((int unit));
static int cbcp_printpkt __P((u_char *pkt, int len,
void (*printer) __P((void *, char *, ...)),
void *arg));
struct protent cbcp_protent = {
PPP_CBCP,
cbcp_init,
cbcp_input,
cbcp_protrej,
cbcp_lowerup,
NULL,
cbcp_open,
NULL,
cbcp_printpkt,
NULL,
0,
"CBCP",
NULL,
cbcp_option_list,
NULL,
NULL,
NULL
};
cbcp_state cbcp[NUM_PPP];
/* internal prototypes */
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
static void cbcp_resp __P((cbcp_state *us));
static void cbcp_up __P((cbcp_state *us));
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
/* option processing */
static int
setcbcp(argv)
char **argv;
{
lcp_wantoptions[0].neg_cbcp = 1;
cbcp_protent.enabled_flag = 1;
cbcp[0].us_number = strdup(*argv);
if (cbcp[0].us_number == 0)
novm("callback number");
cbcp[0].us_type |= (1 << CB_CONF_USER);
cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
return (1);
}
/* init state */
static void
cbcp_init(iface)
int iface;
{
cbcp_state *us;
us = &cbcp[iface];
memset(us, 0, sizeof(cbcp_state));
us->us_unit = iface;
us->us_type |= (1 << CB_CONF_NO);
}
/* lower layer is up */
static void
cbcp_lowerup(iface)
int iface;
{
cbcp_state *us = &cbcp[iface];
dbglog("cbcp_lowerup");
dbglog("want: %d", us->us_type);
if (us->us_type == CB_CONF_USER)
dbglog("phone no: %s", us->us_number);
}
static void
cbcp_open(unit)
int unit;
{
dbglog("cbcp_open");
}
/* process an incomming packet */
static void
cbcp_input(unit, inpacket, pktlen)
int unit;
u_char *inpacket;
int pktlen;
{
u_char *inp;
u_char code, id;
u_short len;
cbcp_state *us = &cbcp[unit];
inp = inpacket;
if (pktlen < CBCP_MINLEN) {
error("CBCP packet is too small");
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
#if 0
if (len > pktlen) {
error("CBCP packet: invalid length");
return;
}
#endif
len -= CBCP_MINLEN;
switch(code) {
case CBCP_REQ:
us->us_id = id;
cbcp_recvreq(us, inp, len);
break;
case CBCP_RESP:
dbglog("CBCP_RESP received");
break;
case CBCP_ACK:
if (id != us->us_id)
dbglog("id doesn't match: expected %d recv %d",
us->us_id, id);
cbcp_recvack(us, inp, len);
break;
default:
break;
}
}
/* protocol was rejected by foe */
void cbcp_protrej(int iface)
{
}
char *cbcp_codenames[] = {
"Request", "Response", "Ack"
};
char *cbcp_optionnames[] = {
"NoCallback",
"UserDefined",
"AdminDefined",
"List"
};
/* pretty print a packet */
static int
cbcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, opt, id, len, olen, delay;
u_char *pstart;
if (plen < HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
printer(arg, " %s", cbcp_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= HEADERLEN;
switch (code) {
case CBCP_REQ:
case CBCP_RESP:
case CBCP_ACK:
while(len >= 2) {
GETCHAR(opt, p);
GETCHAR(olen, p);
if (olen < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
printer(arg, " %s", cbcp_optionnames[opt-1]);
else
printer(arg, " option=0x%x", opt);
if (olen > 2) {
GETCHAR(delay, p);
printer(arg, " delay = %d", delay);
}
if (olen > 3) {
int addrt;
char str[256];
GETCHAR(addrt, p);
memcpy(str, p, olen - 4);
str[olen - 4] = 0;
printer(arg, " number = %s", str);
}
printer(arg, ">");
break;
}
default:
break;
}
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}
/* received CBCP request */
static void
cbcp_recvreq(us, pckt, pcktlen)
cbcp_state *us;
char *pckt;
int pcktlen;
{
u_char type, opt_len, delay, addr_type;
char address[256];
int len = pcktlen;
address[0] = 0;
while (len) {
dbglog("length: %d", len);
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
us->us_allowed |= (1 << type);
switch(type) {
case CB_CONF_NO:
dbglog("no callback allowed");
break;
case CB_CONF_USER:
dbglog("user callback allowed");
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("address: %s", address);
}
break;
case CB_CONF_ADMIN:
dbglog("user admin defined allowed");
break;
case CB_CONF_LIST:
break;
}
len -= opt_len;
}
cbcp_resp(us);
}
static void
cbcp_resp(us)
cbcp_state *us;
{
u_char cb_type;
u_char buf[256];
u_char *bufp = buf;
int len = 0;
cb_type = us->us_allowed & us->us_type;
dbglog("cbcp_resp cb_type=%d", cb_type);
#if 0
if (!cb_type)
lcp_down(us->us_unit);
#endif
if (cb_type & ( 1 << CB_CONF_USER ) ) {
dbglog("cbcp_resp CONF_USER");
PUTCHAR(CB_CONF_USER, bufp);
len = 3 + 1 + strlen(us->us_number) + 1;
PUTCHAR(len , bufp);
PUTCHAR(5, bufp); /* delay */
PUTCHAR(1, bufp);
BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
dbglog("cbcp_resp CONF_ADMIN");
PUTCHAR(CB_CONF_ADMIN, bufp);
len = 3;
PUTCHAR(len, bufp);
PUTCHAR(5, bufp); /* delay */
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_NO ) ) {
dbglog("cbcp_resp CONF_NO");
PUTCHAR(CB_CONF_NO, bufp);
len = 3;
PUTCHAR(len , bufp);
PUTCHAR(0, bufp);
cbcp_send(us, CBCP_RESP, buf, len);
start_networks();
return;
}
}
static void
cbcp_send(us, code, buf, len)
cbcp_state *us;
u_char code;
u_char *buf;
int len;
{
u_char *outp;
int outlen;
outp = outpacket_buf;
outlen = 4 + len;
MAKEHEADER(outp, PPP_CBCP);
PUTCHAR(code, outp);
PUTCHAR(us->us_id, outp);
PUTSHORT(outlen, outp);
if (len)
BCOPY(buf, outp, len);
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
}
static void
cbcp_recvack(us, pckt, len)
cbcp_state *us;
char *pckt;
int len;
{
u_char type, delay, addr_type;
int opt_len;
char address[256];
if (len) {
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("peer will call: %s", address);
}
if (type == CB_CONF_NO)
return;
}
cbcp_up(us);
}
/* ok peer will do callback */
static void
cbcp_up(us)
cbcp_state *us;
{
persist = 0;
lcp_close(0, "Call me back, please");
status = EXIT_CALLBACK;
}

View File

@@ -0,0 +1,26 @@
#ifndef CBCP_H
#define CBCP_H
typedef struct cbcp_state {
int us_unit; /* Interface unit number */
u_char us_id; /* Current id */
u_char us_allowed;
int us_type;
char *us_number; /* Telefone Number */
} cbcp_state;
extern cbcp_state cbcp[];
extern struct protent cbcp_protent;
#define CBCP_MINLEN 4
#define CBCP_REQ 1
#define CBCP_RESP 2
#define CBCP_ACK 3
#define CB_CONF_NO 1
#define CB_CONF_USER 2
#define CB_CONF_ADMIN 3
#define CB_CONF_LIST 4
#endif

View File

@@ -14,6 +14,12 @@
* This software is in the public domain.
*
* -----------------
* 22-May-99 added environment substitutuion, enabled with -E switch.
* Andreas Arens <andras@cityweb.de>.
*
* 12-May-99 added a feature to read data to be sent from a file,
* if the send string starts with @. Idea from gpk <gpk@onramp.net>.
*
* added -T and -U option and \T and \U substitution to pass a phone
* number into chat script. Two are needed for some ISDN TA applications.
* Keith Dart <kdart@cisco.com>
@@ -74,18 +80,12 @@
* Columbus, OH 43221
* (614)451-1883
*
*
*/
#ifndef lint
/* static char rcsid[] = ""; */
#endif
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -93,13 +93,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <termios.h>
#include "pppd.h"
#undef TERMIOS
#define TERMIOS
#include <termios.h>
#define STR_LEN 1024
char temp2[STR_LEN];
@@ -142,39 +142,34 @@ static int _O = 0; /* Internal state */
char *program_name;
#define MAX_ABORTS 5
#define MAX_REPORTS 5
#define MAX_ABORTS 16
#define MAX_REPORTS 16
#define DEFAULT_CHAT_TIMEOUT 45
#define fcntl(a, b,c ) 0
#define MAX_TIMEOUTS 10
int echo = 0;
int verbose = 0;
int to_log = 1;
int to_stderr = 0;
int Verbose = 0;
int quiet = 0;
int report = 0;
int use_env = 0;
int exit_code = 0;
char *report_file = (char *) 0;
char *chat_file = (char *) 0;
char *phone_num = (char *) 0;
char *phone_num2 = (char *) 0;
int chat_timeout = DEFAULT_CHAT_TIMEOUT;
static int timeout = DEFAULT_CHAT_TIMEOUT;
int have_tty_parameters = 0;
#ifdef TERMIOS
#define term_parms struct termios
#define get_term_param(param) tcgetattr(ttyfd, param)
#define set_term_param(param) tcsetattr(ttyfd, TCSANOW, param)
#define get_term_param(param) tcgetattr(0, param)
#define set_term_param(param) tcsetattr(0, TCSANOW, param)
struct termios saved_tty_parameters;
#endif
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ASWER","RINGING\r\n\r\nRINGING"};
char *fail_reason = (char *)0,
fail_buffer[50];
int n_aborts = MAX_ABORTS, abort_next = 0, timeout_next = 0, echo_next = 0;
char *fail_reason = (char *)0;
char fail_buffer[50];
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ANSWER","RING\r\nRING"};
int n_aborts = 5;
int abort_next = 0, timeout_next = 0, echo_next = 0;
int clear_abort_next = 0;
char *report_string[MAX_REPORTS] ;
@@ -186,19 +181,7 @@ int say_next = 0, hup_next = 0;
void *dup_mem __P((void *b, size_t c));
void *copy_of __P((char *s));
/*
SIGTYPE sigalrm __P((int signo));
SIGTYPE sigint __P((int signo));
SIGTYPE sigterm __P((int signo));
SIGTYPE sighup __P((int signo));
*/
void unalarm __P((void));
void init __P((void));
void set_tty_parameters __P((void));
void echo_stderr __P((int));
void break_sequence __P((void));
void terminate __P((int status));
void do_file __P((char *chat_file));
int get_string __P((register char *string));
int put_string __P((register char *s));
int write_char __P((int c));
@@ -208,19 +191,9 @@ void chat_send __P((register char *s));
char *character __P((int c));
void chat_expect __P((register char *s));
char *clean __P((register char *s, int sending));
void break_sequence __P((void));
void terminate __P((int status));
void pack_array __P((char **array, int end));
char *expect_strtok __P((char *, char *));
int vfmtmsg __P((char *, int, const char *, va_list)); /* vsprintf++ */
int chatmain __P((char *));
#if 0
int usleep( long usec ); /* returns 0 if ok, else -1 */
#endif
extern int input_fd,output_fd;
int main __P((int, char *[]));
void *dup_mem(b, c)
void *b;
@@ -240,17 +213,10 @@ char *s;
return dup_mem(s, strlen (s) + 1);
}
/*
* chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \
* [ -r report-file ] \
* [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]]
*
* Perform a UUCP-dialer-like chat script on stdin and stdout.
*/
char *getnextcommand(char **string)
{
char *buf=*string,*res;
res=strchr(buf,'@');
res=strchr(buf,'|');
if (res==NULL)
return NULL;
*res='\0';
@@ -258,8 +224,6 @@ char *getnextcommand(char **string)
return buf;
}
extern int ttyfd;
int chatmain(argv)
char *argv;
{
@@ -268,14 +232,16 @@ char *argv;
/* initialize exit code */
exit_code = 0;
printf("chat_main: %s\n", argv);
if ( debug ) {
dbglog("chat_main: %s\n", argv);
}
/* get first expect string */
arg = getnextcommand(&argv);
while ( arg != NULL ) {
while (( arg != NULL ) && ( exit_code == 0 )) {
/* process the expect string */
chat_expect(arg);
if ( exit_code == 0 ) {
/* get the next send string */
arg = getnextcommand(&argv);
if ( arg != NULL ) {
@@ -286,60 +252,20 @@ printf("chat_main: %s\n", argv);
arg = getnextcommand(&argv);
}
}
return 0;
}
/*
* Print an error message and terminate.
*/
void init()
{
set_tty_parameters();
if ( exit_code ) {
exit_code = -exit_code;
}
void set_tty_parameters()
{
term_parms t;
if (get_term_param (&t) < 0)
syslog(LOG_NOTICE,"Can't get terminal parameters:")
;
saved_tty_parameters = t;
have_tty_parameters = 1;
t.c_iflag |= IGNBRK | ISTRIP | IGNPAR;
t.c_oflag = 0;
t.c_lflag = 0;
t.c_cc[VERASE] =
t.c_cc[VKILL] = 0;
t.c_cc[VMIN] = 0;
t.c_cc[VTIME] = 1;
if (set_term_param (&t) < 0)
syslog(LOG_NOTICE,"Can't set terminal parameters:")
;
return ( exit_code );
}
void break_sequence()
{
/* tcsendbreak (0, 0);*/
tcsendbreak(ttyfd, 0);
}
/*void terminate(status)
int status;
{
echo_stderr(-1);
if (have_tty_parameters) {
if (set_term_param (&saved_tty_parameters) < 0)
fatal(2, "Can't restore terminal parameters: %m");
}
}
*/
/*
* 'Clean up' this string.
*/
@@ -347,10 +273,14 @@ char *clean(s, sending)
register char *s;
int sending; /* set to 1 when sending (putting) this string. */
{
char temp[STR_LEN], cur_chr;
char temp[STR_LEN], env_str[STR_LEN], cur_chr;
register char *s1, *phchar;
int add_return = sending;
#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7'))
#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \
|| (((chr) >= 'a') && ((chr) <= 'z')) \
|| (((chr) >= 'A') && ((chr) <= 'Z')) \
|| (chr) == '_')
s1 = temp;
while (*s) {
@@ -368,6 +298,18 @@ int sending; /* set to 1 when sending (putting) this string. */
continue;
}
if (use_env && cur_chr == '$') { /* ARI */
phchar = env_str;
while (isalnumx(*s))
*phchar++ = *s++;
*phchar = '\0';
phchar = getenv(env_str);
if (phchar)
while (*phchar)
*s1++ = *phchar++;
continue;
}
if (cur_chr != '\\') {
*s1++ = cur_chr;
continue;
@@ -400,7 +342,6 @@ int sending; /* set to 1 when sending (putting) this string. */
case 'd':
if (sending)
*s1++ = '\\';
*s1++ = cur_chr;
break;
@@ -455,6 +396,13 @@ int sending; /* set to 1 when sending (putting) this string. */
*s1++ = 'N';
break;
case '$': /* ARI */
if (use_env) {
*s1++ = cur_chr;
break;
}
/* FALL THROUGH */
default:
if (isoctal (cur_chr)) {
cur_chr &= 0x07;
@@ -493,7 +441,6 @@ int sending; /* set to 1 when sending (putting) this string. */
/*
* A modified version of 'strtok'. This version skips \ sequences.
*/
char *expect_strtok (s, term)
char *s, *term;
{
@@ -548,7 +495,6 @@ char *expect_strtok (s, term)
/*
* Process the expect string
*/
void chat_expect (s)
char *s;
{
@@ -622,11 +568,30 @@ char *s;
chat_send (reply);
}
}
/*
* The expectation did not occur. This is terminal.
* Translate the input character to the appropriate string for printing
* the data.
*/
return ;
char *character(c)
int c;
{
static char string[10];
char *meta;
meta = (c & 0x80) ? "M-" : "";
c &= 0x7F;
if (c < 32)
sprintf(string, "%s^%c", meta, (int)c + '@');
else if (c == 127)
sprintf(string, "%s^?", meta);
else
sprintf(string, "%s%c", meta, c);
return (string);
}
/*
@@ -635,16 +600,19 @@ char *s;
void chat_send (s)
register char *s;
{
char file_data[STR_LEN];
if (say_next) {
say_next = 0;
s = clean(s,0);
write(ttyfd, s, strlen(s));
s = clean(s, 1);
write(2, s, strlen(s));
free(s);
return;
}
if (hup_next) {
hup_next = 0;
return;
}
if (echo_next) {
@@ -654,35 +622,52 @@ register char *s;
}
if (abort_next) {
/* char *s1; */
char *s1;
abort_next = 0;
if ( n_aborts < MAX_ABORTS ) {
s1 = clean(s, 0);
if (( strlen(s1) <= strlen(s) ) &&
( strlen(s1) < sizeof(fail_buffer))) {
;
abort_string[n_aborts++] = s1;
}
}
return;
}
if (clear_abort_next) {
clear_abort_next = 0;
return;
}
if (report_next) {
report_next = 0;
return;
}
if (clear_report_next) {
clear_report_next = 0;
return;
}
if (timeout_next) {
timeout=atoi(s);
timeout_next = 0;
chat_timeout = atoi(s);
if (chat_timeout <= 0)
chat_timeout = DEFAULT_CHAT_TIMEOUT;
timeout = atoi(s);
if (timeout <= 0)
timeout = DEFAULT_CHAT_TIMEOUT;
return;
}
if (strcmp(s, "EOT") == 0)
s = "^D\\c";
else if (strcmp(s, "BREAK") == 0)
s = "\\K\\c";
if (!put_string(s))
{
exit_code=1;
return;
if (!put_string(s)) {
exit_code = 2;
}
}
@@ -708,21 +693,10 @@ int get_char()
int put_char(c)
int c;
{
int status;
char ch = c;
/* inter-character typing delay (?) */
write(ttyfd, &ch, 1);
status = write(ttyfd, &ch, 1);
switch (status) {
case 1:
return (0);
default:
}
return 0;
}
@@ -774,44 +748,12 @@ register char *s;
}
}
/* alarm(0);*/
return (1);
}
/*
* Echo a character to stderr.
* When called with -1, a '\n' character is generated when
* the cursor is not at the beginning of a line.
*/
void echo_stderr(n)
int n;
{
/* static int need_lf;
char *s;
switch (n) {
case '\r':
break;
case -1:
if (need_lf == 0)
break;
case '\n':
write(2, "\n", 1);
need_lf = 0;
break;
default:
s = character(n);
write(2, s, strlen(s));
need_lf = 1;
break;
}*/
}
/*
* 'Wait for' this string to appear on this file descriptor.
*/
int get_string(string)
register char *string;
{
@@ -820,6 +762,8 @@ register char *string;
char *logged = temp2;
struct termios tios;
memset(temp2, 0, sizeof(temp2));
tcgetattr(ttyfd, &tios);
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS;
@@ -838,7 +782,6 @@ register char *string;
return (1);
}
while ( (c = get_char()) >= 0) {
int n, abort_len;
@@ -871,60 +814,7 @@ register char *string;
s = temp2 + minlen;
}
}
exit_code = 3;
return (0);
}
/*
* Gross kludge to handle Solaris versions >= 2.6 having usleep.
*/
/*
usleep -- support routine for 4.2BSD system call emulations
last edit: 29-Oct-1984 D A Gwyn
*/
#if 0
int
usleep( usec ) /* returns 0 if ok, else -1 */
long usec; /* delay in microseconds */
{
rtems_status_code status;
rtems_interval ticks_per_second;
rtems_interval ticks;
status = rtems_clock_get(
RTEMS_CLOCK_GET_TICKS_PER_SECOND,
&ticks_per_second);
ticks = (usec * (ticks_per_second/1000))/1000;
status = rtems_task_wake_after( ticks );
return 0;
}
#endif
void pack_array (array, end)
char **array; /* The address of the array of string pointers */
int end; /* The index of the next free entry before CLR_ */
{
int i, j;
for (i = 0; i < end; i++) {
if (array[i] == NULL) {
for (j = i+1; j < end; ++j)
if (array[j] != NULL)
array[i++] = array[j];
for (; i < end; ++i)
array[i] = NULL;
break;
}
}
}
/*
* vfmtmsg - format a message into a buffer. Like vsprintf except we
* also specify the length of the output buffer, and we handle the
* %m (error message) format.
* Doesn't do floating-point formats.
* Returns the number of chars put into buf.
*/
#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)

View File

@@ -6,3 +6,10 @@ This is an example user application using pppd. It is built using
the RTEMS application Makefiles. The file Makefile-user should
be renamed to Makefile or the -f option given to make. The file
is renamed to avoid bootstrap -c removing it.
The files ppp.conf and pppd.options are sample configuration files
that have successfully used to make ppp connections over a null
modem serial cable to a UNIX box. Please review the man pages
for either the ppp or pppd applications to ensure they are configured
correctly.

View File

@@ -0,0 +1,9 @@
/dev/tty00
57600
crtscts
passive
local
noauth
debug
persist
192.168.2.222:192.168.2.111

View File

@@ -1,110 +0,0 @@
/*
*-------------------------------------------------------------------
*
* 16550 -- header file for National Semiconducor's 16550 UART
*
* This file has been created by John S. Gwynne for the efi68k
* project.
*
* The license and distribution terms for this file may in
* the file LICENSE in this distribution or at
* http://www.OARcorp.com/rtems/license.html.
*
*------------------------------------------------------------------
*
* $Id$
*/
#ifndef _16550_H_
#define _16550_H_
/* base address is the physical location of register 0 */
#define UART_BASE_ADDRESS 0xF0000000
/* definitions of register addresses and associate bits */
#define RBR (volatile unsigned char * const)(0+UART_BASE_ADDRESS)
/* Receiver Buffer Register (w/DLAB=0)*/
/* 8-bit data */
#define THR (volatile unsigned char * const)(0+UART_BASE_ADDRESS)
/* Transmitter Holding Register (w/DLAB=0) */
/* 8-bit data */
#define DLL (volatile unsigned char * const)(0+UART_BASE_ADDRESS)
/* Divisor Latch (LS) (w/DLAB=1) */
/* LSB of Divisor */
#define DLM (volatile unsigned char * const)(1+UART_BASE_ADDRESS)
/* Divisor Latch (MS) (w/DLAB=1) */
/* MSB of Divisor */
#define IER (volatile unsigned char * const)(1+UART_BASE_ADDRESS)
/* Interrupt Enable Register (w/DLAB=0) */
#define ERBFI 0x01 /* Enable Recv Data Available Interrupt */
#define ETBEI 0x02 /* Enable Trans Holding Reg Empty Inter */
#define ELSI 0x04 /* Enable Recv Line Status Interrupt */
#define EDSSI 0x08 /* Enable Modem Status Interrupt */
#define IIR (volatile unsigned char * const)(2+UART_BASE_ADDRESS)
/* Interrupt Ident Register (read only) */
#define NIP 0x01 /* No Interrupt Pending */
#define IID_MASK 0x0e /* Interrupt ID mask */
#define FE_MASK 0xc0 /* FIFO's Enabled */
#define FCR (volatile unsigned char * const)(2+UART_BASE_ADDRESS)
/* FIFO Control Register (write only) */
#define FIFO_E 0x01 /* FIFO Enable */
#define RFR 0x02 /* RCVR FIFO Reset */
#define XFR 0x04 /* XMIT FIFO Reset */
#define DMAMS 0x08 /* DMA Mode Select */
#define RCVRTG_MASK 0xC0 /* RCVR Triger MSBit/LSBit */
#define LCR (volatile unsigned char * const)(3+UART_BASE_ADDRESS)
/* Line Control Register */
#define WLS_MASK 0x03 /* Word Legth Select Mask */
#define WL_5 0x00 /* 5 bits */
#define WL_6 0x01 /* 6 bits */
#define WL_7 0x02 /* 7 bits */
#define WL_8 0x03 /* 8 bits */
#define NSB 0x04 /* Number of Stop Bits (set is 2/1.5) */
#define PEN 0x08 /* Parity Enable */
#define EPS 0x10 /* Even Parity Select */
#define STP 0x20 /* Stick Parity */
#define SETBK 0x40 /* Set Break */
#define DLAB 0x80 /* Divisor Latch Access Bit */
#define MCR (volatile unsigned char * const)(4+UART_BASE_ADDRESS)
/* Modem Control Register */
#define DTR 0x01 /* Data Terminal Ready */
#define RTS 0x02 /* Request to Send */
#define OUT1 0x04 /* Out 1 */
#define OUT2 0x08 /* Out 2 */
#define LOOP 0x10 /* Loop */
#define LSR (volatile unsigned char * const)(5+UART_BASE_ADDRESS)
/* Line Status Register */
#define DR 0x01 /* Data Ready */
#define OE 0x02 /* Overrun error */
#define PE 0x04 /* Parity error */
#define FE 0x08 /* Framing error */
#define BI 0x10 /* Break Interrupt */
#define THRE 0x20 /* Transmitter Holding Register */
#define TEMT 0x40 /* Transmitter Empty */
#define RCVFIE 0x80 /* Recv FIFO Error */
#define MDSR (volatile unsigned char * const)(6+UART_BASE_ADDRESS)
/* Modem Status Register */
#define DCTS 0x01 /* Delta Clear to Send */
#define DDSR 0x02 /* Delta Data Set Ready */
#define TERI 0x04 /* Trailing Edge Ring Indicator */
#define DDCD 0x08 /* Delta Data Carrier Detect */
#define CTS 0x10 /* Clear to Send */
#define DSR 0x20 /* Data Set Ready */
#define RI 0x40 /* Ring Indicator */
#define DCD 0x80 /* Data Carrier Detect */
#define SCR (volatile unsigned char * const)(7+UART_BASE_ADDRESS)
/* Scratch Register */
/* 8-bit register */
#endif

View File

@@ -1,7 +0,0 @@
#
# $Id$
#
This is a modem driver which should work with limited modifications
on any 16550.

File diff suppressed because it is too large Load Diff

View File

@@ -1,45 +0,0 @@
#ifndef _MODEM_H_
#define _MODEM_H_
void modem_reserve_resources(
rtems_configuration_table * configuration
);
rtems_device_driver modem_initialize(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver modem_open(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver modem_close(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver modem_read(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver modem_write(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
rtems_device_driver modem_control(
rtems_device_major_number,
rtems_device_minor_number,
void *
);
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,7 +0,0 @@
#ifndef __PPP_H__
#define __PPP_H__
#define NPPP 1
#define NBPFILER 0
#define VJC
/*#define PPP_COMPRESS*/
#endif

View File

@@ -1,593 +0,0 @@
/*-
* Copyright (c) 1989 The Regents of the University of California.
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* 3. All advertising materials mentioning features or use of this software
* must display the following acknowledgement:
* This product includes software developed by the University of
* California, Berkeley and its contributors.
* 4. Neither the name of the University nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* @(#)slcompress.c 7.7 (Berkeley) 5/7/91
*/
/*
* Routines to compress and uncompess tcp packets (for transmission
* over low speed serial lines.
*
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
* - Initial distribution.
*
* $Id$
*/
#include <sys/types.h>
#include <sys/param.h>
#include <sys/systm.h>
#include <sys/mbuf.h>
#include <sys/socket.h>
#include <sys/socketvar.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
#include <netinet/tcp.h>
#include <net/pppcompress.h>
#ifndef SL_NO_STATS
#define INCR(counter) ++comp->counter;
#else
#define INCR(counter)
#endif
#define BCMP(p1, p2, n) bcmp((char *)(p1), (char *)(p2), (int)(n))
#define BCOPY(p1, p2, n) bcopy((char *)(p1), (char *)(p2), (int)(n))
#ifndef KERNEL
#define ovbcopy bcopy
#endif
void
vj_compress_init(comp, max_state)
struct vjcompress *comp;
int max_state;
{
register u_int i;
register struct cstate *tstate = comp->tstate;
if ((unsigned) max_state > MAX_STATES - 1)
max_state = MAX_STATES - 1;
bzero((char *)comp, sizeof(*comp));
for (i = max_state; i > 0; --i) {
tstate[i].cs_id = i;
tstate[i].cs_next = &tstate[i - 1];
}
tstate[0].cs_next = &tstate[max_state];
tstate[0].cs_id = 0;
comp->last_cs = &tstate[0];
comp->last_recv = 255;
comp->last_xmit = 255;
comp->flags = SLF_TOSS;
}
/* ENCODE encodes a number that is known to be non-zero. ENCODEZ
* checks for zero (since zero has to be encoded in the long, 3 byte
* form).
*/
#define ENCODE(n) { \
if ((u_short)(n) >= 256) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
cp += 2; \
} else { \
*cp++ = (n); \
} \
}
#define ENCODEZ(n) { \
if ((u_short)(n) >= 256 || (u_short)(n) == 0) { \
*cp++ = 0; \
cp[1] = (n); \
cp[0] = (n) >> 8; \
cp += 2; \
} else { \
*cp++ = (n); \
} \
}
#define DECODEL(f) { \
if (*cp == 0) {\
(f) = htonl(ntohl(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
(f) = htonl(ntohl(f) + (u_long)*cp++); \
} \
}
#define DECODES(f) { \
if (*cp == 0) {\
(f) = htons(ntohs(f) + ((cp[1] << 8) | cp[2])); \
cp += 3; \
} else { \
(f) = htons(ntohs(f) + (u_long)*cp++); \
} \
}
#define DECODEU(f) { \
if (*cp == 0) {\
(f) = htons((cp[1] << 8) | cp[2]); \
cp += 3; \
} else { \
(f) = htons((u_long)*cp++); \
} \
}
u_int
vj_compress_tcp(m, ip, comp, compress_cid)
struct mbuf *m;
register struct ip *ip;
struct vjcompress *comp;
int compress_cid;
{
register struct cstate *cs = comp->last_cs->cs_next;
register u_int hlen = ip->ip_hl;
register struct tcphdr *oth;
register struct tcphdr *th;
register u_int deltaS, deltaA;
register u_int changes = 0;
u_char new_seq[16];
register u_char *cp = new_seq;
/*
* Bail if this is an IP fragment or if the TCP packet isn't
* `compressible' (i.e., ACK isn't set or some other control bit is
* set). (We assume that the caller has already made sure the
* packet is IP proto TCP).
*/
if ((ip->ip_off & htons(0x3fff)) || m->m_len < 40)
return (TYPE_IP);
th = (struct tcphdr *)&((int *)ip)[hlen];
if ((th->th_flags & (TH_SYN|TH_FIN|TH_RST|TH_ACK)) != TH_ACK)
return (TYPE_IP);
/*
* Packet is compressible -- we're going to send either a
* COMPRESSED_TCP or UNCOMPRESSED_TCP packet. Either way we need
* to locate (or create) the connection state. Special case the
* most recently used connection since it's most likely to be used
* again & we don't have to do any reordering if it's used.
*/
INCR(sls_packets)
if (ip->ip_src.s_addr != cs->cs_ip.ip_src.s_addr ||
ip->ip_dst.s_addr != cs->cs_ip.ip_dst.s_addr ||
*(int *)th != ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl]) {
/*
* Wasn't the first -- search for it.
*
* States are kept in a circularly linked list with
* last_cs pointing to the end of the list. The
* list is kept in lru order by moving a state to the
* head of the list whenever it is referenced. Since
* the list is short and, empirically, the connection
* we want is almost always near the front, we locate
* states via linear search. If we don't find a state
* for the datagram, the oldest state is (re-)used.
*/
register struct cstate *lcs;
register struct cstate *lastcs = comp->last_cs;
do {
lcs = cs; cs = cs->cs_next;
INCR(sls_searches)
if (ip->ip_src.s_addr == cs->cs_ip.ip_src.s_addr
&& ip->ip_dst.s_addr == cs->cs_ip.ip_dst.s_addr
&& *(int *)th == ((int *)&cs->cs_ip)[cs->cs_ip.ip_hl])
goto found;
} while (cs != lastcs);
/*
* Didn't find it -- re-use oldest cstate. Send an
* uncompressed packet that tells the other side what
* connection number we're using for this conversation.
* Note that since the state list is circular, the oldest
* state points to the newest and we only need to set
* last_cs to update the lru linkage.
*/
INCR(sls_misses)
comp->last_cs = lcs;
hlen += th->th_off;
hlen <<= 2;
goto uncompressed;
found:
/*
* Found it -- move to the front on the connection list.
*/
if (cs == lastcs)
comp->last_cs = lcs;
else {
lcs->cs_next = cs->cs_next;
cs->cs_next = lastcs->cs_next;
lastcs->cs_next = cs;
}
}
/*
* Make sure that only what we expect to change changed. The first
* line of the `if' checks the IP protocol version, header length &
* type of service. The 2nd line checks the "Don't fragment" bit.
* The 3rd line checks the time-to-live and protocol (the protocol
* check is unnecessary but costless). The 4th line checks the TCP
* header length. The 5th line checks IP options, if any. The 6th
* line checks TCP options, if any. If any of these things are
* different between the previous & current datagram, we send the
* current datagram `uncompressed'.
*/
oth = (struct tcphdr *)&((int *)&cs->cs_ip)[hlen];
deltaS = hlen;
hlen += th->th_off;
hlen <<= 2;
if (((u_short *)ip)[0] != ((u_short *)&cs->cs_ip)[0] ||
((u_short *)ip)[3] != ((u_short *)&cs->cs_ip)[3] ||
((u_short *)ip)[4] != ((u_short *)&cs->cs_ip)[4] ||
th->th_off != oth->th_off ||
(deltaS > 5 &&
BCMP(ip + 1, &cs->cs_ip + 1, (deltaS - 5) << 2)) ||
(th->th_off > 5 &&
BCMP(th + 1, oth + 1, (th->th_off - 5) << 2)))
goto uncompressed;
/*
* Figure out which of the changing fields changed. The
* receiver expects changes in the order: urgent, window,
* ack, seq (the order minimizes the number of temporaries
* needed in this section of code).
*/
if (th->th_flags & TH_URG) {
deltaS = ntohs(th->th_urp);
ENCODEZ(deltaS);
changes |= NEW_U;
} else if (th->th_urp != oth->th_urp)
/* argh! URG not set but urp changed -- a sensible
* implementation should never do this but RFC793
* doesn't prohibit the change so we have to deal
* with it. */
goto uncompressed;
if (deltaS = (u_short)(ntohs(th->th_win) - ntohs(oth->th_win))) {
ENCODE(deltaS);
changes |= NEW_W;
}
if (deltaA = ntohl(th->th_ack) - ntohl(oth->th_ack)) {
if (deltaA > 0xffff)
goto uncompressed;
ENCODE(deltaA);
changes |= NEW_A;
}
if (deltaS = ntohl(th->th_seq) - ntohl(oth->th_seq)) {
if (deltaS > 0xffff)
goto uncompressed;
ENCODE(deltaS);
changes |= NEW_S;
}
switch(changes) {
case 0:
/*
* Nothing changed. If this packet contains data and the
* last one didn't, this is probably a data packet following
* an ack (normal on an interactive connection) and we send
* it compressed. Otherwise it's probably a retransmit,
* retransmitted ack or window probe. Send it uncompressed
* in case the other side missed the compressed version.
*/
if (ip->ip_len != cs->cs_ip.ip_len &&
ntohs(cs->cs_ip.ip_len) == hlen)
break;
/* (fall through) */
case SPECIAL_I:
case SPECIAL_D:
/*
* actual changes match one of our special case encodings --
* send packet uncompressed.
*/
goto uncompressed;
case NEW_S|NEW_A:
if (deltaS == deltaA &&
deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
/* special case for echoed terminal traffic */
changes = SPECIAL_I;
cp = new_seq;
}
break;
case NEW_S:
if (deltaS == ntohs(cs->cs_ip.ip_len) - hlen) {
/* special case for data xfer */
changes = SPECIAL_D;
cp = new_seq;
}
break;
}
deltaS = ntohs(ip->ip_id) - ntohs(cs->cs_ip.ip_id);
if (deltaS != 1) {
ENCODEZ(deltaS);
changes |= NEW_I;
}
if (th->th_flags & TH_PUSH)
changes |= TCP_PUSH_BIT;
/*
* Grab the cksum before we overwrite it below. Then update our
* state with this packet's header.
*/
deltaA = ntohs(th->th_sum);
BCOPY(ip, &cs->cs_ip, hlen);
/*
* We want to use the original packet as our compressed packet.
* (cp - new_seq) is the number of bytes we need for compressed
* sequence numbers. In addition we need one byte for the change
* mask, one for the connection id and two for the tcp checksum.
* So, (cp - new_seq) + 4 bytes of header are needed. hlen is how
* many bytes of the original packet to toss so subtract the two to
* get the new packet size.
*/
deltaS = cp - new_seq;
cp = (u_char *)ip;
if (compress_cid == 0 || comp->last_xmit != cs->cs_id) {
comp->last_xmit = cs->cs_id;
hlen -= deltaS + 4;
cp += hlen;
*cp++ = changes | NEW_C;
*cp++ = cs->cs_id;
} else {
hlen -= deltaS + 3;
cp += hlen;
*cp++ = changes;
}
m->m_len -= hlen;
m->m_data += hlen;
*cp++ = deltaA >> 8;
*cp++ = deltaA;
BCOPY(new_seq, cp, deltaS);
INCR(sls_compressed)
return (TYPE_COMPRESSED_TCP);
/*
* Update connection state cs & send uncompressed packet ('uncompressed'
* means a regular ip/tcp packet but with the 'conversation id' we hope
* to use on future compressed packets in the protocol field).
*/
uncompressed:
BCOPY(ip, &cs->cs_ip, hlen);
ip->ip_p = cs->cs_id;
comp->last_xmit = cs->cs_id;
return (TYPE_UNCOMPRESSED_TCP);
}
int
vj_uncompress_tcp(bufp, len, type, comp)
u_char **bufp;
int len;
u_int type;
struct vjcompress *comp;
{
u_char *hdr, *cp;
int hlen, vjlen;
cp = bufp? *bufp: NULL;
vjlen = vj_uncompress_tcp_core(cp, len, len, type, comp, &hdr, &hlen);
if (vjlen < 0)
return (0); /* error */
if (vjlen == 0)
return (len); /* was uncompressed already */
cp += vjlen;
len -= vjlen;
/*
* At this point, cp points to the first byte of data in the
* packet. If we're not aligned on a 4-byte boundary, copy the
* data down so the ip & tcp headers will be aligned. Then back up
* cp by the tcp/ip header length to make room for the reconstructed
* header (we assume the packet we were handed has enough space to
* prepend 128 bytes of header).
*/
if ((int)cp & 3) {
if (len > 0)
(void) ovbcopy(cp, (caddr_t)((int)cp &~ 3), len);
cp = (u_char *)((int)cp &~ 3);
}
cp -= hlen;
len += hlen;
BCOPY(hdr, cp, hlen);
*bufp = cp;
return (len);
}
/*
* Uncompress a packet of total length total_len. The first buflen
* bytes are at buf; this must include the entire (compressed or
* uncompressed) TCP/IP header. This procedure returns the length
* of the VJ header, with a pointer to the uncompressed IP header
* in *hdrp and its length in *hlenp.
*/
int
vj_uncompress_tcp_core(buf, buflen, total_len, type, comp, hdrp, hlenp)
u_char *buf;
int buflen, total_len;
u_int type;
struct vjcompress *comp;
u_char **hdrp;
u_int *hlenp;
{
register u_char *cp;
register u_int hlen, changes;
register struct tcphdr *th;
register struct cstate *cs;
register struct ip *ip;
register u_short *bp;
register u_int vjlen;
switch (type) {
case TYPE_UNCOMPRESSED_TCP:
ip = (struct ip *) buf;
if (ip->ip_p >= MAX_STATES)
goto bad;
cs = &comp->rstate[comp->last_recv = ip->ip_p];
comp->flags &=~ SLF_TOSS;
ip->ip_p = IPPROTO_TCP;
/*
* Calculate the size of the TCP/IP header and make sure that
* we don't overflow the space we have available for it.
*/
hlen = ip->ip_hl << 2;
if (hlen + sizeof(struct tcphdr) > buflen)
goto bad;
hlen += ((struct tcphdr *)&((char *)ip)[hlen])->th_off << 2;
if (hlen > MAX_HDR || hlen > buflen)
goto bad;
BCOPY(ip, &cs->cs_ip, hlen);
cs->cs_hlen = hlen;
INCR(sls_uncompressedin)
*hdrp = (u_char *) &cs->cs_ip;
*hlenp = hlen;
return (0);
default:
goto bad;
case TYPE_COMPRESSED_TCP:
break;
}
/* We've got a compressed packet. */
INCR(sls_compressedin)
cp = buf;
changes = *cp++;
if (changes & NEW_C) {
/* Make sure the state index is in range, then grab the state.
* If we have a good state index, clear the 'discard' flag. */
if (*cp >= MAX_STATES)
goto bad;
comp->flags &=~ SLF_TOSS;
comp->last_recv = *cp++;
} else {
/* this packet has an implicit state index. If we've
* had a line error since the last time we got an
* explicit state index, we have to toss the packet. */
if (comp->flags & SLF_TOSS) {
INCR(sls_tossed)
return (-1);
}
}
cs = &comp->rstate[comp->last_recv];
hlen = cs->cs_ip.ip_hl << 2;
th = (struct tcphdr *)&((u_char *)&cs->cs_ip)[hlen];
th->th_sum = htons((*cp << 8) | cp[1]);
cp += 2;
if (changes & TCP_PUSH_BIT)
th->th_flags |= TH_PUSH;
else
th->th_flags &=~ TH_PUSH;
switch (changes & SPECIALS_MASK) {
case SPECIAL_I:
{
register u_int i = ntohs(cs->cs_ip.ip_len) - cs->cs_hlen;
th->th_ack = htonl(ntohl(th->th_ack) + i);
th->th_seq = htonl(ntohl(th->th_seq) + i);
}
break;
case SPECIAL_D:
th->th_seq = htonl(ntohl(th->th_seq) + ntohs(cs->cs_ip.ip_len)
- cs->cs_hlen);
break;
default:
if (changes & NEW_U) {
th->th_flags |= TH_URG;
DECODEU(th->th_urp)
} else
th->th_flags &=~ TH_URG;
if (changes & NEW_W)
DECODES(th->th_win)
if (changes & NEW_A)
DECODEL(th->th_ack)
if (changes & NEW_S)
DECODEL(th->th_seq)
break;
}
if (changes & NEW_I) {
DECODES(cs->cs_ip.ip_id)
} else
cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1);
/*
* At this point, cp points to the first byte of data in the
* packet. Fill in the IP total length and update the IP
* header checksum.
*/
vjlen = cp - buf;
buflen -= vjlen;
if (buflen < 0)
/* we must have dropped some characters (crc should detect
* this but the old slip framing won't) */
goto bad;
total_len += cs->cs_hlen - vjlen;
cs->cs_ip.ip_len = htons(total_len);
/* recompute the ip header checksum */
bp = (u_short *) &cs->cs_ip;
cs->cs_ip.ip_sum = 0;
for (changes = 0; hlen > 0; hlen -= 2)
changes += *bp++;
changes = (changes & 0xffff) + (changes >> 16);
changes = (changes & 0xffff) + (changes >> 16);
cs->cs_ip.ip_sum = ~ changes;
*hdrp = (u_char *) &cs->cs_ip;
*hlenp = cs->cs_hlen;
return vjlen;
bad:
comp->flags |= SLF_TOSS;
INCR(sls_errorin)
return (-1);
}

View File

@@ -589,6 +589,8 @@ extern void (*auth_linkdown_hook) __P((void));
#define DEBUGCHAP 1
#endif
#define DEBUGMAIN 1
#define DEBUGUPAP 1
#define DEBUGCHAP 1
#ifdef DEBUGMAIN

View File

@@ -107,8 +107,6 @@ int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
static int waiting;
char **script_env; /* Env. variable values for scripts */
int s_env_nalloc; /* # words avail at script_env */
@@ -234,8 +232,6 @@ pppdmain(argc, argv)
setlogmask(LOG_UPTO(LOG_DEBUG));
*/
waiting = 0;
do_callback = 0;
for (;;) {
@@ -400,12 +396,10 @@ pppdmain(argc, argv)
status = EXIT_NEGOTIATION_FAILED;
new_phase(PHASE_ESTABLISH);
while (phase != PHASE_DEAD) {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
get_input();
if (kill_link) {
lcp_close(0, "User request");
kill_link = 0;
@@ -469,9 +463,7 @@ pppdmain(argc, argv)
new_phase(PHASE_HOLDOFF);
TIMEOUT(holdoff_end, NULL, t);
do {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
if (kill_link) {

View File

@@ -1,3 +1,14 @@
2001-10-12 Mike Siers <mikes@poliac.com>
* Update to stable working state. Congratulations Mike! :)
* modem_example: Directory removed.
* modem_example/16550.h, modem_example/README, modem_example/modem.c,
modem_example/modem.h, modem_example/ppp.c, modem_example/ppp.h,
modem_example/pppcompress.c: Files removed.
* pppd/example/pppd.options: New file.
* pppd/README, pppd/STATUS, pppd/cbcp.c, pppd/cbcp.h, pppd/chat.c,
pppd/pppd.h, pppd/rtemsmain.c: Updated.
2001-10-11 Ralf Corsepius <corsepiu@faw.uni-ulm.de>
* .cvsignore: Add autom4te.cache for autoconf > 2.52.

View File

@@ -16,5 +16,9 @@ provided the modem driver as well.
The port was updated to 2.3.11 by Mike Siers <mikes@poliac.com>
who added an example test.
Updated the chat program to return the correct errors and support
the ABORT commands. Removed some dead code and did a lot of
testing on a new Coldfire BSP. Version seems to be very stable.
=================================================================

View File

@@ -2,39 +2,28 @@
# $Id$
#
The pppd application seems to very stable. It has been tested using
the example application with the i386/pc586 and m68k/sbc5206e BSPs.
The tests were executed using a null modem serial cable to connect
with a UNIX box running either the ppp or pppd application and with
an external modem to dial up a local ISP.
Notes from Mike Siers <mikes@poliac.com>
========================================
If you have problems getting your target to make consistent connections
with an ISP, the problem is most likely with the ppp options. First
try using the "novj" and "noaccomp" options. If you have questions
about what other option values are available for the rtems_pppd_set_option
function, please look at the pppd.8 man page file or the the source code.
The majority of options that are documented in man page should work
with this function call.
I know that several users have tried out this version of
pppd under RTEMS. It has been successfully used as both
a client and server. Below are the only issues that I
know of.
The pppd application requires the BSP termios driver support task
driven I/O. Below is a list of known issues that need to be resolved:
1) Large packet ping causes RTEMS box to lock up
If you ping the RTEMS box over the ppp link with a packet
size greater than 1500, the RTEMS box locks up. I think
the problem is in the pppd ethernet driver.
- pppd locks up when it receives large packet pings (> 1500 bytes)
- pppd occasionaly locks up with mbuf allocation error
(problem is rare and may be BSP related)
2) Upgrade the libnetworking/modem files
This upgrade did not modify the ppp ethernet driver files
in the libnetworking/modem directory. Would like to
upgrade these files. Hopefully, it will fix the large
packet ping problem.
3) The files cbcp.c and cbcp.h provide a callback feature
that I have not tried to compile or use. The files in
this directory are identical to the 2.3.11 versions.
for completeness.
JOEL: Are the modifications to the original pppd such that the
real maintainers will accept them?
No. The pppd 2.3.11 branch is an old branch. The current
version is 2.4.x and it contains alot of extra items that
just did not make sense to have in an embedded environment.
I could make the RTEMS changes compatible with the standard
2.3.11 release by using compilation flags. I have not
contacted the maintainers to see if they are interested.
If you find any other problems or fix some problems, please post your
changes to the RTEMS mailing list.
Good Luck

View File

@@ -0,0 +1,456 @@
/*
* cbcp - Call Back Configuration Protocol.
*
* Copyright (c) 1995 Pedro Roque Marques
* 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 Pedro Roque Marques. The name of the author 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.
*/
#define RCSID "$Id$"
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/time.h>
#include "pppd.h"
#include "cbcp.h"
#include "fsm.h"
#include "lcp.h"
static const char rcsid[] = RCSID;
/*
* Options.
*/
static int setcbcp __P((char **));
static option_t cbcp_option_list[] = {
{ "callback", o_special, setcbcp,
"Ask for callback" },
{ NULL }
};
/*
* Protocol entry points.
*/
static void cbcp_init __P((int unit));
static void cbcp_open __P((int unit));
static void cbcp_lowerup __P((int unit));
static void cbcp_input __P((int unit, u_char *pkt, int len));
static void cbcp_protrej __P((int unit));
static int cbcp_printpkt __P((u_char *pkt, int len,
void (*printer) __P((void *, char *, ...)),
void *arg));
struct protent cbcp_protent = {
PPP_CBCP,
cbcp_init,
cbcp_input,
cbcp_protrej,
cbcp_lowerup,
NULL,
cbcp_open,
NULL,
cbcp_printpkt,
NULL,
0,
"CBCP",
NULL,
cbcp_option_list,
NULL,
NULL,
NULL
};
cbcp_state cbcp[NUM_PPP];
/* internal prototypes */
static void cbcp_recvreq __P((cbcp_state *us, char *pckt, int len));
static void cbcp_resp __P((cbcp_state *us));
static void cbcp_up __P((cbcp_state *us));
static void cbcp_recvack __P((cbcp_state *us, char *pckt, int len));
static void cbcp_send __P((cbcp_state *us, u_char code, u_char *buf, int len));
/* option processing */
static int
setcbcp(argv)
char **argv;
{
lcp_wantoptions[0].neg_cbcp = 1;
cbcp_protent.enabled_flag = 1;
cbcp[0].us_number = strdup(*argv);
if (cbcp[0].us_number == 0)
novm("callback number");
cbcp[0].us_type |= (1 << CB_CONF_USER);
cbcp[0].us_type |= (1 << CB_CONF_ADMIN);
return (1);
}
/* init state */
static void
cbcp_init(iface)
int iface;
{
cbcp_state *us;
us = &cbcp[iface];
memset(us, 0, sizeof(cbcp_state));
us->us_unit = iface;
us->us_type |= (1 << CB_CONF_NO);
}
/* lower layer is up */
static void
cbcp_lowerup(iface)
int iface;
{
cbcp_state *us = &cbcp[iface];
dbglog("cbcp_lowerup");
dbglog("want: %d", us->us_type);
if (us->us_type == CB_CONF_USER)
dbglog("phone no: %s", us->us_number);
}
static void
cbcp_open(unit)
int unit;
{
dbglog("cbcp_open");
}
/* process an incomming packet */
static void
cbcp_input(unit, inpacket, pktlen)
int unit;
u_char *inpacket;
int pktlen;
{
u_char *inp;
u_char code, id;
u_short len;
cbcp_state *us = &cbcp[unit];
inp = inpacket;
if (pktlen < CBCP_MINLEN) {
error("CBCP packet is too small");
return;
}
GETCHAR(code, inp);
GETCHAR(id, inp);
GETSHORT(len, inp);
#if 0
if (len > pktlen) {
error("CBCP packet: invalid length");
return;
}
#endif
len -= CBCP_MINLEN;
switch(code) {
case CBCP_REQ:
us->us_id = id;
cbcp_recvreq(us, inp, len);
break;
case CBCP_RESP:
dbglog("CBCP_RESP received");
break;
case CBCP_ACK:
if (id != us->us_id)
dbglog("id doesn't match: expected %d recv %d",
us->us_id, id);
cbcp_recvack(us, inp, len);
break;
default:
break;
}
}
/* protocol was rejected by foe */
void cbcp_protrej(int iface)
{
}
char *cbcp_codenames[] = {
"Request", "Response", "Ack"
};
char *cbcp_optionnames[] = {
"NoCallback",
"UserDefined",
"AdminDefined",
"List"
};
/* pretty print a packet */
static int
cbcp_printpkt(p, plen, printer, arg)
u_char *p;
int plen;
void (*printer) __P((void *, char *, ...));
void *arg;
{
int code, opt, id, len, olen, delay;
u_char *pstart;
if (plen < HEADERLEN)
return 0;
pstart = p;
GETCHAR(code, p);
GETCHAR(id, p);
GETSHORT(len, p);
if (len < HEADERLEN || len > plen)
return 0;
if (code >= 1 && code <= sizeof(cbcp_codenames) / sizeof(char *))
printer(arg, " %s", cbcp_codenames[code-1]);
else
printer(arg, " code=0x%x", code);
printer(arg, " id=0x%x", id);
len -= HEADERLEN;
switch (code) {
case CBCP_REQ:
case CBCP_RESP:
case CBCP_ACK:
while(len >= 2) {
GETCHAR(opt, p);
GETCHAR(olen, p);
if (olen < 2 || olen > len) {
break;
}
printer(arg, " <");
len -= olen;
if (opt >= 1 && opt <= sizeof(cbcp_optionnames) / sizeof(char *))
printer(arg, " %s", cbcp_optionnames[opt-1]);
else
printer(arg, " option=0x%x", opt);
if (olen > 2) {
GETCHAR(delay, p);
printer(arg, " delay = %d", delay);
}
if (olen > 3) {
int addrt;
char str[256];
GETCHAR(addrt, p);
memcpy(str, p, olen - 4);
str[olen - 4] = 0;
printer(arg, " number = %s", str);
}
printer(arg, ">");
break;
}
default:
break;
}
for (; len > 0; --len) {
GETCHAR(code, p);
printer(arg, " %.2x", code);
}
return p - pstart;
}
/* received CBCP request */
static void
cbcp_recvreq(us, pckt, pcktlen)
cbcp_state *us;
char *pckt;
int pcktlen;
{
u_char type, opt_len, delay, addr_type;
char address[256];
int len = pcktlen;
address[0] = 0;
while (len) {
dbglog("length: %d", len);
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
us->us_allowed |= (1 << type);
switch(type) {
case CB_CONF_NO:
dbglog("no callback allowed");
break;
case CB_CONF_USER:
dbglog("user callback allowed");
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("address: %s", address);
}
break;
case CB_CONF_ADMIN:
dbglog("user admin defined allowed");
break;
case CB_CONF_LIST:
break;
}
len -= opt_len;
}
cbcp_resp(us);
}
static void
cbcp_resp(us)
cbcp_state *us;
{
u_char cb_type;
u_char buf[256];
u_char *bufp = buf;
int len = 0;
cb_type = us->us_allowed & us->us_type;
dbglog("cbcp_resp cb_type=%d", cb_type);
#if 0
if (!cb_type)
lcp_down(us->us_unit);
#endif
if (cb_type & ( 1 << CB_CONF_USER ) ) {
dbglog("cbcp_resp CONF_USER");
PUTCHAR(CB_CONF_USER, bufp);
len = 3 + 1 + strlen(us->us_number) + 1;
PUTCHAR(len , bufp);
PUTCHAR(5, bufp); /* delay */
PUTCHAR(1, bufp);
BCOPY(us->us_number, bufp, strlen(us->us_number) + 1);
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_ADMIN ) ) {
dbglog("cbcp_resp CONF_ADMIN");
PUTCHAR(CB_CONF_ADMIN, bufp);
len = 3;
PUTCHAR(len, bufp);
PUTCHAR(5, bufp); /* delay */
cbcp_send(us, CBCP_RESP, buf, len);
return;
}
if (cb_type & ( 1 << CB_CONF_NO ) ) {
dbglog("cbcp_resp CONF_NO");
PUTCHAR(CB_CONF_NO, bufp);
len = 3;
PUTCHAR(len , bufp);
PUTCHAR(0, bufp);
cbcp_send(us, CBCP_RESP, buf, len);
start_networks();
return;
}
}
static void
cbcp_send(us, code, buf, len)
cbcp_state *us;
u_char code;
u_char *buf;
int len;
{
u_char *outp;
int outlen;
outp = outpacket_buf;
outlen = 4 + len;
MAKEHEADER(outp, PPP_CBCP);
PUTCHAR(code, outp);
PUTCHAR(us->us_id, outp);
PUTSHORT(outlen, outp);
if (len)
BCOPY(buf, outp, len);
output(us->us_unit, outpacket_buf, outlen + PPP_HDRLEN);
}
static void
cbcp_recvack(us, pckt, len)
cbcp_state *us;
char *pckt;
int len;
{
u_char type, delay, addr_type;
int opt_len;
char address[256];
if (len) {
GETCHAR(type, pckt);
GETCHAR(opt_len, pckt);
if (opt_len > 2)
GETCHAR(delay, pckt);
if (opt_len > 4) {
GETCHAR(addr_type, pckt);
memcpy(address, pckt, opt_len - 4);
address[opt_len - 4] = 0;
if (address[0])
dbglog("peer will call: %s", address);
}
if (type == CB_CONF_NO)
return;
}
cbcp_up(us);
}
/* ok peer will do callback */
static void
cbcp_up(us)
cbcp_state *us;
{
persist = 0;
lcp_close(0, "Call me back, please");
status = EXIT_CALLBACK;
}

View File

@@ -0,0 +1,26 @@
#ifndef CBCP_H
#define CBCP_H
typedef struct cbcp_state {
int us_unit; /* Interface unit number */
u_char us_id; /* Current id */
u_char us_allowed;
int us_type;
char *us_number; /* Telefone Number */
} cbcp_state;
extern cbcp_state cbcp[];
extern struct protent cbcp_protent;
#define CBCP_MINLEN 4
#define CBCP_REQ 1
#define CBCP_RESP 2
#define CBCP_ACK 3
#define CB_CONF_NO 1
#define CB_CONF_USER 2
#define CB_CONF_ADMIN 3
#define CB_CONF_LIST 4
#endif

View File

@@ -14,6 +14,12 @@
* This software is in the public domain.
*
* -----------------
* 22-May-99 added environment substitutuion, enabled with -E switch.
* Andreas Arens <andras@cityweb.de>.
*
* 12-May-99 added a feature to read data to be sent from a file,
* if the send string starts with @. Idea from gpk <gpk@onramp.net>.
*
* added -T and -U option and \T and \U substitution to pass a phone
* number into chat script. Two are needed for some ISDN TA applications.
* Keith Dart <kdart@cisco.com>
@@ -74,18 +80,12 @@
* Columbus, OH 43221
* (614)451-1883
*
*
*/
#ifndef lint
/* static char rcsid[] = ""; */
#endif
#include <stdio.h>
#include <ctype.h>
#include <time.h>
#include <fcntl.h>
#include <signal.h>
#include <errno.h>
#include <string.h>
#include <stdlib.h>
@@ -93,13 +93,13 @@
#include <sys/types.h>
#include <sys/stat.h>
#include <syslog.h>
#include <termios.h>
#include "pppd.h"
#undef TERMIOS
#define TERMIOS
#include <termios.h>
#define STR_LEN 1024
char temp2[STR_LEN];
@@ -142,39 +142,34 @@ static int _O = 0; /* Internal state */
char *program_name;
#define MAX_ABORTS 5
#define MAX_REPORTS 5
#define MAX_ABORTS 16
#define MAX_REPORTS 16
#define DEFAULT_CHAT_TIMEOUT 45
#define fcntl(a, b,c ) 0
#define MAX_TIMEOUTS 10
int echo = 0;
int verbose = 0;
int to_log = 1;
int to_stderr = 0;
int Verbose = 0;
int quiet = 0;
int report = 0;
int use_env = 0;
int exit_code = 0;
char *report_file = (char *) 0;
char *chat_file = (char *) 0;
char *phone_num = (char *) 0;
char *phone_num2 = (char *) 0;
int chat_timeout = DEFAULT_CHAT_TIMEOUT;
static int timeout = DEFAULT_CHAT_TIMEOUT;
int have_tty_parameters = 0;
#ifdef TERMIOS
#define term_parms struct termios
#define get_term_param(param) tcgetattr(ttyfd, param)
#define set_term_param(param) tcsetattr(ttyfd, TCSANOW, param)
#define get_term_param(param) tcgetattr(0, param)
#define set_term_param(param) tcsetattr(0, TCSANOW, param)
struct termios saved_tty_parameters;
#endif
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ASWER","RINGING\r\n\r\nRINGING"};
char *fail_reason = (char *)0,
fail_buffer[50];
int n_aborts = MAX_ABORTS, abort_next = 0, timeout_next = 0, echo_next = 0;
char *fail_reason = (char *)0;
char fail_buffer[50];
char *abort_string[MAX_ABORTS]={"BUSY","NO DIALTONE","NO CARRIER","NO ANSWER","RING\r\nRING"};
int n_aborts = 5;
int abort_next = 0, timeout_next = 0, echo_next = 0;
int clear_abort_next = 0;
char *report_string[MAX_REPORTS] ;
@@ -186,19 +181,7 @@ int say_next = 0, hup_next = 0;
void *dup_mem __P((void *b, size_t c));
void *copy_of __P((char *s));
/*
SIGTYPE sigalrm __P((int signo));
SIGTYPE sigint __P((int signo));
SIGTYPE sigterm __P((int signo));
SIGTYPE sighup __P((int signo));
*/
void unalarm __P((void));
void init __P((void));
void set_tty_parameters __P((void));
void echo_stderr __P((int));
void break_sequence __P((void));
void terminate __P((int status));
void do_file __P((char *chat_file));
int get_string __P((register char *string));
int put_string __P((register char *s));
int write_char __P((int c));
@@ -208,19 +191,9 @@ void chat_send __P((register char *s));
char *character __P((int c));
void chat_expect __P((register char *s));
char *clean __P((register char *s, int sending));
void break_sequence __P((void));
void terminate __P((int status));
void pack_array __P((char **array, int end));
char *expect_strtok __P((char *, char *));
int vfmtmsg __P((char *, int, const char *, va_list)); /* vsprintf++ */
int chatmain __P((char *));
#if 0
int usleep( long usec ); /* returns 0 if ok, else -1 */
#endif
extern int input_fd,output_fd;
int main __P((int, char *[]));
void *dup_mem(b, c)
void *b;
@@ -240,17 +213,10 @@ char *s;
return dup_mem(s, strlen (s) + 1);
}
/*
* chat [ -v ] [-T number] [-U number] [ -t timeout ] [ -f chat-file ] \
* [ -r report-file ] \
* [...[[expect[-say[-expect...]] say expect[-say[-expect]] ...]]]
*
* Perform a UUCP-dialer-like chat script on stdin and stdout.
*/
char *getnextcommand(char **string)
{
char *buf=*string,*res;
res=strchr(buf,'@');
res=strchr(buf,'|');
if (res==NULL)
return NULL;
*res='\0';
@@ -258,8 +224,6 @@ char *getnextcommand(char **string)
return buf;
}
extern int ttyfd;
int chatmain(argv)
char *argv;
{
@@ -268,14 +232,16 @@ char *argv;
/* initialize exit code */
exit_code = 0;
printf("chat_main: %s\n", argv);
if ( debug ) {
dbglog("chat_main: %s\n", argv);
}
/* get first expect string */
arg = getnextcommand(&argv);
while ( arg != NULL ) {
while (( arg != NULL ) && ( exit_code == 0 )) {
/* process the expect string */
chat_expect(arg);
if ( exit_code == 0 ) {
/* get the next send string */
arg = getnextcommand(&argv);
if ( arg != NULL ) {
@@ -286,60 +252,20 @@ printf("chat_main: %s\n", argv);
arg = getnextcommand(&argv);
}
}
return 0;
}
/*
* Print an error message and terminate.
*/
void init()
{
set_tty_parameters();
if ( exit_code ) {
exit_code = -exit_code;
}
void set_tty_parameters()
{
term_parms t;
if (get_term_param (&t) < 0)
syslog(LOG_NOTICE,"Can't get terminal parameters:")
;
saved_tty_parameters = t;
have_tty_parameters = 1;
t.c_iflag |= IGNBRK | ISTRIP | IGNPAR;
t.c_oflag = 0;
t.c_lflag = 0;
t.c_cc[VERASE] =
t.c_cc[VKILL] = 0;
t.c_cc[VMIN] = 0;
t.c_cc[VTIME] = 1;
if (set_term_param (&t) < 0)
syslog(LOG_NOTICE,"Can't set terminal parameters:")
;
return ( exit_code );
}
void break_sequence()
{
/* tcsendbreak (0, 0);*/
tcsendbreak(ttyfd, 0);
}
/*void terminate(status)
int status;
{
echo_stderr(-1);
if (have_tty_parameters) {
if (set_term_param (&saved_tty_parameters) < 0)
fatal(2, "Can't restore terminal parameters: %m");
}
}
*/
/*
* 'Clean up' this string.
*/
@@ -347,10 +273,14 @@ char *clean(s, sending)
register char *s;
int sending; /* set to 1 when sending (putting) this string. */
{
char temp[STR_LEN], cur_chr;
char temp[STR_LEN], env_str[STR_LEN], cur_chr;
register char *s1, *phchar;
int add_return = sending;
#define isoctal(chr) (((chr) >= '0') && ((chr) <= '7'))
#define isalnumx(chr) ((((chr) >= '0') && ((chr) <= '9')) \
|| (((chr) >= 'a') && ((chr) <= 'z')) \
|| (((chr) >= 'A') && ((chr) <= 'Z')) \
|| (chr) == '_')
s1 = temp;
while (*s) {
@@ -368,6 +298,18 @@ int sending; /* set to 1 when sending (putting) this string. */
continue;
}
if (use_env && cur_chr == '$') { /* ARI */
phchar = env_str;
while (isalnumx(*s))
*phchar++ = *s++;
*phchar = '\0';
phchar = getenv(env_str);
if (phchar)
while (*phchar)
*s1++ = *phchar++;
continue;
}
if (cur_chr != '\\') {
*s1++ = cur_chr;
continue;
@@ -400,7 +342,6 @@ int sending; /* set to 1 when sending (putting) this string. */
case 'd':
if (sending)
*s1++ = '\\';
*s1++ = cur_chr;
break;
@@ -455,6 +396,13 @@ int sending; /* set to 1 when sending (putting) this string. */
*s1++ = 'N';
break;
case '$': /* ARI */
if (use_env) {
*s1++ = cur_chr;
break;
}
/* FALL THROUGH */
default:
if (isoctal (cur_chr)) {
cur_chr &= 0x07;
@@ -493,7 +441,6 @@ int sending; /* set to 1 when sending (putting) this string. */
/*
* A modified version of 'strtok'. This version skips \ sequences.
*/
char *expect_strtok (s, term)
char *s, *term;
{
@@ -548,7 +495,6 @@ char *expect_strtok (s, term)
/*
* Process the expect string
*/
void chat_expect (s)
char *s;
{
@@ -622,11 +568,30 @@ char *s;
chat_send (reply);
}
}
/*
* The expectation did not occur. This is terminal.
* Translate the input character to the appropriate string for printing
* the data.
*/
return ;
char *character(c)
int c;
{
static char string[10];
char *meta;
meta = (c & 0x80) ? "M-" : "";
c &= 0x7F;
if (c < 32)
sprintf(string, "%s^%c", meta, (int)c + '@');
else if (c == 127)
sprintf(string, "%s^?", meta);
else
sprintf(string, "%s%c", meta, c);
return (string);
}
/*
@@ -635,16 +600,19 @@ char *s;
void chat_send (s)
register char *s;
{
char file_data[STR_LEN];
if (say_next) {
say_next = 0;
s = clean(s,0);
write(ttyfd, s, strlen(s));
s = clean(s, 1);
write(2, s, strlen(s));
free(s);
return;
}
if (hup_next) {
hup_next = 0;
return;
}
if (echo_next) {
@@ -654,35 +622,52 @@ register char *s;
}
if (abort_next) {
/* char *s1; */
char *s1;
abort_next = 0;
if ( n_aborts < MAX_ABORTS ) {
s1 = clean(s, 0);
if (( strlen(s1) <= strlen(s) ) &&
( strlen(s1) < sizeof(fail_buffer))) {
;
abort_string[n_aborts++] = s1;
}
}
return;
}
if (clear_abort_next) {
clear_abort_next = 0;
return;
}
if (report_next) {
report_next = 0;
return;
}
if (clear_report_next) {
clear_report_next = 0;
return;
}
if (timeout_next) {
timeout=atoi(s);
timeout_next = 0;
chat_timeout = atoi(s);
if (chat_timeout <= 0)
chat_timeout = DEFAULT_CHAT_TIMEOUT;
timeout = atoi(s);
if (timeout <= 0)
timeout = DEFAULT_CHAT_TIMEOUT;
return;
}
if (strcmp(s, "EOT") == 0)
s = "^D\\c";
else if (strcmp(s, "BREAK") == 0)
s = "\\K\\c";
if (!put_string(s))
{
exit_code=1;
return;
if (!put_string(s)) {
exit_code = 2;
}
}
@@ -708,21 +693,10 @@ int get_char()
int put_char(c)
int c;
{
int status;
char ch = c;
/* inter-character typing delay (?) */
write(ttyfd, &ch, 1);
status = write(ttyfd, &ch, 1);
switch (status) {
case 1:
return (0);
default:
}
return 0;
}
@@ -774,44 +748,12 @@ register char *s;
}
}
/* alarm(0);*/
return (1);
}
/*
* Echo a character to stderr.
* When called with -1, a '\n' character is generated when
* the cursor is not at the beginning of a line.
*/
void echo_stderr(n)
int n;
{
/* static int need_lf;
char *s;
switch (n) {
case '\r':
break;
case -1:
if (need_lf == 0)
break;
case '\n':
write(2, "\n", 1);
need_lf = 0;
break;
default:
s = character(n);
write(2, s, strlen(s));
need_lf = 1;
break;
}*/
}
/*
* 'Wait for' this string to appear on this file descriptor.
*/
int get_string(string)
register char *string;
{
@@ -820,6 +762,8 @@ register char *string;
char *logged = temp2;
struct termios tios;
memset(temp2, 0, sizeof(temp2));
tcgetattr(ttyfd, &tios);
tios.c_cc[VMIN] = 0;
tios.c_cc[VTIME] = timeout*10/MAX_TIMEOUTS;
@@ -838,7 +782,6 @@ register char *string;
return (1);
}
while ( (c = get_char()) >= 0) {
int n, abort_len;
@@ -871,60 +814,7 @@ register char *string;
s = temp2 + minlen;
}
}
exit_code = 3;
return (0);
}
/*
* Gross kludge to handle Solaris versions >= 2.6 having usleep.
*/
/*
usleep -- support routine for 4.2BSD system call emulations
last edit: 29-Oct-1984 D A Gwyn
*/
#if 0
int
usleep( usec ) /* returns 0 if ok, else -1 */
long usec; /* delay in microseconds */
{
rtems_status_code status;
rtems_interval ticks_per_second;
rtems_interval ticks;
status = rtems_clock_get(
RTEMS_CLOCK_GET_TICKS_PER_SECOND,
&ticks_per_second);
ticks = (usec * (ticks_per_second/1000))/1000;
status = rtems_task_wake_after( ticks );
return 0;
}
#endif
void pack_array (array, end)
char **array; /* The address of the array of string pointers */
int end; /* The index of the next free entry before CLR_ */
{
int i, j;
for (i = 0; i < end; i++) {
if (array[i] == NULL) {
for (j = i+1; j < end; ++j)
if (array[j] != NULL)
array[i++] = array[j];
for (; i < end; ++i)
array[i] = NULL;
break;
}
}
}
/*
* vfmtmsg - format a message into a buffer. Like vsprintf except we
* also specify the length of the output buffer, and we handle the
* %m (error message) format.
* Doesn't do floating-point formats.
* Returns the number of chars put into buf.
*/
#define OUTCHAR(c) (buflen > 0? (--buflen, *buf++ = (c)): 0)

View File

@@ -6,3 +6,10 @@ This is an example user application using pppd. It is built using
the RTEMS application Makefiles. The file Makefile-user should
be renamed to Makefile or the -f option given to make. The file
is renamed to avoid bootstrap -c removing it.
The files ppp.conf and pppd.options are sample configuration files
that have successfully used to make ppp connections over a null
modem serial cable to a UNIX box. Please review the man pages
for either the ppp or pppd applications to ensure they are configured
correctly.

View File

@@ -0,0 +1,9 @@
/dev/tty00
57600
crtscts
passive
local
noauth
debug
persist
192.168.2.222:192.168.2.111

View File

@@ -589,6 +589,8 @@ extern void (*auth_linkdown_hook) __P((void));
#define DEBUGCHAP 1
#endif
#define DEBUGMAIN 1
#define DEBUGUPAP 1
#define DEBUGCHAP 1
#ifdef DEBUGMAIN

View File

@@ -107,8 +107,6 @@ int phase; /* where the link is at */
int kill_link;
int open_ccp_flag;
static int waiting;
char **script_env; /* Env. variable values for scripts */
int s_env_nalloc; /* # words avail at script_env */
@@ -234,8 +232,6 @@ pppdmain(argc, argv)
setlogmask(LOG_UPTO(LOG_DEBUG));
*/
waiting = 0;
do_callback = 0;
for (;;) {
@@ -400,12 +396,10 @@ pppdmain(argc, argv)
status = EXIT_NEGOTIATION_FAILED;
new_phase(PHASE_ESTABLISH);
while (phase != PHASE_DEAD) {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
get_input();
if (kill_link) {
lcp_close(0, "User request");
kill_link = 0;
@@ -469,9 +463,7 @@ pppdmain(argc, argv)
new_phase(PHASE_HOLDOFF);
TIMEOUT(holdoff_end, NULL, t);
do {
waiting = 1;
wait_input(timeleft(&timo));
waiting = 0;
calltimeout();
if (kill_link) {