MFMP: Make ppp multilink capable.
See the file README.changes, and re-read the man page.
This commit is contained in:
commit
d91d286164
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36285
@ -1,19 +1,27 @@
|
||||
# $Id: Makefile,v 1.35 1998/01/17 14:21:21 brian Exp $
|
||||
# $Id: Makefile,v 1.36.2.12 1998/05/04 03:01:34 brian Exp $
|
||||
|
||||
PROG= ppp
|
||||
SRCS= arp.c async.c auth.c ccp.c chap.c chat.c command.c deflate.c \
|
||||
defs.c filter.c fsm.c hdlc.c id.c ip.c ipcp.c iplist.c lcp.c \
|
||||
log.c lqr.c main.c mbuf.c modem.c os.c pap.c phase.c \
|
||||
pred.c route.c server.c sig.c slcompress.c systems.c throughput.c \
|
||||
timer.c tun.c vars.c vjcomp.c
|
||||
CFLAGS+=-Wall
|
||||
LDADD+= -lmd -lcrypt -lutil -lz
|
||||
DPADD+= ${LIBMD} ${LIBCRYPT} ${LIBUTIL} ${LIBZ}
|
||||
MAN8= ppp.8
|
||||
SRCS= arp.c async.c auth.c bundle.c ccp.c chap.c chat.c command.c \
|
||||
datalink.c deflate.c defs.c filter.c fsm.c hdlc.c id.c ip.c \
|
||||
ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c mbuf.c modem.c \
|
||||
mp.c pap.c physical.c pred.c prompt.c route.c server.c sig.c \
|
||||
slcompress.c systems.c throughput.c timer.c tun.c vjcomp.c
|
||||
CFLAGS+=-Wall -Wpointer-arith
|
||||
LDADD+= -lutil -lz
|
||||
DPADD+= ${LIBUTIL} ${LIBZ}
|
||||
BINMODE=4550
|
||||
BINOWN= root
|
||||
BINGRP= network
|
||||
|
||||
OPSYS!= uname -s
|
||||
.if (${OPSYS} == "OpenBSD")
|
||||
MAN= ppp.8
|
||||
.else
|
||||
MAN8= ppp.8
|
||||
LDADD+= -lmd -lcrypt
|
||||
DPADD+= ${LIBMD} ${LIBCRYPT}
|
||||
.endif
|
||||
|
||||
.if defined(RELEASE_CRUNCH)
|
||||
CFLAGS+=-DRELEASE_CRUNCH
|
||||
.endif
|
||||
|
70
usr.sbin/ppp/README.changes
Normal file
70
usr.sbin/ppp/README.changes
Normal file
@ -0,0 +1,70 @@
|
||||
This file summarises changes made to ppp that effect
|
||||
its configuration.
|
||||
|
||||
It does not describe new features, rather it attempts
|
||||
to answer any `this used to work, why doesn't it now?'
|
||||
questions.
|
||||
|
||||
o The `set debug' command was replaced with `set log'.
|
||||
o The `set log LCP' command was split into LCP, IPCP and CCP logs.
|
||||
o Syslogd is used for logging. /etc/syslog.conf must be updated.
|
||||
o LQR is disabled by default.
|
||||
o Openmode is active by default.
|
||||
o Users must be a member of group `network' for ppp access. Furthermore,
|
||||
they must be `allow'ed to run ppp via the `allow' command in the
|
||||
configuration file.
|
||||
For a brief period, ppp could only be run as root.
|
||||
o No diagnostic socket is created by default. The `set server' command
|
||||
must be used.
|
||||
o The diagnostic socket password must be specified *only* on the `set
|
||||
server' command line.
|
||||
o When `set server' is used to re-select a diagnostic port, all existing
|
||||
diagnostic connections are dropped.
|
||||
o pppd-deflate is now called deflate24.
|
||||
o Filter IPs of 0.0.0.0 have a default width of 0, not 32.
|
||||
o Errors in `add' and `delete' are logged as warnings rather than being
|
||||
written to the TCP/IP log.
|
||||
o Any number of diagnostic prompts are allowed, and they are allowed in
|
||||
interactive mode.
|
||||
o The default `device' is cuaa1, then cuaa0
|
||||
o A password of "*" in ppp.secret causes a passwd database lookup in
|
||||
pap mode.
|
||||
o The value of the CONNECT environment variable is logged in the
|
||||
utmp host field in -direct mode.
|
||||
o Out-of-sequence FSM packets (IPCP/LCP/CCP) are dropped by default.
|
||||
o Reconnect values are used after an LQR timeout.
|
||||
o ^C works on the parent in -background mode.
|
||||
o The dial/call/open command works asyncronously. As a result, prompts
|
||||
do not lose control while dialing.
|
||||
o The `display' command has been removed. All information is available
|
||||
with the appropriate `show' command.
|
||||
o Msext does not need to be enabled/disabled. Setting the NBNS (set nbns)
|
||||
will auto enable it. The DNS side may be enabled/disabled, and if
|
||||
enabled without a `set dns' will use values from /etc/resolv.conf.
|
||||
o Filters are now called `allow', `dial', `in' and `out'. `set
|
||||
ifilter ...' becomes `set filter in ...' etc.
|
||||
o Authname and Authkey may only be `set' in phase DEAD.
|
||||
o Set encrypt is no longer necessary. Ppp will respond to M$CHAP
|
||||
servers correctly if it's built with DES.
|
||||
o Throughput statistics are enabled by default.
|
||||
o `Set stopped' only has two parameters. It's no longer possible to
|
||||
have an IPCP stopped timer.
|
||||
o `Set timeout' only has one parameter. Use `set lqrperiod' and `set
|
||||
{lcp,ccp,ipcp,chap,pap}retry' for the other timers. `show timeout'
|
||||
is also now available using the relevent show commands.
|
||||
o `set loopback' is now `enable/disable loopback'.
|
||||
o `show auto', `show loopback' and `show mtu' are all part of `show bundle'.
|
||||
o `show mru' is part of `show lcp'
|
||||
o `show msext' and `show vj' are part of `show ipcp'
|
||||
o `show reconnect' and `show redial' are part of `show link'
|
||||
o A signal 15 (TERM) will now shut down the link gracefully.
|
||||
o A signal 2 (HUP) will drop all links immediately.
|
||||
o Signal 30 (USR1) is now ignored.
|
||||
o Add & delete commands are not necessary in ppp.linkup if they are
|
||||
`sticky routes' (ie, contain MYADDR or HISADDR).
|
||||
o LINK and CARRIER logging are no longer available.
|
||||
o Timer based DEBUG messages are now logged in the new TIMER log.
|
||||
o Ppp can use tun devices > tun255.
|
||||
o Protocol-compressed packets are accepted even if they were denied
|
||||
at LCP negotiation time.
|
||||
o Passwords aren't logged when logging the ``set server'' line.
|
@ -2,26 +2,25 @@
|
||||
* The code in this file was written by Eivind Eklund <perhaps@yes.no>,
|
||||
* who places it in the public domain without restriction.
|
||||
*
|
||||
* $Id: alias_cmd.c,v 1.11 1997/12/24 10:28:37 brian Exp $
|
||||
* $Id: alias_cmd.c,v 1.12.2.8 1998/05/01 19:23:43 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "alias_cmd.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
|
||||
|
||||
static int StrToAddr(const char *, struct in_addr *);
|
||||
@ -30,13 +29,12 @@ static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const cha
|
||||
|
||||
|
||||
int
|
||||
AliasRedirectPort(struct cmdargs const *arg)
|
||||
alias_RedirectPort(struct cmdargs const *arg)
|
||||
{
|
||||
if (!(mode & MODE_ALIAS)) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "Alias not enabled\n");
|
||||
if (!alias_IsEnabled()) {
|
||||
prompt_Printf(arg->prompt, "Alias not enabled\n");
|
||||
return 1;
|
||||
} else if (arg->argc == 3) {
|
||||
} else if (arg->argc == arg->argn+3) {
|
||||
char proto_constant;
|
||||
const char *proto;
|
||||
u_short local_port;
|
||||
@ -46,45 +44,44 @@ AliasRedirectPort(struct cmdargs const *arg)
|
||||
struct in_addr null_addr;
|
||||
struct alias_link *link;
|
||||
|
||||
proto = arg->argv[0];
|
||||
proto = arg->argv[arg->argn];
|
||||
if (strcmp(proto, "tcp") == 0) {
|
||||
proto_constant = IPPROTO_TCP;
|
||||
} else if (strcmp(proto, "udp") == 0) {
|
||||
proto_constant = IPPROTO_UDP;
|
||||
} else {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: protocol must be"
|
||||
" tcp or udp\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
error = StrToAddrAndPort(arg->argv[1], &local_addr, &local_port, proto);
|
||||
error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &local_port,
|
||||
proto);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: error reading local addr:port\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: error reading"
|
||||
" local addr:port\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
error = StrToPort(arg->argv[2], &alias_port, proto);
|
||||
error = StrToPort(arg->argv[arg->argn+2], &alias_port, proto);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: error reading alias port\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: error reading alias port\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
null_addr.s_addr = 0;
|
||||
null_addr.s_addr = INADDR_ANY;
|
||||
|
||||
link = VarPacketAliasRedirectPort(local_addr, local_port,
|
||||
link = (*PacketAlias.RedirectPort)(local_addr, local_port,
|
||||
null_addr, 0,
|
||||
null_addr, alias_port,
|
||||
proto_constant);
|
||||
|
||||
if (link == NULL && VarTerm)
|
||||
fprintf(VarTerm, "port redirect: error returned by packed"
|
||||
if (link == NULL)
|
||||
prompt_Printf(arg->prompt, "port redirect: error returned by packed"
|
||||
" aliasing engine (code=%d)\n", error);
|
||||
} else
|
||||
return -1;
|
||||
@ -94,36 +91,35 @@ AliasRedirectPort(struct cmdargs const *arg)
|
||||
|
||||
|
||||
int
|
||||
AliasRedirectAddr(struct cmdargs const *arg)
|
||||
alias_RedirectAddr(struct cmdargs const *arg)
|
||||
{
|
||||
if (!(mode & MODE_ALIAS)) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "alias not enabled\n");
|
||||
if (!alias_IsEnabled()) {
|
||||
prompt_Printf(arg->prompt, "alias not enabled\n");
|
||||
return 1;
|
||||
} else if (arg->argc == 2) {
|
||||
} else if (arg->argc == arg->argn+2) {
|
||||
int error;
|
||||
struct in_addr local_addr;
|
||||
struct in_addr alias_addr;
|
||||
struct alias_link *link;
|
||||
|
||||
error = StrToAddr(arg->argv[0], &local_addr);
|
||||
error = StrToAddr(arg->argv[arg->argn], &local_addr);
|
||||
if (error) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "address redirect: invalid local address\n");
|
||||
prompt_Printf(arg->prompt, "address redirect: invalid local address\n");
|
||||
return 1;
|
||||
}
|
||||
error = StrToAddr(arg->argv[1], &alias_addr);
|
||||
error = StrToAddr(arg->argv[arg->argn+1], &alias_addr);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "address redirect: invalid alias address\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "address redirect: invalid alias address\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
|
||||
if (link == NULL && VarTerm) {
|
||||
fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
link = (*PacketAlias.RedirectAddr)(local_addr, alias_addr);
|
||||
if (link == NULL) {
|
||||
prompt_Printf(arg->prompt, "address redirect: packet aliasing"
|
||||
" engine error\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
@ -142,7 +138,7 @@ StrToAddr(const char *str, struct in_addr *addr)
|
||||
|
||||
hp = gethostbyname(str);
|
||||
if (!hp) {
|
||||
LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
|
||||
log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
|
||||
return -1;
|
||||
}
|
||||
*addr = *((struct in_addr *) hp->h_addr);
|
||||
@ -164,7 +160,7 @@ StrToPort(const char *str, u_short *port, const char *proto)
|
||||
}
|
||||
sp = getservbyname(str, proto);
|
||||
if (!sp) {
|
||||
LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
|
||||
log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
|
||||
str, proto);
|
||||
return -1;
|
||||
}
|
||||
@ -181,7 +177,7 @@ StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const cha
|
||||
|
||||
colon = strchr(str, ':');
|
||||
if (!colon) {
|
||||
LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
|
||||
log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,10 @@
|
||||
* The code in this file was written by Eivind Eklund <perhaps@yes.no>,
|
||||
* who places it in the public domain without restriction.
|
||||
*
|
||||
* $Id: alias_cmd.h,v 1.6 1997/12/21 14:28:24 brian Exp $
|
||||
* $Id: alias_cmd.h,v 1.7.2.2 1998/05/01 19:23:44 brian Exp $
|
||||
*/
|
||||
|
||||
extern int AliasRedirectPort(struct cmdargs const *);
|
||||
extern int AliasRedirectAddr(struct cmdargs const *);
|
||||
struct cmdargs;
|
||||
|
||||
extern int alias_RedirectPort(struct cmdargs const *);
|
||||
extern int alias_RedirectAddr(struct cmdargs const *);
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: arp.c,v 1.26 1998/01/23 22:29:16 brian Exp $
|
||||
* $Id: arp.c,v 1.27.2.15 1998/05/01 19:23:46 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
@ -25,57 +25,46 @@
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_types.h>
|
||||
#include <netinet/if_ether.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/uio.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
#include "route.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "defs.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "arp.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
/*
|
||||
* To test the proxy arp stuff, just
|
||||
*
|
||||
* cc -o arp-test -DDEBUG arp.c
|
||||
*
|
||||
*/
|
||||
#define LogIsKept(x) 1
|
||||
#define LogPrintf fprintf
|
||||
#undef LogDEBUG
|
||||
#define LogDEBUG stderr
|
||||
#undef LogERROR
|
||||
#define LogERROR stderr
|
||||
#undef LogPHASE
|
||||
#define LogPHASE stdout
|
||||
#define ID0socket socket
|
||||
#define ID0ioctl ioctl
|
||||
#endif
|
||||
|
||||
static int rtm_seq;
|
||||
|
||||
static int get_ether_addr(int, struct in_addr, struct sockaddr_dl *);
|
||||
|
||||
/*
|
||||
* SET_SA_FAMILY - set the sa_family field of a struct sockaddr,
|
||||
* if it exists.
|
||||
@ -89,7 +78,7 @@ static int get_ether_addr(int, struct in_addr, struct sockaddr_dl *);
|
||||
#if RTM_VERSION >= 3
|
||||
|
||||
/*
|
||||
* sifproxyarp - Make a proxy ARP entry for the peer.
|
||||
* arp_SetProxy - Make a proxy ARP entry for the peer.
|
||||
*/
|
||||
static struct {
|
||||
struct rt_msghdr hdr;
|
||||
@ -101,7 +90,7 @@ static struct {
|
||||
static int arpmsg_valid;
|
||||
|
||||
int
|
||||
sifproxyarp(int unit, struct in_addr hisaddr)
|
||||
arp_SetProxy(struct bundle *bundle, struct in_addr addr, int s)
|
||||
{
|
||||
int routes;
|
||||
|
||||
@ -110,31 +99,31 @@ sifproxyarp(int unit, struct in_addr hisaddr)
|
||||
* address.
|
||||
*/
|
||||
memset(&arpmsg, 0, sizeof arpmsg);
|
||||
if (!get_ether_addr(unit, hisaddr, &arpmsg.hwa)) {
|
||||
LogPrintf(LogERROR, "Cannot determine ethernet address for proxy ARP\n");
|
||||
if (!get_ether_addr(s, addr, &arpmsg.hwa)) {
|
||||
log_Printf(LogERROR, "Cannot determine ethernet address for proxy ARP\n");
|
||||
return 0;
|
||||
}
|
||||
routes = ID0socket(PF_ROUTE, SOCK_RAW, AF_INET);
|
||||
if (routes < 0) {
|
||||
LogPrintf(LogERROR, "sifproxyarp: opening routing socket: %s\n",
|
||||
log_Printf(LogERROR, "arp_SetProxy: opening routing socket: %s\n",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
arpmsg.hdr.rtm_type = RTM_ADD;
|
||||
arpmsg.hdr.rtm_flags = RTF_ANNOUNCE | RTF_HOST | RTF_STATIC;
|
||||
arpmsg.hdr.rtm_version = RTM_VERSION;
|
||||
arpmsg.hdr.rtm_seq = ++rtm_seq;
|
||||
arpmsg.hdr.rtm_seq = ++bundle->routing_seq;
|
||||
arpmsg.hdr.rtm_addrs = RTA_DST | RTA_GATEWAY;
|
||||
arpmsg.hdr.rtm_inits = RTV_EXPIRE;
|
||||
arpmsg.dst.sin_len = sizeof(struct sockaddr_inarp);
|
||||
arpmsg.dst.sin_family = AF_INET;
|
||||
arpmsg.dst.sin_addr.s_addr = hisaddr.s_addr;
|
||||
arpmsg.dst.sin_addr.s_addr = addr.s_addr;
|
||||
arpmsg.dst.sin_other = SIN_PROXY;
|
||||
|
||||
arpmsg.hdr.rtm_msglen = (char *) &arpmsg.hwa - (char *) &arpmsg
|
||||
+ arpmsg.hwa.sdl_len;
|
||||
if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
|
||||
LogPrintf(LogERROR, "Add proxy arp entry: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "Add proxy arp entry: %s\n", strerror(errno));
|
||||
close(routes);
|
||||
return 0;
|
||||
}
|
||||
@ -144,10 +133,10 @@ sifproxyarp(int unit, struct in_addr hisaddr)
|
||||
}
|
||||
|
||||
/*
|
||||
* cifproxyarp - Delete the proxy ARP entry for the peer.
|
||||
* arp_ClearProxy - Delete the proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
cifproxyarp(int unit, struct in_addr hisaddr)
|
||||
arp_ClearProxy(struct bundle *bundle, struct in_addr addr, int s)
|
||||
{
|
||||
int routes;
|
||||
|
||||
@ -156,16 +145,16 @@ cifproxyarp(int unit, struct in_addr hisaddr)
|
||||
arpmsg_valid = 0;
|
||||
|
||||
arpmsg.hdr.rtm_type = RTM_DELETE;
|
||||
arpmsg.hdr.rtm_seq = ++rtm_seq;
|
||||
arpmsg.hdr.rtm_seq = ++bundle->routing_seq;
|
||||
|
||||
routes = ID0socket(PF_ROUTE, SOCK_RAW, AF_INET);
|
||||
if (routes < 0) {
|
||||
LogPrintf(LogERROR, "sifproxyarp: opening routing socket: %s\n",
|
||||
log_Printf(LogERROR, "arp_SetProxy: opening routing socket: %s\n",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
if (write(routes, &arpmsg, arpmsg.hdr.rtm_msglen) < 0) {
|
||||
LogPrintf(LogERROR, "Delete proxy arp entry: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "Delete proxy arp entry: %s\n", strerror(errno));
|
||||
close(routes);
|
||||
return 0;
|
||||
}
|
||||
@ -176,10 +165,10 @@ cifproxyarp(int unit, struct in_addr hisaddr)
|
||||
#else /* RTM_VERSION */
|
||||
|
||||
/*
|
||||
* sifproxyarp - Make a proxy ARP entry for the peer.
|
||||
* arp_SetProxy - Make a proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
sifproxyarp(int unit, struct in_addr hisaddr)
|
||||
arp_SetProxy(struct bundle *bundle, struct in_addr addr, int s)
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
struct {
|
||||
@ -193,36 +182,36 @@ sifproxyarp(int unit, struct in_addr hisaddr)
|
||||
* Get the hardware address of an interface on the same subnet as our local
|
||||
* address.
|
||||
*/
|
||||
if (!get_ether_addr(unit, hisaddr, &dls.sdl)) {
|
||||
LogPrintf(LOG_PHASE_BIT, "Cannot determine ethernet address for proxy ARP\n");
|
||||
if (!get_ether_addr(s, addr, &dls.sdl)) {
|
||||
log_Printf(LOG_PHASE_BIT, "Cannot determine ethernet address for proxy ARP\n");
|
||||
return 0;
|
||||
}
|
||||
arpreq.arp_ha.sa_len = sizeof(struct sockaddr);
|
||||
arpreq.arp_ha.sa_family = AF_UNSPEC;
|
||||
memcpy(arpreq.arp_ha.sa_data, LLADDR(&dls.sdl), dls.sdl.sdl_alen);
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) & arpreq.arp_pa)->sin_addr.s_addr = hisaddr.s_addr;
|
||||
((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr = addr.s_addr;
|
||||
arpreq.arp_flags = ATF_PERM | ATF_PUBL;
|
||||
if (ID0ioctl(unit, SIOCSARP, (caddr_t) & arpreq) < 0) {
|
||||
LogPrintf(LogERROR, "sifproxyarp: ioctl(SIOCSARP): %s\n", strerror(errno));
|
||||
if (ID0ioctl(s, SIOCSARP, (caddr_t) & arpreq) < 0) {
|
||||
log_Printf(LogERROR, "arp_SetProxy: ioctl(SIOCSARP): %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
* cifproxyarp - Delete the proxy ARP entry for the peer.
|
||||
* arp_ClearProxy - Delete the proxy ARP entry for the peer.
|
||||
*/
|
||||
int
|
||||
cifproxyarp(int unit, struct in_addr hisaddr)
|
||||
arp_ClearProxy(struct bundle *bundle, struct in_addr addr, int s)
|
||||
{
|
||||
struct arpreq arpreq;
|
||||
|
||||
memset(&arpreq, '\0', sizeof arpreq);
|
||||
SET_SA_FAMILY(arpreq.arp_pa, AF_INET);
|
||||
((struct sockaddr_in *) & arpreq.arp_pa)->sin_addr.s_addr = hisaddr.s_addr;
|
||||
if (ID0ioctl(unit, SIOCDARP, (caddr_t) & arpreq) < 0) {
|
||||
LogPrintf(LogERROR, "cifproxyarp: ioctl(SIOCDARP): %s\n", strerror(errno));
|
||||
((struct sockaddr_in *)&arpreq.arp_pa)->sin_addr.s_addr = addr.s_addr;
|
||||
if (ID0ioctl(s, SIOCDARP, (caddr_t) & arpreq) < 0) {
|
||||
log_Printf(LogERROR, "arp_ClearProxy: ioctl(SIOCDARP): %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
@ -236,7 +225,7 @@ cifproxyarp(int unit, struct in_addr hisaddr)
|
||||
* the same subnet as ipaddr.
|
||||
*/
|
||||
|
||||
static int
|
||||
int
|
||||
get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
|
||||
{
|
||||
int mib[6], sa_len, skip, b;
|
||||
@ -256,7 +245,7 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "get_ether_addr: sysctl: estimate: %s\n",
|
||||
log_Printf(LogERROR, "get_ether_addr: sysctl: estimate: %s\n",
|
||||
strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
@ -289,9 +278,9 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
|
||||
(RTA_NETMASK|RTA_IFA))
|
||||
continue;
|
||||
/* Found a candidate. Do the addresses match ? */
|
||||
if (LogIsKept(LogDEBUG) &&
|
||||
if (log_IsKept(LogDEBUG) &&
|
||||
ptr == (char *)ifm + ifm->ifm_msglen + ifam->ifam_msglen)
|
||||
LogPrintf(LogDEBUG, "%.*s interface is a candidate for proxy\n",
|
||||
log_Printf(LogDEBUG, "%.*s interface is a candidate for proxy\n",
|
||||
dl->sdl_nlen, dl->sdl_data);
|
||||
b = 1;
|
||||
ifa = mask = NULL;
|
||||
@ -315,18 +304,18 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
|
||||
}
|
||||
b <<= 1;
|
||||
}
|
||||
if (LogIsKept(LogDEBUG)) {
|
||||
if (log_IsKept(LogDEBUG)) {
|
||||
char a[16];
|
||||
strncpy(a, inet_ntoa(mask->sin_addr), sizeof a - 1);
|
||||
a[sizeof a - 1] = '\0';
|
||||
LogPrintf(LogDEBUG, "Check addr %s, mask %s\n",
|
||||
log_Printf(LogDEBUG, "Check addr %s, mask %s\n",
|
||||
inet_ntoa(ifa->sin_addr), a);
|
||||
}
|
||||
if (ifa->sin_family == AF_INET &&
|
||||
(ifa->sin_addr.s_addr & mask->sin_addr.s_addr) ==
|
||||
(ipaddr.s_addr & mask->sin_addr.s_addr)) {
|
||||
LogPrintf(LogPHASE, "Found interface %.*s for proxy arp\n",
|
||||
dl->sdl_alen, dl->sdl_data);
|
||||
log_Printf(LogPHASE, "Found interface %.*s for %s\n",
|
||||
dl->sdl_alen, dl->sdl_data, inet_ntoa(ipaddr));
|
||||
memcpy(hwaddr, dl, dl->sdl_len);
|
||||
free(buf);
|
||||
return 1;
|
||||
@ -337,19 +326,3 @@ get_ether_addr(int s, struct in_addr ipaddr, struct sockaddr_dl *hwaddr)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
int
|
||||
main(int argc, char **argv)
|
||||
{
|
||||
struct in_addr ipaddr;
|
||||
int s, f;
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
for (f = 1; f < argc; f++) {
|
||||
if (inet_aton(argv[f], &ipaddr))
|
||||
sifproxyarp(s, ipaddr);
|
||||
}
|
||||
close(s);
|
||||
}
|
||||
#endif
|
||||
|
@ -17,9 +17,13 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: arp.h,v 1.6 1997/10/26 01:02:04 brian Exp $
|
||||
* $Id: arp.h,v 1.7.2.7 1998/05/01 19:23:50 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
extern int cifproxyarp(int, struct in_addr);
|
||||
extern int sifproxyarp(int, struct in_addr);
|
||||
struct sockaddr_dl;
|
||||
struct bundle;
|
||||
|
||||
extern int arp_ClearProxy(struct bundle *, struct in_addr, int);
|
||||
extern int arp_SetProxy(struct bundle *, struct in_addr, int);
|
||||
extern int get_ether_addr(int, struct in_addr, struct sockaddr_dl *);
|
||||
|
@ -17,78 +17,64 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: async.c,v 1.14 1997/11/22 03:37:23 brian Exp $
|
||||
* $Id: async.c,v 1.15.2.14 1998/05/01 19:23:51 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "lcpproto.h"
|
||||
#include "modem.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "async.h"
|
||||
|
||||
#define HDLCSIZE (MAX_MRU*2+6)
|
||||
|
||||
static struct async_state {
|
||||
int mode;
|
||||
int length;
|
||||
u_char hbuff[HDLCSIZE]; /* recv buffer */
|
||||
u_char xbuff[HDLCSIZE]; /* xmit buffer */
|
||||
u_long my_accmap;
|
||||
u_long his_accmap;
|
||||
} AsyncState;
|
||||
#include "throughput.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
|
||||
#define MODE_HUNT 0x01
|
||||
#define MODE_ESC 0x02
|
||||
|
||||
void
|
||||
AsyncInit()
|
||||
async_Init(struct async *async)
|
||||
{
|
||||
struct async_state *stp = &AsyncState;
|
||||
|
||||
stp->mode = MODE_HUNT;
|
||||
stp->length = 0;
|
||||
stp->my_accmap = stp->his_accmap = 0xffffffff;
|
||||
async->mode = MODE_HUNT;
|
||||
async->length = 0;
|
||||
async->my_accmap = async->his_accmap = 0xffffffff;
|
||||
memset(async->cfg.EscMap, '\0', sizeof async->cfg.EscMap);
|
||||
}
|
||||
|
||||
void
|
||||
SetLinkParams(struct lcpstate *lcp)
|
||||
async_SetLinkParams(struct async *async, struct lcp *lcp)
|
||||
{
|
||||
struct async_state *stp = &AsyncState;
|
||||
|
||||
stp->my_accmap = lcp->want_accmap;
|
||||
stp->his_accmap = lcp->his_accmap;
|
||||
async->my_accmap = lcp->want_accmap;
|
||||
async->his_accmap = lcp->his_accmap;
|
||||
}
|
||||
|
||||
/*
|
||||
* Encode into async HDLC byte code if necessary
|
||||
*/
|
||||
static void
|
||||
HdlcPutByte(u_char **cp, u_char c, int proto)
|
||||
HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto)
|
||||
{
|
||||
u_char *wp;
|
||||
|
||||
wp = *cp;
|
||||
if ((c < 0x20 && (proto == PROTO_LCP || (AsyncState.his_accmap & (1 << c))))
|
||||
if ((c < 0x20 && (proto == PROTO_LCP || (async->his_accmap & (1 << c))))
|
||||
|| (c == HDLC_ESC) || (c == HDLC_SYN)) {
|
||||
*wp++ = HDLC_ESC;
|
||||
c ^= HDLC_XOR;
|
||||
}
|
||||
if (EscMap[32] && EscMap[c >> 3] & (1 << (c & 7))) {
|
||||
if (async->cfg.EscMap[32] && async->cfg.EscMap[c >> 3] & (1 << (c & 7))) {
|
||||
*wp++ = HDLC_ESC;
|
||||
c ^= HDLC_XOR;
|
||||
}
|
||||
@ -97,27 +83,26 @@ HdlcPutByte(u_char **cp, u_char c, int proto)
|
||||
}
|
||||
|
||||
void
|
||||
AsyncOutput(int pri, struct mbuf *bp, int proto)
|
||||
async_Output(int pri, struct mbuf *bp, int proto, struct physical *physical)
|
||||
{
|
||||
struct async_state *hs = &AsyncState;
|
||||
u_char *cp, *sp, *ep;
|
||||
struct mbuf *wp;
|
||||
int cnt;
|
||||
|
||||
if (plength(bp) > HDLCSIZE) {
|
||||
pfree(bp);
|
||||
if (mbuf_Length(bp) > HDLCSIZE) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
cp = hs->xbuff;
|
||||
cp = physical->async.xbuff;
|
||||
ep = cp + HDLCSIZE - 10;
|
||||
wp = bp;
|
||||
*cp++ = HDLC_SYN;
|
||||
while (wp) {
|
||||
sp = MBUF_CTOP(wp);
|
||||
for (cnt = wp->cnt; cnt > 0; cnt--) {
|
||||
HdlcPutByte(&cp, *sp++, proto);
|
||||
HdlcPutByte(&physical->async, &cp, *sp++, proto);
|
||||
if (cp >= ep) {
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@ -125,72 +110,73 @@ AsyncOutput(int pri, struct mbuf *bp, int proto)
|
||||
}
|
||||
*cp++ = HDLC_SYN;
|
||||
|
||||
cnt = cp - hs->xbuff;
|
||||
LogDumpBuff(LogASYNC, "WriteModem", hs->xbuff, cnt);
|
||||
WriteModem(pri, (char *) hs->xbuff, cnt);
|
||||
ModemAddOutOctets(cnt);
|
||||
pfree(bp);
|
||||
cnt = cp - physical->async.xbuff;
|
||||
log_DumpBuff(LogASYNC, "WriteModem", physical->async.xbuff, cnt);
|
||||
link_Write(&physical->link, pri, (char *)physical->async.xbuff, cnt);
|
||||
link_AddOutOctets(&physical->link, cnt);
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
AsyncDecode(u_char c)
|
||||
async_Decode(struct async *async, u_char c)
|
||||
{
|
||||
struct async_state *hs = &AsyncState;
|
||||
struct mbuf *bp;
|
||||
|
||||
if ((hs->mode & MODE_HUNT) && c != HDLC_SYN)
|
||||
if ((async->mode & MODE_HUNT) && c != HDLC_SYN)
|
||||
return NULL;
|
||||
|
||||
switch (c) {
|
||||
case HDLC_SYN:
|
||||
hs->mode &= ~MODE_HUNT;
|
||||
if (hs->length) { /* packet is ready. */
|
||||
bp = mballoc(hs->length, MB_ASYNC);
|
||||
mbwrite(bp, hs->hbuff, hs->length);
|
||||
hs->length = 0;
|
||||
async->mode &= ~MODE_HUNT;
|
||||
if (async->length) { /* packet is ready. */
|
||||
bp = mbuf_Alloc(async->length, MB_ASYNC);
|
||||
mbuf_Write(bp, async->hbuff, async->length);
|
||||
async->length = 0;
|
||||
return bp;
|
||||
}
|
||||
break;
|
||||
case HDLC_ESC:
|
||||
if (!(hs->mode & MODE_ESC)) {
|
||||
hs->mode |= MODE_ESC;
|
||||
if (!(async->mode & MODE_ESC)) {
|
||||
async->mode |= MODE_ESC;
|
||||
break;
|
||||
}
|
||||
/* Fall into ... */
|
||||
default:
|
||||
if (hs->length >= HDLCSIZE) {
|
||||
if (async->length >= HDLCSIZE) {
|
||||
/* packet is too large, discard it */
|
||||
LogPrintf(LogERROR, "Packet too large (%d), discarding.\n", hs->length);
|
||||
hs->length = 0;
|
||||
hs->mode = MODE_HUNT;
|
||||
log_Printf(LogERROR, "Packet too large (%d), discarding.\n", async->length);
|
||||
async->length = 0;
|
||||
async->mode = MODE_HUNT;
|
||||
break;
|
||||
}
|
||||
if (hs->mode & MODE_ESC) {
|
||||
if (async->mode & MODE_ESC) {
|
||||
c ^= HDLC_XOR;
|
||||
hs->mode &= ~MODE_ESC;
|
||||
async->mode &= ~MODE_ESC;
|
||||
}
|
||||
hs->hbuff[hs->length++] = c;
|
||||
async->hbuff[async->length++] = c;
|
||||
break;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
AsyncInput(u_char *buff, int cnt)
|
||||
async_Input(struct bundle *bundle, u_char *buff, int cnt,
|
||||
struct physical *physical)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
|
||||
ModemAddInOctets(cnt);
|
||||
if (DEV_IS_SYNC) {
|
||||
bp = mballoc(cnt, MB_ASYNC);
|
||||
link_AddInOctets(&physical->link, cnt);
|
||||
|
||||
if (physical_IsSync(physical)) {
|
||||
bp = mbuf_Alloc(cnt, MB_ASYNC);
|
||||
memcpy(MBUF_CTOP(bp), buff, cnt);
|
||||
bp->cnt = cnt;
|
||||
HdlcInput(bp);
|
||||
hdlc_Input(bundle, bp, physical);
|
||||
} else {
|
||||
while (cnt > 0) {
|
||||
bp = AsyncDecode(*buff++);
|
||||
bp = async_Decode(&physical->async, *buff++);
|
||||
if (bp)
|
||||
HdlcInput(bp);
|
||||
hdlc_Input(bundle, bp, physical);
|
||||
cnt--;
|
||||
}
|
||||
}
|
||||
|
@ -23,10 +23,30 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: async.h,v 1.2.4.7 1998/04/07 00:53:17 brian Exp $
|
||||
*/
|
||||
|
||||
extern void AsyncInit(void);
|
||||
extern void SetLinkParams(struct lcpstate *);
|
||||
extern void AsyncOutput(int, struct mbuf *, int);
|
||||
extern void AsyncInput(u_char *, int);
|
||||
#define HDLCSIZE (MAX_MRU*2+6)
|
||||
|
||||
struct async {
|
||||
int mode;
|
||||
int length;
|
||||
u_char hbuff[HDLCSIZE]; /* recv buffer */
|
||||
u_char xbuff[HDLCSIZE]; /* xmit buffer */
|
||||
u_long my_accmap;
|
||||
u_long his_accmap;
|
||||
|
||||
struct {
|
||||
u_char EscMap[33];
|
||||
} cfg;
|
||||
};
|
||||
|
||||
struct lcp;
|
||||
struct mbuf;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
|
||||
extern void async_Init(struct async *);
|
||||
extern void async_SetLinkParams(struct async *, struct lcp *);
|
||||
extern void async_Output(int, struct mbuf *, int, struct physical *);
|
||||
extern void async_Input(struct bundle *, u_char *, int, struct physical *);
|
||||
|
@ -17,136 +17,176 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: auth.c,v 1.27 1998/01/21 02:15:09 brian Exp $
|
||||
* $Id: auth.c,v 1.27.2.26 1998/05/01 19:23:52 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Implement check against with registered IP addresses.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "auth.h"
|
||||
#include "chat.h"
|
||||
#include "systems.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "chat.h"
|
||||
#include "lcpproto.h"
|
||||
#include "filter.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
|
||||
void
|
||||
LocalAuthInit()
|
||||
const char *
|
||||
Auth2Nam(u_short auth)
|
||||
{
|
||||
if (!(mode&MODE_DAEMON))
|
||||
/* We're allowed in interactive mode */
|
||||
VarLocalAuth = LOCAL_AUTH;
|
||||
else if (VarHaveLocalAuthKey)
|
||||
VarLocalAuth = *VarLocalAuthKey == '\0' ? LOCAL_AUTH : LOCAL_NO_AUTH;
|
||||
else
|
||||
switch (LocalAuthValidate(SECRETFILE, VarShortHost, "")) {
|
||||
case NOT_FOUND:
|
||||
VarLocalAuth = LOCAL_DENY;
|
||||
break;
|
||||
case VALID:
|
||||
VarLocalAuth = LOCAL_AUTH;
|
||||
break;
|
||||
case INVALID:
|
||||
VarLocalAuth = LOCAL_NO_AUTH;
|
||||
break;
|
||||
}
|
||||
switch (auth) {
|
||||
case PROTO_PAP:
|
||||
return "PAP";
|
||||
case PROTO_CHAP:
|
||||
return "CHAP";
|
||||
case 0:
|
||||
return "none";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
LOCAL_AUTH_VALID
|
||||
LocalAuthValidate(const char *fname, const char *system, const char *key)
|
||||
static int
|
||||
auth_CheckPasswd(const char *name, const char *data, const char *key)
|
||||
{
|
||||
FILE *fp;
|
||||
int n;
|
||||
char *vector[3];
|
||||
char buff[LINE_LEN];
|
||||
LOCAL_AUTH_VALID rc;
|
||||
if (!strcmp(data, "*")) {
|
||||
/* Then look up the real password database */
|
||||
struct passwd *pw;
|
||||
int result;
|
||||
|
||||
rc = NOT_FOUND; /* No system entry */
|
||||
fp = OpenSecret(fname);
|
||||
if (fp == NULL)
|
||||
return (rc);
|
||||
while (fgets(buff, sizeof buff, fp)) {
|
||||
if (buff[0] == '#')
|
||||
continue;
|
||||
buff[strlen(buff) - 1] = 0;
|
||||
memset(vector, '\0', sizeof vector);
|
||||
n = MakeArgs(buff, vector, VECSIZE(vector));
|
||||
if (n < 1)
|
||||
continue;
|
||||
if (strcmp(vector[0], system) == 0) {
|
||||
if ((vector[1] == (char *) NULL && (key == NULL || *key == '\0')) ||
|
||||
(vector[1] != (char *) NULL && strcmp(vector[1], key) == 0)) {
|
||||
rc = VALID; /* Valid */
|
||||
} else {
|
||||
rc = INVALID; /* Invalid */
|
||||
}
|
||||
break;
|
||||
}
|
||||
result = (pw = getpwnam(name)) &&
|
||||
!strcmp(crypt(key, pw->pw_passwd), pw->pw_passwd);
|
||||
endpwent();
|
||||
return result;
|
||||
}
|
||||
CloseSecret(fp);
|
||||
return (rc);
|
||||
|
||||
return !strcmp(data, key);
|
||||
}
|
||||
|
||||
int
|
||||
AuthValidate(const char *fname, const char *system, const char *key)
|
||||
auth_Select(struct bundle *bundle, const char *name, struct physical *physical)
|
||||
{
|
||||
FILE *fp;
|
||||
int n;
|
||||
char *vector[5];
|
||||
char buff[LINE_LEN];
|
||||
char passwd[100];
|
||||
|
||||
fp = OpenSecret(fname);
|
||||
if (fp == NULL)
|
||||
return (0);
|
||||
while (fgets(buff, sizeof buff, fp)) {
|
||||
if (buff[0] == '#')
|
||||
continue;
|
||||
buff[strlen(buff) - 1] = 0;
|
||||
memset(vector, '\0', sizeof vector);
|
||||
n = MakeArgs(buff, vector, VECSIZE(vector));
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (strcmp(vector[0], system) == 0) {
|
||||
ExpandString(vector[1], passwd, sizeof passwd, 0);
|
||||
if (strcmp(passwd, key) == 0) {
|
||||
if (*name == '\0') {
|
||||
ipcp_Setup(&bundle->ncp.ipcp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fp = OpenSecret(SECRETFILE);
|
||||
if (fp != NULL) {
|
||||
while (fgets(buff, sizeof buff, fp)) {
|
||||
if (buff[0] == '#')
|
||||
continue;
|
||||
buff[strlen(buff) - 1] = 0;
|
||||
memset(vector, '\0', sizeof vector);
|
||||
n = MakeArgs(buff, vector, VECSIZE(vector));
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (strcmp(vector[0], name) == 0)
|
||||
CloseSecret(fp);
|
||||
if (n > 2 && !UseHisaddr(vector[2], 1))
|
||||
return (0);
|
||||
IpcpInit();
|
||||
/*
|
||||
memset(&bundle->ncp.ipcp.cfg.peer_range, '\0',
|
||||
sizeof bundle->ncp.ipcp.cfg.peer_range);
|
||||
*/
|
||||
if (n > 2 && !ipcp_UseHisaddr(bundle, vector[2], 1))
|
||||
return 0;
|
||||
ipcp_Setup(&bundle->ncp.ipcp);
|
||||
if (n > 3)
|
||||
SetLabel(vector[3]);
|
||||
return (1); /* Valid */
|
||||
bundle_SetLabel(bundle, vector[3]);
|
||||
return 1; /* Valid */
|
||||
}
|
||||
CloseSecret(fp);
|
||||
}
|
||||
|
||||
#ifndef NOPASSWDAUTH
|
||||
/* Let 'em in anyway - they must have been in the passwd file */
|
||||
ipcp_Setup(&bundle->ncp.ipcp);
|
||||
return 1;
|
||||
#else
|
||||
/* Disappeared from ppp.secret ? */
|
||||
return 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
auth_Validate(struct bundle *bundle, const char *system,
|
||||
const char *key, struct physical *physical)
|
||||
{
|
||||
/* Used by PAP routines */
|
||||
|
||||
FILE *fp;
|
||||
int n;
|
||||
char *vector[5];
|
||||
char buff[LINE_LEN];
|
||||
|
||||
fp = OpenSecret(SECRETFILE);
|
||||
if (fp != NULL) {
|
||||
while (fgets(buff, sizeof buff, fp)) {
|
||||
if (buff[0] == '#')
|
||||
continue;
|
||||
buff[strlen(buff) - 1] = 0;
|
||||
memset(vector, '\0', sizeof vector);
|
||||
n = MakeArgs(buff, vector, VECSIZE(vector));
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (strcmp(vector[0], system) == 0) {
|
||||
CloseSecret(fp);
|
||||
return auth_CheckPasswd(vector[0], vector[1], key);
|
||||
}
|
||||
}
|
||||
CloseSecret(fp);
|
||||
}
|
||||
CloseSecret(fp);
|
||||
return (0); /* Invalid */
|
||||
|
||||
#ifndef NOPASSWDAUTH
|
||||
if (Enabled(bundle, OPT_PASSWDAUTH))
|
||||
return auth_CheckPasswd(system, "*", key);
|
||||
#endif
|
||||
|
||||
return 0; /* Invalid */
|
||||
}
|
||||
|
||||
char *
|
||||
AuthGetSecret(const char *fname, const char *system, int len, int setaddr)
|
||||
auth_GetSecret(struct bundle *bundle, const char *system, int len,
|
||||
struct physical *physical)
|
||||
{
|
||||
/* Used by CHAP routines */
|
||||
|
||||
FILE *fp;
|
||||
int n;
|
||||
char *vector[5];
|
||||
char buff[LINE_LEN];
|
||||
static char passwd[100];
|
||||
static char buff[LINE_LEN];
|
||||
|
||||
fp = OpenSecret(fname);
|
||||
fp = OpenSecret(SECRETFILE);
|
||||
if (fp == NULL)
|
||||
return (NULL);
|
||||
|
||||
while (fgets(buff, sizeof buff, fp)) {
|
||||
if (buff[0] == '#')
|
||||
continue;
|
||||
@ -156,19 +196,8 @@ AuthGetSecret(const char *fname, const char *system, int len, int setaddr)
|
||||
if (n < 2)
|
||||
continue;
|
||||
if (strlen(vector[0]) == len && strncmp(vector[0], system, len) == 0) {
|
||||
ExpandString(vector[1], passwd, sizeof passwd, 0);
|
||||
if (setaddr) {
|
||||
memset(&DefHisAddress, '\0', sizeof DefHisAddress);
|
||||
}
|
||||
if (n > 2 && setaddr) {
|
||||
if (UseHisaddr(vector[2], 1))
|
||||
IpcpInit();
|
||||
else
|
||||
return NULL;
|
||||
}
|
||||
if (n > 3)
|
||||
SetLabel(vector[3]);
|
||||
return (passwd);
|
||||
CloseSecret(fp);
|
||||
return vector[1];
|
||||
}
|
||||
}
|
||||
CloseSecret(fp);
|
||||
@ -178,36 +207,42 @@ AuthGetSecret(const char *fname, const char *system, int len, int setaddr)
|
||||
static void
|
||||
AuthTimeout(void *vauthp)
|
||||
{
|
||||
struct pppTimer *tp;
|
||||
struct authinfo *authp = (struct authinfo *)vauthp;
|
||||
|
||||
tp = &authp->authtimer;
|
||||
StopTimer(tp);
|
||||
timer_Stop(&authp->authtimer);
|
||||
if (--authp->retry > 0) {
|
||||
StartTimer(tp);
|
||||
(authp->ChallengeFunc) (++authp->id);
|
||||
timer_Start(&authp->authtimer);
|
||||
(*authp->ChallengeFunc)(authp, ++authp->id, authp->physical);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StartAuthChallenge(struct authinfo *authp)
|
||||
auth_Init(struct authinfo *authinfo)
|
||||
{
|
||||
struct pppTimer *tp;
|
||||
|
||||
tp = &authp->authtimer;
|
||||
StopTimer(tp);
|
||||
tp->func = AuthTimeout;
|
||||
tp->load = VarRetryTimeout * SECTICKS;
|
||||
tp->state = TIMER_STOPPED;
|
||||
tp->arg = (void *) authp;
|
||||
StartTimer(tp);
|
||||
authp->retry = 3;
|
||||
authp->id = 1;
|
||||
(authp->ChallengeFunc) (authp->id);
|
||||
memset(authinfo, '\0', sizeof(struct authinfo));
|
||||
authinfo->cfg.fsmretry = DEF_FSMRETRY;
|
||||
}
|
||||
|
||||
void
|
||||
StopAuthTimer(struct authinfo *authp)
|
||||
auth_StartChallenge(struct authinfo *authp, struct physical *physical,
|
||||
void (*fn)(struct authinfo *, int, struct physical *))
|
||||
{
|
||||
StopTimer(&authp->authtimer);
|
||||
authp->ChallengeFunc = fn;
|
||||
authp->physical = physical;
|
||||
timer_Stop(&authp->authtimer);
|
||||
authp->authtimer.func = AuthTimeout;
|
||||
authp->authtimer.name = "auth";
|
||||
authp->authtimer.load = authp->cfg.fsmretry * SECTICKS;
|
||||
authp->authtimer.arg = (void *) authp;
|
||||
authp->retry = 3;
|
||||
authp->id = 1;
|
||||
(*authp->ChallengeFunc)(authp, authp->id, physical);
|
||||
timer_Start(&authp->authtimer);
|
||||
}
|
||||
|
||||
void
|
||||
auth_StopTimer(struct authinfo *authp)
|
||||
{
|
||||
timer_Stop(&authp->authtimer);
|
||||
authp->physical = NULL;
|
||||
}
|
||||
|
@ -15,27 +15,34 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: auth.h,v 1.9 1997/10/26 01:02:09 brian Exp $
|
||||
* $Id: auth.h,v 1.10.2.9 1998/05/01 19:23:54 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
typedef enum {
|
||||
VALID,
|
||||
INVALID,
|
||||
NOT_FOUND
|
||||
} LOCAL_AUTH_VALID;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
|
||||
struct authinfo {
|
||||
void (*ChallengeFunc) (int);
|
||||
void (*ChallengeFunc)(struct authinfo *, int, struct physical *);
|
||||
struct pppTimer authtimer;
|
||||
int retry;
|
||||
int id;
|
||||
struct physical *physical;
|
||||
struct {
|
||||
u_int fsmretry;
|
||||
} cfg;
|
||||
};
|
||||
|
||||
extern LOCAL_AUTH_VALID LocalAuthValidate(const char *, const char *, const char *);
|
||||
extern void StopAuthTimer(struct authinfo *);
|
||||
extern void StartAuthChallenge(struct authinfo *);
|
||||
extern void LocalAuthInit(void);
|
||||
extern int AuthValidate(const char *, const char *, const char *);
|
||||
extern char *AuthGetSecret(const char *, const char *, int, int);
|
||||
extern const char *Auth2Nam(u_short);
|
||||
|
||||
extern void auth_Init(struct authinfo *);
|
||||
extern void auth_StopTimer(struct authinfo *);
|
||||
extern void auth_StartChallenge(struct authinfo *, struct physical *,
|
||||
void (*fn)(struct authinfo *, int,
|
||||
struct physical *));
|
||||
extern int auth_Validate(struct bundle *, const char *, const char *,
|
||||
struct physical *);
|
||||
extern char *auth_GetSecret(struct bundle *, const char *, int,
|
||||
struct physical *);
|
||||
extern int auth_Select(struct bundle *, const char *, struct physical *);
|
||||
|
1615
usr.sbin/ppp/bundle.c
Normal file
1615
usr.sbin/ppp/bundle.c
Normal file
File diff suppressed because it is too large
Load Diff
170
usr.sbin/ppp/bundle.h
Normal file
170
usr.sbin/ppp/bundle.h
Normal file
@ -0,0 +1,170 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: bundle.h,v 1.1.2.42 1998/05/21 01:13:24 brian Exp $
|
||||
*/
|
||||
|
||||
#define PHASE_DEAD 0 /* Link is dead */
|
||||
#define PHASE_ESTABLISH 1 /* Establishing link */
|
||||
#define PHASE_AUTHENTICATE 2 /* Being authenticated */
|
||||
#define PHASE_NETWORK 3 /* We're alive ! */
|
||||
#define PHASE_TERMINATE 4 /* Terminating link */
|
||||
|
||||
/* cfg.opt bit settings */
|
||||
#define OPT_IDCHECK 0x01
|
||||
#define OPT_LOOPBACK 0x02
|
||||
#define OPT_PASSWDAUTH 0x04
|
||||
#define OPT_PROXY 0x08
|
||||
#define OPT_SROUTES 0x10
|
||||
#define OPT_THROUGHPUT 0x20
|
||||
#define OPT_UTMP 0x40
|
||||
|
||||
#define MAX_ENDDISC_CLASS 5
|
||||
|
||||
#define Enabled(b, o) ((b)->cfg.opt & (o))
|
||||
|
||||
struct sockaddr_un;
|
||||
struct datalink;
|
||||
struct physical;
|
||||
struct link;
|
||||
struct server;
|
||||
struct prompt;
|
||||
|
||||
struct bundle {
|
||||
struct descriptor desc; /* really all our datalinks */
|
||||
int unit; /* The device/interface unit number */
|
||||
|
||||
struct {
|
||||
char Name[20]; /* The /dev/XXXX name */
|
||||
int fd; /* The /dev/XXXX descriptor */
|
||||
} dev;
|
||||
|
||||
struct {
|
||||
u_long Speed; /* struct tuninfo speed */
|
||||
int Index; /* The interface index */
|
||||
char *Name; /* The interface name */
|
||||
} ifp;
|
||||
|
||||
int routing_seq; /* The current routing sequence number */
|
||||
u_int phase; /* Curent phase */
|
||||
int phys_type; /* Union of all physical::type's */
|
||||
|
||||
unsigned CleaningUp : 1; /* Going to exit.... */
|
||||
|
||||
struct fsm_parent fsm; /* Our callback functions */
|
||||
struct datalink *links; /* Our data links */
|
||||
|
||||
struct {
|
||||
int idle_timeout; /* NCP Idle timeout value */
|
||||
struct {
|
||||
char name[50]; /* PAP/CHAP system name */
|
||||
char key[50]; /* PAP/CHAP key */
|
||||
} auth;
|
||||
unsigned opt; /* Uses OPT_ bits from above */
|
||||
char label[50]; /* last thing `load'ed */
|
||||
u_short mtu; /* Interface mtu */
|
||||
|
||||
struct { /* We need/don't need another link when */
|
||||
struct { /* more/less than */
|
||||
int packets; /* this number of packets are queued for */
|
||||
int timeout; /* this number of seconds */
|
||||
} max, min;
|
||||
} autoload;
|
||||
} cfg;
|
||||
|
||||
struct {
|
||||
struct ipcp ipcp; /* Our IPCP FSM */
|
||||
struct mp mp; /* Our MP */
|
||||
} ncp;
|
||||
|
||||
struct {
|
||||
struct filter in; /* incoming packet filter */
|
||||
struct filter out; /* outgoing packet filter */
|
||||
struct filter dial; /* dial-out packet filter */
|
||||
struct filter alive; /* keep-alive packet filter */
|
||||
} filter;
|
||||
|
||||
struct {
|
||||
struct pppTimer timer; /* timeout after cfg.idle_timeout */
|
||||
time_t done;
|
||||
} idle;
|
||||
|
||||
struct {
|
||||
int fd; /* write status here */
|
||||
} notify;
|
||||
|
||||
struct {
|
||||
struct pppTimer timer;
|
||||
time_t done;
|
||||
unsigned running : 1;
|
||||
unsigned comingup : 1;
|
||||
} autoload;
|
||||
};
|
||||
|
||||
#define descriptor2bundle(d) \
|
||||
((d)->type == BUNDLE_DESCRIPTOR ? (struct bundle *)(d) : NULL)
|
||||
|
||||
extern struct bundle *bundle_Create(const char *, struct prompt *, int);
|
||||
extern void bundle_Destroy(struct bundle *);
|
||||
extern const char *bundle_PhaseName(struct bundle *);
|
||||
#define bundle_Phase(b) ((b)->phase)
|
||||
extern void bundle_NewPhase(struct bundle *, u_int);
|
||||
extern int bundle_LinkIsUp(const struct bundle *);
|
||||
extern int bundle_SetRoute(struct bundle *, int, struct in_addr,
|
||||
struct in_addr, struct in_addr, int);
|
||||
extern void bundle_Close(struct bundle *, const char *, int);
|
||||
extern void bundle_Down(struct bundle *);
|
||||
extern void bundle_Open(struct bundle *, const char *, int);
|
||||
extern void bundle_LinkClosed(struct bundle *, struct datalink *);
|
||||
|
||||
extern int bundle_FillQueues(struct bundle *);
|
||||
extern int bundle_ShowLinks(struct cmdargs const *);
|
||||
extern int bundle_ShowStatus(struct cmdargs const *);
|
||||
extern void bundle_StartIdleTimer(struct bundle *);
|
||||
extern void bundle_SetIdleTimer(struct bundle *, int);
|
||||
extern void bundle_StopIdleTimer(struct bundle *);
|
||||
extern int bundle_IsDead(struct bundle *);
|
||||
extern struct datalink *bundle2datalink(struct bundle *, const char *);
|
||||
|
||||
extern void bundle_RegisterDescriptor(struct bundle *, struct descriptor *);
|
||||
extern void bundle_UnRegisterDescriptor(struct bundle *, struct descriptor *);
|
||||
|
||||
extern void bundle_DelPromptDescriptors(struct bundle *, struct server *);
|
||||
extern void bundle_DisplayPrompt(struct bundle *);
|
||||
extern void bundle_WriteTermPrompt(struct bundle *, struct datalink *,
|
||||
const char *, int);
|
||||
extern void bundle_SetTtyCommandMode(struct bundle *, struct datalink *);
|
||||
|
||||
extern int bundle_DatalinkClone(struct bundle *, struct datalink *,
|
||||
const char *);
|
||||
extern void bundle_DatalinkRemove(struct bundle *, struct datalink *);
|
||||
extern void bundle_CleanDatalinks(struct bundle *);
|
||||
extern void bundle_SetLabel(struct bundle *, const char *);
|
||||
extern const char *bundle_GetLabel(struct bundle *);
|
||||
extern void bundle_SendDatalink(struct datalink *, int, struct sockaddr_un *);
|
||||
extern void bundle_ReceiveDatalink(struct bundle *, int, struct sockaddr_un *);
|
||||
extern int bundle_SetMode(struct bundle *, struct datalink *, int);
|
||||
extern int bundle_RenameDatalink(struct bundle *, struct datalink *,
|
||||
const char *);
|
@ -17,16 +17,20 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ccp.c,v 1.30 1998/01/21 02:15:10 brian Exp $
|
||||
* $Id: ccp.c,v 1.30.2.45 1998/05/21 01:26:05 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Support other compression protocols
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
@ -37,47 +41,53 @@
|
||||
#include "lcpproto.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "phase.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "pred.h"
|
||||
#include "deflate.h"
|
||||
|
||||
struct ccpstate CcpInfo = { -1, -1, -1, -1 };
|
||||
#include "throughput.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
#include "bundle.h"
|
||||
|
||||
static void CcpSendConfigReq(struct fsm *);
|
||||
static void CcpSendTerminateReq(struct fsm *);
|
||||
static void CcpSendTerminateAck(struct fsm *);
|
||||
static void CcpDecodeConfig(u_char *, int, int);
|
||||
static void CcpSentTerminateReq(struct fsm *);
|
||||
static void CcpSendTerminateAck(struct fsm *, u_char);
|
||||
static void CcpDecodeConfig(struct fsm *, u_char *, int, int,
|
||||
struct fsm_decode *);
|
||||
static void CcpLayerStart(struct fsm *);
|
||||
static void CcpLayerFinish(struct fsm *);
|
||||
static void CcpLayerUp(struct fsm *);
|
||||
static int CcpLayerUp(struct fsm *);
|
||||
static void CcpLayerDown(struct fsm *);
|
||||
static void CcpInitRestartCounter(struct fsm *);
|
||||
static void CcpRecvResetReq(struct fsm *);
|
||||
static void CcpRecvResetAck(struct fsm *, u_char);
|
||||
|
||||
struct fsm CcpFsm = {
|
||||
"CCP",
|
||||
PROTO_CCP,
|
||||
CCP_MAXCODE,
|
||||
0,
|
||||
ST_INITIAL,
|
||||
0, 0, 0,
|
||||
{0, 0, 0, NULL, NULL, NULL}, /* FSM timer */
|
||||
{0, 0, 0, NULL, NULL, NULL}, /* Open timer */
|
||||
{0, 0, 0, NULL, NULL, NULL}, /* Stopped timer */
|
||||
LogCCP,
|
||||
|
||||
static struct fsm_callbacks ccp_Callbacks = {
|
||||
CcpLayerUp,
|
||||
CcpLayerDown,
|
||||
CcpLayerStart,
|
||||
CcpLayerFinish,
|
||||
CcpInitRestartCounter,
|
||||
CcpSendConfigReq,
|
||||
CcpSendTerminateReq,
|
||||
CcpSentTerminateReq,
|
||||
CcpSendTerminateAck,
|
||||
CcpDecodeConfig,
|
||||
CcpRecvResetReq,
|
||||
CcpRecvResetAck
|
||||
};
|
||||
|
||||
static const char *ccp_TimerNames[] =
|
||||
{"CCP restart", "CCP openmode", "CCP stopped"};
|
||||
|
||||
static char const *cftypes[] = {
|
||||
/* Check out the latest ``Compression Control Protocol'' rfc (rfc1962.txt) */
|
||||
"OUI", /* 0: OUI */
|
||||
@ -88,14 +98,14 @@ static char const *cftypes[] = {
|
||||
"???", "???", "???", "???", "???", "???",
|
||||
"HWPPC", /* 16: Hewlett-Packard PPC */
|
||||
"STAC", /* 17: Stac Electronics LZS (rfc1974) */
|
||||
"MSPPC", /* 18: Microsoft PPC */
|
||||
"MPPC", /* 18: Microsoft PPC (rfc2118) */
|
||||
"GAND", /* 19: Gandalf FZA (rfc1993) */
|
||||
"V42BIS", /* 20: ARG->DATA.42bis compression */
|
||||
"BSD", /* 21: BSD LZW Compress */
|
||||
"???",
|
||||
"LZS-DCP", /* 23: LZS-DCP Compression Protocol (rfc1967) */
|
||||
"MAGNALINK/DEFLATE", /* 24: Magnalink Variable Resource (rfc1975) */
|
||||
/* 24: Deflate (according to pppd-2.3.1) */
|
||||
/* 24: Deflate (according to pppd-2.3.*) */
|
||||
"DCE", /* 25: Data Circuit-Terminating Equip (rfc1976) */
|
||||
"DEFLATE", /* 26: Deflate (rfc1979) */
|
||||
};
|
||||
@ -117,316 +127,464 @@ static const struct ccp_algorithm *algorithm[] = {
|
||||
&PppdDeflateAlgorithm
|
||||
};
|
||||
|
||||
static int in_algorithm = -1;
|
||||
static int out_algorithm = -1;
|
||||
#define NALGORITHMS (sizeof algorithm/sizeof algorithm[0])
|
||||
|
||||
int
|
||||
ReportCcpStatus(struct cmdargs const *arg)
|
||||
ccp_ReportStatus(struct cmdargs const *arg)
|
||||
{
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "%s [%s]\n", CcpFsm.name, StateNames[CcpFsm.state]);
|
||||
fprintf(VarTerm, "My protocol = %s, His protocol = %s\n",
|
||||
protoname(CcpInfo.my_proto), protoname(CcpInfo.his_proto));
|
||||
fprintf(VarTerm, "Output: %ld --> %ld, Input: %ld --> %ld\n",
|
||||
CcpInfo.uncompout, CcpInfo.compout,
|
||||
CcpInfo.compin, CcpInfo.uncompin);
|
||||
}
|
||||
struct link *l;
|
||||
struct ccp *ccp;
|
||||
|
||||
if (!(l = command_ChooseLink(arg)))
|
||||
return -1;
|
||||
ccp = &l->ccp;
|
||||
|
||||
prompt_Printf(arg->prompt, "%s: %s [%s]\n", l->name, ccp->fsm.name,
|
||||
State2Nam(ccp->fsm.state));
|
||||
prompt_Printf(arg->prompt, " My protocol = %s, His protocol = %s\n",
|
||||
protoname(ccp->my_proto), protoname(ccp->his_proto));
|
||||
prompt_Printf(arg->prompt, " Output: %ld --> %ld, Input: %ld --> %ld\n",
|
||||
ccp->uncompout, ccp->compout,
|
||||
ccp->compin, ccp->uncompin);
|
||||
|
||||
prompt_Printf(arg->prompt, "\n Defaults: ");
|
||||
prompt_Printf(arg->prompt, "FSM retry = %us\n", ccp->cfg.fsmretry);
|
||||
prompt_Printf(arg->prompt, " deflate windows: ");
|
||||
prompt_Printf(arg->prompt, "incoming = %d, ", ccp->cfg.deflate.in.winsize);
|
||||
prompt_Printf(arg->prompt, "outgoing = %d\n", ccp->cfg.deflate.out.winsize);
|
||||
prompt_Printf(arg->prompt, " DEFLATE: %s\n",
|
||||
command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE]));
|
||||
prompt_Printf(arg->prompt, " PREDICTOR1: %s\n",
|
||||
command_ShowNegval(ccp->cfg.neg[CCP_NEG_PRED1]));
|
||||
prompt_Printf(arg->prompt, " DEFLATE24: %s\n",
|
||||
command_ShowNegval(ccp->cfg.neg[CCP_NEG_DEFLATE24]));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
ccpstateInit(void)
|
||||
void
|
||||
ccp_SetupCallbacks(struct ccp *ccp)
|
||||
{
|
||||
if (CcpInfo.in_init)
|
||||
(*algorithm[in_algorithm]->i.Term)();
|
||||
if (CcpInfo.out_init)
|
||||
(*algorithm[out_algorithm]->o.Term)();
|
||||
in_algorithm = -1;
|
||||
out_algorithm = -1;
|
||||
memset(&CcpInfo, '\0', sizeof CcpInfo);
|
||||
CcpInfo.his_proto = CcpInfo.my_proto = -1;
|
||||
CcpInfo.reset_sent = CcpInfo.last_reset = -1;
|
||||
ccp->fsm.fn = &ccp_Callbacks;
|
||||
ccp->fsm.FsmTimer.name = ccp_TimerNames[0];
|
||||
ccp->fsm.OpenTimer.name = ccp_TimerNames[1];
|
||||
ccp->fsm.StoppedTimer.name = ccp_TimerNames[2];
|
||||
}
|
||||
|
||||
void
|
||||
CcpInit()
|
||||
ccp_Init(struct ccp *ccp, struct bundle *bundle, struct link *l,
|
||||
const struct fsm_parent *parent)
|
||||
{
|
||||
FsmInit(&CcpFsm);
|
||||
ccpstateInit();
|
||||
CcpFsm.maxconfig = 10;
|
||||
/* Initialise ourselves */
|
||||
|
||||
fsm_Init(&ccp->fsm, "CCP", PROTO_CCP, 1, CCP_MAXCODE, 10, LogCCP,
|
||||
bundle, l, parent, &ccp_Callbacks, ccp_TimerNames);
|
||||
|
||||
ccp->cfg.deflate.in.winsize = 0;
|
||||
ccp->cfg.deflate.out.winsize = 15;
|
||||
ccp->cfg.fsmretry = DEF_FSMRETRY;
|
||||
ccp->cfg.neg[CCP_NEG_DEFLATE] = NEG_ENABLED|NEG_ACCEPTED;
|
||||
ccp->cfg.neg[CCP_NEG_PRED1] = NEG_ENABLED|NEG_ACCEPTED;
|
||||
ccp->cfg.neg[CCP_NEG_DEFLATE24] = 0;
|
||||
|
||||
ccp_Setup(ccp);
|
||||
}
|
||||
|
||||
void
|
||||
ccp_Setup(struct ccp *ccp)
|
||||
{
|
||||
/* Set ourselves up for a startup */
|
||||
ccp->fsm.open_mode = 0;
|
||||
ccp->fsm.maxconfig = 10;
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
ccp->reset_sent = ccp->last_reset = -1;
|
||||
ccp->in.algorithm = ccp->out.algorithm = -1;
|
||||
ccp->in.state = ccp->out.state = NULL;
|
||||
ccp->in.opt.id = -1;
|
||||
ccp->out.opt = NULL;
|
||||
ccp->his_reject = ccp->my_reject = 0;
|
||||
ccp->uncompout = ccp->compout = 0;
|
||||
ccp->uncompin = ccp->compin = 0;
|
||||
}
|
||||
|
||||
static void
|
||||
CcpInitRestartCounter(struct fsm *fp)
|
||||
{
|
||||
fp->FsmTimer.load = VarRetryTimeout * SECTICKS;
|
||||
/* Set fsm timer load */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
|
||||
fp->FsmTimer.load = ccp->cfg.fsmretry * SECTICKS;
|
||||
fp->restart = 5;
|
||||
}
|
||||
|
||||
static void
|
||||
CcpSendConfigReq(struct fsm *fp)
|
||||
{
|
||||
u_char *cp;
|
||||
int f;
|
||||
/* Send config REQ please */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
struct ccp_opt **o;
|
||||
u_char *cp, buff[100];
|
||||
int f, alloc;
|
||||
|
||||
LogPrintf(LogCCP, "CcpSendConfigReq\n");
|
||||
cp = ReqBuff;
|
||||
CcpInfo.my_proto = -1;
|
||||
out_algorithm = -1;
|
||||
cp = buff;
|
||||
o = &ccp->out.opt;
|
||||
alloc = ccp->his_reject == 0 && ccp->out.opt == NULL;
|
||||
ccp->my_proto = -1;
|
||||
ccp->out.algorithm = -1;
|
||||
for (f = 0; f < NALGORITHMS; f++)
|
||||
if (Enabled(algorithm[f]->Conf) && !REJECTED(&CcpInfo, algorithm[f]->id)) {
|
||||
struct lcp_opt o;
|
||||
if (IsEnabled(ccp->cfg.neg[algorithm[f]->Neg]) &&
|
||||
!REJECTED(ccp, algorithm[f]->id)) {
|
||||
|
||||
(*algorithm[f]->o.Get)(&o);
|
||||
cp += LcpPutConf(LogCCP, cp, &o, cftypes[o.id],
|
||||
(*algorithm[f]->Disp)(&o));
|
||||
CcpInfo.my_proto = o.id;
|
||||
out_algorithm = f;
|
||||
if (!alloc)
|
||||
for (o = &ccp->out.opt; *o != NULL; o = &(*o)->next)
|
||||
if ((*o)->val.id == algorithm[f]->id && (*o)->algorithm == f)
|
||||
break;
|
||||
|
||||
if (alloc || *o == NULL) {
|
||||
*o = (struct ccp_opt *)malloc(sizeof(struct ccp_opt));
|
||||
(*o)->val.id = algorithm[f]->id;
|
||||
(*o)->val.len = 2;
|
||||
(*o)->next = NULL;
|
||||
(*o)->algorithm = f;
|
||||
(*algorithm[f]->o.OptInit)(&(*o)->val, &ccp->cfg);
|
||||
}
|
||||
|
||||
if (cp + (*o)->val.len > buff + sizeof buff) {
|
||||
log_Printf(LogERROR, "%s: CCP REQ buffer overrun !\n", fp->link->name);
|
||||
break;
|
||||
}
|
||||
memcpy(cp, &(*o)->val, (*o)->val.len);
|
||||
cp += (*o)->val.len;
|
||||
|
||||
ccp->my_proto = (*o)->val.id;
|
||||
ccp->out.algorithm = f;
|
||||
|
||||
if (alloc)
|
||||
o = &(*o)->next;
|
||||
}
|
||||
FsmOutput(fp, CODE_CONFIGREQ, fp->reqid++, ReqBuff, cp - ReqBuff);
|
||||
|
||||
fsm_Output(fp, CODE_CONFIGREQ, fp->reqid, buff, cp - buff);
|
||||
}
|
||||
|
||||
void
|
||||
CcpSendResetReq(struct fsm *fp)
|
||||
ccp_SendResetReq(struct fsm *fp)
|
||||
{
|
||||
LogPrintf(LogCCP, "SendResetReq(%d)\n", fp->reqid);
|
||||
CcpInfo.reset_sent = fp->reqid;
|
||||
CcpInfo.last_reset = -1;
|
||||
FsmOutput(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
|
||||
/* We can't read our input - ask peer to reset */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
|
||||
ccp->reset_sent = fp->reqid;
|
||||
ccp->last_reset = -1;
|
||||
fsm_Output(fp, CODE_RESETREQ, fp->reqid, NULL, 0);
|
||||
}
|
||||
|
||||
static void
|
||||
CcpSendTerminateReq(struct fsm *fp)
|
||||
CcpSentTerminateReq(struct fsm *fp)
|
||||
{
|
||||
/* XXX: No code yet */
|
||||
/* Term REQ just sent by FSM */
|
||||
}
|
||||
|
||||
static void
|
||||
CcpSendTerminateAck(struct fsm *fp)
|
||||
CcpSendTerminateAck(struct fsm *fp, u_char id)
|
||||
{
|
||||
LogPrintf(LogCCP, "CcpSendTerminateAck\n");
|
||||
FsmOutput(fp, CODE_TERMACK, fp->reqid++, NULL, 0);
|
||||
/* Send Term ACK please */
|
||||
fsm_Output(fp, CODE_TERMACK, id, NULL, 0);
|
||||
}
|
||||
|
||||
void
|
||||
static void
|
||||
CcpRecvResetReq(struct fsm *fp)
|
||||
{
|
||||
if (out_algorithm >= 0 && out_algorithm < NALGORITHMS)
|
||||
(*algorithm[out_algorithm]->o.Reset)();
|
||||
/* Got a reset REQ, reset outgoing dictionary */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
if (ccp->out.state != NULL)
|
||||
(*algorithm[ccp->out.algorithm]->o.Reset)(ccp->out.state);
|
||||
}
|
||||
|
||||
static void
|
||||
CcpLayerStart(struct fsm *fp)
|
||||
{
|
||||
LogPrintf(LogCCP, "CcpLayerStart.\n");
|
||||
/* We're about to start up ! */
|
||||
log_Printf(LogCCP, "%s: CcpLayerStart.\n", fp->link->name);
|
||||
}
|
||||
|
||||
static void
|
||||
CcpLayerFinish(struct fsm *fp)
|
||||
{
|
||||
LogPrintf(LogCCP, "CcpLayerFinish.\n");
|
||||
ccpstateInit();
|
||||
/* We're now down */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
struct ccp_opt *next;
|
||||
|
||||
log_Printf(LogCCP, "%s: CcpLayerFinish.\n", fp->link->name);
|
||||
if (ccp->in.state != NULL) {
|
||||
(*algorithm[ccp->in.algorithm]->i.Term)(ccp->in.state);
|
||||
ccp->in.state = NULL;
|
||||
ccp->in.algorithm = -1;
|
||||
}
|
||||
if (ccp->out.state != NULL) {
|
||||
(*algorithm[ccp->out.algorithm]->o.Term)(ccp->out.state);
|
||||
ccp->out.state = NULL;
|
||||
ccp->out.algorithm = -1;
|
||||
}
|
||||
ccp->his_reject = ccp->my_reject = 0;
|
||||
|
||||
while (ccp->out.opt) {
|
||||
next = ccp->out.opt->next;
|
||||
free(ccp->out.opt);
|
||||
ccp->out.opt = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
CcpLayerDown(struct fsm *fp)
|
||||
{
|
||||
LogPrintf(LogCCP, "CcpLayerDown.\n");
|
||||
ccpstateInit();
|
||||
/* About to come down */
|
||||
log_Printf(LogCCP, "%s: CcpLayerDown.\n", fp->link->name);
|
||||
}
|
||||
|
||||
/*
|
||||
* Called when CCP has reached the OPEN state
|
||||
*/
|
||||
static void
|
||||
static int
|
||||
CcpLayerUp(struct fsm *fp)
|
||||
{
|
||||
LogPrintf(LogCCP, "CcpLayerUp(%d).\n", fp->state);
|
||||
LogPrintf(LogCCP, "Out = %s[%d], In = %s[%d]\n",
|
||||
protoname(CcpInfo.my_proto), CcpInfo.my_proto,
|
||||
protoname(CcpInfo.his_proto), CcpInfo.his_proto);
|
||||
if (!CcpInfo.in_init && in_algorithm >= 0 && in_algorithm < NALGORITHMS) {
|
||||
(*algorithm[in_algorithm]->i.Init)();
|
||||
CcpInfo.in_init = 1;
|
||||
}
|
||||
if (!CcpInfo.out_init && out_algorithm >= 0 && out_algorithm < NALGORITHMS) {
|
||||
(*algorithm[out_algorithm]->o.Init)();
|
||||
CcpInfo.out_init = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CcpUp()
|
||||
{
|
||||
FsmUp(&CcpFsm);
|
||||
LogPrintf(LogCCP, "CCP Up event!!\n");
|
||||
}
|
||||
|
||||
void
|
||||
CcpOpen()
|
||||
{
|
||||
int f;
|
||||
|
||||
for (f = 0; f < NALGORITHMS; f++)
|
||||
if (Enabled(algorithm[f]->Conf)) {
|
||||
CcpFsm.open_mode = 0;
|
||||
FsmOpen(&CcpFsm);
|
||||
break;
|
||||
/* We're now up */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
log_Printf(LogCCP, "%s: CcpLayerUp.\n", fp->link->name);
|
||||
if (ccp->in.state == NULL && ccp->in.algorithm >= 0 &&
|
||||
ccp->in.algorithm < NALGORITHMS) {
|
||||
ccp->in.state = (*algorithm[ccp->in.algorithm]->i.Init)(&ccp->in.opt);
|
||||
if (ccp->in.state == NULL) {
|
||||
log_Printf(LogERROR, "%s: %s (in) initialisation failure\n",
|
||||
fp->link->name, protoname(ccp->his_proto));
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
fsm_Close(fp);
|
||||
}
|
||||
}
|
||||
|
||||
if (f == NALGORITHMS)
|
||||
for (f = 0; f < NALGORITHMS; f++)
|
||||
if (Acceptable(algorithm[f]->Conf)) {
|
||||
CcpFsm.open_mode = OPEN_PASSIVE;
|
||||
FsmOpen(&CcpFsm);
|
||||
break;
|
||||
}
|
||||
if (ccp->out.state == NULL && ccp->out.algorithm >= 0 &&
|
||||
ccp->out.algorithm < NALGORITHMS) {
|
||||
ccp->out.state = (*algorithm[ccp->out.algorithm]->o.Init)
|
||||
(&ccp->out.opt->val);
|
||||
if (ccp->out.state == NULL) {
|
||||
log_Printf(LogERROR, "%s: %s (out) initialisation failure\n",
|
||||
fp->link->name, protoname(ccp->my_proto));
|
||||
ccp->his_proto = ccp->my_proto = -1;
|
||||
fsm_Close(fp);
|
||||
}
|
||||
}
|
||||
|
||||
log_Printf(LogCCP, "%s: Out = %s[%d], In = %s[%d]\n",
|
||||
fp->link->name, protoname(ccp->my_proto), ccp->my_proto,
|
||||
protoname(ccp->his_proto), ccp->his_proto);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
CcpDecodeConfig(u_char *cp, int plen, int mode_type)
|
||||
CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
||||
struct fsm_decode *dec)
|
||||
{
|
||||
/* Deal with incoming data */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
int type, length;
|
||||
int f;
|
||||
|
||||
ackp = AckBuff;
|
||||
nakp = NakBuff;
|
||||
rejp = RejBuff;
|
||||
const char *end;
|
||||
|
||||
while (plen >= sizeof(struct fsmconfig)) {
|
||||
type = *cp;
|
||||
length = cp[1];
|
||||
if (type < NCFTYPES)
|
||||
LogPrintf(LogCCP, " %s[%d]\n", cftypes[type], length);
|
||||
else
|
||||
LogPrintf(LogCCP, " ???[%d]\n", length);
|
||||
|
||||
if (length == 0) {
|
||||
log_Printf(LogCCP, "%s: CCP size zero\n", fp->link->name);
|
||||
break;
|
||||
}
|
||||
|
||||
if (length > sizeof(struct lcp_opt)) {
|
||||
length = sizeof(struct lcp_opt);
|
||||
log_Printf(LogCCP, "%s: Warning: Truncating length to %d\n",
|
||||
fp->link->name, length);
|
||||
}
|
||||
|
||||
for (f = NALGORITHMS-1; f > -1; f--)
|
||||
if (algorithm[f]->id == type)
|
||||
break;
|
||||
|
||||
end = f == -1 ? "" : (*algorithm[f]->Disp)((struct lcp_opt *)cp);
|
||||
if (end == NULL)
|
||||
end = "";
|
||||
|
||||
if (type < NCFTYPES)
|
||||
log_Printf(LogCCP, " %s[%d] %s\n", cftypes[type], length, end);
|
||||
else
|
||||
log_Printf(LogCCP, " ???[%d] %s\n", length, end);
|
||||
|
||||
if (f == -1) {
|
||||
/* Don't understand that :-( */
|
||||
if (mode_type == MODE_REQ) {
|
||||
CcpInfo.my_reject |= (1 << type);
|
||||
memcpy(rejp, cp, length);
|
||||
rejp += length;
|
||||
ccp->my_reject |= (1 << type);
|
||||
memcpy(dec->rejend, cp, length);
|
||||
dec->rejend += length;
|
||||
}
|
||||
} else {
|
||||
struct lcp_opt o;
|
||||
struct ccp_opt *o;
|
||||
|
||||
switch (mode_type) {
|
||||
case MODE_REQ:
|
||||
if (Acceptable(algorithm[f]->Conf) && in_algorithm == -1) {
|
||||
memcpy(&o, cp, length);
|
||||
switch ((*algorithm[f]->i.Set)(&o)) {
|
||||
if (IsAccepted(ccp->cfg.neg[algorithm[f]->Neg]) &&
|
||||
ccp->in.algorithm == -1) {
|
||||
memcpy(&ccp->in.opt, cp, length);
|
||||
switch ((*algorithm[f]->i.Set)(&ccp->in.opt, &ccp->cfg)) {
|
||||
case MODE_REJ:
|
||||
memcpy(rejp, &o, o.len);
|
||||
rejp += o.len;
|
||||
memcpy(dec->rejend, &ccp->in.opt, ccp->in.opt.len);
|
||||
dec->rejend += ccp->in.opt.len;
|
||||
break;
|
||||
case MODE_NAK:
|
||||
memcpy(nakp, &o, o.len);
|
||||
nakp += o.len;
|
||||
memcpy(dec->nakend, &ccp->in.opt, ccp->in.opt.len);
|
||||
dec->nakend += ccp->in.opt.len;
|
||||
break;
|
||||
case MODE_ACK:
|
||||
memcpy(ackp, cp, length);
|
||||
ackp += length;
|
||||
CcpInfo.his_proto = type;
|
||||
in_algorithm = f; /* This one'll do ! */
|
||||
memcpy(dec->ackend, cp, length);
|
||||
dec->ackend += length;
|
||||
ccp->his_proto = type;
|
||||
ccp->in.algorithm = f; /* This one'll do :-) */
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
memcpy(rejp, cp, length);
|
||||
rejp += length;
|
||||
memcpy(dec->rejend, cp, length);
|
||||
dec->rejend += length;
|
||||
}
|
||||
break;
|
||||
case MODE_NAK:
|
||||
memcpy(&o, cp, length);
|
||||
if ((*algorithm[f]->o.Set)(&o) == MODE_ACK)
|
||||
CcpInfo.my_proto = algorithm[f]->id;
|
||||
for (o = ccp->out.opt; o != NULL; o = o->next)
|
||||
if (o->val.id == cp[0])
|
||||
break;
|
||||
if (o == NULL)
|
||||
log_Printf(LogCCP, "%s: Warning: Ignoring peer NAK of unsent option\n",
|
||||
fp->link->name);
|
||||
else {
|
||||
CcpInfo.his_reject |= (1 << type);
|
||||
CcpInfo.my_proto = -1;
|
||||
memcpy(&o->val, cp, length);
|
||||
if ((*algorithm[f]->o.Set)(&o->val) == MODE_ACK)
|
||||
ccp->my_proto = algorithm[f]->id;
|
||||
else {
|
||||
ccp->his_reject |= (1 << type);
|
||||
ccp->my_proto = -1;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case MODE_REJ:
|
||||
CcpInfo.his_reject |= (1 << type);
|
||||
CcpInfo.my_proto = -1;
|
||||
ccp->his_reject |= (1 << type);
|
||||
ccp->my_proto = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
plen -= length;
|
||||
cp += length;
|
||||
plen -= cp[1];
|
||||
cp += cp[1];
|
||||
}
|
||||
|
||||
if (rejp != RejBuff) {
|
||||
ackp = AckBuff; /* let's not send both ! */
|
||||
CcpInfo.his_proto = -1;
|
||||
in_algorithm = -1;
|
||||
if (mode_type != MODE_NOP) {
|
||||
if (dec->rejend != dec->rej) {
|
||||
/* rejects are preferred */
|
||||
dec->ackend = dec->ack;
|
||||
dec->nakend = dec->nak;
|
||||
if (ccp->in.state == NULL) {
|
||||
ccp->his_proto = -1;
|
||||
ccp->in.algorithm = -1;
|
||||
}
|
||||
} else if (dec->nakend != dec->nak) {
|
||||
/* then NAKs */
|
||||
dec->ackend = dec->ack;
|
||||
if (ccp->in.state == NULL) {
|
||||
ccp->his_proto = -1;
|
||||
ccp->in.algorithm = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CcpInput(struct mbuf *bp)
|
||||
ccp_Input(struct ccp *ccp, struct bundle *bundle, struct mbuf *bp)
|
||||
{
|
||||
if (phase == PHASE_NETWORK)
|
||||
FsmInput(&CcpFsm, bp);
|
||||
/* Got PROTO_CCP from link */
|
||||
if (bundle_Phase(bundle) == PHASE_NETWORK)
|
||||
fsm_Input(&ccp->fsm, bp);
|
||||
else {
|
||||
if (phase > PHASE_NETWORK)
|
||||
LogPrintf(LogCCP, "Error: Unexpected CCP in phase %d\n", phase);
|
||||
pfree(bp);
|
||||
if (bundle_Phase(bundle) < PHASE_NETWORK)
|
||||
log_Printf(LogCCP, "%s: Error: Unexpected CCP in phase %s (ignored)\n",
|
||||
ccp->fsm.link->name, bundle_PhaseName(bundle));
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
CcpResetInput(u_char id)
|
||||
static void
|
||||
CcpRecvResetAck(struct fsm *fp, u_char id)
|
||||
{
|
||||
if (CcpInfo.reset_sent != -1) {
|
||||
if (id != CcpInfo.reset_sent) {
|
||||
LogPrintf(LogWARN, "CCP: Incorrect ResetAck (id %d, not %d) ignored\n",
|
||||
id, CcpInfo.reset_sent);
|
||||
/* Got a reset ACK, reset incoming dictionary */
|
||||
struct ccp *ccp = fsm2ccp(fp);
|
||||
|
||||
if (ccp->reset_sent != -1) {
|
||||
if (id != ccp->reset_sent) {
|
||||
log_Printf(LogWARN, "CCP: %s: Incorrect ResetAck (id %d, not %d)"
|
||||
" ignored\n", fp->link->name, id, ccp->reset_sent);
|
||||
return;
|
||||
}
|
||||
/* Whaddaya know - a correct reset ack */
|
||||
} else if (id == CcpInfo.last_reset)
|
||||
LogPrintf(LogCCP, "Duplicate ResetAck (resetting again)\n");
|
||||
} else if (id == ccp->last_reset)
|
||||
log_Printf(LogCCP, "%s: Duplicate ResetAck (resetting again)\n",
|
||||
fp->link->name);
|
||||
else {
|
||||
LogPrintf(LogWARN, "CCP: Unexpected ResetAck (id %d) ignored\n", id);
|
||||
log_Printf(LogWARN, "CCP: %s: Unexpected ResetAck (id %d) ignored\n",
|
||||
fp->link->name, id);
|
||||
return;
|
||||
}
|
||||
|
||||
CcpInfo.last_reset = CcpInfo.reset_sent;
|
||||
CcpInfo.reset_sent = -1;
|
||||
if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
|
||||
(*algorithm[in_algorithm]->i.Reset)();
|
||||
ccp->last_reset = ccp->reset_sent;
|
||||
ccp->reset_sent = -1;
|
||||
if (ccp->in.state != NULL)
|
||||
(*algorithm[ccp->in.algorithm]->i.Reset)(ccp->in.state);
|
||||
}
|
||||
|
||||
int
|
||||
CcpOutput(int pri, u_short proto, struct mbuf *m)
|
||||
ccp_Compress(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *m)
|
||||
{
|
||||
if (out_algorithm >= 0 && out_algorithm < NALGORITHMS)
|
||||
return (*algorithm[out_algorithm]->o.Write)(pri, proto, m);
|
||||
/*
|
||||
* Compress outgoing data. It's already deemed to be suitable Network
|
||||
* Layer data.
|
||||
*/
|
||||
if (ccp->fsm.state == ST_OPENED && ccp->out.state != NULL)
|
||||
return (*algorithm[ccp->out.algorithm]->o.Write)
|
||||
(ccp->out.state, ccp, l, pri, proto, m);
|
||||
return 0;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
CompdInput(u_short *proto, struct mbuf *m)
|
||||
ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
||||
{
|
||||
if (CcpInfo.reset_sent != -1) {
|
||||
/* Send another REQ and put the packet in the bit bucket */
|
||||
LogPrintf(LogCCP, "ReSendResetReq(%d)\n", CcpInfo.reset_sent);
|
||||
FsmOutput(&CcpFsm, CODE_RESETREQ, CcpInfo.reset_sent, NULL, 0);
|
||||
} else if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
|
||||
return (*algorithm[in_algorithm]->i.Read)(proto, m);
|
||||
pfree(m);
|
||||
return NULL;
|
||||
/*
|
||||
* If proto isn't PROTO_[I]COMPD, we still want to pass it to the
|
||||
* decompression routines so that the dictionary's updated
|
||||
*/
|
||||
if (ccp->fsm.state == ST_OPENED) {
|
||||
if (*proto == PROTO_COMPD || *proto == PROTO_ICOMPD) {
|
||||
/* Decompress incoming data */
|
||||
if (ccp->reset_sent != -1)
|
||||
/* Send another REQ and put the packet in the bit bucket */
|
||||
fsm_Output(&ccp->fsm, CODE_RESETREQ, ccp->reset_sent, NULL, 0);
|
||||
else if (ccp->in.state != NULL)
|
||||
return (*algorithm[ccp->in.algorithm]->i.Read)
|
||||
(ccp->in.state, ccp, proto, bp);
|
||||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
} else if (PROTO_COMPRESSIBLE(*proto) && ccp->in.state != NULL)
|
||||
/* Add incoming Network Layer traffic to our dictionary */
|
||||
(*algorithm[ccp->in.algorithm]->i.DictSetup)
|
||||
(ccp->in.state, ccp, *proto, bp);
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
void
|
||||
CcpDictSetup(u_short proto, struct mbuf *m)
|
||||
u_short
|
||||
ccp_Proto(struct ccp *ccp)
|
||||
{
|
||||
if (in_algorithm >= 0 && in_algorithm < NALGORITHMS)
|
||||
(*algorithm[in_algorithm]->i.DictSetup)(proto, m);
|
||||
return !link2physical(ccp->fsm.link) || !ccp->fsm.bundle->ncp.mp.active ?
|
||||
PROTO_COMPD : PROTO_ICOMPD;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ccp.h,v 1.13 1998/01/10 01:55:09 brian Exp $
|
||||
* $Id: ccp.h,v 1.14.2.20 1998/05/01 19:24:00 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -35,58 +35,93 @@
|
||||
#define TY_PPPD_DEFLATE 24 /* Deflate (gzip) - (mis) numbered by pppd */
|
||||
#define TY_DEFLATE 26 /* Deflate (gzip) - rfc 1979 */
|
||||
|
||||
struct ccpstate {
|
||||
#define CCP_NEG_DEFLATE 0
|
||||
#define CCP_NEG_PRED1 1
|
||||
#define CCP_NEG_DEFLATE24 2
|
||||
#define CCP_NEG_TOTAL 3
|
||||
|
||||
struct mbuf;
|
||||
struct link;
|
||||
|
||||
struct ccp_config {
|
||||
struct {
|
||||
struct {
|
||||
int winsize;
|
||||
} in, out;
|
||||
} deflate;
|
||||
u_int fsmretry; /* FSM retry frequency */
|
||||
unsigned neg[CCP_NEG_TOTAL];
|
||||
};
|
||||
|
||||
struct ccp_opt {
|
||||
struct ccp_opt *next;
|
||||
int algorithm;
|
||||
struct lcp_opt val;
|
||||
};
|
||||
|
||||
struct ccp {
|
||||
struct fsm fsm; /* The finite state machine */
|
||||
|
||||
int his_proto; /* peer's compression protocol */
|
||||
int my_proto; /* our compression protocol */
|
||||
|
||||
int reset_sent; /* If != -1, ignore compressed 'till ack */
|
||||
int last_reset; /* We can receive more (dups) w/ this id */
|
||||
|
||||
struct {
|
||||
int algorithm; /* Algorithm in use */
|
||||
void *state; /* Returned by implementations Init() */
|
||||
struct lcp_opt opt; /* Set by implementations OptInit() */
|
||||
} in;
|
||||
|
||||
struct {
|
||||
int algorithm; /* Algorithm in use */
|
||||
void *state; /* Returned by implementations Init() */
|
||||
struct ccp_opt *opt; /* Set by implementations OptInit() */
|
||||
} out;
|
||||
|
||||
u_int32_t his_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
int out_init; /* Init called for out algorithm */
|
||||
int in_init; /* Init called for in algorithm */
|
||||
|
||||
u_long uncompout, compout;
|
||||
u_long uncompin, compin;
|
||||
|
||||
struct ccp_config cfg;
|
||||
};
|
||||
|
||||
extern struct ccpstate CcpInfo;
|
||||
#define fsm2ccp(fp) (fp->proto == PROTO_CCP ? (struct ccp *)fp : NULL)
|
||||
|
||||
struct ccp_algorithm {
|
||||
int id;
|
||||
int Conf; /* A Conf value from vars.h */
|
||||
int Neg; /* ccp_config neg array item */
|
||||
const char *(*Disp)(struct lcp_opt *);
|
||||
struct {
|
||||
void (*Get)(struct lcp_opt *);
|
||||
int (*Set)(struct lcp_opt *);
|
||||
int (*Init)(void);
|
||||
void (*Term)(void);
|
||||
void (*Reset)(void);
|
||||
struct mbuf *(*Read)(u_short *, struct mbuf *);
|
||||
void (*DictSetup)(u_short, struct mbuf *);
|
||||
int (*Set)(struct lcp_opt *, const struct ccp_config *);
|
||||
void *(*Init)(struct lcp_opt *);
|
||||
void (*Term)(void *);
|
||||
void (*Reset)(void *);
|
||||
struct mbuf *(*Read)(void *, struct ccp *, u_short *, struct mbuf *);
|
||||
void (*DictSetup)(void *, struct ccp *, u_short, struct mbuf *);
|
||||
} i;
|
||||
struct {
|
||||
void (*Get)(struct lcp_opt *);
|
||||
void (*OptInit)(struct lcp_opt *, const struct ccp_config *);
|
||||
int (*Set)(struct lcp_opt *);
|
||||
int (*Init)(void);
|
||||
void (*Term)(void);
|
||||
void (*Reset)(void);
|
||||
int (*Write)(int, u_short, struct mbuf *);
|
||||
void *(*Init)(struct lcp_opt *);
|
||||
void (*Term)(void *);
|
||||
void (*Reset)(void *);
|
||||
int (*Write)(void *, struct ccp *, struct link *, int, u_short,
|
||||
struct mbuf *);
|
||||
} o;
|
||||
};
|
||||
|
||||
extern struct fsm CcpFsm;
|
||||
extern void ccp_Init(struct ccp *, struct bundle *, struct link *,
|
||||
const struct fsm_parent *);
|
||||
extern void ccp_Setup(struct ccp *);
|
||||
|
||||
extern void CcpRecvResetReq(struct fsm *);
|
||||
extern void CcpSendResetReq(struct fsm *);
|
||||
extern void CcpInput(struct mbuf *);
|
||||
extern void CcpUp(void);
|
||||
extern void CcpOpen(void);
|
||||
extern void CcpInit(void);
|
||||
extern int ReportCcpStatus(struct cmdargs const *);
|
||||
extern void CcpResetInput(u_char);
|
||||
extern int CcpOutput(int, u_short, struct mbuf *);
|
||||
extern struct mbuf *CompdInput(u_short *, struct mbuf *);
|
||||
extern void CcpDictSetup(u_short, struct mbuf *);
|
||||
extern void ccp_SendResetReq(struct fsm *);
|
||||
extern void ccp_Input(struct ccp *, struct bundle *, struct mbuf *);
|
||||
extern int ccp_ReportStatus(struct cmdargs const *);
|
||||
extern int ccp_Compress(struct ccp *, struct link *, int, u_short, struct mbuf *);
|
||||
extern struct mbuf *ccp_Decompress(struct ccp *, u_short *, struct mbuf *);
|
||||
extern u_short ccp_Proto(struct ccp *);
|
||||
extern void ccp_SetupCallbacks(struct ccp *);
|
||||
|
@ -17,53 +17,53 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.c,v 1.29 1998/02/19 02:10:06 brian Exp $
|
||||
* $Id: chap.c,v 1.28.2.27 1998/05/01 19:24:03 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#ifdef HAVE_DES
|
||||
#include <md4.h>
|
||||
#endif
|
||||
#include <md5.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <util.h>
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "chap.h"
|
||||
#include "chap_ms.h"
|
||||
#include "lcpproto.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "phase.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "auth.h"
|
||||
#include "id.h"
|
||||
#include "chap.h"
|
||||
#include "async.h"
|
||||
#include "throughput.h"
|
||||
#include "descriptor.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "chat.h"
|
||||
#include "datalink.h"
|
||||
|
||||
static const char *chapcodes[] = {
|
||||
"???", "CHALLENGE", "RESPONSE", "SUCCESS", "FAILURE"
|
||||
};
|
||||
|
||||
static void
|
||||
ChapOutput(u_int code, u_int id, const u_char * ptr, int count)
|
||||
ChapOutput(struct physical *physical, u_int code, u_int id,
|
||||
const u_char * ptr, int count)
|
||||
{
|
||||
int plen;
|
||||
struct fsmheader lh;
|
||||
@ -73,42 +73,37 @@ ChapOutput(u_int code, u_int id, const u_char * ptr, int count)
|
||||
lh.code = code;
|
||||
lh.id = id;
|
||||
lh.length = htons(plen);
|
||||
bp = mballoc(plen, MB_FSM);
|
||||
bp = mbuf_Alloc(plen, MB_FSM);
|
||||
memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
|
||||
if (count)
|
||||
memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count);
|
||||
LogDumpBp(LogDEBUG, "ChapOutput", bp);
|
||||
LogPrintf(LogLCP, "ChapOutput: %s\n", chapcodes[code]);
|
||||
HdlcOutput(PRI_LINK, PROTO_CHAP, bp);
|
||||
log_DumpBp(LogDEBUG, "ChapOutput", bp);
|
||||
log_Printf(LogLCP, "ChapOutput: %s\n", chapcodes[code]);
|
||||
hdlc_Output(&physical->link, PRI_LINK, PROTO_CHAP, bp);
|
||||
}
|
||||
|
||||
|
||||
static char challenge_data[80];
|
||||
static int challenge_len;
|
||||
|
||||
static void
|
||||
SendChapChallenge(int chapid)
|
||||
void
|
||||
chap_SendChallenge(struct authinfo *auth, int chapid, struct physical *physical)
|
||||
{
|
||||
struct chap *chap = auth2chap(auth);
|
||||
int len, i;
|
||||
char *cp;
|
||||
|
||||
randinit();
|
||||
cp = challenge_data;
|
||||
*cp++ = challenge_len = random() % 32 + 16;
|
||||
for (i = 0; i < challenge_len; i++)
|
||||
cp = chap->challenge_data;
|
||||
*cp++ = chap->challenge_len = random() % 32 + 16;
|
||||
for (i = 0; i < chap->challenge_len; i++)
|
||||
*cp++ = random() & 0xff;
|
||||
len = strlen(VarAuthName);
|
||||
memcpy(cp, VarAuthName, len);
|
||||
len = strlen(physical->dl->bundle->cfg.auth.name);
|
||||
memcpy(cp, physical->dl->bundle->cfg.auth.name, len);
|
||||
cp += len;
|
||||
ChapOutput(CHAP_CHALLENGE, chapid, challenge_data, cp - challenge_data);
|
||||
ChapOutput(physical, CHAP_CHALLENGE, chapid, chap->challenge_data,
|
||||
cp - chap->challenge_data);
|
||||
}
|
||||
|
||||
struct authinfo AuthChapInfo = {
|
||||
SendChapChallenge,
|
||||
};
|
||||
|
||||
static void
|
||||
RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
RecvChapTalk(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
|
||||
struct physical *physical)
|
||||
{
|
||||
int valsize, len;
|
||||
int arglen, keylen, namelen;
|
||||
@ -123,35 +118,35 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
#endif
|
||||
|
||||
len = ntohs(chp->length);
|
||||
LogPrintf(LogDEBUG, "RecvChapTalk: length: %d\n", len);
|
||||
log_Printf(LogDEBUG, "RecvChapTalk: length: %d\n", len);
|
||||
arglen = len - sizeof(struct fsmheader);
|
||||
cp = (char *) MBUF_CTOP(bp);
|
||||
valsize = *cp++ & 255;
|
||||
name = cp + valsize;
|
||||
namelen = arglen - valsize - 1;
|
||||
name[namelen] = 0;
|
||||
LogPrintf(LogLCP, " Valsize = %d, Name = \"%s\"\n", valsize, name);
|
||||
log_Printf(LogLCP, " Valsize = %d, Name = \"%s\"\n", valsize, name);
|
||||
|
||||
switch (chp->code) {
|
||||
case CHAP_CHALLENGE:
|
||||
keyp = VarAuthKey;
|
||||
keylen = strlen(VarAuthKey);
|
||||
name = VarAuthName;
|
||||
namelen = strlen(VarAuthName);
|
||||
keyp = bundle->cfg.auth.key;
|
||||
keylen = strlen(bundle->cfg.auth.key);
|
||||
name = bundle->cfg.auth.name;
|
||||
namelen = strlen(bundle->cfg.auth.name);
|
||||
|
||||
#ifdef HAVE_DES
|
||||
if (VarMSChap)
|
||||
if (physical->dl->chap.using_MSChap)
|
||||
argp = malloc(1 + namelen + MS_CHAP_RESPONSE_LEN);
|
||||
else
|
||||
#endif
|
||||
argp = malloc(1 + valsize + namelen + 16);
|
||||
|
||||
if (argp == NULL) {
|
||||
ChapOutput(CHAP_FAILURE, chp->id, "Out of memory!", 14);
|
||||
ChapOutput(physical, CHAP_FAILURE, chp->id, "Out of memory!", 14);
|
||||
return;
|
||||
}
|
||||
#ifdef HAVE_DES
|
||||
if (VarMSChap) {
|
||||
if (physical->dl->chap.using_MSChap) {
|
||||
digest = argp; /* this is the response */
|
||||
*digest++ = MS_CHAP_RESPONSE_LEN; /* 49 */
|
||||
memset(digest, '\0', 24);
|
||||
@ -161,7 +156,7 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
memcpy(ap, keyp, keylen);
|
||||
ap += 2 * keylen;
|
||||
memcpy(ap, cp, valsize);
|
||||
LogDumpBuff(LogDEBUG, "recv", ap, valsize);
|
||||
log_DumpBuff(LogDEBUG, "recv", ap, valsize);
|
||||
ap += valsize;
|
||||
for (ix = keylen; ix > 0 ; ix--) {
|
||||
answer[2*ix-2] = answer[ix-1];
|
||||
@ -172,9 +167,10 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
MD4Final(digest, &MD4context);
|
||||
memcpy(digest + 25, name, namelen);
|
||||
ap += 2 * keylen;
|
||||
ChapMS(digest, answer + 2 * keylen, valsize);
|
||||
LogDumpBuff(LogDEBUG, "answer", digest, 24);
|
||||
ChapOutput(CHAP_RESPONSE, chp->id, argp, namelen + MS_CHAP_RESPONSE_LEN + 1);
|
||||
chap_MS(digest, answer + 2 * keylen, valsize);
|
||||
log_DumpBuff(LogDEBUG, "answer", digest, 24);
|
||||
ChapOutput(physical, CHAP_RESPONSE, chp->id, argp,
|
||||
namelen + MS_CHAP_RESPONSE_LEN + 1);
|
||||
} else {
|
||||
#endif
|
||||
digest = argp;
|
||||
@ -184,16 +180,16 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
memcpy(ap, keyp, keylen);
|
||||
ap += keylen;
|
||||
memcpy(ap, cp, valsize);
|
||||
LogDumpBuff(LogDEBUG, "recv", ap, valsize);
|
||||
log_DumpBuff(LogDEBUG, "recv", ap, valsize);
|
||||
ap += valsize;
|
||||
MD5Init(&MD5context);
|
||||
MD5Update(&MD5context, answer, ap - answer);
|
||||
MD5Final(digest, &MD5context);
|
||||
LogDumpBuff(LogDEBUG, "answer", digest, 16);
|
||||
log_DumpBuff(LogDEBUG, "answer", digest, 16);
|
||||
memcpy(digest + 16, name, namelen);
|
||||
ap += namelen;
|
||||
/* Send answer to the peer */
|
||||
ChapOutput(CHAP_RESPONSE, chp->id, argp, namelen + 17);
|
||||
ChapOutput(physical, CHAP_RESPONSE, chp->id, argp, namelen + 17);
|
||||
#ifdef HAVE_DES
|
||||
}
|
||||
#endif
|
||||
@ -203,7 +199,7 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
/*
|
||||
* Get a secret key corresponds to the peer
|
||||
*/
|
||||
keyp = AuthGetSecret(SECRETFILE, name, namelen, chp->code == CHAP_RESPONSE);
|
||||
keyp = auth_GetSecret(bundle, name, namelen, physical);
|
||||
if (keyp) {
|
||||
/*
|
||||
* Compute correct digest value
|
||||
@ -215,31 +211,28 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
ap += keylen;
|
||||
MD5Init(&MD5context);
|
||||
MD5Update(&MD5context, answer, ap - answer);
|
||||
MD5Update(&MD5context, challenge_data + 1, challenge_len);
|
||||
MD5Update(&MD5context, physical->dl->chap.challenge_data + 1,
|
||||
physical->dl->chap.challenge_len);
|
||||
MD5Final(cdigest, &MD5context);
|
||||
LogDumpBuff(LogDEBUG, "got", cp, 16);
|
||||
LogDumpBuff(LogDEBUG, "expect", cdigest, 16);
|
||||
log_DumpBuff(LogDEBUG, "got", cp, 16);
|
||||
log_DumpBuff(LogDEBUG, "expect", cdigest, 16);
|
||||
|
||||
/*
|
||||
* Compare with the response
|
||||
*/
|
||||
if (memcmp(cp, cdigest, 16) == 0) {
|
||||
ChapOutput(CHAP_SUCCESS, chp->id, "Welcome!!", 10);
|
||||
if ((mode & MODE_DIRECT) && isatty(modem) && Enabled(ConfUtmp)) {
|
||||
if (Utmp)
|
||||
LogPrintf(LogERROR, "Oops, already logged in on %s\n",
|
||||
VarBaseDevice);
|
||||
else {
|
||||
struct utmp ut;
|
||||
memset(&ut, 0, sizeof ut);
|
||||
time(&ut.ut_time);
|
||||
strncpy(ut.ut_name, name, sizeof ut.ut_name);
|
||||
strncpy(ut.ut_line, VarBaseDevice, sizeof ut.ut_line - 1);
|
||||
ID0login(&ut);
|
||||
Utmp = 1;
|
||||
}
|
||||
}
|
||||
NewPhase(PHASE_NETWORK);
|
||||
datalink_GotAuthname(physical->dl, name, namelen);
|
||||
ChapOutput(physical, CHAP_SUCCESS, chp->id, "Welcome!!", 10);
|
||||
if (Enabled(bundle, OPT_UTMP))
|
||||
physical_Login(physical, name);
|
||||
|
||||
if (physical->link.lcp.auth_iwait == 0)
|
||||
/*
|
||||
* Either I didn't need to authenticate, or I've already been
|
||||
* told that I got the answer right.
|
||||
*/
|
||||
datalink_AuthOk(physical->dl);
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -247,40 +240,42 @@ RecvChapTalk(struct fsmheader *chp, struct mbuf *bp)
|
||||
/*
|
||||
* Peer is not registerd, or response digest is wrong.
|
||||
*/
|
||||
ChapOutput(CHAP_FAILURE, chp->id, "Invalid!!", 9);
|
||||
reconnect(RECON_FALSE);
|
||||
LcpClose();
|
||||
ChapOutput(physical, CHAP_FAILURE, chp->id, "Invalid!!", 9);
|
||||
datalink_AuthNotOk(physical->dl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
RecvChapResult(struct fsmheader *chp, struct mbuf *bp)
|
||||
RecvChapResult(struct bundle *bundle, struct fsmheader *chp, struct mbuf *bp,
|
||||
struct physical *physical)
|
||||
{
|
||||
int len;
|
||||
struct lcpstate *lcp = &LcpInfo;
|
||||
|
||||
len = ntohs(chp->length);
|
||||
LogPrintf(LogDEBUG, "RecvChapResult: length: %d\n", len);
|
||||
log_Printf(LogDEBUG, "RecvChapResult: length: %d\n", len);
|
||||
if (chp->code == CHAP_SUCCESS) {
|
||||
if (lcp->auth_iwait == PROTO_CHAP) {
|
||||
lcp->auth_iwait = 0;
|
||||
if (lcp->auth_ineed == 0)
|
||||
NewPhase(PHASE_NETWORK);
|
||||
if (physical->link.lcp.auth_iwait == PROTO_CHAP) {
|
||||
physical->link.lcp.auth_iwait = 0;
|
||||
if (physical->link.lcp.auth_ineed == 0)
|
||||
/*
|
||||
* We've succeeded in our ``login''
|
||||
* If we're not expecting the peer to authenticate (or he already
|
||||
* has), proceed to network phase.
|
||||
*/
|
||||
datalink_AuthOk(physical->dl);
|
||||
}
|
||||
} else {
|
||||
|
||||
/*
|
||||
* Maybe, we shoud close LCP. Of cause, peer may take close action, too.
|
||||
*/
|
||||
;
|
||||
/* CHAP failed - it's not going to get any better */
|
||||
log_Printf(LogPHASE, "Received CHAP_FAILURE\n");
|
||||
datalink_AuthNotOk(physical->dl);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ChapInput(struct mbuf *bp)
|
||||
chap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
|
||||
{
|
||||
int len = plength(bp);
|
||||
int len = mbuf_Length(bp);
|
||||
struct fsmheader *chp;
|
||||
|
||||
if (len >= sizeof(struct fsmheader)) {
|
||||
@ -288,24 +283,24 @@ ChapInput(struct mbuf *bp)
|
||||
if (len >= ntohs(chp->length)) {
|
||||
if (chp->code < 1 || chp->code > 4)
|
||||
chp->code = 0;
|
||||
LogPrintf(LogLCP, "ChapInput: %s\n", chapcodes[chp->code]);
|
||||
log_Printf(LogLCP, "chap_Input: %s\n", chapcodes[chp->code]);
|
||||
|
||||
bp->offset += sizeof(struct fsmheader);
|
||||
bp->cnt -= sizeof(struct fsmheader);
|
||||
|
||||
switch (chp->code) {
|
||||
case CHAP_RESPONSE:
|
||||
StopAuthTimer(&AuthChapInfo);
|
||||
auth_StopTimer(&physical->dl->chap.auth);
|
||||
/* Fall into.. */
|
||||
case CHAP_CHALLENGE:
|
||||
RecvChapTalk(chp, bp);
|
||||
RecvChapTalk(bundle, chp, bp, physical);
|
||||
break;
|
||||
case CHAP_SUCCESS:
|
||||
case CHAP_FAILURE:
|
||||
RecvChapResult(chp, bp);
|
||||
RecvChapResult(bundle, chp, bp, physical);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
|
@ -15,16 +15,28 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.h,v 1.8 1997/10/26 01:02:19 brian Exp $
|
||||
* $Id: chap.h,v 1.9.2.6 1998/05/01 19:24:05 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
|
||||
#define CHAP_CHALLENGE 1
|
||||
#define CHAP_RESPONSE 2
|
||||
#define CHAP_SUCCESS 3
|
||||
#define CHAP_FAILURE 4
|
||||
|
||||
extern struct authinfo AuthChapInfo;
|
||||
struct chap {
|
||||
struct authinfo auth;
|
||||
char challenge_data[80];
|
||||
int challenge_len;
|
||||
unsigned using_MSChap : 1; /* A combination of MD4 & DES */
|
||||
};
|
||||
|
||||
extern void ChapInput(struct mbuf *);
|
||||
#define auth2chap(a) ((struct chap *)(a))
|
||||
|
||||
extern void chap_Input(struct bundle *, struct mbuf *, struct physical *);
|
||||
extern void chap_SendChallenge(struct authinfo *, int, struct physical *);
|
||||
|
@ -19,28 +19,24 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap_ms.c,v 1.4 1997/12/24 09:28:53 brian Exp $
|
||||
* $Id: chap_ms.c,v 1.5.4.3 1998/05/01 19:24:07 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <des.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "chap_ms.h"
|
||||
|
||||
/* unused, for documentation only */
|
||||
/* only NTResp is filled in for FreeBSD */
|
||||
typedef struct {
|
||||
struct MS_ChapResponse {
|
||||
u_char LANManResp[24];
|
||||
u_char NTResp[24];
|
||||
u_char UseNT; /* If 1, ignore the LANMan response field */
|
||||
} MS_ChapResponse;
|
||||
};
|
||||
|
||||
static void DesEncrypt(u_char *, u_char *, u_char *);
|
||||
static void MakeKey(u_char *, u_char *);
|
||||
@ -101,7 +97,7 @@ static void MakeKey(u_char *key, u_char *des_key)
|
||||
challenge 8-bytes peer CHAP challenge
|
||||
since passwordHash is in a 24-byte buffer, response is written in there */
|
||||
void
|
||||
ChapMS(char *passwordHash, char *challenge, int challenge_len)
|
||||
chap_MS(char *passwordHash, char *challenge, int challenge_len)
|
||||
{
|
||||
u_char response[24];
|
||||
|
||||
|
@ -19,7 +19,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap_ms.h,v 1.1 1997/09/25 00:58:20 brian Exp $
|
||||
* $Id: chap_ms.h,v 1.2.4.1 1998/05/01 19:24:08 brian Exp $
|
||||
*/
|
||||
|
||||
/* Max # of (Unicode) chars in an NT password */
|
||||
@ -28,4 +28,4 @@
|
||||
/* Don't rely on sizeof(MS_ChapResponse) in case of struct padding */
|
||||
#define MS_CHAP_RESPONSE_LEN 49
|
||||
|
||||
extern void ChapMS(char *, char *, int);
|
||||
extern void chap_MS(char *, char *, int);
|
||||
|
1032
usr.sbin/ppp/chat.c
1032
usr.sbin/ppp/chat.c
File diff suppressed because it is too large
Load Diff
@ -1,29 +1,82 @@
|
||||
/*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
* 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.
|
||||
*
|
||||
* Most of codes are derived from chat.c by Karl Fox (karl@MorningStar.Com).
|
||||
*
|
||||
* Chat -- a program for automatic session establishment (i.e. dial
|
||||
* the phone and log in).
|
||||
*
|
||||
* This software is in the public domain.
|
||||
*
|
||||
* Please send all bug reports, requests for information, etc. to:
|
||||
*
|
||||
* Karl Fox <karl@MorningStar.Com>
|
||||
* Morning Star Technologies, Inc.
|
||||
* 1760 Zollinger Road
|
||||
* Columbus, OH 43221
|
||||
* (614)451-1883
|
||||
*
|
||||
* $Id: chat.h,v 1.8 1997/10/26 01:02:23 brian Exp $
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: chat.h,v 1.9.2.8 1998/05/01 19:24:13 brian Exp $
|
||||
*/
|
||||
|
||||
#define CHAT_EXPECT 0
|
||||
#define CHAT_SEND 1
|
||||
#define CHAT_DONE 2
|
||||
#define CHAT_FAILED 3
|
||||
|
||||
#define MAXABORTS 50
|
||||
|
||||
struct physical;
|
||||
|
||||
struct chat {
|
||||
struct descriptor desc;
|
||||
struct physical *physical;
|
||||
|
||||
int state; /* Our CHAT_* status */
|
||||
|
||||
char script[LINE_LEN]; /* Our arg buffer */
|
||||
char *argv[MAXARGS]; /* Our arguments (pointing to script) */
|
||||
int argc; /* Number of argv's */
|
||||
|
||||
int arg; /* Our current arg number */
|
||||
char exp[LINE_LEN]; /* Our translated current argument */
|
||||
char *argptr; /* Our current arg pointer */
|
||||
int arglen; /* The length of argptr */
|
||||
char *nargptr; /* Our next for expect-send-expect */
|
||||
|
||||
char buf[LINE_LEN*2]; /* Our input */
|
||||
char *bufstart; /* start of relevent data */
|
||||
char *bufend; /* end of relevent data */
|
||||
|
||||
int TimeoutSec; /* Expect timeout value */
|
||||
int TimedOut; /* We timed out */
|
||||
|
||||
const char *phone; /* Our phone number */
|
||||
|
||||
struct {
|
||||
struct {
|
||||
char *data; /* Abort the dial if we get one */
|
||||
int len;
|
||||
} string[MAXABORTS];
|
||||
int num; /* How many AbortStrings */
|
||||
} abort;
|
||||
|
||||
struct pppTimer pause; /* Inactivity timer */
|
||||
struct pppTimer timeout; /* TimeoutSec timer */
|
||||
};
|
||||
|
||||
#define descriptor2chat(d) \
|
||||
((d)->type == CHAT_DESCRIPTOR ? (struct chat *)(d) : NULL)
|
||||
#define VECSIZE(v) (sizeof(v) / sizeof(v[0]))
|
||||
|
||||
extern char *ExpandString(const char *, char *, int, int);
|
||||
extern void chat_Init(struct chat *, struct physical *, const char *, int,
|
||||
const char *);
|
||||
extern void chat_Destroy(struct chat *);
|
||||
extern int MakeArgs(char *, char **, int); /* Mangles the first arg ! */
|
||||
extern int DoChat(char *); /* passes arg to MakeArgs() */
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,18 +15,25 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: command.h,v 1.11 1997/11/13 14:43:15 brian Exp $
|
||||
* $Id: command.h,v 1.12.2.13 1998/05/01 19:24:18 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
struct cmdtab;
|
||||
struct bundle;
|
||||
struct datalink;
|
||||
struct prompt;
|
||||
|
||||
struct cmdargs {
|
||||
struct cmdtab const *cmd;
|
||||
int argc;
|
||||
char const *const *argv;
|
||||
const void *data;
|
||||
struct cmdtab const *cmdtab; /* The entire command table */
|
||||
struct cmdtab const *cmd; /* This command entry */
|
||||
int argc; /* Number of arguments (excluding cmd */
|
||||
int argn; /* Argument to start processing from */
|
||||
char const *const *argv; /* Arguments */
|
||||
struct bundle *bundle; /* Our bundle */
|
||||
struct datalink *cx; /* Our context */
|
||||
struct prompt *prompt; /* Who executed us */
|
||||
};
|
||||
|
||||
struct cmdtab {
|
||||
@ -39,24 +46,18 @@ struct cmdtab {
|
||||
const void *args;
|
||||
};
|
||||
|
||||
#define VAR_AUTHKEY 0
|
||||
#define VAR_DIAL 1
|
||||
#define VAR_LOGIN 2
|
||||
#define VAR_AUTHNAME 3
|
||||
#define VAR_DEVICE 4
|
||||
#define VAR_ACCMAP 5
|
||||
#define VAR_PHONE 6
|
||||
#define VAR_HANGUP 7
|
||||
#ifdef HAVE_DES
|
||||
#define VAR_ENC 8
|
||||
#endif
|
||||
#define NEG_ACCEPTED (1)
|
||||
#define NEG_ENABLED (2)
|
||||
#define IsAccepted(x) ((x) & NEG_ACCEPTED)
|
||||
#define IsEnabled(x) ((x) & NEG_ENABLED)
|
||||
|
||||
extern struct in_addr ifnetmask;
|
||||
extern int aft_cmd;
|
||||
extern const char Version[];
|
||||
extern const char VersionDate[];
|
||||
|
||||
extern int SetVariable(struct cmdargs const *);
|
||||
extern void Prompt(void);
|
||||
extern int IsInteractive(int);
|
||||
extern void InterpretCommand(char *, int, int *, char ***);
|
||||
extern void RunCommand(int, char const *const *, const char *label);
|
||||
extern void DecodeCommand(char *, int, const char *label);
|
||||
extern void command_Interpret(char *, int, int *, char ***);
|
||||
extern void command_Run(struct bundle *, int, char const *const *,
|
||||
struct prompt *, const char *);
|
||||
extern void command_Decode(struct bundle *, char *, int, struct prompt *,
|
||||
const char *);
|
||||
extern struct link *command_ChooseLink(struct cmdargs const *);
|
||||
extern const char *command_ShowNegval(unsigned);
|
||||
|
1096
usr.sbin/ppp/datalink.c
Normal file
1096
usr.sbin/ppp/datalink.c
Normal file
File diff suppressed because it is too large
Load Diff
130
usr.sbin/ppp/datalink.h
Normal file
130
usr.sbin/ppp/datalink.h
Normal file
@ -0,0 +1,130 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: datalink.h,v 1.1.2.26 1998/05/16 23:47:25 brian Exp $
|
||||
*/
|
||||
|
||||
#define DATALINK_CLOSED (0)
|
||||
#define DATALINK_OPENING (1)
|
||||
#define DATALINK_HANGUP (2)
|
||||
#define DATALINK_DIAL (3)
|
||||
#define DATALINK_LOGIN (4)
|
||||
#define DATALINK_READY (5)
|
||||
#define DATALINK_LCP (6)
|
||||
#define DATALINK_AUTH (7)
|
||||
#define DATALINK_OPEN (8)
|
||||
|
||||
#define DATALINK_MAXNAME (20)
|
||||
|
||||
struct iovec;
|
||||
struct prompt;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
|
||||
struct datalink {
|
||||
struct descriptor desc; /* We play either a physical or a chat */
|
||||
int state; /* Our DATALINK_* state */
|
||||
struct physical *physical; /* Our link */
|
||||
|
||||
struct chat chat; /* For bringing the link up & down */
|
||||
|
||||
struct {
|
||||
unsigned run : 1; /* run scripts ? */
|
||||
unsigned packetmode : 1; /* Go into packet mode after login ? */
|
||||
} script;
|
||||
|
||||
struct pppTimer dial_timer; /* For timing between opens & scripts */
|
||||
|
||||
struct {
|
||||
struct {
|
||||
char dial[SCRIPT_LEN]; /* dial */
|
||||
char login[SCRIPT_LEN]; /* login */
|
||||
char hangup[SCRIPT_LEN]; /* hangup */
|
||||
} script;
|
||||
struct {
|
||||
char list[SCRIPT_LEN]; /* Telephone Numbers */
|
||||
} phone;
|
||||
struct {
|
||||
int max; /* initially try again this number of times */
|
||||
int next_timeout; /* Redial next timeout value */
|
||||
int timeout; /* Redial timeout value (end of phone list) */
|
||||
} dial;
|
||||
struct {
|
||||
int max; /* initially try again this number of times */
|
||||
int timeout; /* Timeout before reconnect on carrier loss */
|
||||
} reconnect;
|
||||
} cfg; /* All our config data is in here */
|
||||
|
||||
struct {
|
||||
char list[SCRIPT_LEN]; /* copy of cfg.list for strsep() */
|
||||
char *next; /* Next phone from the list */
|
||||
char *alt; /* Next phone from the list */
|
||||
const char *chosen; /* Chosen phone number after DIAL */
|
||||
} phone;
|
||||
|
||||
int dial_tries; /* currently try again this number of times */
|
||||
unsigned reconnect_tries; /* currently try again this number of times */
|
||||
|
||||
char *name; /* Our name */
|
||||
|
||||
struct peerid peer; /* Peer identification */
|
||||
|
||||
struct fsm_parent fsmp; /* Our callback functions */
|
||||
const struct fsm_parent *parent; /* Our parent */
|
||||
|
||||
struct authinfo pap; /* Authentication using pap */
|
||||
struct chap chap; /* Authentication using chap */
|
||||
|
||||
struct mp_link mp; /* multilink data */
|
||||
|
||||
struct bundle *bundle; /* for the moment */
|
||||
struct datalink *next; /* Next in the list */
|
||||
};
|
||||
|
||||
#define descriptor2datalink(d) \
|
||||
((d)->type == DATALINK_DESCRIPTOR ? (struct datalink *)(d) : NULL)
|
||||
|
||||
extern struct datalink *datalink_Create(const char *name, struct bundle *, int);
|
||||
extern struct datalink *datalink_Clone(struct datalink *, const char *);
|
||||
extern struct datalink *iov2datalink(struct bundle *, struct iovec *, int *,
|
||||
int, int);
|
||||
extern int datalink2iov(struct datalink *, struct iovec *, int *, int);
|
||||
extern struct datalink *datalink_Destroy(struct datalink *);
|
||||
extern void datalink_GotAuthname(struct datalink *, const char *, int);
|
||||
extern void datalink_Up(struct datalink *, int, int);
|
||||
extern void datalink_Close(struct datalink *, int);
|
||||
extern void datalink_Down(struct datalink *, int);
|
||||
extern void datalink_StayDown(struct datalink *);
|
||||
extern void datalink_AuthOk(struct datalink *);
|
||||
extern void datalink_AuthNotOk(struct datalink *);
|
||||
extern int datalink_Show(struct cmdargs const *);
|
||||
extern int datalink_SetRedial(struct cmdargs const *);
|
||||
extern int datalink_SetReconnect(struct cmdargs const *);
|
||||
extern const char *datalink_State(struct datalink *);
|
||||
extern void datalink_Rename(struct datalink *, const char *);
|
||||
extern char *datalink_NextName(struct datalink *);
|
||||
extern int datalink_RemoveFromSet(struct datalink *, fd_set *, fd_set *,
|
||||
fd_set *);
|
||||
extern int datalink_SetMode(struct datalink *, int);
|
@ -23,67 +23,64 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: deflate.c,v 1.6 1998/01/10 01:55:09 brian Exp $
|
||||
* $Id: deflate.c,v 1.6.4.16 1998/05/15 18:21:03 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "lcpproto.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "deflate.h"
|
||||
|
||||
/* Our state */
|
||||
struct deflate_state {
|
||||
u_short seqno;
|
||||
int uncomp_rec;
|
||||
int winsize;
|
||||
z_stream cx;
|
||||
};
|
||||
|
||||
static int iWindowSize = 15;
|
||||
static int oWindowSize = 15;
|
||||
static struct deflate_state InputState, OutputState;
|
||||
static char garbage[10];
|
||||
static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
#define DEFLATE_CHUNK_LEN 1024 /* Allocate mbufs this size */
|
||||
|
||||
static void
|
||||
DeflateResetOutput(void)
|
||||
DeflateResetOutput(void *v)
|
||||
{
|
||||
OutputState.seqno = 0;
|
||||
OutputState.uncomp_rec = 0;
|
||||
deflateReset(&OutputState.cx);
|
||||
LogPrintf(LogCCP, "Deflate: Output channel reset\n");
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
state->seqno = 0;
|
||||
state->uncomp_rec = 0;
|
||||
deflateReset(&state->cx);
|
||||
log_Printf(LogCCP, "Deflate: Output channel reset\n");
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateOutput(int pri, u_short proto, struct mbuf *mp)
|
||||
DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *mp)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
u_char *wp, *rp;
|
||||
int olen, ilen, len, res, flush;
|
||||
struct mbuf *mo_head, *mo, *mi_head, *mi;
|
||||
|
||||
ilen = plength(mp);
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", proto, ilen);
|
||||
LogDumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp);
|
||||
ilen = mbuf_Length(mp);
|
||||
log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", proto, ilen);
|
||||
log_DumpBp(LogDEBUG, "DeflateOutput: Compress packet:", mp);
|
||||
|
||||
/* Stuff the protocol in front of the input */
|
||||
mi_head = mi = mballoc(2, MB_HDLCOUT);
|
||||
mi_head = mi = mbuf_Alloc(2, MB_HDLCOUT);
|
||||
mi->next = mp;
|
||||
rp = MBUF_CTOP(mi);
|
||||
if (proto < 0x100) { /* Compress the protocol */
|
||||
@ -96,74 +93,73 @@ DeflateOutput(int pri, u_short proto, struct mbuf *mp)
|
||||
}
|
||||
|
||||
/* Allocate the initial output mbuf */
|
||||
mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
mo_head = mo = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
mo->cnt = 2;
|
||||
wp = MBUF_CTOP(mo);
|
||||
*wp++ = OutputState.seqno >> 8;
|
||||
*wp++ = OutputState.seqno & 0377;
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: Seq %d\n", OutputState.seqno);
|
||||
OutputState.seqno++;
|
||||
*wp++ = state->seqno >> 8;
|
||||
*wp++ = state->seqno & 0377;
|
||||
log_Printf(LogDEBUG, "DeflateOutput: Seq %d\n", state->seqno);
|
||||
state->seqno++;
|
||||
|
||||
/* Set up the deflation context */
|
||||
OutputState.cx.next_out = wp;
|
||||
OutputState.cx.avail_out = DEFLATE_CHUNK_LEN - 2;
|
||||
OutputState.cx.next_in = MBUF_CTOP(mi);
|
||||
OutputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = wp;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN - 2;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
flush = Z_NO_FLUSH;
|
||||
|
||||
olen = 0;
|
||||
while (1) {
|
||||
if ((res = deflate(&OutputState.cx, flush)) != Z_OK) {
|
||||
if ((res = deflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
LogPrintf(LogERROR, "DeflateOutput: deflate returned %d (%s)\n",
|
||||
res, OutputState.cx.msg ? OutputState.cx.msg : "");
|
||||
pfree(mo_head);
|
||||
mbfree(mi_head);
|
||||
OutputState.seqno--;
|
||||
log_Printf(LogERROR, "DeflateOutput: deflate returned %d (%s)\n",
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
mbuf_Free(mo_head);
|
||||
mbuf_FreeSeg(mi_head);
|
||||
state->seqno--;
|
||||
return 1; /* packet dropped */
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && OutputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (OutputState.cx.avail_in == 0 && mi->next != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi->next != NULL) {
|
||||
mi = mi->next;
|
||||
OutputState.cx.next_in = MBUF_CTOP(mi);
|
||||
OutputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (OutputState.cx.avail_out == 0) {
|
||||
mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
if (state->cx.avail_out == 0) {
|
||||
mo->next = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_HDLCOUT);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN);
|
||||
mo = mo->next;
|
||||
mo->cnt = 0;
|
||||
OutputState.cx.next_out = MBUF_CTOP(mo);
|
||||
OutputState.cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
state->cx.next_out = MBUF_CTOP(mo);
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
}
|
||||
}
|
||||
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - OutputState.cx.avail_out);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out);
|
||||
olen -= 4; /* exclude the trailing EMPTY_BLOCK */
|
||||
|
||||
/*
|
||||
* If the output packet (including seqno and excluding the EMPTY_BLOCK)
|
||||
* got bigger, send the original - returning 0 to HdlcOutput() will
|
||||
* continue to send ``mp''.
|
||||
* got bigger, send the original.
|
||||
*/
|
||||
if (olen >= ilen) {
|
||||
pfree(mo_head);
|
||||
mbfree(mi_head);
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n",
|
||||
mbuf_Free(mo_head);
|
||||
mbuf_FreeSeg(mi_head);
|
||||
log_Printf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n",
|
||||
ilen, olen, proto);
|
||||
CcpInfo.uncompout += ilen;
|
||||
CcpInfo.compout += ilen; /* We measure this stuff too */
|
||||
ccp->uncompout += ilen;
|
||||
ccp->compout += ilen; /* We measure this stuff too */
|
||||
return 0;
|
||||
}
|
||||
|
||||
pfree(mi_head);
|
||||
mbuf_Free(mi_head);
|
||||
|
||||
/*
|
||||
* Lose the last four bytes of our output.
|
||||
@ -174,66 +170,69 @@ DeflateOutput(int pri, u_short proto, struct mbuf *mp)
|
||||
;
|
||||
mo->cnt -= len - olen;
|
||||
if (mo->next != NULL) {
|
||||
pfree(mo->next);
|
||||
mbuf_Free(mo->next);
|
||||
mo->next = NULL;
|
||||
}
|
||||
|
||||
CcpInfo.uncompout += ilen;
|
||||
CcpInfo.compout += olen;
|
||||
ccp->uncompout += ilen;
|
||||
ccp->compout += olen;
|
||||
|
||||
LogPrintf(LogDEBUG, "DeflateOutput: %d => %d bytes, proto 0x%04x\n",
|
||||
log_Printf(LogDEBUG, "DeflateOutput: %d => %d bytes, proto 0x%04x\n",
|
||||
ilen, olen, proto);
|
||||
|
||||
HdlcOutput(PRI_NORMAL, PROTO_COMPD, mo_head);
|
||||
hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mo_head);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateResetInput(void)
|
||||
DeflateResetInput(void *v)
|
||||
{
|
||||
InputState.seqno = 0;
|
||||
InputState.uncomp_rec = 0;
|
||||
inflateReset(&InputState.cx);
|
||||
LogPrintf(LogCCP, "Deflate: Input channel reset\n");
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
state->seqno = 0;
|
||||
state->uncomp_rec = 0;
|
||||
inflateReset(&state->cx);
|
||||
log_Printf(LogCCP, "Deflate: Input channel reset\n");
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
DeflateInput(u_short *proto, struct mbuf *mi)
|
||||
DeflateInput(void *v, struct ccp *ccp, u_short *proto, struct mbuf *mi)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
struct mbuf *mo, *mo_head, *mi_head;
|
||||
u_char *wp;
|
||||
int ilen, olen;
|
||||
int seq, flush, res, first;
|
||||
u_char hdr[2];
|
||||
|
||||
LogDumpBp(LogDEBUG, "DeflateInput: Decompress packet:", mi);
|
||||
mi_head = mi = mbread(mi, hdr, 2);
|
||||
log_DumpBp(LogDEBUG, "DeflateInput: Decompress packet:", mi);
|
||||
mi_head = mi = mbuf_Read(mi, hdr, 2);
|
||||
ilen = 2;
|
||||
|
||||
/* Check the sequence number. */
|
||||
seq = (hdr[0] << 8) + hdr[1];
|
||||
LogPrintf(LogDEBUG, "DeflateInput: Seq %d\n", seq);
|
||||
if (seq != InputState.seqno) {
|
||||
if (seq <= InputState.uncomp_rec)
|
||||
log_Printf(LogDEBUG, "DeflateInput: Seq %d\n", seq);
|
||||
if (seq != state->seqno) {
|
||||
if (seq <= state->uncomp_rec)
|
||||
/*
|
||||
* So the peer's started at zero again - fine ! If we're wrong,
|
||||
* inflate() will fail. This is better than getting into a loop
|
||||
* trying to get a ResetReq to a busy sender.
|
||||
*/
|
||||
InputState.seqno = seq;
|
||||
state->seqno = seq;
|
||||
else {
|
||||
LogPrintf(LogERROR, "DeflateInput: Seq error: Got %d, expected %d\n",
|
||||
seq, InputState.seqno);
|
||||
pfree(mi_head);
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
log_Printf(LogERROR, "DeflateInput: Seq error: Got %d, expected %d\n",
|
||||
seq, state->seqno);
|
||||
mbuf_Free(mi_head);
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
InputState.seqno++;
|
||||
InputState.uncomp_rec = 0;
|
||||
state->seqno++;
|
||||
state->uncomp_rec = 0;
|
||||
|
||||
/* Allocate an output mbuf */
|
||||
mo_head = mo = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
mo_head = mo = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
|
||||
/* Our proto starts with 0 if it's compressed */
|
||||
wp = MBUF_CTOP(mo);
|
||||
@ -244,10 +243,10 @@ DeflateInput(u_short *proto, struct mbuf *mi)
|
||||
* byte of the output and decide whether we have a compressed
|
||||
* proto field.
|
||||
*/
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
InputState.cx.next_out = wp + 1;
|
||||
InputState.cx.avail_out = 1;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = wp + 1;
|
||||
state->cx.avail_out = 1;
|
||||
ilen += mi->cnt;
|
||||
|
||||
flush = mi->next ? Z_NO_FLUSH : Z_SYNC_FLUSH;
|
||||
@ -255,102 +254,103 @@ DeflateInput(u_short *proto, struct mbuf *mi)
|
||||
olen = 0;
|
||||
|
||||
while (1) {
|
||||
if ((res = inflate(&InputState.cx, flush)) != Z_OK) {
|
||||
if ((res = inflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
LogPrintf(LogERROR, "DeflateInput: inflate returned %d (%s)\n",
|
||||
res, InputState.cx.msg ? InputState.cx.msg : "");
|
||||
pfree(mo_head);
|
||||
pfree(mi);
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
log_Printf(LogERROR, "DeflateInput: inflate returned %d (%s)\n",
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
mbuf_Free(mo_head);
|
||||
mbuf_Free(mi);
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (InputState.cx.avail_in == 0 && mi && (mi = mbfree(mi)) != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi && (mi = mbuf_FreeSeg(mi)) != NULL) {
|
||||
/* underflow */
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
ilen += (InputState.cx.avail_in = mi->cnt);
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
ilen += (state->cx.avail_in = mi->cnt);
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (InputState.cx.avail_out == 0) {
|
||||
if (state->cx.avail_out == 0) {
|
||||
/* overflow */
|
||||
if (first) {
|
||||
if (!(wp[1] & 1)) {
|
||||
/* 2 byte proto, shuffle it back in output */
|
||||
wp[0] = wp[1];
|
||||
InputState.cx.next_out--;
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN-1;
|
||||
state->cx.next_out--;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN-1;
|
||||
} else
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN-2;
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN-2;
|
||||
first = 0;
|
||||
} else {
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN);
|
||||
mo->next = mballoc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
mo->next = mbuf_Alloc(DEFLATE_CHUNK_LEN, MB_IPIN);
|
||||
mo = mo->next;
|
||||
InputState.cx.next_out = MBUF_CTOP(mo);
|
||||
InputState.cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
state->cx.next_out = MBUF_CTOP(mo);
|
||||
state->cx.avail_out = DEFLATE_CHUNK_LEN;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (mi != NULL)
|
||||
pfree(mi);
|
||||
mbuf_Free(mi);
|
||||
|
||||
if (first) {
|
||||
LogPrintf(LogERROR, "DeflateInput: Length error\n");
|
||||
pfree(mo_head);
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
log_Printf(LogERROR, "DeflateInput: Length error\n");
|
||||
mbuf_Free(mo_head);
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - InputState.cx.avail_out);
|
||||
olen += (mo->cnt = DEFLATE_CHUNK_LEN - state->cx.avail_out);
|
||||
|
||||
*proto = ((u_short)wp[0] << 8) | wp[1];
|
||||
mo_head->offset += 2;
|
||||
mo_head->cnt -= 2;
|
||||
olen -= 2;
|
||||
|
||||
CcpInfo.compin += ilen;
|
||||
CcpInfo.uncompin += olen;
|
||||
ccp->compin += ilen;
|
||||
ccp->uncompin += olen;
|
||||
|
||||
LogPrintf(LogDEBUG, "DeflateInput: %d => %d bytes, proto 0x%04x\n",
|
||||
log_Printf(LogDEBUG, "DeflateInput: %d => %d bytes, proto 0x%04x\n",
|
||||
ilen, olen, *proto);
|
||||
|
||||
/*
|
||||
* Simulate an EMPTY_BLOCK so that our dictionary stays in sync.
|
||||
* The peer will have silently removed this!
|
||||
*/
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
InputState.cx.next_in = EMPTY_BLOCK;
|
||||
InputState.cx.avail_in = sizeof EMPTY_BLOCK;
|
||||
inflate(&InputState.cx, Z_SYNC_FLUSH);
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
state->cx.next_in = EMPTY_BLOCK;
|
||||
state->cx.avail_in = sizeof EMPTY_BLOCK;
|
||||
inflate(&state->cx, Z_SYNC_FLUSH);
|
||||
|
||||
return mo_head;
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateDictSetup(u_short proto, struct mbuf *mi)
|
||||
DeflateDictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf *mi)
|
||||
{
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
int res, flush, expect_error;
|
||||
u_char *rp;
|
||||
struct mbuf *mi_head;
|
||||
short len;
|
||||
|
||||
LogPrintf(LogDEBUG, "DeflateDictSetup: Got seq %d\n", InputState.seqno);
|
||||
log_Printf(LogDEBUG, "DeflateDictSetup: Got seq %d\n", state->seqno);
|
||||
|
||||
/*
|
||||
* Stuff an ``uncompressed data'' block header followed by the
|
||||
* protocol in front of the input
|
||||
*/
|
||||
mi_head = mballoc(7, MB_HDLCOUT);
|
||||
mi_head = mbuf_Alloc(7, MB_HDLCOUT);
|
||||
mi_head->next = mi;
|
||||
len = plength(mi);
|
||||
len = mbuf_Length(mi);
|
||||
mi = mi_head;
|
||||
rp = MBUF_CTOP(mi);
|
||||
if (proto < 0x100) { /* Compress the protocol */
|
||||
@ -369,41 +369,41 @@ DeflateDictSetup(u_short proto, struct mbuf *mi)
|
||||
rp[3] = (~len) & 0377; /* One's compliment of the length */
|
||||
rp[4] = (~len) >> 8;
|
||||
|
||||
InputState.cx.next_in = rp;
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
state->cx.next_in = rp;
|
||||
state->cx.avail_in = mi->cnt;
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
flush = Z_NO_FLUSH;
|
||||
expect_error = 0;
|
||||
|
||||
while (1) {
|
||||
if ((res = inflate(&InputState.cx, flush)) != Z_OK) {
|
||||
if ((res = inflate(&state->cx, flush)) != Z_OK) {
|
||||
if (res == Z_STREAM_END)
|
||||
break; /* Done */
|
||||
if (expect_error && res == Z_BUF_ERROR)
|
||||
break;
|
||||
LogPrintf(LogERROR, "DeflateDictSetup: inflate returned %d (%s)\n",
|
||||
res, InputState.cx.msg ? InputState.cx.msg : "");
|
||||
LogPrintf(LogERROR, "DeflateDictSetup: avail_in %d, avail_out %d\n",
|
||||
InputState.cx.avail_in, InputState.cx.avail_out);
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
mbfree(mi_head); /* lose our allocated ``head'' buf */
|
||||
log_Printf(LogERROR, "DeflateDictSetup: inflate returned %d (%s)\n",
|
||||
res, state->cx.msg ? state->cx.msg : "");
|
||||
log_Printf(LogERROR, "DeflateDictSetup: avail_in %d, avail_out %d\n",
|
||||
state->cx.avail_in, state->cx.avail_out);
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
mbuf_FreeSeg(mi_head); /* lose our allocated ``head'' buf */
|
||||
return;
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && InputState.cx.avail_out != 0)
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
break;
|
||||
|
||||
if (InputState.cx.avail_in == 0 && mi && (mi = mi->next) != NULL) {
|
||||
if (state->cx.avail_in == 0 && mi && (mi = mi->next) != NULL) {
|
||||
/* underflow */
|
||||
InputState.cx.next_in = MBUF_CTOP(mi);
|
||||
InputState.cx.avail_in = mi->cnt;
|
||||
state->cx.next_in = MBUF_CTOP(mi);
|
||||
state->cx.avail_in = mi->cnt;
|
||||
if (mi->next == NULL)
|
||||
flush = Z_SYNC_FLUSH;
|
||||
}
|
||||
|
||||
if (InputState.cx.avail_out == 0) {
|
||||
if (InputState.cx.avail_in == 0)
|
||||
if (state->cx.avail_out == 0) {
|
||||
if (state->cx.avail_in == 0)
|
||||
/*
|
||||
* This seems to be a bug in libz ! If inflate() finished
|
||||
* with 0 avail_in and 0 avail_out *and* this is the end of
|
||||
@ -417,17 +417,17 @@ DeflateDictSetup(u_short proto, struct mbuf *mi)
|
||||
*/
|
||||
expect_error = 1;
|
||||
/* overflow */
|
||||
InputState.cx.next_out = garbage;
|
||||
InputState.cx.avail_out = sizeof garbage;
|
||||
state->cx.next_out = garbage;
|
||||
state->cx.avail_out = sizeof garbage;
|
||||
}
|
||||
}
|
||||
|
||||
CcpInfo.compin += len;
|
||||
CcpInfo.uncompin += len;
|
||||
ccp->compin += len;
|
||||
ccp->uncompin += len;
|
||||
|
||||
InputState.seqno++;
|
||||
InputState.uncomp_rec++;
|
||||
mbfree(mi_head); /* lose our allocated ``head'' buf */
|
||||
state->seqno++;
|
||||
state->uncomp_rec++;
|
||||
mbuf_FreeSeg(mi_head); /* lose our allocated ``head'' buf */
|
||||
}
|
||||
|
||||
static const char *
|
||||
@ -440,50 +440,21 @@ DeflateDispOpts(struct lcp_opt *o)
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateGetInputOpts(struct lcp_opt *o)
|
||||
DeflateInitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
o->id = TY_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((iWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateGetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((oWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
PppdDeflateGetInputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_PPPD_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((iWindowSize-8)<<4)+8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static void
|
||||
PppdDeflateGetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
o->id = TY_PPPD_DEFLATE;
|
||||
o->len = 4;
|
||||
o->data[0] = ((oWindowSize-8)<<4)+8;
|
||||
o->data[0] = ((cfg->deflate.out.winsize - 8) << 4) + 8;
|
||||
o->data[1] = '\0';
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateSetOpts(struct lcp_opt *o, int *sz)
|
||||
DeflateSetOptsOutput(struct lcp_opt *o)
|
||||
{
|
||||
if (o->len != 4 || (o->data[0]&15) != 8 || o->data[1] != '\0') {
|
||||
if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0')
|
||||
return MODE_REJ;
|
||||
}
|
||||
*sz = (o->data[0] >> 4) + 8;
|
||||
if (*sz > 15) {
|
||||
*sz = 15;
|
||||
|
||||
if ((o->data[0] >> 4) + 8 > 15) {
|
||||
o->data[0] = ((15 - 8) << 4) + 8;
|
||||
return MODE_NAK;
|
||||
}
|
||||
|
||||
@ -491,93 +462,97 @@ DeflateSetOpts(struct lcp_opt *o, int *sz)
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateSetInputOpts(struct lcp_opt *o)
|
||||
DeflateSetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &iWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
DeflateGetInputOpts(o);
|
||||
return res;
|
||||
int want;
|
||||
|
||||
if (o->len != 4 || (o->data[0] & 15) != 8 || o->data[1] != '\0')
|
||||
return MODE_REJ;
|
||||
|
||||
want = (o->data[0] >> 4) + 8;
|
||||
if (cfg->deflate.in.winsize == 0) {
|
||||
if (want < 8 || want > 15) {
|
||||
o->data[0] = ((15 - 8) << 4) + 8;
|
||||
}
|
||||
} else if (want != cfg->deflate.in.winsize) {
|
||||
o->data[0] = ((cfg->deflate.in.winsize - 8) << 4) + 8;
|
||||
return MODE_NAK;
|
||||
}
|
||||
|
||||
return MODE_ACK;
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateSetOutputOpts(struct lcp_opt *o)
|
||||
static void *
|
||||
DeflateInitInput(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &oWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
DeflateGetOutputOpts(o);
|
||||
return res;
|
||||
struct deflate_state *state;
|
||||
|
||||
state = (struct deflate_state *)malloc(sizeof(struct deflate_state));
|
||||
if (state != NULL) {
|
||||
state->winsize = (o->data[0] >> 4) + 8;
|
||||
state->cx.zalloc = NULL;
|
||||
state->cx.opaque = NULL;
|
||||
state->cx.zfree = NULL;
|
||||
state->cx.next_out = NULL;
|
||||
if (inflateInit2(&state->cx, -state->winsize) == Z_OK)
|
||||
DeflateResetInput(state);
|
||||
else {
|
||||
free(state);
|
||||
state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return state;
|
||||
}
|
||||
|
||||
static int
|
||||
PppdDeflateSetInputOpts(struct lcp_opt *o)
|
||||
static void *
|
||||
DeflateInitOutput(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &iWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
PppdDeflateGetInputOpts(o);
|
||||
return res;
|
||||
}
|
||||
struct deflate_state *state;
|
||||
|
||||
static int
|
||||
PppdDeflateSetOutputOpts(struct lcp_opt *o)
|
||||
{
|
||||
int res;
|
||||
res = DeflateSetOpts(o, &oWindowSize);
|
||||
if (res != MODE_ACK)
|
||||
PppdDeflateGetOutputOpts(o);
|
||||
return res;
|
||||
}
|
||||
state = (struct deflate_state *)malloc(sizeof(struct deflate_state));
|
||||
if (state != NULL) {
|
||||
state->winsize = (o->data[0] >> 4) + 8;
|
||||
state->cx.zalloc = NULL;
|
||||
state->cx.opaque = NULL;
|
||||
state->cx.zfree = NULL;
|
||||
state->cx.next_in = NULL;
|
||||
if (deflateInit2(&state->cx, Z_DEFAULT_COMPRESSION, 8,
|
||||
-state->winsize, 8, Z_DEFAULT_STRATEGY) == Z_OK)
|
||||
DeflateResetOutput(state);
|
||||
else {
|
||||
free(state);
|
||||
state = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateInitInput(void)
|
||||
{
|
||||
InputState.cx.zalloc = NULL;
|
||||
InputState.cx.opaque = NULL;
|
||||
InputState.cx.zfree = NULL;
|
||||
InputState.cx.next_out = NULL;
|
||||
if (inflateInit2(&InputState.cx, -iWindowSize) != Z_OK)
|
||||
return 0;
|
||||
DeflateResetInput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateInitOutput(void)
|
||||
{
|
||||
OutputState.cx.zalloc = NULL;
|
||||
OutputState.cx.opaque = NULL;
|
||||
OutputState.cx.zfree = NULL;
|
||||
OutputState.cx.next_in = NULL;
|
||||
if (deflateInit2(&OutputState.cx, Z_DEFAULT_COMPRESSION, 8,
|
||||
-oWindowSize, 8, Z_DEFAULT_STRATEGY) != Z_OK)
|
||||
return 0;
|
||||
DeflateResetOutput();
|
||||
return 1;
|
||||
return state;
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateTermInput(void)
|
||||
DeflateTermInput(void *v)
|
||||
{
|
||||
iWindowSize = 15;
|
||||
inflateEnd(&InputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
inflateEnd(&state->cx);
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void
|
||||
DeflateTermOutput(void)
|
||||
DeflateTermOutput(void *v)
|
||||
{
|
||||
oWindowSize = 15;
|
||||
deflateEnd(&OutputState.cx);
|
||||
struct deflate_state *state = (struct deflate_state *)v;
|
||||
|
||||
deflateEnd(&state->cx);
|
||||
free(state);
|
||||
}
|
||||
|
||||
const struct ccp_algorithm PppdDeflateAlgorithm = {
|
||||
TY_PPPD_DEFLATE, /* pppd (wrongly) expects this ``type'' field */
|
||||
ConfPppdDeflate,
|
||||
CCP_NEG_DEFLATE24,
|
||||
DeflateDispOpts,
|
||||
{
|
||||
PppdDeflateGetInputOpts,
|
||||
PppdDeflateSetInputOpts,
|
||||
DeflateSetOptsInput,
|
||||
DeflateInitInput,
|
||||
DeflateTermInput,
|
||||
DeflateResetInput,
|
||||
@ -585,8 +560,8 @@ const struct ccp_algorithm PppdDeflateAlgorithm = {
|
||||
DeflateDictSetup
|
||||
},
|
||||
{
|
||||
PppdDeflateGetOutputOpts,
|
||||
PppdDeflateSetOutputOpts,
|
||||
DeflateInitOptsOutput,
|
||||
DeflateSetOptsOutput,
|
||||
DeflateInitOutput,
|
||||
DeflateTermOutput,
|
||||
DeflateResetOutput,
|
||||
@ -596,11 +571,10 @@ const struct ccp_algorithm PppdDeflateAlgorithm = {
|
||||
|
||||
const struct ccp_algorithm DeflateAlgorithm = {
|
||||
TY_DEFLATE, /* rfc 1979 */
|
||||
ConfDeflate,
|
||||
CCP_NEG_DEFLATE,
|
||||
DeflateDispOpts,
|
||||
{
|
||||
DeflateGetInputOpts,
|
||||
DeflateSetInputOpts,
|
||||
DeflateSetOptsInput,
|
||||
DeflateInitInput,
|
||||
DeflateTermInput,
|
||||
DeflateResetInput,
|
||||
@ -608,8 +582,8 @@ const struct ccp_algorithm DeflateAlgorithm = {
|
||||
DeflateDictSetup
|
||||
},
|
||||
{
|
||||
DeflateGetOutputOpts,
|
||||
DeflateSetOutputOpts,
|
||||
DeflateInitOptsOutput,
|
||||
DeflateSetOptsOutput,
|
||||
DeflateInitOutput,
|
||||
DeflateTermOutput,
|
||||
DeflateResetOutput,
|
||||
|
@ -23,54 +23,22 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: defs.c,v 1.11 1998/01/21 02:15:14 brian Exp $
|
||||
* $Id: defs.c,v 1.11.4.12 1998/05/15 23:58:21 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/errno.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
|
||||
int mode = MODE_INTER;
|
||||
int BGFiledes[2] = { -1, -1 };
|
||||
int modem = -1;
|
||||
int tun_in = -1;
|
||||
int tun_out = -1;
|
||||
int netfd = -1;
|
||||
|
||||
static char dstsystem[50];
|
||||
|
||||
void
|
||||
SetLabel(const char *label)
|
||||
{
|
||||
if (label)
|
||||
strncpy(dstsystem, label, sizeof dstsystem - 1);
|
||||
else
|
||||
*dstsystem = '\0';
|
||||
}
|
||||
|
||||
const char *
|
||||
GetLabel()
|
||||
{
|
||||
return *dstsystem ? dstsystem : NULL;
|
||||
}
|
||||
|
||||
void
|
||||
randinit()
|
||||
{
|
||||
#if __FreeBSD__ >= 3
|
||||
#if __FreeBSD__ >= 2
|
||||
static int initdone;
|
||||
|
||||
if (!initdone) {
|
||||
@ -78,40 +46,69 @@ randinit()
|
||||
srandomdev();
|
||||
}
|
||||
#else
|
||||
srandom(time(NULL)^getpid());
|
||||
srandom((time(NULL)^getpid())+random());
|
||||
#endif
|
||||
}
|
||||
|
||||
ssize_t
|
||||
fullread(int fd, void *v, size_t n)
|
||||
{
|
||||
size_t got, total;
|
||||
|
||||
for (total = 0; total < n; total += got)
|
||||
switch ((got = read(fd, (char *)v + total, n - total))) {
|
||||
case 0:
|
||||
return total;
|
||||
case -1:
|
||||
if (errno == EINTR)
|
||||
got = 0;
|
||||
else
|
||||
return -1;
|
||||
}
|
||||
return total;
|
||||
}
|
||||
|
||||
static struct {
|
||||
int mode;
|
||||
const char *name;
|
||||
} modes[] = {
|
||||
{ PHYS_MANUAL, "interactive" },
|
||||
{ PHYS_DEMAND, "auto" },
|
||||
{ PHYS_DIRECT, "direct" },
|
||||
{ PHYS_DEDICATED, "dedicated" },
|
||||
{ PHYS_PERM, "ddial" },
|
||||
{ PHYS_1OFF, "background" },
|
||||
{ PHYS_ALL, "*" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
const char *
|
||||
mode2Nam(int mode)
|
||||
{
|
||||
int m;
|
||||
|
||||
for (m = 0; modes[m].mode; m++)
|
||||
if (modes[m].mode == mode)
|
||||
return modes[m].name;
|
||||
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
int
|
||||
GetShortHost()
|
||||
Nam2mode(const char *name)
|
||||
{
|
||||
char *p;
|
||||
int m, got, len;
|
||||
|
||||
if (gethostname(VarShortHost, sizeof VarShortHost)) {
|
||||
LogPrintf(LogERROR, "GetShortHost: gethostname: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
len = strlen(name);
|
||||
got = -1;
|
||||
for (m = 0; modes[m].mode; m++)
|
||||
if (!strncasecmp(name, modes[m].name, len)) {
|
||||
if (modes[m].name[len] == '\0')
|
||||
return modes[m].mode;
|
||||
if (got != -1)
|
||||
return 0;
|
||||
got = m;
|
||||
}
|
||||
|
||||
if ((p = strchr(VarShortHost, '.')))
|
||||
*p = '\0';
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
DropClient(int verbose)
|
||||
{
|
||||
FILE *oVarTerm;
|
||||
|
||||
if (VarTerm && !(mode & MODE_INTER)) {
|
||||
oVarTerm = VarTerm;
|
||||
VarTerm = 0;
|
||||
if (oVarTerm)
|
||||
fclose(oVarTerm);
|
||||
close(netfd);
|
||||
netfd = -1;
|
||||
if (verbose)
|
||||
LogPrintf(LogPHASE, "Client connection dropped.\n");
|
||||
}
|
||||
return got == -1 ? 0 : modes[got].mode;
|
||||
}
|
||||
|
@ -15,57 +15,47 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: defs.h,v 1.28 1997/11/22 03:37:29 brian Exp $
|
||||
* $Id: defs.h,v 1.29.2.18 1998/05/15 23:58:22 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Check following definitions for your machine environment
|
||||
*/
|
||||
/* Check the following definitions for your machine environment */
|
||||
#ifdef __FreeBSD__
|
||||
# define MODEM_DEV "/dev/cuaa1" /* name of tty device */
|
||||
# define BASE_MODEM_DEV "cuaa1" /* name of base tty device */
|
||||
# define MODEM_LIST "/dev/cuaa1, /dev/cuaa0" /* name of tty device */
|
||||
#else
|
||||
# ifdef __OpenBSD__
|
||||
# define MODEM_DEV "/dev/cua01" /* name of tty device */
|
||||
# define BASE_MODEM_DEV "cua01" /* name of base tty device */
|
||||
# define MODEM_LIST "/dev/cua01, /dev/cua00" /* name of tty device */
|
||||
# else
|
||||
# define MODEM_DEV "/dev/tty01" /* name of tty device */
|
||||
# define BASE_MODEM_DEV "tty01" /* name of base tty device */
|
||||
# define MODEM_LIST "/dev/tty01, /dev/tty00" /* name of tty device */
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#define _PATH_PPP "/etc/ppp"
|
||||
|
||||
#define TUN_PREFIX "/dev/tun" /* tunnel device prefix */
|
||||
#define CATPROG "/bin/cat" /* Multilink pipe program name */
|
||||
|
||||
#define MODEM_SPEED B38400 /* tty speed */
|
||||
#define SERVER_PORT 3000 /* Base server port no. */
|
||||
#define MODEM_CTSRTS 1 /* Default (true): use CTS/RTS signals */
|
||||
#define RECONNECT_TIMER 3 /* Default timer for carrier loss */
|
||||
#define RECONNECT_TRIES 0 /* Default retries on carrier loss */
|
||||
#define REDIAL_PERIOD 30 /* Default Hold time to redial */
|
||||
#define NEXT_REDIAL_PERIOD 3 /* Default Hold time to next number redial */
|
||||
#define RECONNECT_TIMEOUT 3 /* Default timer for carrier loss */
|
||||
#define DIAL_TIMEOUT 30 /* Default and Max random time to redial */
|
||||
#define DIAL_NEXT_TIMEOUT 3 /* Default Hold time to next number redial */
|
||||
#define SCRIPT_LEN 512 /* Size of login scripts */
|
||||
#define LINE_LEN SCRIPT_LEN /* Size of login scripts */
|
||||
#define MAXARGS 40 /* How many args per config line */
|
||||
#define NCP_IDLE_TIMEOUT 180 /* Drop all links */
|
||||
|
||||
#define LINK_MINWEIGHT 20
|
||||
#define DEF_LQRPERIOD 30 /* LQR frequency */
|
||||
#define DEF_FSMRETRY 3 /* FSM retry frequency */
|
||||
|
||||
#define CONFFILE "ppp.conf"
|
||||
#define LINKUPFILE "ppp.linkup"
|
||||
#define LINKDOWNFILE "ppp.linkdown"
|
||||
#define SECRETFILE "ppp.secret"
|
||||
|
||||
/*
|
||||
* Definition of working mode
|
||||
*/
|
||||
#define MODE_INTER 1 /* Interactive mode */
|
||||
#define MODE_AUTO 2 /* Auto calling mode */
|
||||
#define MODE_DIRECT 4 /* Direct connection mode */
|
||||
#define MODE_DEDICATED 8 /* Dedicated line mode */
|
||||
#define MODE_DDIAL 16 /* Dedicated dialing line mode */
|
||||
#define MODE_ALIAS 32 /* Packet aliasing (masquerading) */
|
||||
#define MODE_BACKGROUND 64 /* Background mode. */
|
||||
|
||||
#define MODE_DAEMON (2|4|8|16|64)
|
||||
#define MODE_OUTGOING_DAEMON (2|8|16|64)
|
||||
|
||||
#define EX_SIG -1
|
||||
#define EX_NORMAL 0
|
||||
#define EX_START 1
|
||||
@ -81,15 +71,17 @@
|
||||
#define EX_NODIAL 12
|
||||
#define EX_NOLOGIN 13
|
||||
|
||||
extern int mode;
|
||||
extern int BGFiledes[2];
|
||||
extern int modem;
|
||||
extern int tun_in;
|
||||
extern int tun_out;
|
||||
extern int netfd;
|
||||
/* physical::type values (OR'd in bundle::phys_type) */
|
||||
#define PHYS_NONE 0
|
||||
#define PHYS_MANUAL 1 /* Manual link */
|
||||
#define PHYS_DEMAND 2 /* Dial-on-demand link (-auto) */
|
||||
#define PHYS_DIRECT 4 /* Incoming link (-direct) */
|
||||
#define PHYS_DEDICATED 8 /* Dedicated link (-dedicated) */
|
||||
#define PHYS_PERM 16 /* Dial immediately, stay connected (-ddial) */
|
||||
#define PHYS_1OFF 32 /* Dial immediately, delete when done. (-background) */
|
||||
#define PHYS_ALL 63
|
||||
|
||||
extern void SetLabel(const char *);
|
||||
extern const char *GetLabel(void);
|
||||
extern void randinit(void);
|
||||
extern int GetShortHost(void);
|
||||
extern void DropClient(int);
|
||||
extern ssize_t fullread(int, void *, size_t);
|
||||
extern const char *mode2Nam(int);
|
||||
extern int Nam2mode(const char *);
|
||||
|
@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright (c) 1989 The Regents of the University of California.
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
@ -10,18 +10,11 @@
|
||||
* 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
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR 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)
|
||||
@ -30,14 +23,30 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
*
|
||||
* $Id: pathnames.h,v 1.7 1997/09/10 02:20:33 brian Exp $
|
||||
*
|
||||
* @(#)pathnames.h 5.2 (Berkeley) 6/1/90
|
||||
* $Id: descriptor.h,v 1.1.2.10 1998/04/28 01:25:13 brian Exp $
|
||||
*/
|
||||
|
||||
#if defined(__FreeBSD__) || defined(__OpenBSD__)
|
||||
#define _PATH_PPP "/etc/ppp"
|
||||
#else
|
||||
#define _PATH_PPP "/etc"
|
||||
#endif
|
||||
#define PHYSICAL_DESCRIPTOR (1)
|
||||
#define SERVER_DESCRIPTOR (2)
|
||||
#define PROMPT_DESCRIPTOR (3)
|
||||
#define CHAT_DESCRIPTOR (4)
|
||||
#define DATALINK_DESCRIPTOR (5)
|
||||
#define BUNDLE_DESCRIPTOR (6)
|
||||
#define MPSERVER_DESCRIPTOR (7)
|
||||
|
||||
struct bundle;
|
||||
|
||||
struct descriptor {
|
||||
int type;
|
||||
struct descriptor *next;
|
||||
|
||||
int (*UpdateSet)(struct descriptor *, fd_set *, fd_set *, fd_set *, int *);
|
||||
int (*IsSet)(struct descriptor *, const fd_set *);
|
||||
void (*Read)(struct descriptor *, struct bundle *, const fd_set *);
|
||||
void (*Write)(struct descriptor *, struct bundle *, const fd_set *);
|
||||
};
|
||||
|
||||
#define descriptor_UpdateSet(d, r, w, e, n) ((*(d)->UpdateSet)(d, r, w, e, n))
|
||||
#define descriptor_IsSet(d, s) ((*(d)->IsSet)(d, s))
|
||||
#define descriptor_Read(d, b, f) ((*(d)->Read)(d, b, f))
|
||||
#define descriptor_Write(d, b, f) ((*(d)->Write)(d, b, f))
|
@ -17,37 +17,49 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: filter.c,v 1.21 1997/12/24 09:28:57 brian Exp $
|
||||
* $Id: filter.c,v 1.22.2.19 1998/05/01 19:24:28 brian Exp $
|
||||
*
|
||||
* TODO: Shoud send ICMP error message when we discard packets.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <strings.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "defs.h"
|
||||
#include "vars.h"
|
||||
#include "iplist.h"
|
||||
#include "timer.h"
|
||||
#include "throughput.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
|
||||
struct filterent ifilters[MAXFILTERS]; /* incoming packet filter */
|
||||
struct filterent ofilters[MAXFILTERS]; /* outgoing packet filter */
|
||||
struct filterent dfilters[MAXFILTERS]; /* dial-out packet filter */
|
||||
struct filterent afilters[MAXFILTERS]; /* keep-alive packet filter */
|
||||
static int filter_Nam2Proto(int, char const *const *);
|
||||
static int filter_Nam2Op(const char *);
|
||||
|
||||
static struct filterent filterdata;
|
||||
|
||||
static u_long netmasks[33] = {
|
||||
static const u_long netmasks[33] = {
|
||||
0x00000000,
|
||||
0x80000000, 0xC0000000, 0xE0000000, 0xF0000000,
|
||||
0xF8000000, 0xFC000000, 0xFE000000, 0xFF000000,
|
||||
@ -60,52 +72,51 @@ static u_long netmasks[33] = {
|
||||
};
|
||||
|
||||
int
|
||||
ParseAddr(int argc,
|
||||
char const *const *argv,
|
||||
struct in_addr * paddr,
|
||||
struct in_addr * pmask,
|
||||
int *pwidth)
|
||||
ParseAddr(struct ipcp *ipcp, int argc, char const *const *argv,
|
||||
struct in_addr *paddr, struct in_addr *pmask, int *pwidth)
|
||||
{
|
||||
int bits, len;
|
||||
char *wp;
|
||||
const char *cp;
|
||||
|
||||
if (argc < 1) {
|
||||
LogPrintf(LogWARN, "ParseAddr: address/mask is expected.\n");
|
||||
log_Printf(LogWARN, "ParseAddr: address/mask is expected.\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (pmask)
|
||||
pmask->s_addr = 0xffffffff; /* Assume 255.255.255.255 as default */
|
||||
pmask->s_addr = INADDR_BROADCAST; /* Assume 255.255.255.255 as default */
|
||||
|
||||
cp = pmask || pwidth ? strchr(*argv, '/') : NULL;
|
||||
len = cp ? cp - *argv : strlen(*argv);
|
||||
|
||||
if (strncasecmp(*argv, "HISADDR", len) == 0)
|
||||
*paddr = IpcpInfo.his_ipaddr;
|
||||
*paddr = ipcp->peer_ip;
|
||||
else if (strncasecmp(*argv, "MYADDR", len) == 0)
|
||||
*paddr = IpcpInfo.want_ipaddr;
|
||||
*paddr = ipcp->my_ip;
|
||||
else if (len > 15)
|
||||
LogPrintf(LogWARN, "ParseAddr: %s: Bad address\n", *argv);
|
||||
log_Printf(LogWARN, "ParseAddr: %s: Bad address\n", *argv);
|
||||
else {
|
||||
char s[16];
|
||||
strncpy(s, *argv, len);
|
||||
s[len] = '\0';
|
||||
if (inet_aton(s, paddr) == 0) {
|
||||
LogPrintf(LogWARN, "ParseAddr: %s: Bad address\n", s);
|
||||
log_Printf(LogWARN, "ParseAddr: %s: Bad address\n", s);
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (cp && *++cp) {
|
||||
bits = strtol(cp, &wp, 0);
|
||||
if (cp == wp || bits < 0 || bits > 32) {
|
||||
LogPrintf(LogWARN, "ParseAddr: bad mask width.\n");
|
||||
log_Printf(LogWARN, "ParseAddr: bad mask width.\n");
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
/* if width is not given, assume whole 32 bits are meaningfull */
|
||||
} else if (paddr->s_addr == INADDR_ANY)
|
||||
/* An IP of 0.0.0.0 without a width is anything */
|
||||
bits = 0;
|
||||
else
|
||||
/* If a valid IP is given without a width, assume 32 bits */
|
||||
bits = 32;
|
||||
}
|
||||
|
||||
if (pwidth)
|
||||
*pwidth = bits;
|
||||
@ -116,25 +127,6 @@ ParseAddr(int argc,
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ParseProto(int argc, char const *const *argv)
|
||||
{
|
||||
int proto;
|
||||
|
||||
if (argc < 1)
|
||||
return (P_NONE);
|
||||
|
||||
if (!strcmp(*argv, "tcp"))
|
||||
proto = P_TCP;
|
||||
else if (!strcmp(*argv, "udp"))
|
||||
proto = P_UDP;
|
||||
else if (!strcmp(*argv, "icmp"))
|
||||
proto = P_ICMP;
|
||||
else
|
||||
proto = P_NONE;
|
||||
return (proto);
|
||||
}
|
||||
|
||||
static int
|
||||
ParsePort(const char *service, int proto)
|
||||
{
|
||||
@ -160,7 +152,7 @@ ParsePort(const char *service, int proto)
|
||||
|
||||
port = strtol(service, &cp, 0);
|
||||
if (cp == service) {
|
||||
LogPrintf(LogWARN, "ParsePort: %s is not a port name or number.\n",
|
||||
log_Printf(LogWARN, "ParsePort: %s is not a port name or number.\n",
|
||||
service);
|
||||
return (0);
|
||||
}
|
||||
@ -171,7 +163,7 @@ ParsePort(const char *service, int proto)
|
||||
* ICMP Syntax: src eq icmp_message_type
|
||||
*/
|
||||
static int
|
||||
ParseIcmp(int argc, char const *const *argv)
|
||||
ParseIcmp(int argc, char const *const *argv, struct filterent *tgt)
|
||||
{
|
||||
int type;
|
||||
char *cp;
|
||||
@ -179,108 +171,96 @@ ParseIcmp(int argc, char const *const *argv)
|
||||
switch (argc) {
|
||||
case 0:
|
||||
/* permit/deny all ICMP types */
|
||||
filterdata.opt.srcop = OP_NONE;
|
||||
tgt->opt.srcop = OP_NONE;
|
||||
break;
|
||||
default:
|
||||
LogPrintf(LogWARN, "ParseIcmp: bad icmp syntax.\n");
|
||||
return (0);
|
||||
|
||||
case 3:
|
||||
if (!strcmp(*argv, "src") && !strcmp(argv[1], "eq")) {
|
||||
type = strtol(argv[2], &cp, 0);
|
||||
if (cp == argv[2]) {
|
||||
LogPrintf(LogWARN, "ParseIcmp: type is expected.\n");
|
||||
log_Printf(LogWARN, "ParseIcmp: type is expected.\n");
|
||||
return (0);
|
||||
}
|
||||
filterdata.opt.srcop = OP_EQ;
|
||||
filterdata.opt.srcport = type;
|
||||
tgt->opt.srcop = OP_EQ;
|
||||
tgt->opt.srcport = type;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
log_Printf(LogWARN, "ParseIcmp: bad icmp syntax.\n");
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
static int
|
||||
ParseOp(const char *cp)
|
||||
{
|
||||
int op = OP_NONE;
|
||||
|
||||
if (!strcmp(cp, "eq"))
|
||||
op = OP_EQ;
|
||||
else if (!strcmp(cp, "gt"))
|
||||
op = OP_GT;
|
||||
else if (!strcmp(cp, "lt"))
|
||||
op = OP_LT;
|
||||
return (op);
|
||||
}
|
||||
|
||||
/*
|
||||
* UDP Syntax: [src op port] [dst op port]
|
||||
*/
|
||||
static int
|
||||
ParseUdpOrTcp(int argc, char const *const *argv, int proto)
|
||||
ParseUdpOrTcp(int argc, char const *const *argv, int proto,
|
||||
struct filterent *tgt)
|
||||
{
|
||||
filterdata.opt.srcop = filterdata.opt.dstop = OP_NONE;
|
||||
filterdata.opt.estab = 0;
|
||||
|
||||
if (argc == 0) {
|
||||
/* permit/deny all tcp traffic */
|
||||
return (1);
|
||||
}
|
||||
tgt->opt.srcop = tgt->opt.dstop = OP_NONE;
|
||||
tgt->opt.estab = tgt->opt.syn = tgt->opt.finrst = 0;
|
||||
|
||||
if (argc >= 3 && !strcmp(*argv, "src")) {
|
||||
filterdata.opt.srcop = ParseOp(argv[1]);
|
||||
if (filterdata.opt.srcop == OP_NONE) {
|
||||
LogPrintf(LogWARN, "ParseUdpOrTcp: bad operation\n");
|
||||
tgt->opt.srcop = filter_Nam2Op(argv[1]);
|
||||
if (tgt->opt.srcop == OP_NONE) {
|
||||
log_Printf(LogWARN, "ParseUdpOrTcp: bad operation\n");
|
||||
return (0);
|
||||
}
|
||||
filterdata.opt.srcport = ParsePort(argv[2], proto);
|
||||
if (filterdata.opt.srcport == 0)
|
||||
tgt->opt.srcport = ParsePort(argv[2], proto);
|
||||
if (tgt->opt.srcport == 0)
|
||||
return (0);
|
||||
argc -= 3;
|
||||
argv += 3;
|
||||
if (argc == 0)
|
||||
return (1);
|
||||
}
|
||||
|
||||
if (argc >= 3 && !strcmp(argv[0], "dst")) {
|
||||
filterdata.opt.dstop = ParseOp(argv[1]);
|
||||
if (filterdata.opt.dstop == OP_NONE) {
|
||||
LogPrintf(LogWARN, "ParseUdpOrTcp: bad operation\n");
|
||||
tgt->opt.dstop = filter_Nam2Op(argv[1]);
|
||||
if (tgt->opt.dstop == OP_NONE) {
|
||||
log_Printf(LogWARN, "ParseUdpOrTcp: bad operation\n");
|
||||
return (0);
|
||||
}
|
||||
filterdata.opt.dstport = ParsePort(argv[2], proto);
|
||||
if (filterdata.opt.dstport == 0)
|
||||
tgt->opt.dstport = ParsePort(argv[2], proto);
|
||||
if (tgt->opt.dstport == 0)
|
||||
return (0);
|
||||
argc -= 3;
|
||||
argv += 3;
|
||||
if (argc == 0)
|
||||
return (1);
|
||||
}
|
||||
if (argc == 1 && proto == P_TCP) {
|
||||
if (!strcmp(*argv, "estab")) {
|
||||
filterdata.opt.estab = 1;
|
||||
return (1);
|
||||
}
|
||||
LogPrintf(LogWARN, "ParseUdpOrTcp: estab is expected: %s\n", *argv);
|
||||
return (0);
|
||||
|
||||
if (proto == P_TCP) {
|
||||
for (; argc > 0; argc--, argv++)
|
||||
if (!strcmp(*argv, "estab"))
|
||||
tgt->opt.estab = 1;
|
||||
else if (!strcmp(*argv, "syn"))
|
||||
tgt->opt.syn = 1;
|
||||
else if (!strcmp(*argv, "finrst"))
|
||||
tgt->opt.finrst = 1;
|
||||
else
|
||||
break;
|
||||
}
|
||||
if (argc > 0)
|
||||
LogPrintf(LogWARN, "ParseUdpOrTcp: bad src/dst port syntax: %s\n", *argv);
|
||||
return (0);
|
||||
|
||||
if (argc > 0) {
|
||||
log_Printf(LogWARN, "ParseUdpOrTcp: bad src/dst port syntax: %s\n", *argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static const char *opname[] = {"none", "eq", "gt", NULL, "lt"};
|
||||
|
||||
static int
|
||||
Parse(int argc, char const *const *argv, struct filterent * ofp)
|
||||
Parse(struct ipcp *ipcp, int argc, char const *const *argv,
|
||||
struct filterent *ofp)
|
||||
{
|
||||
int action, proto;
|
||||
int val;
|
||||
char *wp;
|
||||
struct filterent *fp = &filterdata;
|
||||
struct filterent filterdata;
|
||||
|
||||
val = strtol(*argv, &wp, 0);
|
||||
if (*argv == wp || val > MAXFILTERS) {
|
||||
LogPrintf(LogWARN, "Parse: invalid filter number.\n");
|
||||
log_Printf(LogWARN, "Parse: invalid filter number.\n");
|
||||
return (0);
|
||||
}
|
||||
if (val < 0) {
|
||||
@ -288,13 +268,13 @@ Parse(int argc, char const *const *argv, struct filterent * ofp)
|
||||
ofp->action = A_NONE;
|
||||
ofp++;
|
||||
}
|
||||
LogPrintf(LogWARN, "Parse: filter cleared.\n");
|
||||
log_Printf(LogWARN, "Parse: filter cleared.\n");
|
||||
return (1);
|
||||
}
|
||||
ofp += val;
|
||||
|
||||
if (--argc == 0) {
|
||||
LogPrintf(LogWARN, "Parse: missing action.\n");
|
||||
log_Printf(LogWARN, "Parse: missing action.\n");
|
||||
return (0);
|
||||
}
|
||||
argv++;
|
||||
@ -310,37 +290,39 @@ Parse(int argc, char const *const *argv, struct filterent * ofp)
|
||||
ofp->action = A_NONE;
|
||||
return (1);
|
||||
} else {
|
||||
LogPrintf(LogWARN, "Parse: bad action: %s\n", *argv);
|
||||
log_Printf(LogWARN, "Parse: bad action: %s\n", *argv);
|
||||
return (0);
|
||||
}
|
||||
fp->action = action;
|
||||
filterdata.action = action;
|
||||
|
||||
argc--;
|
||||
argv++;
|
||||
|
||||
if (fp->action == A_DENY) {
|
||||
if (filterdata.action == A_DENY) {
|
||||
if (!strcmp(*argv, "host")) {
|
||||
fp->action |= A_UHOST;
|
||||
filterdata.action |= A_UHOST;
|
||||
argc--;
|
||||
argv++;
|
||||
} else if (!strcmp(*argv, "port")) {
|
||||
fp->action |= A_UPORT;
|
||||
filterdata.action |= A_UPORT;
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
}
|
||||
proto = ParseProto(argc, argv);
|
||||
proto = filter_Nam2Proto(argc, argv);
|
||||
if (proto == P_NONE) {
|
||||
if (ParseAddr(argc, argv, &fp->saddr, &fp->smask, &fp->swidth)) {
|
||||
if (ParseAddr(ipcp, argc, argv, &filterdata.saddr, &filterdata.smask,
|
||||
&filterdata.swidth)) {
|
||||
argc--;
|
||||
argv++;
|
||||
proto = ParseProto(argc, argv);
|
||||
proto = filter_Nam2Proto(argc, argv);
|
||||
if (proto == P_NONE) {
|
||||
if (ParseAddr(argc, argv, &fp->daddr, &fp->dmask, &fp->dwidth)) {
|
||||
if (ParseAddr(ipcp, argc, argv, &filterdata.daddr, &filterdata.dmask,
|
||||
&filterdata.dwidth)) {
|
||||
argc--;
|
||||
argv++;
|
||||
}
|
||||
proto = ParseProto(argc, argv);
|
||||
proto = filter_Nam2Proto(argc, argv);
|
||||
if (proto != P_NONE) {
|
||||
argc--;
|
||||
argv++;
|
||||
@ -350,7 +332,7 @@ Parse(int argc, char const *const *argv, struct filterent * ofp)
|
||||
argv++;
|
||||
}
|
||||
} else {
|
||||
LogPrintf(LogWARN, "Parse: Address/protocol expected.\n");
|
||||
log_Printf(LogWARN, "Parse: Address/protocol expected.\n");
|
||||
return (0);
|
||||
}
|
||||
} else {
|
||||
@ -359,141 +341,193 @@ Parse(int argc, char const *const *argv, struct filterent * ofp)
|
||||
}
|
||||
|
||||
val = 1;
|
||||
fp->proto = proto;
|
||||
filterdata.proto = proto;
|
||||
|
||||
switch (proto) {
|
||||
case P_TCP:
|
||||
val = ParseUdpOrTcp(argc, argv, P_TCP);
|
||||
val = ParseUdpOrTcp(argc, argv, P_TCP, &filterdata);
|
||||
break;
|
||||
case P_UDP:
|
||||
val = ParseUdpOrTcp(argc, argv, P_UDP);
|
||||
val = ParseUdpOrTcp(argc, argv, P_UDP, &filterdata);
|
||||
break;
|
||||
case P_ICMP:
|
||||
val = ParseIcmp(argc, argv);
|
||||
val = ParseIcmp(argc, argv, &filterdata);
|
||||
break;
|
||||
}
|
||||
|
||||
LogPrintf(LogDEBUG, "Parse: Src: %s\n", inet_ntoa(fp->saddr));
|
||||
LogPrintf(LogDEBUG, "Parse: Src mask: %s\n", inet_ntoa(fp->smask));
|
||||
LogPrintf(LogDEBUG, "Parse: Dst: %s\n", inet_ntoa(fp->daddr));
|
||||
LogPrintf(LogDEBUG, "Parse: Dst mask: %s\n", inet_ntoa(fp->dmask));
|
||||
LogPrintf(LogDEBUG, "Parse: Proto = %d\n", proto);
|
||||
log_Printf(LogDEBUG, "Parse: Src: %s\n", inet_ntoa(filterdata.saddr));
|
||||
log_Printf(LogDEBUG, "Parse: Src mask: %s\n", inet_ntoa(filterdata.smask));
|
||||
log_Printf(LogDEBUG, "Parse: Dst: %s\n", inet_ntoa(filterdata.daddr));
|
||||
log_Printf(LogDEBUG, "Parse: Dst mask: %s\n", inet_ntoa(filterdata.dmask));
|
||||
log_Printf(LogDEBUG, "Parse: Proto = %d\n", proto);
|
||||
|
||||
LogPrintf(LogDEBUG, "Parse: src: %s (%d)\n", opname[fp->opt.srcop],
|
||||
fp->opt.srcport);
|
||||
LogPrintf(LogDEBUG, "Parse: dst: %s (%d)\n", opname[fp->opt.dstop],
|
||||
fp->opt.dstport);
|
||||
LogPrintf(LogDEBUG, "Parse: estab: %d\n", fp->opt.estab);
|
||||
log_Printf(LogDEBUG, "Parse: src: %s (%d)\n",
|
||||
filter_Op2Nam(filterdata.opt.srcop), filterdata.opt.srcport);
|
||||
log_Printf(LogDEBUG, "Parse: dst: %s (%d)\n",
|
||||
filter_Op2Nam(filterdata.opt.dstop), filterdata.opt.dstport);
|
||||
log_Printf(LogDEBUG, "Parse: estab: %u\n", filterdata.opt.estab);
|
||||
log_Printf(LogDEBUG, "Parse: syn: %u\n", filterdata.opt.syn);
|
||||
log_Printf(LogDEBUG, "Parse: finrst: %u\n", filterdata.opt.finrst);
|
||||
|
||||
if (val)
|
||||
*ofp = *fp;
|
||||
*ofp = filterdata;
|
||||
return (val);
|
||||
}
|
||||
|
||||
int
|
||||
SetIfilter(struct cmdargs const *arg)
|
||||
filter_Set(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc > 0) {
|
||||
Parse(arg->argc, arg->argv, ifilters);
|
||||
return 0;
|
||||
struct filter *filter;
|
||||
|
||||
if (arg->argc < arg->argn+2)
|
||||
return -1;
|
||||
|
||||
if (!strcmp(arg->argv[arg->argn], "in"))
|
||||
filter = &arg->bundle->filter.in;
|
||||
else if (!strcmp(arg->argv[arg->argn], "out"))
|
||||
filter = &arg->bundle->filter.out;
|
||||
else if (!strcmp(arg->argv[arg->argn], "dial"))
|
||||
filter = &arg->bundle->filter.dial;
|
||||
else if (!strcmp(arg->argv[arg->argn], "alive"))
|
||||
filter = &arg->bundle->filter.alive;
|
||||
else {
|
||||
log_Printf(LogWARN, "filter_Set: %s: Invalid filter name.\n",
|
||||
arg->argv[arg->argn]);
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
|
||||
Parse(&arg->bundle->ncp.ipcp, arg->argc - arg->argn - 1,
|
||||
arg->argv + arg->argn + 1, filter->rule);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SetOfilter(struct cmdargs const *arg)
|
||||
const char *
|
||||
filter_Action2Nam(int act)
|
||||
{
|
||||
if (arg->argc > 0) {
|
||||
(void) Parse(arg->argc, arg->argv, ofilters);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
static const char *actname[] = { "none ", "permit ", "deny " };
|
||||
return actname[act & (A_PERMIT|A_DENY)];
|
||||
}
|
||||
|
||||
int
|
||||
SetDfilter(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc > 0) {
|
||||
(void) Parse(arg->argc, arg->argv, dfilters);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
SetAfilter(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc > 0) {
|
||||
(void) Parse(arg->argc, arg->argv, afilters);
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static const char *protoname[] = { "none", "tcp", "udp", "icmp" };
|
||||
static const char *actname[] = { "none ", "permit ", "deny " };
|
||||
|
||||
static void
|
||||
ShowFilter(struct filterent * fp)
|
||||
doShowFilter(struct filterent *fp, struct prompt *prompt)
|
||||
{
|
||||
int n;
|
||||
|
||||
if (!VarTerm)
|
||||
return;
|
||||
|
||||
for (n = 0; n < MAXFILTERS; n++, fp++) {
|
||||
if (fp->action != A_NONE) {
|
||||
fprintf(VarTerm, "%2d %s", n, actname[fp->action & (A_PERMIT|A_DENY)]);
|
||||
prompt_Printf(prompt, " %2d %s", n, filter_Action2Nam(fp->action));
|
||||
if (fp->action & A_UHOST)
|
||||
fprintf(VarTerm, "host ");
|
||||
prompt_Printf(prompt, "host ");
|
||||
else if (fp->action & A_UPORT)
|
||||
fprintf(VarTerm, "port ");
|
||||
prompt_Printf(prompt, "port ");
|
||||
else
|
||||
fprintf(VarTerm, " ");
|
||||
fprintf(VarTerm, "%s/%d ", inet_ntoa(fp->saddr), fp->swidth);
|
||||
fprintf(VarTerm, "%s/%d ", inet_ntoa(fp->daddr), fp->dwidth);
|
||||
prompt_Printf(prompt, " ");
|
||||
prompt_Printf(prompt, "%s/%d ", inet_ntoa(fp->saddr), fp->swidth);
|
||||
prompt_Printf(prompt, "%s/%d ", inet_ntoa(fp->daddr), fp->dwidth);
|
||||
if (fp->proto) {
|
||||
fprintf(VarTerm, "%s", protoname[fp->proto]);
|
||||
prompt_Printf(prompt, "%s", filter_Proto2Nam(fp->proto));
|
||||
|
||||
if (fp->opt.srcop)
|
||||
fprintf(VarTerm, " src %s %d", opname[fp->opt.srcop],
|
||||
prompt_Printf(prompt, " src %s %d", filter_Op2Nam(fp->opt.srcop),
|
||||
fp->opt.srcport);
|
||||
if (fp->opt.dstop)
|
||||
fprintf(VarTerm, " dst %s %d", opname[fp->opt.dstop],
|
||||
prompt_Printf(prompt, " dst %s %d", filter_Op2Nam(fp->opt.dstop),
|
||||
fp->opt.dstport);
|
||||
if (fp->opt.estab)
|
||||
fprintf(VarTerm, " estab");
|
||||
|
||||
prompt_Printf(prompt, " estab");
|
||||
if (fp->opt.syn)
|
||||
prompt_Printf(prompt, " syn");
|
||||
if (fp->opt.finrst)
|
||||
prompt_Printf(prompt, " finrst");
|
||||
}
|
||||
fprintf(VarTerm, "\n");
|
||||
prompt_Printf(prompt, "\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ShowIfilter(struct cmdargs const *arg)
|
||||
filter_Show(struct cmdargs const *arg)
|
||||
{
|
||||
ShowFilter(ifilters);
|
||||
if (arg->argc > arg->argn+1)
|
||||
return -1;
|
||||
|
||||
if (arg->argc == arg->argn+1) {
|
||||
struct filter *filter;
|
||||
|
||||
if (!strcmp(arg->argv[arg->argn], "in"))
|
||||
filter = &arg->bundle->filter.in;
|
||||
else if (!strcmp(arg->argv[arg->argn], "out"))
|
||||
filter = &arg->bundle->filter.out;
|
||||
else if (!strcmp(arg->argv[arg->argn], "dial"))
|
||||
filter = &arg->bundle->filter.dial;
|
||||
else if (!strcmp(arg->argv[arg->argn], "alive"))
|
||||
filter = &arg->bundle->filter.alive;
|
||||
else
|
||||
return -1;
|
||||
doShowFilter(filter->rule, arg->prompt);
|
||||
} else {
|
||||
struct filter *filter[4];
|
||||
int f;
|
||||
|
||||
filter[0] = &arg->bundle->filter.in;
|
||||
filter[1] = &arg->bundle->filter.out;
|
||||
filter[2] = &arg->bundle->filter.dial;
|
||||
filter[3] = &arg->bundle->filter.alive;
|
||||
for (f = 0; f < 4; f++) {
|
||||
if (f)
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
prompt_Printf(arg->prompt, "%s:\n", filter[f]->name);
|
||||
doShowFilter(filter[f]->rule, arg->prompt);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ShowOfilter(struct cmdargs const *arg)
|
||||
static const char *protoname[] = { "none", "tcp", "udp", "icmp" };
|
||||
|
||||
const char *
|
||||
filter_Proto2Nam(int proto)
|
||||
{
|
||||
ShowFilter(ofilters);
|
||||
return 0;
|
||||
if (proto >= sizeof protoname / sizeof protoname[0])
|
||||
return "unknown";
|
||||
return protoname[proto];
|
||||
}
|
||||
|
||||
int
|
||||
ShowDfilter(struct cmdargs const *arg)
|
||||
static int
|
||||
filter_Nam2Proto(int argc, char const *const *argv)
|
||||
{
|
||||
ShowFilter(dfilters);
|
||||
return 0;
|
||||
int proto;
|
||||
|
||||
if (argc == 0)
|
||||
proto = 0;
|
||||
else
|
||||
for (proto = sizeof protoname / sizeof protoname[0] - 1; proto; proto--)
|
||||
if (!strcasecmp(*argv, protoname[proto]))
|
||||
break;
|
||||
|
||||
return proto;
|
||||
}
|
||||
|
||||
int
|
||||
ShowAfilter(struct cmdargs const *arg)
|
||||
static const char *opname[] = {"none", "eq", "gt", "unknown", "lt"};
|
||||
|
||||
const char *
|
||||
filter_Op2Nam(int op)
|
||||
{
|
||||
ShowFilter(afilters);
|
||||
return 0;
|
||||
if (op >= sizeof opname / sizeof opname[0])
|
||||
return "unknown";
|
||||
return opname[op];
|
||||
|
||||
}
|
||||
|
||||
static int
|
||||
filter_Nam2Op(const char *cp)
|
||||
{
|
||||
int op;
|
||||
|
||||
for (op = sizeof opname / sizeof opname[0] - 1; op; op--)
|
||||
if (!strcasecmp(cp, opname[op]))
|
||||
break;
|
||||
|
||||
return op;
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: filter.h,v 1.10 1997/10/26 01:02:35 brian Exp $
|
||||
* $Id: filter.h,v 1.11.2.7 1998/05/01 19:24:30 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -60,28 +60,33 @@ struct filterent {
|
||||
u_short srcport;
|
||||
short dstop;
|
||||
u_short dstport;
|
||||
int estab;
|
||||
unsigned estab : 1;
|
||||
unsigned syn : 1;
|
||||
unsigned finrst : 1;
|
||||
} opt;
|
||||
};
|
||||
|
||||
#define MAXFILTERS 20
|
||||
#define MAXFILTERS 20 /* in each filter set */
|
||||
|
||||
struct filter {
|
||||
struct filterent rule[MAXFILTERS]; /* incoming packet filter */
|
||||
const char *name;
|
||||
unsigned fragok : 1;
|
||||
unsigned logok : 1;
|
||||
};
|
||||
|
||||
#define FL_IN 0
|
||||
#define FL_OUT 1
|
||||
#define FL_DIAL 2
|
||||
#define FL_KEEP 3
|
||||
|
||||
extern struct filterent ifilters[MAXFILTERS]; /* incoming packet filter */
|
||||
extern struct filterent ofilters[MAXFILTERS]; /* outgoing packet filter */
|
||||
extern struct filterent dfilters[MAXFILTERS]; /* dial-out packet filter */
|
||||
extern struct filterent afilters[MAXFILTERS]; /* keep-alive packet filter */
|
||||
struct ipcp;
|
||||
struct cmdargs;
|
||||
|
||||
extern int ParseAddr(int, char const *const *, struct in_addr *, struct in_addr *, int *);
|
||||
extern int ShowIfilter(struct cmdargs const *);
|
||||
extern int ShowOfilter(struct cmdargs const *);
|
||||
extern int ShowDfilter(struct cmdargs const *);
|
||||
extern int ShowAfilter(struct cmdargs const *);
|
||||
extern int SetIfilter(struct cmdargs const *);
|
||||
extern int SetOfilter(struct cmdargs const *);
|
||||
extern int SetDfilter(struct cmdargs const *);
|
||||
extern int SetAfilter(struct cmdargs const *);
|
||||
extern int ParseAddr(struct ipcp *, int, char const *const *, struct in_addr *,
|
||||
struct in_addr *, int *);
|
||||
extern int filter_Show(struct cmdargs const *);
|
||||
extern int filter_Set(struct cmdargs const *);
|
||||
extern const char * filter_Action2Nam(int);
|
||||
extern const char *filter_Proto2Nam(int);
|
||||
extern const char *filter_Op2Nam(int);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: fsm.h,v 1.15 1998/01/20 22:47:37 brian Exp $
|
||||
* $Id: fsm.h,v 1.16.2.16 1998/05/01 19:24:35 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -45,15 +45,50 @@
|
||||
|
||||
#define OPEN_PASSIVE -1
|
||||
|
||||
struct fsm;
|
||||
|
||||
struct fsm_decode {
|
||||
u_char ack[100], *ackend;
|
||||
u_char nak[100], *nakend;
|
||||
u_char rej[100], *rejend;
|
||||
};
|
||||
|
||||
struct fsm_callbacks {
|
||||
int (*LayerUp) (struct fsm *); /* Layer is now up (tlu) */
|
||||
void (*LayerDown) (struct fsm *); /* About to come down (tld) */
|
||||
void (*LayerStart) (struct fsm *); /* Layer about to start up (tls) */
|
||||
void (*LayerFinish) (struct fsm *); /* Layer now down (tlf) */
|
||||
void (*InitRestartCounter) (struct fsm *); /* Set fsm timer load */
|
||||
void (*SendConfigReq) (struct fsm *); /* Send REQ please */
|
||||
void (*SentTerminateReq) (struct fsm *); /* Term REQ just sent */
|
||||
void (*SendTerminateAck) (struct fsm *, u_char); /* Send Term ACK please */
|
||||
void (*DecodeConfig) (struct fsm *, u_char *, int, int, struct fsm_decode *);
|
||||
/* Deal with incoming data */
|
||||
void (*RecvResetReq) (struct fsm *fp); /* Reset output */
|
||||
void (*RecvResetAck) (struct fsm *fp, u_char); /* Reset input */
|
||||
};
|
||||
|
||||
struct fsm_parent {
|
||||
void (*LayerStart) (void *, struct fsm *); /* tls */
|
||||
void (*LayerUp) (void *, struct fsm *); /* tlu */
|
||||
void (*LayerDown) (void *, struct fsm *); /* tld */
|
||||
void (*LayerFinish) (void *, struct fsm *); /* tlf */
|
||||
void *object;
|
||||
};
|
||||
|
||||
struct link;
|
||||
struct bundle;
|
||||
|
||||
struct fsm {
|
||||
const char *name; /* Name of protocol */
|
||||
u_short proto; /* Protocol number */
|
||||
u_short min_code;
|
||||
u_short max_code;
|
||||
int open_mode;
|
||||
int open_mode; /* Delay before config REQ (-1 forever) */
|
||||
int state; /* State of the machine */
|
||||
u_char reqid; /* Next request id */
|
||||
int restart; /* Restart counter value */
|
||||
int maxconfig;
|
||||
int maxconfig; /* Max config REQ before a close() */
|
||||
|
||||
struct pppTimer FsmTimer; /* Restart Timer */
|
||||
struct pppTimer OpenTimer; /* Delay before opening */
|
||||
@ -70,15 +105,14 @@ struct fsm {
|
||||
struct pppTimer StoppedTimer;
|
||||
int LogLevel;
|
||||
|
||||
void (*LayerUp) (struct fsm *);
|
||||
void (*LayerDown) (struct fsm *);
|
||||
void (*LayerStart) (struct fsm *);
|
||||
void (*LayerFinish) (struct fsm *);
|
||||
void (*InitRestartCounter) (struct fsm *);
|
||||
void (*SendConfigReq) (struct fsm *);
|
||||
void (*SendTerminateReq) (struct fsm *);
|
||||
void (*SendTerminateAck) (struct fsm *);
|
||||
void (*DecodeConfig) (u_char *, int, int);
|
||||
/* The link layer active with this FSM (may be our bundle below) */
|
||||
struct link *link;
|
||||
|
||||
/* Our high-level link */
|
||||
struct bundle *bundle;
|
||||
|
||||
const struct fsm_parent *parent;
|
||||
const struct fsm_callbacks *fn;
|
||||
};
|
||||
|
||||
struct fsmheader {
|
||||
@ -103,30 +137,21 @@ struct fsmheader {
|
||||
#define CODE_RESETREQ 14 /* Used in CCP */
|
||||
#define CODE_RESETACK 15 /* Used in CCP */
|
||||
|
||||
struct fsmcodedesc {
|
||||
void (*action) (struct fsm *, struct fsmheader *, struct mbuf *);
|
||||
const char *name;
|
||||
};
|
||||
|
||||
/* Minimum config req size. This struct is *only* used for it's size */
|
||||
struct fsmconfig {
|
||||
u_char type;
|
||||
u_char length;
|
||||
};
|
||||
|
||||
extern u_char AckBuff[200];
|
||||
extern u_char NakBuff[200];
|
||||
extern u_char RejBuff[100];
|
||||
extern u_char ReqBuff[200];
|
||||
extern u_char *ackp;
|
||||
extern u_char *nakp;
|
||||
extern u_char *rejp;
|
||||
|
||||
extern char const *StateNames[];
|
||||
|
||||
extern void FsmInit(struct fsm *);
|
||||
extern void FsmOutput(struct fsm *, u_int, u_int, u_char *, int);
|
||||
extern void FsmOpen(struct fsm *);
|
||||
extern void FsmUp(struct fsm *);
|
||||
extern void FsmDown(struct fsm *);
|
||||
extern void FsmInput(struct fsm *, struct mbuf *);
|
||||
extern void FsmClose(struct fsm *);
|
||||
extern void fsm_Init(struct fsm *, const char *, u_short, int, int, int, int,
|
||||
struct bundle *, struct link *, const struct fsm_parent *,
|
||||
struct fsm_callbacks *, const char *[3]);
|
||||
extern void fsm_Output(struct fsm *, u_int, u_int, u_char *, int);
|
||||
extern void fsm_Open(struct fsm *);
|
||||
extern void fsm_Up(struct fsm *);
|
||||
extern void fsm_Down(struct fsm *);
|
||||
extern void fsm_Input(struct fsm *, struct mbuf *);
|
||||
extern void fsm_Close(struct fsm *);
|
||||
extern void fsm_NullRecvResetReq(struct fsm *fp);
|
||||
extern void fsm_NullRecvResetAck(struct fsm *fp, u_char);
|
||||
extern const char *State2Nam(u_int);
|
||||
|
@ -17,12 +17,15 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: hdlc.c,v 1.29 1998/03/12 02:23:38 brian Exp $
|
||||
* $Id: hdlc.c,v 1.28.2.37 1998/05/21 01:26:07 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
@ -34,50 +37,30 @@
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcpproto.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "ip.h"
|
||||
#include "vjcomp.h"
|
||||
#include "auth.h"
|
||||
#include "pap.h"
|
||||
#include "chap.h"
|
||||
#include "lcp.h"
|
||||
#include "async.h"
|
||||
#include "lqr.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "modem.h"
|
||||
#include "ccp.h"
|
||||
|
||||
static struct hdlcstat {
|
||||
int badfcs;
|
||||
int badaddr;
|
||||
int badcommand;
|
||||
int unknownproto;
|
||||
} HdlcStat;
|
||||
|
||||
static u_int32_t ifOutPackets;
|
||||
static u_int32_t ifOutOctets;
|
||||
static u_int32_t ifOutLQRs;
|
||||
|
||||
static struct protostat {
|
||||
u_short number;
|
||||
const char *name;
|
||||
u_long in_count;
|
||||
u_long out_count;
|
||||
} ProtocolStat[] = {
|
||||
{ PROTO_IP, "IP" },
|
||||
{ PROTO_VJUNCOMP, "VJ_UNCOMP" },
|
||||
{ PROTO_VJCOMP, "VJ_COMP" },
|
||||
{ PROTO_COMPD, "COMPD" },
|
||||
{ PROTO_LCP, "LCP" },
|
||||
{ PROTO_IPCP, "IPCP" },
|
||||
{ PROTO_CCP, "CCP" },
|
||||
{ PROTO_PAP, "PAP" },
|
||||
{ PROTO_LQR, "LQR" },
|
||||
{ PROTO_CHAP, "CHAP" },
|
||||
{ 0, "Others" }
|
||||
};
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "prompt.h"
|
||||
#include "chat.h"
|
||||
#include "mp.h"
|
||||
#include "datalink.h"
|
||||
#include "filter.h"
|
||||
#include "bundle.h"
|
||||
|
||||
static u_short const fcstab[256] = {
|
||||
/* 00 */ 0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
|
||||
@ -114,14 +97,11 @@ static u_short const fcstab[256] = {
|
||||
/* f8 */ 0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
|
||||
};
|
||||
|
||||
u_char EscMap[33];
|
||||
|
||||
void
|
||||
HdlcInit()
|
||||
hdlc_Init(struct hdlc *hdlc, struct lcp *lcp)
|
||||
{
|
||||
ifOutOctets = 0;
|
||||
ifOutPackets = 0;
|
||||
ifOutLQRs = 0;
|
||||
memset(hdlc, '\0', sizeof(struct hdlc));
|
||||
hdlc->lqm.owner = lcp;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -129,7 +109,7 @@ HdlcInit()
|
||||
* 2.27 for further details.
|
||||
*/
|
||||
inline u_short
|
||||
HdlcFcs(u_short fcs, u_char * cp, int len)
|
||||
hdlc_Fcs(u_short fcs, u_char * cp, int len)
|
||||
{
|
||||
while (len--)
|
||||
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
|
||||
@ -142,7 +122,7 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m)
|
||||
int len;
|
||||
u_char *pos, *end;
|
||||
|
||||
len = plength(m);
|
||||
len = mbuf_Length(m);
|
||||
pos = MBUF_CTOP(m);
|
||||
end = pos + m->cnt;
|
||||
while (len--) {
|
||||
@ -157,28 +137,22 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m)
|
||||
}
|
||||
|
||||
void
|
||||
HdlcOutput(int pri, u_short proto, struct mbuf * bp)
|
||||
hdlc_Output(struct link *l, int pri, u_short proto, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct mbuf *mhp, *mfcs;
|
||||
struct protostat *statp;
|
||||
struct lqrdata *lqr;
|
||||
u_char *cp;
|
||||
u_short fcs;
|
||||
|
||||
if ((proto & 0xfff1) == 0x21) /* Network Layer protocol */
|
||||
if (CcpFsm.state == ST_OPENED)
|
||||
if (CcpOutput(pri, proto, bp))
|
||||
return;
|
||||
|
||||
if (DEV_IS_SYNC)
|
||||
if (!p || physical_IsSync(p))
|
||||
mfcs = NULL;
|
||||
else
|
||||
mfcs = mballoc(2, MB_HDLCOUT);
|
||||
mfcs = mbuf_Alloc(2, MB_HDLCOUT);
|
||||
|
||||
mhp = mballoc(4, MB_HDLCOUT);
|
||||
mhp = mbuf_Alloc(4, MB_HDLCOUT);
|
||||
mhp->cnt = 0;
|
||||
cp = MBUF_CTOP(mhp);
|
||||
if (proto == PROTO_LCP || LcpInfo.his_acfcomp == 0) {
|
||||
if (p && (proto == PROTO_LCP || l->lcp.his_acfcomp == 0)) {
|
||||
*cp++ = HDLC_ADDR;
|
||||
*cp++ = HDLC_UI;
|
||||
mhp->cnt += 2;
|
||||
@ -187,7 +161,7 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp)
|
||||
/*
|
||||
* If possible, compress protocol field.
|
||||
*/
|
||||
if (LcpInfo.his_protocomp && (proto & 0xff00) == 0) {
|
||||
if (l->lcp.his_protocomp && (proto & 0xff00) == 0) {
|
||||
*cp++ = proto;
|
||||
mhp->cnt++;
|
||||
} else {
|
||||
@ -195,41 +169,60 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp)
|
||||
*cp = proto & 0377;
|
||||
mhp->cnt += 2;
|
||||
}
|
||||
|
||||
mhp->next = bp;
|
||||
|
||||
if (!p) {
|
||||
/*
|
||||
* This is where we multiplex the data over our available physical
|
||||
* links. We don't frame our logical link data. Instead we wait
|
||||
* for the logical link implementation to chop our data up and pile
|
||||
* it into the physical links by re-calling this function with the
|
||||
* encapsulated fragments.
|
||||
*/
|
||||
link_Output(l, pri, mhp);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Tack mfcs onto the end, then set bp back to the start of the data */
|
||||
while (bp->next != NULL)
|
||||
bp = bp->next;
|
||||
bp->next = mfcs;
|
||||
bp = mhp->next;
|
||||
|
||||
lqr = &MyLqrData;
|
||||
lqr->PeerOutPackets = ifOutPackets++;
|
||||
ifOutOctets += plength(mhp) + 1;
|
||||
lqr->PeerOutOctets = ifOutOctets;
|
||||
p->hdlc.lqm.OutOctets += mbuf_Length(mhp) + 1;
|
||||
p->hdlc.lqm.OutPackets++;
|
||||
|
||||
if (proto == PROTO_LQR) {
|
||||
lqr->MagicNumber = LcpInfo.want_magic;
|
||||
lqr->LastOutLQRs = HisLqrData.PeerOutLQRs;
|
||||
lqr->LastOutPackets = HisLqrData.PeerOutPackets;
|
||||
lqr->LastOutOctets = HisLqrData.PeerOutOctets;
|
||||
lqr->PeerInLQRs = HisLqrSave.SaveInLQRs;
|
||||
lqr->PeerInPackets = HisLqrSave.SaveInPackets;
|
||||
lqr->PeerInDiscards = HisLqrSave.SaveInDiscards;
|
||||
lqr->PeerInErrors = HisLqrSave.SaveInErrors;
|
||||
lqr->PeerInOctets = HisLqrSave.SaveInOctets;
|
||||
if (HisLqrData.LastOutLQRs == ifOutLQRs) {
|
||||
/* Overwrite the entire packet */
|
||||
struct lqrdata lqr;
|
||||
|
||||
lqr.MagicNumber = p->link.lcp.want_magic;
|
||||
lqr.LastOutLQRs = p->hdlc.lqm.lqr.peer.PeerOutLQRs;
|
||||
lqr.LastOutPackets = p->hdlc.lqm.lqr.peer.PeerOutPackets;
|
||||
lqr.LastOutOctets = p->hdlc.lqm.lqr.peer.PeerOutOctets;
|
||||
lqr.PeerInLQRs = p->hdlc.lqm.lqr.SaveInLQRs;
|
||||
lqr.PeerInPackets = p->hdlc.lqm.SaveInPackets;
|
||||
lqr.PeerInDiscards = p->hdlc.lqm.SaveInDiscards;
|
||||
lqr.PeerInErrors = p->hdlc.lqm.SaveInErrors;
|
||||
lqr.PeerInOctets = p->hdlc.lqm.SaveInOctets;
|
||||
lqr.PeerOutPackets = p->hdlc.lqm.OutPackets;
|
||||
lqr.PeerOutOctets = p->hdlc.lqm.OutOctets;
|
||||
if (p->hdlc.lqm.lqr.peer.LastOutLQRs == p->hdlc.lqm.lqr.OutLQRs) {
|
||||
/*
|
||||
* only increment if it's the first time or we've got a reply
|
||||
* from the last one
|
||||
*/
|
||||
lqr->PeerOutLQRs = ++ifOutLQRs;
|
||||
LqrDump("LqrOutput", lqr);
|
||||
lqr.PeerOutLQRs = ++p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output", &lqr);
|
||||
} else {
|
||||
lqr->PeerOutLQRs = ifOutLQRs;
|
||||
LqrDump("LqrOutput (again)", lqr);
|
||||
lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output (again)", &lqr);
|
||||
}
|
||||
LqrChangeOrder(lqr, (struct lqrdata *) (MBUF_CTOP(bp)));
|
||||
lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
|
||||
}
|
||||
if (!DEV_IS_SYNC) {
|
||||
|
||||
if (mfcs) {
|
||||
mfcs->cnt = 0;
|
||||
fcs = HdlcFcsBuf(INITFCS, mhp);
|
||||
fcs = ~fcs;
|
||||
@ -238,18 +231,16 @@ HdlcOutput(int pri, u_short proto, struct mbuf * bp)
|
||||
*cp++ = fcs >> 8;
|
||||
mfcs->cnt = 2;
|
||||
}
|
||||
LogDumpBp(LogHDLC, "HdlcOutput", mhp);
|
||||
for (statp = ProtocolStat; statp->number; statp++)
|
||||
if (statp->number == proto)
|
||||
break;
|
||||
statp->out_count++;
|
||||
|
||||
LogPrintf(LogDEBUG, "HdlcOutput: proto = 0x%04x\n", proto);
|
||||
log_DumpBp(LogHDLC, "hdlc_Output", mhp);
|
||||
|
||||
if (DEV_IS_SYNC)
|
||||
ModemOutput(pri, mhp);
|
||||
link_ProtocolRecord(l, proto, PROTO_OUT);
|
||||
log_Printf(LogDEBUG, "hdlc_Output: proto = 0x%04x\n", proto);
|
||||
|
||||
if (physical_IsSync(p))
|
||||
link_Output(l, pri, mhp); /* Send it raw */
|
||||
else
|
||||
AsyncOutput(pri, mhp, proto);
|
||||
async_Output(pri, mhp, proto, p);
|
||||
}
|
||||
|
||||
/* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
|
||||
@ -365,8 +356,8 @@ static struct {
|
||||
|
||||
#define NPROTOCOLS (sizeof protocols/sizeof protocols[0])
|
||||
|
||||
static const char *
|
||||
Protocol2Nam(u_short proto)
|
||||
const char *
|
||||
hdlc_Protocol2Nam(u_short proto)
|
||||
{
|
||||
int f;
|
||||
|
||||
@ -378,209 +369,260 @@ Protocol2Nam(u_short proto)
|
||||
return "unrecognised protocol";
|
||||
}
|
||||
|
||||
static void
|
||||
DecodePacket(u_short proto, struct mbuf * bp)
|
||||
void
|
||||
hdlc_DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp,
|
||||
struct link *l)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
u_char *cp;
|
||||
|
||||
LogPrintf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto);
|
||||
log_Printf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto);
|
||||
|
||||
/*
|
||||
* If proto isn't PROTO_COMPD, we still want to pass it to the
|
||||
* decompression routines so that the dictionary's updated
|
||||
*/
|
||||
if (CcpFsm.state == ST_OPENED) {
|
||||
if (proto == PROTO_COMPD) {
|
||||
if ((bp = CompdInput(&proto, bp)) == NULL)
|
||||
return;
|
||||
} else if ((proto & 0xfff1) == 0x21) /* Network Layer protocol */
|
||||
CcpDictSetup(proto, bp);
|
||||
}
|
||||
/* decompress everything. CCP needs uncompressed data too */
|
||||
if ((bp = ccp_Decompress(&l->ccp, &proto, bp)) == NULL)
|
||||
return;
|
||||
|
||||
switch (proto) {
|
||||
case PROTO_LCP:
|
||||
LcpInput(bp);
|
||||
lcp_Input(&l->lcp, bp);
|
||||
break;
|
||||
case PROTO_PAP:
|
||||
PapInput(bp);
|
||||
if (p)
|
||||
pap_Input(bundle, bp, p);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: PAP: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_LQR:
|
||||
HisLqrSave.SaveInLQRs++;
|
||||
LqrInput(bp);
|
||||
if (p) {
|
||||
p->hdlc.lqm.lqr.SaveInLQRs++;
|
||||
lqr_Input(p, bp);
|
||||
} else {
|
||||
log_Printf(LogERROR, "DecodePacket: LQR: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_CHAP:
|
||||
ChapInput(bp);
|
||||
if (p)
|
||||
chap_Input(bundle, bp, p);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: CHAP: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_VJUNCOMP:
|
||||
case PROTO_VJCOMP:
|
||||
bp = VjCompInput(bp, proto);
|
||||
if (bp == NULL) {
|
||||
bp = vj_Input(&bundle->ncp.ipcp, bp, proto);
|
||||
if (bp == NULL)
|
||||
break;
|
||||
}
|
||||
/* fall down */
|
||||
case PROTO_IP:
|
||||
IpInput(bp);
|
||||
ip_Input(bundle, bp);
|
||||
break;
|
||||
case PROTO_IPCP:
|
||||
IpcpInput(bp);
|
||||
ipcp_Input(&bundle->ncp.ipcp, bundle, bp);
|
||||
break;
|
||||
case PROTO_CCP:
|
||||
CcpInput(bp);
|
||||
ccp_Input(&l->ccp, bundle, bp);
|
||||
break;
|
||||
case PROTO_MP:
|
||||
if (bundle->ncp.mp.active) {
|
||||
if (p)
|
||||
mp_Input(&bundle->ncp.mp, bp, p);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: MP inside MP ?!\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
LogPrintf(LogPHASE, "Unknown protocol 0x%04x (%s)\n",
|
||||
proto, Protocol2Nam(proto));
|
||||
log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n",
|
||||
proto == PROTO_MP ? "Unexpected" : "Unknown",
|
||||
proto, hdlc_Protocol2Nam(proto));
|
||||
bp->offset -= 2;
|
||||
bp->cnt += 2;
|
||||
cp = MBUF_CTOP(bp);
|
||||
LcpSendProtoRej(cp, bp->cnt);
|
||||
HisLqrSave.SaveInDiscards++;
|
||||
HdlcStat.unknownproto++;
|
||||
pfree(bp);
|
||||
lcp_SendProtoRej(&l->lcp, cp, bp->cnt);
|
||||
if (p) {
|
||||
p->hdlc.lqm.SaveInDiscards++;
|
||||
p->hdlc.stats.unknownproto++;
|
||||
}
|
||||
mbuf_Free(bp);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
ReportProtStatus(struct cmdargs const *arg)
|
||||
static int
|
||||
hdlc_GetProto(const u_char *cp, u_short *proto)
|
||||
{
|
||||
struct protostat *statp;
|
||||
int cnt;
|
||||
|
||||
statp = ProtocolStat;
|
||||
statp--;
|
||||
cnt = 0;
|
||||
fprintf(VarTerm, " Protocol in out Protocol in out\n");
|
||||
do {
|
||||
statp++;
|
||||
fprintf(VarTerm, " %-9s: %8lu, %8lu",
|
||||
statp->name, statp->in_count, statp->out_count);
|
||||
if (++cnt == 2) {
|
||||
fprintf(VarTerm, "\n");
|
||||
cnt = 0;
|
||||
}
|
||||
} while (statp->number);
|
||||
if (cnt)
|
||||
fprintf(VarTerm, "\n");
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ReportHdlcStatus(struct cmdargs const *arg)
|
||||
{
|
||||
struct hdlcstat *hp = &HdlcStat;
|
||||
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "HDLC level errors\n\n");
|
||||
fprintf(VarTerm, "FCS: %u ADDR: %u COMMAND: %u PROTO: %u\n",
|
||||
hp->badfcs, hp->badaddr, hp->badcommand, hp->unknownproto);
|
||||
*proto = *cp;
|
||||
if (!(*proto & 1)) {
|
||||
*proto = (*proto << 8) | cp[1];
|
||||
return 2;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct hdlcstat laststat;
|
||||
|
||||
void
|
||||
HdlcErrorCheck()
|
||||
{
|
||||
struct hdlcstat *hp = &HdlcStat;
|
||||
struct hdlcstat *op = &laststat;
|
||||
|
||||
if (memcmp(hp, op, sizeof laststat)) {
|
||||
LogPrintf(LogPHASE, "HDLC errors -> FCS: %u ADDR: %u COMD: %u PROTO: %u\n",
|
||||
hp->badfcs - op->badfcs, hp->badaddr - op->badaddr,
|
||||
hp->badcommand - op->badcommand, hp->unknownproto - op->unknownproto);
|
||||
}
|
||||
laststat = HdlcStat;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
HdlcInput(struct mbuf * bp)
|
||||
hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical)
|
||||
{
|
||||
u_short fcs, proto;
|
||||
u_char *cp, addr, ctrl;
|
||||
struct protostat *statp;
|
||||
int n;
|
||||
|
||||
LogDumpBp(LogHDLC, "HdlcInput:", bp);
|
||||
if (DEV_IS_SYNC)
|
||||
log_DumpBp(LogHDLC, "hdlc_Input:", bp);
|
||||
if (physical_IsSync(physical))
|
||||
fcs = GOODFCS;
|
||||
else
|
||||
fcs = HdlcFcs(INITFCS, MBUF_CTOP(bp), bp->cnt);
|
||||
HisLqrSave.SaveInOctets += bp->cnt + 1;
|
||||
fcs = hdlc_Fcs(INITFCS, MBUF_CTOP(bp), bp->cnt);
|
||||
physical->hdlc.lqm.SaveInOctets += bp->cnt + 1;
|
||||
|
||||
LogPrintf(LogDEBUG, "HdlcInput: fcs = %04x (%s)\n",
|
||||
fcs, (fcs == GOODFCS) ? "good" : "bad");
|
||||
log_Printf(LogDEBUG, "%s: hdlc_Input: fcs = %04x (%s)\n",
|
||||
physical->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
|
||||
if (fcs != GOODFCS) {
|
||||
HisLqrSave.SaveInErrors++;
|
||||
LogPrintf(LogDEBUG, "HdlcInput: Bad FCS\n");
|
||||
HdlcStat.badfcs++;
|
||||
pfree(bp);
|
||||
physical->hdlc.lqm.SaveInErrors++;
|
||||
physical->hdlc.stats.badfcs++;
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
if (!DEV_IS_SYNC)
|
||||
if (!physical_IsSync(physical))
|
||||
bp->cnt -= 2; /* discard FCS part */
|
||||
|
||||
if (bp->cnt < 2) { /* XXX: raise this bar ? */
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
cp = MBUF_CTOP(bp);
|
||||
|
||||
if (!LcpInfo.want_acfcomp) {
|
||||
|
||||
/*
|
||||
* We expect that packet is not compressed.
|
||||
*/
|
||||
if (!physical->link.lcp.want_acfcomp) {
|
||||
/* We expect the packet not to be compressed */
|
||||
addr = *cp++;
|
||||
if (addr != HDLC_ADDR) {
|
||||
HisLqrSave.SaveInErrors++;
|
||||
HdlcStat.badaddr++;
|
||||
LogPrintf(LogDEBUG, "HdlcInput: addr %02x\n", *cp);
|
||||
pfree(bp);
|
||||
physical->hdlc.lqm.SaveInErrors++;
|
||||
physical->hdlc.stats.badaddr++;
|
||||
log_Printf(LogDEBUG, "hdlc_Input: addr %02x\n", *cp);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
ctrl = *cp++;
|
||||
if (ctrl != HDLC_UI) {
|
||||
HisLqrSave.SaveInErrors++;
|
||||
HdlcStat.badcommand++;
|
||||
LogPrintf(LogDEBUG, "HdlcInput: %02x\n", *cp);
|
||||
pfree(bp);
|
||||
physical->hdlc.lqm.SaveInErrors++;
|
||||
physical->hdlc.stats.badcommand++;
|
||||
log_Printf(LogDEBUG, "hdlc_Input: %02x\n", *cp);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
bp->offset += 2;
|
||||
bp->cnt -= 2;
|
||||
} else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
|
||||
|
||||
/*
|
||||
* We can receive compressed packet, but peer still send uncompressed
|
||||
* packet to me.
|
||||
* We can receive compressed packets, but the peer still sends
|
||||
* uncompressed packets !
|
||||
*/
|
||||
cp += 2;
|
||||
bp->offset += 2;
|
||||
bp->cnt -= 2;
|
||||
}
|
||||
if (LcpInfo.want_protocomp) {
|
||||
proto = 0;
|
||||
cp--;
|
||||
do {
|
||||
cp++;
|
||||
bp->offset++;
|
||||
bp->cnt--;
|
||||
proto = proto << 8;
|
||||
proto += *cp;
|
||||
} while (!(proto & 1));
|
||||
} else {
|
||||
proto = *cp++ << 8;
|
||||
proto |= *cp++;
|
||||
bp->offset += 2;
|
||||
bp->cnt -= 2;
|
||||
|
||||
n = hdlc_GetProto(cp, &proto);
|
||||
bp->offset += n;
|
||||
bp->cnt -= n;
|
||||
if (!physical->link.lcp.want_protocomp && n == 1)
|
||||
log_Printf(LogHDLC, "%s: Warning: received a proto-compressed packet !\n",
|
||||
physical->link.name);
|
||||
|
||||
link_ProtocolRecord(&physical->link, proto, PROTO_IN);
|
||||
physical->hdlc.lqm.SaveInPackets++;
|
||||
|
||||
hdlc_DecodePacket(bundle, proto, bp, &physical->link);
|
||||
}
|
||||
|
||||
/*
|
||||
* Detect a HDLC frame
|
||||
*/
|
||||
|
||||
static const char *FrameHeaders[] = {
|
||||
"\176\377\003\300\041",
|
||||
"\176\377\175\043\300\041",
|
||||
"\176\177\175\043\100\041",
|
||||
"\176\175\337\175\043\300\041",
|
||||
"\176\175\137\175\043\100\041",
|
||||
NULL,
|
||||
};
|
||||
|
||||
u_char *
|
||||
hdlc_Detect(struct physical *physical, u_char *cp, int n)
|
||||
{
|
||||
const char *fp, **hp;
|
||||
char *ptr;
|
||||
|
||||
cp[n] = '\0'; /* be sure to null terminate */
|
||||
ptr = NULL;
|
||||
for (hp = FrameHeaders; *hp; hp++) {
|
||||
fp = *hp;
|
||||
if (physical_IsSync(physical))
|
||||
fp++;
|
||||
ptr = strstr((char *)cp, fp); /* XXX: cp may have embedded NULs */
|
||||
if (ptr)
|
||||
break;
|
||||
}
|
||||
return (u_char *)ptr;
|
||||
}
|
||||
|
||||
int
|
||||
hdlc_ReportStatus(struct cmdargs const *arg)
|
||||
{
|
||||
struct hdlc *hdlc = &arg->cx->physical->hdlc;
|
||||
|
||||
prompt_Printf(arg->prompt, "%s HDLC level errors:\n", arg->cx->name);
|
||||
prompt_Printf(arg->prompt, " Bad Frame Check Sequence fields: %u\n",
|
||||
hdlc->stats.badfcs);
|
||||
prompt_Printf(arg->prompt, " Bad address (!= 0x%02x) fields: %u\n",
|
||||
HDLC_ADDR, hdlc->stats.badaddr);
|
||||
prompt_Printf(arg->prompt, " Bad command (!= 0x%02x) fields: %u\n",
|
||||
HDLC_UI, hdlc->stats.badcommand);
|
||||
prompt_Printf(arg->prompt, " Unrecognised protocol fields: %u\n",
|
||||
hdlc->stats.unknownproto);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
hdlc_ReportTime(void *v)
|
||||
{
|
||||
/* Moan about HDLC errors */
|
||||
struct hdlc *hdlc = (struct hdlc *)v;
|
||||
|
||||
timer_Stop(&hdlc->ReportTimer);
|
||||
|
||||
if (memcmp(&hdlc->laststats, &hdlc->stats, sizeof hdlc->stats)) {
|
||||
log_Printf(LogPHASE,
|
||||
"%s: HDLC errors -> FCS: %u, ADDR: %u, COMD: %u, PROTO: %u\n",
|
||||
hdlc->lqm.owner->fsm.link->name,
|
||||
hdlc->stats.badfcs - hdlc->laststats.badfcs,
|
||||
hdlc->stats.badaddr - hdlc->laststats.badaddr,
|
||||
hdlc->stats.badcommand - hdlc->laststats.badcommand,
|
||||
hdlc->stats.unknownproto - hdlc->laststats.unknownproto);
|
||||
hdlc->laststats = hdlc->stats;
|
||||
}
|
||||
|
||||
for (statp = ProtocolStat; statp->number; statp++)
|
||||
if (statp->number == proto)
|
||||
break;
|
||||
statp->in_count++;
|
||||
HisLqrSave.SaveInPackets++;
|
||||
|
||||
DecodePacket(proto, bp);
|
||||
timer_Start(&hdlc->ReportTimer);
|
||||
}
|
||||
|
||||
void
|
||||
hdlc_StartTimer(struct hdlc *hdlc)
|
||||
{
|
||||
timer_Stop(&hdlc->ReportTimer);
|
||||
hdlc->ReportTimer.load = 60 * SECTICKS;
|
||||
hdlc->ReportTimer.arg = hdlc;
|
||||
hdlc->ReportTimer.func = hdlc_ReportTime;
|
||||
hdlc->ReportTimer.name = "hdlc";
|
||||
timer_Start(&hdlc->ReportTimer);
|
||||
}
|
||||
|
||||
void
|
||||
hdlc_StopTimer(struct hdlc *hdlc)
|
||||
{
|
||||
timer_Stop(&hdlc->ReportTimer);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: hdlc.h,v 1.13 1997/12/03 10:23:48 brian Exp $
|
||||
* $Id: hdlc.h,v 1.14.2.12 1998/05/01 19:24:39 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -54,13 +54,62 @@
|
||||
#define PRI_NORMAL 0 /* Normal priority */
|
||||
#define PRI_FAST 1 /* Fast (interractive) */
|
||||
#define PRI_LINK 1 /* Urgent (LQR packets) */
|
||||
#define PRI_MAX 1
|
||||
|
||||
extern u_char EscMap[33];
|
||||
struct physical;
|
||||
struct link;
|
||||
struct lcp;
|
||||
struct bundle;
|
||||
struct mbuf;
|
||||
struct cmdargs;
|
||||
|
||||
extern void HdlcInit(void);
|
||||
extern void HdlcErrorCheck(void);
|
||||
extern void HdlcInput(struct mbuf *);
|
||||
extern void HdlcOutput(int, u_short, struct mbuf *bp);
|
||||
extern u_short HdlcFcs(u_short, u_char *, int);
|
||||
extern int ReportHdlcStatus(struct cmdargs const *);
|
||||
extern int ReportProtStatus(struct cmdargs const *);
|
||||
struct hdlc {
|
||||
struct pppTimer ReportTimer;
|
||||
|
||||
struct {
|
||||
int badfcs;
|
||||
int badaddr;
|
||||
int badcommand;
|
||||
int unknownproto;
|
||||
} laststats, stats;
|
||||
|
||||
struct {
|
||||
struct lcp *owner; /* parent LCP */
|
||||
struct pppTimer timer; /* When to send */
|
||||
int method; /* bit-mask for LQM_* from lqr.h */
|
||||
|
||||
u_int32_t OutPackets; /* Packets sent by me */
|
||||
u_int32_t OutOctets; /* Octets sent by me */
|
||||
u_int32_t SaveInPackets; /* Packets received from peer */
|
||||
u_int32_t SaveInDiscards; /* Discards */
|
||||
u_int32_t SaveInErrors; /* Errors */
|
||||
u_int32_t SaveInOctets; /* Octets received from peer */
|
||||
|
||||
struct {
|
||||
u_int32_t OutLQRs; /* LQRs sent by me */
|
||||
u_int32_t SaveInLQRs; /* LQRs received from peer */
|
||||
struct lqrdata peer; /* Last LQR from peer */
|
||||
int peer_timeout; /* peers max lqr timeout */
|
||||
int resent; /* Resent last packet `resent' times */
|
||||
} lqr;
|
||||
|
||||
struct {
|
||||
u_int32_t seq_sent; /* last echo sent */
|
||||
u_int32_t seq_recv; /* last echo received */
|
||||
} echo;
|
||||
} lqm;
|
||||
};
|
||||
|
||||
|
||||
extern void hdlc_Init(struct hdlc *, struct lcp *);
|
||||
extern void hdlc_StartTimer(struct hdlc *);
|
||||
extern void hdlc_StopTimer(struct hdlc *);
|
||||
extern int hdlc_ReportStatus(struct cmdargs const *);
|
||||
extern const char *hdlc_Protocol2Nam(u_short);
|
||||
extern void hdlc_DecodePacket(struct bundle *, u_short, struct mbuf *,
|
||||
struct link *);
|
||||
|
||||
extern void hdlc_Input(struct bundle *, struct mbuf *, struct physical *);
|
||||
extern void hdlc_Output(struct link *, int, u_short, struct mbuf *bp);
|
||||
extern u_short hdlc_Fcs(u_short, u_char *, int);
|
||||
extern u_char *hdlc_Detect(struct physical *, u_char *, int);
|
||||
|
@ -23,14 +23,16 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: id.c,v 1.6 1998/01/21 02:15:16 brian Exp $
|
||||
* $Id: id.c,v 1.6.4.10 1998/05/01 19:24:41 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <sys/ioctl.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
@ -42,8 +44,6 @@
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "main.h"
|
||||
#include "id.h"
|
||||
@ -62,8 +62,8 @@ static void
|
||||
ID0setuser(void)
|
||||
{
|
||||
if (seteuid(uid) == -1) {
|
||||
LogPrintf(LogERROR, "ID0setuser: Unable to seteuid!\n");
|
||||
Cleanup(EX_NOPERM);
|
||||
log_Printf(LogERROR, "ID0setuser: Unable to seteuid!\n");
|
||||
AbortProgram(EX_NOPERM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -77,8 +77,8 @@ static void
|
||||
ID0set0(void)
|
||||
{
|
||||
if (seteuid(euid) == -1) {
|
||||
LogPrintf(LogERROR, "ID0set0: Unable to seteuid!\n");
|
||||
Cleanup(EX_NOPERM);
|
||||
log_Printf(LogERROR, "ID0set0: Unable to seteuid!\n");
|
||||
AbortProgram(EX_NOPERM);
|
||||
}
|
||||
}
|
||||
|
||||
@ -89,7 +89,7 @@ ID0ioctl(int fd, unsigned long req, void *arg)
|
||||
|
||||
ID0set0();
|
||||
ret = ioctl(fd, req, arg);
|
||||
LogPrintf(LogID0, "%d = ioctl(%d, %d, %p)\n", ret, fd, req, arg);
|
||||
log_Printf(LogID0, "%d = ioctl(%d, %lu, %p)\n", ret, fd, req, arg);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -101,7 +101,7 @@ ID0unlink(const char *name)
|
||||
|
||||
ID0set0();
|
||||
ret = unlink(name);
|
||||
LogPrintf(LogID0, "%d = unlink(\"%s\")\n", ret, name);
|
||||
log_Printf(LogID0, "%d = unlink(\"%s\")\n", ret, name);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -113,7 +113,7 @@ ID0socket(int domain, int type, int protocol)
|
||||
|
||||
ID0set0();
|
||||
ret = socket(domain, type, protocol);
|
||||
LogPrintf(LogID0, "%d = socket(%d, %d, %d)\n", ret, domain, type, protocol);
|
||||
log_Printf(LogID0, "%d = socket(%d, %d, %d)\n", ret, domain, type, protocol);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -125,20 +125,23 @@ ID0fopen(const char *path, const char *mode)
|
||||
|
||||
ID0set0();
|
||||
ret = fopen(path, mode);
|
||||
LogPrintf(LogID0, "%p = fopen(\"%s\", \"%s\")\n", ret, path, mode);
|
||||
log_Printf(LogID0, "%p = fopen(\"%s\", \"%s\")\n", ret, path, mode);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
ID0open(const char *path, int flags)
|
||||
ID0open(const char *path, int flags, ...)
|
||||
{
|
||||
int ret;
|
||||
va_list ap;
|
||||
|
||||
va_start(ap, flags);
|
||||
ID0set0();
|
||||
ret = open(path, flags);
|
||||
LogPrintf(LogID0, "%d = open(\"%s\", %d)\n", ret, path, flags);
|
||||
ret = open(path, flags, va_arg(ap, int));
|
||||
log_Printf(LogID0, "%d = open(\"%s\", %d)\n", ret, path, flags);
|
||||
ID0setuser();
|
||||
va_end(ap);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -149,7 +152,7 @@ ID0write(int fd, const void *data, size_t len)
|
||||
|
||||
ID0set0();
|
||||
ret = write(fd, data, len);
|
||||
LogPrintf(LogID0, "%d = write(%d, data, %d)\n", ret, fd, len);
|
||||
log_Printf(LogID0, "%d = write(%d, data, %d)\n", ret, fd, len);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -161,7 +164,7 @@ ID0uu_lock(const char *basettyname)
|
||||
|
||||
ID0set0();
|
||||
ret = uu_lock(basettyname);
|
||||
LogPrintf(LogID0, "%d = uu_lock(\"%s\")\n", ret, basettyname);
|
||||
log_Printf(LogID0, "%d = uu_lock(\"%s\")\n", ret, basettyname);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -173,7 +176,7 @@ ID0uu_unlock(const char *basettyname)
|
||||
|
||||
ID0set0();
|
||||
ret = uu_unlock(basettyname);
|
||||
LogPrintf(LogID0, "%d = uu_unlock(\"%s\")\n", ret, basettyname);
|
||||
log_Printf(LogID0, "%d = uu_unlock(\"%s\")\n", ret, basettyname);
|
||||
ID0setuser();
|
||||
return ret;
|
||||
}
|
||||
@ -183,13 +186,13 @@ ID0login(struct utmp *ut)
|
||||
{
|
||||
ID0set0();
|
||||
if (logout(ut->ut_line)) {
|
||||
LogPrintf(LogID0, "logout(\"%s\")\n", ut->ut_line);
|
||||
log_Printf(LogID0, "logout(\"%s\")\n", ut->ut_line);
|
||||
logwtmp(ut->ut_line, "", "");
|
||||
LogPrintf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut->ut_line);
|
||||
log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut->ut_line);
|
||||
}
|
||||
login(ut);
|
||||
LogPrintf(LogID0, "login(\"%s\", \"%.*s\")\n",
|
||||
ut->ut_line, sizeof ut->ut_name, ut->ut_name);
|
||||
log_Printf(LogID0, "login(\"%s\", \"%.*s\")\n",
|
||||
ut->ut_line, (int)(sizeof ut->ut_name), ut->ut_name);
|
||||
ID0setuser();
|
||||
}
|
||||
|
||||
@ -203,10 +206,36 @@ ID0logout(const char *device)
|
||||
|
||||
ID0set0();
|
||||
if (logout(ut.ut_line)) {
|
||||
LogPrintf(LogID0, "logout(\"%s\")\n", ut.ut_line);
|
||||
log_Printf(LogID0, "logout(\"%s\")\n", ut.ut_line);
|
||||
logwtmp(ut.ut_line, "", "");
|
||||
LogPrintf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut.ut_line);
|
||||
log_Printf(LogID0, "logwtmp(\"%s\", \"\", \"\")\n", ut.ut_line);
|
||||
} else
|
||||
LogPrintf(LogERROR, "ID0logout: No longer logged in on %s\n", ut.ut_line);
|
||||
log_Printf(LogERROR, "ID0logout: No longer logged in on %s\n", ut.ut_line);
|
||||
ID0setuser();
|
||||
}
|
||||
|
||||
int
|
||||
ID0bind_un(int s, const struct sockaddr_un *name)
|
||||
{
|
||||
int result;
|
||||
|
||||
ID0set0();
|
||||
result = bind(s, (const struct sockaddr *)name, sizeof *name);
|
||||
log_Printf(LogID0, "%d = bind(%d, \"%s\", %d)\n",
|
||||
result, s, name->sun_path, sizeof *name);
|
||||
ID0setuser();
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
ID0connect_un(int s, const struct sockaddr_un *name)
|
||||
{
|
||||
int result;
|
||||
|
||||
ID0set0();
|
||||
result = connect(s, (const struct sockaddr *)name, sizeof *name);
|
||||
log_Printf(LogID0, "%d = connect(%d, \"%s\", %d)\n",
|
||||
result, s, name->sun_path, sizeof *name);
|
||||
ID0setuser();
|
||||
return result;
|
||||
}
|
||||
|
@ -23,10 +23,11 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: id.h,v 1.3 1997/12/27 19:23:13 brian Exp $
|
||||
* $Id: id.h,v 1.3.4.4 1998/04/30 23:53:40 brian Exp $
|
||||
*/
|
||||
|
||||
struct utmp;
|
||||
struct sockaddr_un;
|
||||
|
||||
extern void ID0init(void);
|
||||
extern uid_t ID0realuid(void);
|
||||
@ -34,9 +35,11 @@ extern int ID0ioctl(int, unsigned long, void *);
|
||||
extern int ID0unlink(const char *);
|
||||
extern int ID0socket(int, int, int);
|
||||
extern FILE *ID0fopen(const char *, const char *);
|
||||
extern int ID0open(const char *, int);
|
||||
extern int ID0open(const char *, int, ...);
|
||||
extern int ID0write(int, const void *, size_t);
|
||||
extern int ID0uu_lock(const char *);
|
||||
extern int ID0uu_unlock(const char *);
|
||||
extern void ID0login(struct utmp *);
|
||||
extern void ID0logout(const char *);
|
||||
extern int ID0bind_un(int, const struct sockaddr_un *);
|
||||
extern int ID0connect_un(int, const struct sockaddr_un *);
|
||||
|
@ -17,17 +17,14 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ip.c,v 1.39 1998/03/13 01:36:09 brian Exp $
|
||||
* $Id: ip.c,v 1.38.2.26 1998/05/06 23:50:11 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Return ICMP message for filterd packet
|
||||
* and optionaly record it into log.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if.h>
|
||||
#include <net/if_tun.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
@ -35,6 +32,8 @@
|
||||
#include <netinet/udp.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_tun.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#ifndef NOALIAS
|
||||
#include <alias.h>
|
||||
@ -43,91 +42,31 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "filter.h"
|
||||
#include "os.h"
|
||||
#include "throughput.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "vjcomp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "lcp.h"
|
||||
#include "modem.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "vjcomp.h"
|
||||
#include "tun.h"
|
||||
#include "ip.h"
|
||||
|
||||
static struct pppTimer IdleTimer;
|
||||
|
||||
static void
|
||||
IdleTimeout(void *v)
|
||||
{
|
||||
LogPrintf(LogPHASE, "Idle timer expired.\n");
|
||||
reconnect(RECON_FALSE);
|
||||
LcpClose();
|
||||
}
|
||||
|
||||
/*
|
||||
* Start Idle timer. If timeout is reached, we call LcpClose() to
|
||||
* close LCP and link.
|
||||
*/
|
||||
void
|
||||
StartIdleTimer()
|
||||
{
|
||||
static time_t IdleStarted;
|
||||
|
||||
if (!(mode & (MODE_DEDICATED | MODE_DDIAL))) {
|
||||
StopTimer(&IdleTimer);
|
||||
IdleTimer.func = IdleTimeout;
|
||||
IdleTimer.load = VarIdleTimeout * SECTICKS;
|
||||
IdleTimer.state = TIMER_STOPPED;
|
||||
time(&IdleStarted);
|
||||
IdleTimer.arg = (void *)&IdleStarted;
|
||||
StartTimer(&IdleTimer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
UpdateIdleTimer()
|
||||
{
|
||||
if (OsLinkIsUp())
|
||||
StartIdleTimer();
|
||||
}
|
||||
|
||||
void
|
||||
StopIdleTimer()
|
||||
{
|
||||
StopTimer(&IdleTimer);
|
||||
}
|
||||
|
||||
int
|
||||
RemainingIdleTime()
|
||||
{
|
||||
if (VarIdleTimeout == 0 || IdleTimer.state != TIMER_RUNNING ||
|
||||
IdleTimer.arg == NULL)
|
||||
return -1;
|
||||
return VarIdleTimeout - (time(NULL) - *(time_t *)IdleTimer.arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* If any IP layer traffic is detected, refresh IdleTimer.
|
||||
*/
|
||||
static void
|
||||
RestartIdleTimer(void)
|
||||
{
|
||||
if (!(mode & (MODE_DEDICATED | MODE_DDIAL)) && ipKeepAlive) {
|
||||
time((time_t *)IdleTimer.arg);
|
||||
StartTimer(&IdleTimer);
|
||||
}
|
||||
}
|
||||
|
||||
static const u_short interactive_ports[32] = {
|
||||
544, 513, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
|
||||
0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 543,
|
||||
@ -137,9 +76,6 @@ static const u_short interactive_ports[32] = {
|
||||
|
||||
static const char *TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" };
|
||||
|
||||
static const char *Direction[] = {"INP", "OUT", "OUT", "IN/OUT"};
|
||||
static struct filterent *Filters[] = {ifilters, ofilters, dfilters, afilters};
|
||||
|
||||
static int
|
||||
PortMatch(int op, u_short pport, u_short rport)
|
||||
{
|
||||
@ -159,27 +95,30 @@ PortMatch(int op, u_short pport, u_short rport)
|
||||
* Check a packet against with defined filters
|
||||
*/
|
||||
static int
|
||||
FilterCheck(struct ip * pip, int direction)
|
||||
FilterCheck(struct ip *pip, struct filter *filter)
|
||||
{
|
||||
struct filterent *fp = Filters[direction];
|
||||
int gotinfo, cproto, estab, n;
|
||||
int gotinfo, cproto, estab, syn, finrst, n, len, didname;
|
||||
struct tcphdr *th;
|
||||
struct udphdr *uh;
|
||||
struct icmp *ih;
|
||||
char *ptop;
|
||||
u_short sport, dport;
|
||||
struct filterent *fp = filter->rule;
|
||||
char dbuff[100];
|
||||
|
||||
if (fp->action) {
|
||||
cproto = gotinfo = estab = 0;
|
||||
cproto = gotinfo = estab = syn = finrst = didname = 0;
|
||||
sport = dport = 0;
|
||||
for (n = 0; n < MAXFILTERS; n++) {
|
||||
if (fp->action) {
|
||||
/* permit fragments on in and out filter */
|
||||
if ((direction == FL_IN || direction == FL_OUT) &&
|
||||
(ntohs(pip->ip_off) & IP_OFFMASK) != 0) {
|
||||
if (filter->fragok && (ntohs(pip->ip_off) & IP_OFFMASK) != 0)
|
||||
return (A_PERMIT);
|
||||
}
|
||||
LogPrintf(LogDEBUG, "rule = %d\n", n);
|
||||
|
||||
if (!didname)
|
||||
log_Printf(LogDEBUG, "%s filter:\n", filter->name);
|
||||
didname = 1;
|
||||
|
||||
if ((pip->ip_src.s_addr & fp->smask.s_addr) ==
|
||||
(fp->saddr.s_addr & fp->smask.s_addr) &&
|
||||
(pip->ip_dst.s_addr & fp->dmask.s_addr) ==
|
||||
@ -193,14 +132,19 @@ FilterCheck(struct ip * pip, int direction)
|
||||
cproto = P_ICMP;
|
||||
ih = (struct icmp *) ptop;
|
||||
sport = ih->icmp_type;
|
||||
estab = 1;
|
||||
estab = syn = finrst = -1;
|
||||
if (log_IsKept(LogDEBUG))
|
||||
snprintf(dbuff, sizeof dbuff, "sport = %d", sport);
|
||||
break;
|
||||
case IPPROTO_UDP:
|
||||
cproto = P_UDP;
|
||||
uh = (struct udphdr *) ptop;
|
||||
sport = ntohs(uh->uh_sport);
|
||||
dport = ntohs(uh->uh_dport);
|
||||
estab = 1;
|
||||
estab = syn = finrst = -1;
|
||||
if (log_IsKept(LogDEBUG))
|
||||
snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d",
|
||||
sport, dport);
|
||||
break;
|
||||
case IPPROTO_TCP:
|
||||
cproto = P_TCP;
|
||||
@ -208,39 +152,67 @@ FilterCheck(struct ip * pip, int direction)
|
||||
sport = ntohs(th->th_sport);
|
||||
dport = ntohs(th->th_dport);
|
||||
estab = (th->th_flags & TH_ACK);
|
||||
if (estab == 0)
|
||||
LogPrintf(LogDEBUG, "flag = %02x, sport = %d, dport = %d\n",
|
||||
th->th_flags, sport, dport);
|
||||
syn = (th->th_flags & TH_SYN);
|
||||
finrst = (th->th_flags & (TH_FIN|TH_RST));
|
||||
if (log_IsKept(LogDEBUG) && !estab)
|
||||
snprintf(dbuff, sizeof dbuff,
|
||||
"flags = %02x, sport = %d, dport = %d",
|
||||
th->th_flags, sport, dport);
|
||||
break;
|
||||
default:
|
||||
return (A_DENY);/* We'll block unknown type of packet */
|
||||
return (A_DENY); /* We'll block unknown type of packet */
|
||||
}
|
||||
if (log_IsKept(LogDEBUG)) {
|
||||
if (estab != -1) {
|
||||
len = strlen(dbuff);
|
||||
snprintf(dbuff + len, sizeof dbuff - len,
|
||||
", estab = %d, syn = %d, finrst = %d",
|
||||
estab, syn, finrst);
|
||||
}
|
||||
log_Printf(LogDEBUG, " Filter: proto = %s, %s\n",
|
||||
filter_Proto2Nam(cproto), dbuff);
|
||||
}
|
||||
gotinfo = 1;
|
||||
LogPrintf(LogDEBUG, "dir = %d, proto = %d, srcop = %d,"
|
||||
" dstop = %d, estab = %d\n", direction, cproto,
|
||||
fp->opt.srcop, fp->opt.dstop, estab);
|
||||
}
|
||||
LogPrintf(LogDEBUG, "check0: rule = %d, proto = %d, sport = %d,"
|
||||
" dport = %d\n", n, cproto, sport, dport);
|
||||
LogPrintf(LogDEBUG, "check0: action = %d\n", fp->action);
|
||||
if (log_IsKept(LogDEBUG)) {
|
||||
if (fp->opt.srcop != OP_NONE) {
|
||||
snprintf(dbuff, sizeof dbuff, ", src %s %d",
|
||||
filter_Op2Nam(fp->opt.srcop), fp->opt.srcport);
|
||||
len = strlen(dbuff);
|
||||
} else
|
||||
len = 0;
|
||||
if (fp->opt.dstop != OP_NONE) {
|
||||
snprintf(dbuff + len, sizeof dbuff - len,
|
||||
", dst %s %d", filter_Op2Nam(fp->opt.dstop),
|
||||
fp->opt.dstport);
|
||||
} else if (!len)
|
||||
*dbuff = '\0';
|
||||
|
||||
log_Printf(LogDEBUG, " rule = %d: Address match, "
|
||||
"check against proto %s%s, action = %s\n",
|
||||
n, filter_Proto2Nam(fp->proto),
|
||||
dbuff, filter_Action2Nam(fp->action));
|
||||
}
|
||||
|
||||
if (cproto == fp->proto) {
|
||||
if ((fp->opt.srcop == OP_NONE ||
|
||||
PortMatch(fp->opt.srcop, sport, fp->opt.srcport))
|
||||
&&
|
||||
PortMatch(fp->opt.srcop, sport, fp->opt.srcport)) &&
|
||||
(fp->opt.dstop == OP_NONE ||
|
||||
PortMatch(fp->opt.dstop, dport, fp->opt.dstport))
|
||||
&&
|
||||
(fp->opt.estab == 0 || estab)) {
|
||||
PortMatch(fp->opt.dstop, dport, fp->opt.dstport)) &&
|
||||
(fp->opt.estab == 0 || estab) &&
|
||||
(fp->opt.syn == 0 || syn) &&
|
||||
(fp->opt.finrst == 0 || finrst)) {
|
||||
return (fp->action);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
/* Address is mached. Make a decision. */
|
||||
LogPrintf(LogDEBUG, "check1: action = %d\n", fp->action);
|
||||
log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n,
|
||||
filter_Action2Nam(fp->action));
|
||||
return (fp->action);
|
||||
}
|
||||
}
|
||||
} else
|
||||
log_Printf(LogDEBUG, " rule = %d: Address mismatch\n", n);
|
||||
}
|
||||
fp++;
|
||||
}
|
||||
@ -249,27 +221,26 @@ FilterCheck(struct ip * pip, int direction)
|
||||
return (A_PERMIT); /* No rule is given. Permit this packet */
|
||||
}
|
||||
|
||||
#ifdef notdef
|
||||
static void
|
||||
IcmpError(struct ip * pip, int code)
|
||||
{
|
||||
#ifdef notdef
|
||||
struct mbuf *bp;
|
||||
|
||||
if (pip->ip_p != IPPROTO_ICMP) {
|
||||
bp = mballoc(cnt, MB_IPIN);
|
||||
bp = mbuf_Alloc(cnt, MB_IPIN);
|
||||
memcpy(MBUF_CTOP(bp), ptr, cnt);
|
||||
SendPppFrame(bp);
|
||||
RestartIdleTimer();
|
||||
IpcpAddOutOctets(cnt);
|
||||
vj_SendFrame(bp);
|
||||
ipcp_AddOutOctets(cnt);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* For debugging aid.
|
||||
*/
|
||||
int
|
||||
PacketCheck(char *cp, int nb, int direction)
|
||||
PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
|
||||
{
|
||||
struct ip *pip;
|
||||
struct tcphdr *th;
|
||||
@ -281,14 +252,13 @@ PacketCheck(char *cp, int nb, int direction)
|
||||
int logit, loglen;
|
||||
static char logbuf[200];
|
||||
|
||||
logit = LogIsKept(LogTCPIP) && direction != FL_DIAL;
|
||||
logit = log_IsKept(LogTCPIP) && filter->logok;
|
||||
loglen = 0;
|
||||
|
||||
pip = (struct ip *) cp;
|
||||
|
||||
if (logit && loglen < sizeof logbuf) {
|
||||
snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ",
|
||||
Direction[direction]);
|
||||
snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name);
|
||||
loglen += strlen(logbuf + loglen);
|
||||
}
|
||||
ptop = (cp + (pip->ip_hl << 2));
|
||||
@ -359,42 +329,43 @@ PacketCheck(char *cp, int nb, int direction)
|
||||
break;
|
||||
}
|
||||
|
||||
if ((FilterCheck(pip, direction) & A_DENY)) {
|
||||
if ((FilterCheck(pip, filter) & A_DENY)) {
|
||||
if (logit)
|
||||
LogPrintf(LogTCPIP, "%s - BLOCKED\n", logbuf);
|
||||
log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf);
|
||||
#ifdef notdef
|
||||
if (direction == 0)
|
||||
IcmpError(pip, pri);
|
||||
#endif
|
||||
return (-1);
|
||||
} else {
|
||||
if (FilterCheck(pip, FL_KEEP) & A_DENY) { /* Check Keep Alive filter */
|
||||
if (logit)
|
||||
LogPrintf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
|
||||
ipKeepAlive = 0;
|
||||
} else {
|
||||
if (logit)
|
||||
LogPrintf(LogTCPIP, "%s\n", logbuf);
|
||||
ipKeepAlive = 1;
|
||||
/* Check Keep Alive filter */
|
||||
if (logit) {
|
||||
if (FilterCheck(pip, &bundle->filter.alive) & A_DENY)
|
||||
log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
|
||||
else
|
||||
log_Printf(LogTCPIP, "%s\n", logbuf);
|
||||
}
|
||||
return (pri);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
IpInput(struct mbuf * bp)
|
||||
{ /* IN: Pointer to IP pakcet */
|
||||
ip_Input(struct bundle *bundle, struct mbuf * bp)
|
||||
{
|
||||
u_char *cp;
|
||||
struct mbuf *wp;
|
||||
int nb, nw;
|
||||
struct tun_data tun;
|
||||
struct ip *pip = (struct ip *)tun.data;
|
||||
|
||||
tun_fill_header(tun, AF_INET);
|
||||
cp = tun.data;
|
||||
nb = 0;
|
||||
for (wp = bp; wp; wp = wp->next) { /* Copy to contiguous region */
|
||||
if (sizeof tun.data - (cp - tun.data) < wp->cnt) {
|
||||
LogPrintf(LogERROR, "IpInput: Packet too large (%d) - dropped\n",
|
||||
plength(bp));
|
||||
pfree(bp);
|
||||
log_Printf(LogERROR, "ip_Input: Packet too large (%d) - dropped\n",
|
||||
mbuf_Length(bp));
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
memcpy(cp, MBUF_CTOP(wp), wp->cnt);
|
||||
@ -403,52 +374,56 @@ IpInput(struct mbuf * bp)
|
||||
}
|
||||
|
||||
#ifndef NOALIAS
|
||||
if (mode & MODE_ALIAS) {
|
||||
if (alias_IsEnabled()) {
|
||||
struct tun_data *frag;
|
||||
int iresult;
|
||||
char *fptr;
|
||||
|
||||
iresult = VarPacketAliasIn(tun.data, sizeof tun.data);
|
||||
iresult = (*PacketAlias.In)(tun.data, sizeof tun.data);
|
||||
nb = ntohs(((struct ip *) tun.data)->ip_len);
|
||||
|
||||
if (nb > MAX_MRU) {
|
||||
LogPrintf(LogERROR, "IpInput: Problem with IP header length\n");
|
||||
pfree(bp);
|
||||
log_Printf(LogERROR, "ip_Input: Problem with IP header length\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
if (iresult == PKT_ALIAS_OK
|
||||
|| iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
|
||||
if (PacketCheck(tun.data, nb, FL_IN) < 0) {
|
||||
pfree(bp);
|
||||
if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
IpcpAddInOctets(nb);
|
||||
|
||||
if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
|
||||
bundle_StartIdleTimer(bundle);
|
||||
|
||||
ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
|
||||
|
||||
nb = ntohs(((struct ip *) tun.data)->ip_len);
|
||||
nb += sizeof tun - sizeof tun.data;
|
||||
nw = write(tun_out, &tun, nb);
|
||||
nw = write(bundle->dev.fd, &tun, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb,
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
|
||||
strerror(errno));
|
||||
else
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
|
||||
if (iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
|
||||
while ((fptr = VarPacketAliasGetFragment(tun.data)) != NULL) {
|
||||
VarPacketAliasFragmentIn(tun.data, fptr);
|
||||
while ((fptr = (*PacketAlias.GetFragment)(tun.data)) != NULL) {
|
||||
(*PacketAlias.FragmentIn)(tun.data, fptr);
|
||||
nb = ntohs(((struct ip *) fptr)->ip_len);
|
||||
frag = (struct tun_data *)
|
||||
((char *)fptr - sizeof tun + sizeof tun.data);
|
||||
nb += sizeof tun - sizeof tun.data;
|
||||
nw = write(tun_out, frag, nb);
|
||||
nw = write(bundle->dev.fd, frag, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb,
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
|
||||
strerror(errno));
|
||||
else
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
free(frag);
|
||||
}
|
||||
@ -458,83 +433,86 @@ IpInput(struct mbuf * bp)
|
||||
nb += sizeof tun - sizeof tun.data;
|
||||
frag = (struct tun_data *)malloc(nb);
|
||||
if (frag == NULL)
|
||||
LogPrintf(LogALERT, "IpInput: Cannot allocate memory for fragment\n");
|
||||
log_Printf(LogALERT, "ip_Input: Cannot allocate memory for fragment\n");
|
||||
else {
|
||||
tun_fill_header(*frag, AF_INET);
|
||||
memcpy(frag->data, tun.data, nb - sizeof tun + sizeof tun.data);
|
||||
VarPacketAliasSaveFragment(frag->data);
|
||||
(*PacketAlias.SaveFragment)(frag->data);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* #ifndef NOALIAS */
|
||||
{ /* no aliasing */
|
||||
if (PacketCheck(tun.data, nb, FL_IN) < 0) {
|
||||
pfree(bp);
|
||||
if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
IpcpAddInOctets(nb);
|
||||
|
||||
if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
|
||||
bundle_StartIdleTimer(bundle);
|
||||
|
||||
ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
|
||||
|
||||
nb += sizeof tun - sizeof tun.data;
|
||||
nw = write(tun_out, &tun, nb);
|
||||
nw = write(bundle->dev.fd, &tun, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb, strerror(errno));
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
|
||||
else
|
||||
LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
}
|
||||
pfree(bp);
|
||||
|
||||
RestartIdleTimer();
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
|
||||
static struct mqueue IpOutputQueues[PRI_FAST + 1];
|
||||
|
||||
void
|
||||
IpEnqueue(int pri, char *ptr, int count)
|
||||
ip_Enqueue(int pri, char *ptr, int count)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
|
||||
bp = mballoc(count, MB_IPQ);
|
||||
bp = mbuf_Alloc(count, MB_IPQ);
|
||||
memcpy(MBUF_CTOP(bp), ptr, count);
|
||||
Enqueue(&IpOutputQueues[pri], bp);
|
||||
mbuf_Enqueue(&IpOutputQueues[pri], bp);
|
||||
}
|
||||
|
||||
#if 0
|
||||
int
|
||||
IsIpEnqueued()
|
||||
ip_QueueLen()
|
||||
{
|
||||
struct mqueue *queue;
|
||||
int exist = 0;
|
||||
int result = 0;
|
||||
|
||||
for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--) {
|
||||
if (queue->qlen > 0) {
|
||||
exist = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (exist);
|
||||
for (queue = &IpOutputQueues[PRI_MAX]; queue >= IpOutputQueues; queue--)
|
||||
result += queue->qlen;
|
||||
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
IpStartOutput()
|
||||
int
|
||||
ip_FlushPacket(struct link *l, struct bundle *bundle)
|
||||
{
|
||||
struct mqueue *queue;
|
||||
struct mbuf *bp;
|
||||
int cnt;
|
||||
|
||||
if (IpcpFsm.state != ST_OPENED)
|
||||
return;
|
||||
for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--) {
|
||||
if (bundle->ncp.ipcp.fsm.state != ST_OPENED)
|
||||
return 0;
|
||||
|
||||
for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--)
|
||||
if (queue->top) {
|
||||
bp = Dequeue(queue);
|
||||
bp = mbuf_Dequeue(queue);
|
||||
if (bp) {
|
||||
cnt = plength(bp);
|
||||
SendPppFrame(bp);
|
||||
RestartIdleTimer();
|
||||
IpcpAddOutOctets(cnt);
|
||||
break;
|
||||
struct ip *pip = (struct ip *)MBUF_CTOP(bp);
|
||||
|
||||
cnt = mbuf_Length(bp);
|
||||
vj_SendFrame(l, bp, bundle);
|
||||
if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
|
||||
bundle_StartIdleTimer(bundle);
|
||||
ipcp_AddOutOctets(&bundle->ncp.ipcp, cnt);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -17,15 +17,17 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ip.h,v 1.7 1997/10/26 12:42:11 brian Exp $
|
||||
* $Id: ip.h,v 1.8.2.9 1998/05/01 19:24:46 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
extern void IpStartOutput(void);
|
||||
extern int PacketCheck(char *, int, int);
|
||||
extern void IpEnqueue(int, char *, int);
|
||||
extern void IpInput(struct mbuf *);
|
||||
extern void StartIdleTimer(void);
|
||||
extern void StopIdleTimer(void);
|
||||
extern void UpdateIdleTimer(void);
|
||||
extern int RemainingIdleTime(void);
|
||||
struct mbuf;
|
||||
struct filter;
|
||||
struct link;
|
||||
struct bundle;
|
||||
|
||||
extern int ip_FlushPacket(struct link *, struct bundle *);
|
||||
extern int PacketCheck(struct bundle *, char *, int, struct filter *);
|
||||
extern void ip_Enqueue(int, char *, int);
|
||||
extern void ip_Input(struct bundle *, struct mbuf *);
|
||||
extern int ip_QueueLen(void);
|
||||
|
1190
usr.sbin/ppp/ipcp.c
1190
usr.sbin/ppp/ipcp.c
File diff suppressed because it is too large
Load Diff
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.h,v 1.17 1998/01/11 17:50:33 brian Exp $
|
||||
* $Id: ipcp.h,v 1.18.2.28 1998/05/21 01:26:10 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -26,35 +26,15 @@
|
||||
#define TY_COMPPROTO 2
|
||||
#define TY_IPADDR 3
|
||||
|
||||
/* MS PPP NameServer and NetBIOS NameServer stuff */
|
||||
/* Domain NameServer and NetBIOS NameServer options */
|
||||
|
||||
#ifndef NOMSEXT
|
||||
#define TY_PRIMARY_DNS 129
|
||||
#define TY_PRIMARY_NBNS 130
|
||||
#define TY_SECONDARY_DNS 131
|
||||
#define TY_SECONDARY_NBNS 132
|
||||
#define TY_ADJUST_NS 119 /* subtract from NS val for REJECT bit */
|
||||
|
||||
extern struct in_addr ns_entries[2];
|
||||
extern struct in_addr nbns_entries[2];
|
||||
#endif
|
||||
|
||||
struct ipcpstate {
|
||||
struct in_addr his_ipaddr; /* IP address he is willing to use */
|
||||
u_int32_t his_compproto;
|
||||
|
||||
struct in_addr want_ipaddr; /* IP address I'm willing to use */
|
||||
u_int32_t want_compproto;
|
||||
|
||||
u_int32_t his_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
int heis1172; /* True if he is speaking rfc1172 */
|
||||
};
|
||||
|
||||
struct compreq {
|
||||
u_short proto;
|
||||
u_char slots;
|
||||
u_char compcid;
|
||||
};
|
||||
struct sticky_route;
|
||||
|
||||
struct in_range {
|
||||
struct in_addr ipaddr;
|
||||
@ -62,22 +42,73 @@ struct in_range {
|
||||
int width;
|
||||
};
|
||||
|
||||
extern struct ipcpstate IpcpInfo;
|
||||
extern struct in_range DefMyAddress;
|
||||
extern struct in_range DefHisAddress;
|
||||
extern struct iplist DefHisChoice;
|
||||
extern struct in_addr TriggerAddress;
|
||||
extern int HaveTriggerAddress;
|
||||
extern struct fsm IpcpFsm;
|
||||
struct ipcp {
|
||||
struct fsm fsm; /* The finite state machine */
|
||||
|
||||
extern void IpcpInit(void);
|
||||
extern void IpcpDefAddress(void);
|
||||
extern void IpcpUp(void);
|
||||
extern void IpcpOpen(void);
|
||||
extern int ReportIpcpStatus(struct cmdargs const *);
|
||||
extern void IpcpInput(struct mbuf *);
|
||||
extern void IpcpAddInOctets(int);
|
||||
extern void IpcpAddOutOctets(int);
|
||||
extern int UseHisaddr(const char *, int);
|
||||
extern int SetInitVJ(struct cmdargs const *);
|
||||
extern int ShowInitVJ(struct cmdargs const *);
|
||||
struct {
|
||||
struct {
|
||||
int slots; /* Maximum VJ slots */
|
||||
unsigned slotcomp : 1; /* Slot compression */
|
||||
unsigned neg : 2; /* VJ negotiation */
|
||||
} vj;
|
||||
|
||||
struct in_range my_range; /* MYADDR spec */
|
||||
struct in_addr netmask; /* netmask (unused by most OSs) */
|
||||
struct in_range peer_range; /* HISADDR spec */
|
||||
struct iplist peer_list; /* Ranges of HISADDR values */
|
||||
|
||||
struct in_addr TriggerAddress; /* Address to suggest in REQ */
|
||||
unsigned HaveTriggerAddress : 1; /* Trigger address specified */
|
||||
|
||||
struct {
|
||||
struct in_addr dns[2]; /* DNS addresses offered */
|
||||
unsigned dns_neg : 2; /* dns negotiation */
|
||||
struct in_addr nbns[2]; /* NetBIOS NS addresses offered */
|
||||
} ns;
|
||||
|
||||
u_int fsmretry; /* FSM retry frequency */
|
||||
} cfg;
|
||||
|
||||
struct {
|
||||
struct slcompress cslc; /* VJ state */
|
||||
struct slstat slstat; /* VJ statistics */
|
||||
} vj;
|
||||
|
||||
struct sticky_route *route; /* List of dynamic routes */
|
||||
|
||||
unsigned heis1172 : 1; /* True if he is speaking rfc1172 */
|
||||
|
||||
struct in_addr peer_ip; /* IP address he's willing to use */
|
||||
u_int32_t peer_compproto; /* VJ params he's willing to use */
|
||||
|
||||
struct in_addr my_ip; /* IP address I'm willing to use */
|
||||
u_int32_t my_compproto; /* VJ params I'm willing to use */
|
||||
|
||||
u_int32_t peer_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
struct in_addr my_ifip; /* My configured interface address */
|
||||
struct in_addr peer_ifip; /* My congigured destination address */
|
||||
|
||||
struct pppThroughput throughput; /* throughput statistics */
|
||||
};
|
||||
|
||||
#define fsm2ipcp(fp) (fp->proto == PROTO_IPCP ? (struct ipcp *)fp : NULL)
|
||||
|
||||
struct bundle;
|
||||
struct link;
|
||||
struct cmdargs;
|
||||
|
||||
extern void ipcp_Init(struct ipcp *, struct bundle *, struct link *,
|
||||
const struct fsm_parent *);
|
||||
extern void ipcp_Setup(struct ipcp *);
|
||||
extern void ipcp_SetLink(struct ipcp *, struct link *);
|
||||
|
||||
extern int ipcp_Show(struct cmdargs const *);
|
||||
extern void ipcp_Input(struct ipcp *, struct bundle *, struct mbuf *);
|
||||
extern void ipcp_AddInOctets(struct ipcp *, int);
|
||||
extern void ipcp_AddOutOctets(struct ipcp *, int);
|
||||
extern int ipcp_UseHisaddr(struct bundle *, const char *, int);
|
||||
extern int ipcp_vjset(struct cmdargs const *);
|
||||
extern void ipcp_CleanInterface(struct ipcp *);
|
||||
extern int ipcp_InterfaceUp(struct ipcp *);
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: iplist.c,v 1.3 1997/12/23 22:38:54 brian Exp $
|
||||
* $Id: iplist.c,v 1.4.4.3 1998/05/01 19:24:54 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
@ -33,8 +33,6 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "iplist.h"
|
||||
@ -45,7 +43,7 @@ do_inet_aton(const char *start, const char *end, struct in_addr *ip)
|
||||
static char ipstr[16];
|
||||
|
||||
if (end - start > 15) {
|
||||
LogPrintf(LogWARN, "%.*s: Invalid IP address\n", end-start, start);
|
||||
log_Printf(LogWARN, "%.*s: Invalid IP address\n", end-start, start);
|
||||
return 0;
|
||||
}
|
||||
strncpy(ipstr, start, end-start);
|
||||
@ -112,7 +110,7 @@ iplist_nextrange(struct iplist *list)
|
||||
end = ptr + strlen(ptr);
|
||||
if (end == ptr)
|
||||
return 0;
|
||||
LogPrintf(LogWARN, "%.*s: Invalid IP range (skipping)\n", end - ptr, ptr);
|
||||
log_Printf(LogWARN, "%.*s: Invalid IP range (skipping)\n", end - ptr, ptr);
|
||||
to = ptr;
|
||||
do
|
||||
*to = *end++;
|
||||
|
1003
usr.sbin/ppp/lcp.c
1003
usr.sbin/ppp/lcp.c
File diff suppressed because it is too large
Load Diff
@ -15,38 +15,60 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.15 1997/12/04 18:49:28 brian Exp $
|
||||
* $Id: lcp.h,v 1.16.2.23 1998/05/01 19:24:57 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#define REJECTED(p, x) ((p)->his_reject & (1<<(x)))
|
||||
|
||||
struct lcpstate {
|
||||
u_int16_t his_mru;
|
||||
u_int32_t his_accmap;
|
||||
u_int32_t his_magic;
|
||||
u_int32_t his_lqrperiod;
|
||||
u_char his_protocomp;
|
||||
u_char his_acfcomp;
|
||||
u_short his_auth;
|
||||
struct lcp {
|
||||
struct fsm fsm; /* The finite state machine */
|
||||
u_int16_t his_mru; /* Peers maximum packet size */
|
||||
u_int16_t his_mrru; /* Peers maximum reassembled packet size (MP) */
|
||||
u_int32_t his_accmap; /* Peeers async char control map */
|
||||
u_int32_t his_magic; /* Peers magic number */
|
||||
u_int32_t his_lqrperiod; /* Peers LQR frequency */
|
||||
u_short his_auth; /* Peer wants this type of authentication */
|
||||
unsigned his_shortseq : 1; /* Peer would like only 12bit seqs (MP) */
|
||||
unsigned his_protocomp : 1; /* Does peer do Protocol field compression */
|
||||
unsigned his_acfcomp : 1; /* Does peer do addr & cntrl fld compression */
|
||||
|
||||
u_short want_mru;
|
||||
u_int32_t want_accmap;
|
||||
u_int32_t want_magic;
|
||||
u_int32_t want_lqrperiod;
|
||||
u_char want_protocomp;
|
||||
u_char want_acfcomp;
|
||||
u_short want_auth;
|
||||
u_short want_mru; /* Our maximum packet size */
|
||||
u_short want_mrru; /* Our maximum reassembled packet size (MP) */
|
||||
u_int32_t want_accmap; /* Our async char control map */
|
||||
u_int32_t want_magic; /* Our magic number */
|
||||
u_int32_t want_lqrperiod; /* Our LQR frequency */
|
||||
u_short want_auth; /* We want this type of authentication */
|
||||
unsigned want_shortseq : 1; /* I'd like only 12bit seqs (MP) */
|
||||
unsigned want_protocomp : 1; /* Do we do protocol field compression */
|
||||
unsigned want_acfcomp : 1; /* Do we do addr & cntrl fld compression */
|
||||
|
||||
u_int32_t his_reject; /* Request codes rejected by peer */
|
||||
u_int32_t my_reject; /* Request codes I have rejected */
|
||||
|
||||
u_short auth_iwait;
|
||||
u_short auth_ineed;
|
||||
u_short auth_iwait; /* I must authenticate to the peer */
|
||||
u_short auth_ineed; /* I require that the peer authenticates */
|
||||
|
||||
int LcpFailedMagic; /* Number of `magic is same' errors */
|
||||
|
||||
struct {
|
||||
u_short mru; /* Preferred MRU value */
|
||||
u_int32_t accmap; /* Initial ACCMAP value */
|
||||
int openmode; /* when to start CFG REQs */
|
||||
u_int lqrperiod; /* LQR frequency */
|
||||
u_int fsmretry; /* FSM retry frequency */
|
||||
|
||||
unsigned acfcomp : 2; /* Address & Control Field Compression neg */
|
||||
unsigned chap : 2; /* Challenge Handshake Authentication proto */
|
||||
unsigned lqr : 2; /* Link Quality Report */
|
||||
unsigned pap : 2; /* Password Authentication protocol */
|
||||
unsigned protocomp : 2; /* Protocol field compression */
|
||||
} cfg;
|
||||
};
|
||||
|
||||
#define LCP_MAXCODE CODE_DISCREQ
|
||||
#define LCP_MINMPCODE CODE_CODEREJ
|
||||
|
||||
#define TY_MRU 1 /* Maximum-Receive-Unit */
|
||||
#define TY_ACCMAP 2 /* Async-Control-Character-Map */
|
||||
@ -58,6 +80,9 @@ struct lcpstate {
|
||||
#define TY_ACFCOMP 8 /* Address-and-Control-Field-Compression */
|
||||
#define TY_FCSALT 9 /* FCS-Alternatives */
|
||||
#define TY_SDP 10 /* Self-Describing-Padding */
|
||||
#define TY_MRRU 17 /* Max Reconstructed Receive Unit (MP) */
|
||||
#define TY_SHORTSEQ 18 /* Want short seqs (12bit) please (see mp.h) */
|
||||
#define TY_ENDDISC 19 /* Endpoint discriminator */
|
||||
|
||||
#define MAX_LCP_OPT_LEN 10
|
||||
struct lcp_opt {
|
||||
@ -66,17 +91,26 @@ struct lcp_opt {
|
||||
u_char data[MAX_LCP_OPT_LEN-2];
|
||||
};
|
||||
|
||||
#define INC_LCP_OPT(ty, length, o) \
|
||||
do { \
|
||||
(o)->id = (ty); \
|
||||
(o)->len = (length); \
|
||||
(o) = (struct lcp_opt *)((char *)(o) + (length)); \
|
||||
} while (0)
|
||||
|
||||
extern struct lcpstate LcpInfo;
|
||||
extern struct fsm LcpFsm;
|
||||
struct mbuf;
|
||||
struct link;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
struct cmdargs;
|
||||
|
||||
extern void LcpInit(void);
|
||||
extern void LcpUp(void);
|
||||
extern void LcpSendProtoRej(u_char *, int);
|
||||
extern void LcpOpen(int);
|
||||
extern void LcpClose(void);
|
||||
extern void LcpDown(void);
|
||||
extern int LcpPutConf(int, u_char *, const struct lcp_opt *, const char *,
|
||||
const char *, ...);
|
||||
extern int ReportLcpStatus(struct cmdargs const *);
|
||||
extern void LcpInput(struct mbuf *);
|
||||
#define fsm2lcp(fp) (fp->proto == PROTO_LCP ? (struct lcp *)fp : NULL)
|
||||
|
||||
extern void lcp_Init(struct lcp *, struct bundle *, struct link *,
|
||||
const struct fsm_parent *);
|
||||
extern void lcp_Setup(struct lcp *, int);
|
||||
|
||||
extern void lcp_SendProtoRej(struct lcp *, u_char *, int);
|
||||
extern int lcp_ReportStatus(struct cmdargs const *);
|
||||
extern void lcp_Input(struct lcp *, struct mbuf *);
|
||||
extern void lcp_SetupCallbacks(struct lcp *);
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcpproto.h,v 1.9 1997/10/26 01:02:59 brian Exp $
|
||||
* $Id: lcpproto.h,v 1.10.2.2 1998/05/15 18:21:07 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -26,9 +26,12 @@
|
||||
#define PROTO_IP 0x0021 /* IP */
|
||||
#define PROTO_VJUNCOMP 0x002f /* VJ Uncompressed */
|
||||
#define PROTO_VJCOMP 0x002d /* VJ Compressed */
|
||||
#define PROTO_MP 0x003d /* Multilink fragment */
|
||||
#define PROTO_ICOMPD 0x00fb /* Individual link compressed */
|
||||
#define PROTO_COMPD 0x00fd /* Compressed datagram */
|
||||
|
||||
#define PROTO_COMPRESSIBLE(p) (((p) & 0xffe1) == 0x21)
|
||||
|
||||
#define PROTO_IPCP 0x8021
|
||||
#define PROTO_ICCP 0x80fb
|
||||
#define PROTO_CCP 0x80fd
|
||||
|
198
usr.sbin/ppp/link.c
Normal file
198
usr.sbin/ppp/link.c
Normal file
@ -0,0 +1,198 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: link.c,v 1.1.2.20 1998/05/01 19:24:59 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "lcpproto.h"
|
||||
#include "fsm.h"
|
||||
#include "descriptor.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "prompt.h"
|
||||
|
||||
void
|
||||
link_AddInOctets(struct link *l, int n)
|
||||
{
|
||||
throughput_addin(&l->throughput, n);
|
||||
}
|
||||
|
||||
void
|
||||
link_AddOutOctets(struct link *l, int n)
|
||||
{
|
||||
throughput_addout(&l->throughput, n);
|
||||
}
|
||||
|
||||
void
|
||||
link_SequenceQueue(struct link *l)
|
||||
{
|
||||
log_Printf(LogDEBUG, "link_SequenceQueue\n");
|
||||
while (l->Queue[PRI_NORMAL].qlen)
|
||||
mbuf_Enqueue(l->Queue + PRI_LINK, mbuf_Dequeue(l->Queue + PRI_NORMAL));
|
||||
}
|
||||
|
||||
int
|
||||
link_QueueLen(struct link *l)
|
||||
{
|
||||
int i, len;
|
||||
|
||||
for (i = 0, len = 0; i < LINK_QUEUES; i++)
|
||||
len += l->Queue[i].qlen;
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
int
|
||||
link_QueueBytes(struct link *l)
|
||||
{
|
||||
int i, len, bytes;
|
||||
struct mbuf *m;
|
||||
|
||||
bytes = 0;
|
||||
for (i = 0, len = 0; i < LINK_QUEUES; i++) {
|
||||
len = l->Queue[i].qlen;
|
||||
m = l->Queue[i].top;
|
||||
while (len--) {
|
||||
bytes += mbuf_Length(m);
|
||||
m = m->pnext;
|
||||
}
|
||||
}
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
link_Dequeue(struct link *l)
|
||||
{
|
||||
int pri;
|
||||
struct mbuf *bp;
|
||||
|
||||
for (bp = (struct mbuf *)0, pri = LINK_QUEUES - 1; pri >= 0; pri--)
|
||||
if (l->Queue[pri].qlen) {
|
||||
bp = mbuf_Dequeue(l->Queue + pri);
|
||||
log_Printf(LogDEBUG, "link_Dequeue: Dequeued from queue %d,"
|
||||
" containing %d more packets\n", pri, l->Queue[pri].qlen);
|
||||
break;
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Write to the link. Actualy, requested packets are queued, and go out
|
||||
* at some later time depending on the physical link implementation.
|
||||
*/
|
||||
void
|
||||
link_Write(struct link *l, int pri, const char *ptr, int count)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
|
||||
if(pri < 0 || pri >= LINK_QUEUES)
|
||||
pri = 0;
|
||||
|
||||
bp = mbuf_Alloc(count, MB_LINK);
|
||||
memcpy(MBUF_CTOP(bp), ptr, count);
|
||||
|
||||
mbuf_Enqueue(l->Queue + pri, bp);
|
||||
}
|
||||
|
||||
void
|
||||
link_Output(struct link *l, int pri, struct mbuf *bp)
|
||||
{
|
||||
struct mbuf *wp;
|
||||
int len;
|
||||
|
||||
if(pri < 0 || pri >= LINK_QUEUES)
|
||||
pri = 0;
|
||||
|
||||
len = mbuf_Length(bp);
|
||||
wp = mbuf_Alloc(len, MB_LINK);
|
||||
mbuf_Read(bp, MBUF_CTOP(wp), len);
|
||||
mbuf_Enqueue(l->Queue + pri, wp);
|
||||
}
|
||||
|
||||
static struct protostatheader {
|
||||
u_short number;
|
||||
const char *name;
|
||||
} ProtocolStat[NPROTOSTAT] = {
|
||||
{ PROTO_IP, "IP" },
|
||||
{ PROTO_VJUNCOMP, "VJ_UNCOMP" },
|
||||
{ PROTO_VJCOMP, "VJ_COMP" },
|
||||
{ PROTO_COMPD, "COMPD" },
|
||||
{ PROTO_ICOMPD, "ICOMPD" },
|
||||
{ PROTO_LCP, "LCP" },
|
||||
{ PROTO_IPCP, "IPCP" },
|
||||
{ PROTO_CCP, "CCP" },
|
||||
{ PROTO_PAP, "PAP" },
|
||||
{ PROTO_LQR, "LQR" },
|
||||
{ PROTO_CHAP, "CHAP" },
|
||||
{ PROTO_MP, "MULTILINK" },
|
||||
{ 0, "Others" }
|
||||
};
|
||||
|
||||
void
|
||||
link_ProtocolRecord(struct link *l, u_short proto, int type)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < NPROTOSTAT; i++)
|
||||
if (ProtocolStat[i].number == proto)
|
||||
break;
|
||||
|
||||
if (type == PROTO_IN)
|
||||
l->proto_in[i]++;
|
||||
else
|
||||
l->proto_out[i]++;
|
||||
}
|
||||
|
||||
void
|
||||
link_ReportProtocolStatus(struct link *l, struct prompt *prompt)
|
||||
{
|
||||
int i;
|
||||
|
||||
prompt_Printf(prompt, " Protocol in out "
|
||||
"Protocol in out\n");
|
||||
for (i = 0; i < NPROTOSTAT; i++) {
|
||||
prompt_Printf(prompt, " %-9s: %8lu, %8lu",
|
||||
ProtocolStat[i].name, l->proto_in[i], l->proto_out[i]);
|
||||
if ((i % 2) == 0)
|
||||
prompt_Printf(prompt, "\n");
|
||||
}
|
||||
if (!(i % 2))
|
||||
prompt_Printf(prompt, "\n");
|
||||
}
|
68
usr.sbin/ppp/link.h
Normal file
68
usr.sbin/ppp/link.h
Normal file
@ -0,0 +1,68 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: link.h,v 1.1.2.11 1998/04/24 19:15:26 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define PHYSICAL_LINK 1
|
||||
#define MP_LINK 2
|
||||
|
||||
#define LINK_QUEUES (PRI_MAX + 1)
|
||||
#define NPROTOSTAT 13
|
||||
|
||||
struct bundle;
|
||||
struct prompt;
|
||||
|
||||
struct link {
|
||||
int type; /* _LINK type */
|
||||
const char *name; /* unique id per link type */
|
||||
int len; /* full size of parent struct */
|
||||
struct pppThroughput throughput; /* Link throughput statistics */
|
||||
struct mqueue Queue[LINK_QUEUES]; /* Our output queue of mbufs */
|
||||
|
||||
u_long proto_in[NPROTOSTAT]; /* outgoing protocol stats */
|
||||
u_long proto_out[NPROTOSTAT]; /* incoming protocol stats */
|
||||
|
||||
struct lcp lcp; /* Our line control FSM */
|
||||
struct ccp ccp; /* Our compression FSM */
|
||||
};
|
||||
|
||||
extern void link_AddInOctets(struct link *, int);
|
||||
extern void link_AddOutOctets(struct link *, int);
|
||||
|
||||
extern void link_SequenceQueue(struct link *);
|
||||
extern int link_QueueLen(struct link *);
|
||||
extern int link_QueueBytes(struct link *);
|
||||
extern struct mbuf *link_Dequeue(struct link *);
|
||||
extern void link_Write(struct link *, int, const char *, int);
|
||||
extern void link_StartOutput(struct link *, struct bundle *);
|
||||
extern void link_Output(struct link *, int, struct mbuf *);
|
||||
|
||||
#define PROTO_IN 1 /* third arg to link_ProtocolRecord */
|
||||
#define PROTO_OUT 2
|
||||
extern void link_ProtocolRecord(struct link *, u_short, int);
|
||||
extern void link_ReportProtocolStatus(struct link *, struct prompt *);
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: loadalias.c,v 1.14 1998/01/19 22:59:57 brian Exp $
|
||||
* $Id: loadalias.c,v 1.14.2.5 1998/05/01 19:25:01 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
@ -34,22 +34,16 @@
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/socket.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "systems.h"
|
||||
#include "id.h"
|
||||
#include "loadalias.h"
|
||||
#include "defs.h"
|
||||
#include "vars.h"
|
||||
|
||||
#define _PATH_ALIAS_PREFIX "/usr/lib/libalias.so.2."
|
||||
|
||||
#define off(item) ((int)&(((struct aliasHandlers *)0)->item))
|
||||
#define entry(a) { off(a), "_" #a }
|
||||
#define entry(a) { off(a), "_PacketAlias" #a }
|
||||
|
||||
#ifndef RTLD_NOW
|
||||
#define RTLD_NOW 1 /* really RTLD_LAZY */
|
||||
@ -59,48 +53,51 @@ static struct {
|
||||
int offset;
|
||||
const char *name;
|
||||
} map[] = {
|
||||
entry(PacketAliasGetFragment),
|
||||
entry(PacketAliasInit),
|
||||
entry(PacketAliasIn),
|
||||
entry(PacketAliasOut),
|
||||
entry(PacketAliasRedirectAddr),
|
||||
entry(PacketAliasRedirectPort),
|
||||
entry(PacketAliasSaveFragment),
|
||||
entry(PacketAliasSetAddress),
|
||||
entry(PacketAliasSetMode),
|
||||
entry(PacketAliasFragmentIn),
|
||||
entry(GetFragment),
|
||||
entry(Init),
|
||||
entry(In),
|
||||
entry(Out),
|
||||
entry(RedirectAddr),
|
||||
entry(RedirectPort),
|
||||
entry(SaveFragment),
|
||||
entry(SetAddress),
|
||||
entry(SetMode),
|
||||
entry(FragmentIn),
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static void *dl;
|
||||
struct aliasHandlers PacketAlias;
|
||||
|
||||
int
|
||||
loadAliasHandlers(struct aliasHandlers * h)
|
||||
alias_Load()
|
||||
{
|
||||
const char *path;
|
||||
const char *env;
|
||||
int i;
|
||||
|
||||
if (PacketAlias.dl)
|
||||
return 0;
|
||||
|
||||
path = _PATH_ALIAS_PREFIX;
|
||||
env = getenv("_PATH_ALIAS_PREFIX");
|
||||
if (env) {
|
||||
if (ID0realuid() == 0)
|
||||
path = env;
|
||||
else
|
||||
LogPrintf(LogALERT, "Ignoring environment _PATH_ALIAS_PREFIX"
|
||||
log_Printf(LogALERT, "Ignoring environment _PATH_ALIAS_PREFIX"
|
||||
" value (%s)\n", env);
|
||||
}
|
||||
|
||||
dl = dlopen(path, RTLD_NOW);
|
||||
if (dl == (void *) 0) {
|
||||
PacketAlias.dl = dlopen(path, RTLD_NOW);
|
||||
if (PacketAlias.dl == (void *) 0) {
|
||||
/* Look for _PATH_ALIAS_PREFIX with any number appended */
|
||||
int plen;
|
||||
|
||||
plen = strlen(path);
|
||||
if (plen && plen < MAXPATHLEN - 1 && path[plen-1] == '.') {
|
||||
DIR *d;
|
||||
char p[MAXPATHLEN], *fix;
|
||||
char *file, *dir;
|
||||
char p[MAXPATHLEN], *fix, *file;
|
||||
const char *dir;
|
||||
|
||||
strcpy(p, path);
|
||||
if ((file = strrchr(p, '/')) != NULL) {
|
||||
@ -134,37 +131,37 @@ loadAliasHandlers(struct aliasHandlers * h)
|
||||
|
||||
if (maxver > -1) {
|
||||
sprintf(p + plen, "%ld", maxver);
|
||||
dl = dlopen(p, RTLD_NOW);
|
||||
PacketAlias.dl = dlopen(p, RTLD_NOW);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dl == (void *) 0) {
|
||||
LogPrintf(LogWARN, "_PATH_ALIAS_PREFIX (%s*): Invalid lib: %s\n",
|
||||
if (PacketAlias.dl == (void *) 0) {
|
||||
log_Printf(LogWARN, "_PATH_ALIAS_PREFIX (%s*): Invalid lib: %s\n",
|
||||
path, dlerror());
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
for (i = 0; map[i].name; i++) {
|
||||
*(void **) ((char *) h + map[i].offset) = dlsym(dl, map[i].name);
|
||||
if (*(void **) ((char *) h + map[i].offset) == (void *) 0) {
|
||||
LogPrintf(LogWARN, "_PATH_ALIAS (%s*): %s: %s\n", path,
|
||||
*(void **)((char *)&PacketAlias + map[i].offset) =
|
||||
dlsym(PacketAlias.dl, map[i].name);
|
||||
if (*(void **)((char *)&PacketAlias + map[i].offset) == (void *)0) {
|
||||
log_Printf(LogWARN, "_PATH_ALIAS (%s*): %s: %s\n", path,
|
||||
map[i].name, dlerror());
|
||||
(void) dlclose(dl);
|
||||
dl = (void *) 0;
|
||||
alias_Unload();
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
VarPacketAliasInit();
|
||||
(*PacketAlias.Init)();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
unloadAliasHandlers()
|
||||
alias_Unload()
|
||||
{
|
||||
if (dl) {
|
||||
dlclose(dl);
|
||||
dl = (void *) 0;
|
||||
if (PacketAlias.dl) {
|
||||
dlclose(PacketAlias.dl);
|
||||
memset(&PacketAlias, '\0', sizeof PacketAlias);
|
||||
}
|
||||
}
|
||||
|
@ -23,23 +23,27 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: loadalias.h,v 1.4.2.3 1998/05/01 19:25:03 brian Exp $
|
||||
*/
|
||||
|
||||
struct aliasHandlers {
|
||||
char *(*PacketAliasGetFragment)(char *);
|
||||
void (*PacketAliasInit)(void);
|
||||
int (*PacketAliasIn)(char *, int);
|
||||
int (*PacketAliasOut)(char *, int);
|
||||
struct alias_link *(*PacketAliasRedirectAddr)(struct in_addr, struct in_addr);
|
||||
struct alias_link *(*PacketAliasRedirectPort)
|
||||
(struct in_addr, u_short, struct in_addr, u_short,
|
||||
struct in_addr, u_short, u_char);
|
||||
int (*PacketAliasSaveFragment)(char *);
|
||||
void (*PacketAliasSetAddress)(struct in_addr);
|
||||
unsigned (*PacketAliasSetMode)(unsigned, unsigned);
|
||||
void (*PacketAliasFragmentIn)(char *, char *);
|
||||
void *dl;
|
||||
|
||||
char *(*GetFragment)(char *);
|
||||
void (*Init)(void);
|
||||
int (*In)(char *, int);
|
||||
int (*Out)(char *, int);
|
||||
struct alias_link *(*RedirectAddr)(struct in_addr, struct in_addr);
|
||||
struct alias_link *(*RedirectPort)(struct in_addr, u_short, struct in_addr,
|
||||
u_short, struct in_addr, u_short, u_char);
|
||||
int (*SaveFragment)(char *);
|
||||
void (*SetAddress)(struct in_addr);
|
||||
unsigned (*SetMode)(unsigned, unsigned);
|
||||
void (*FragmentIn)(char *, char *);
|
||||
};
|
||||
|
||||
extern int loadAliasHandlers(struct aliasHandlers *);
|
||||
extern void unloadAliasHandlers(void);
|
||||
extern struct aliasHandlers PacketAlias;
|
||||
|
||||
#define alias_IsEnabled() (PacketAlias.dl ? 1 : 0)
|
||||
extern int alias_Load(void);
|
||||
extern void alias_Unload(void);
|
||||
|
@ -23,27 +23,25 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: log.c,v 1.25 1998/01/21 02:15:18 brian Exp $
|
||||
* $Id: log.c,v 1.25.2.14 1998/05/01 22:39:35 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <syslog.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "defs.h"
|
||||
#include "vars.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
|
||||
static const char *LogNames[] = {
|
||||
"Async",
|
||||
"Carrier",
|
||||
"CCP",
|
||||
"Chat",
|
||||
"Command",
|
||||
@ -53,10 +51,10 @@ static const char *LogNames[] = {
|
||||
"ID0",
|
||||
"IPCP",
|
||||
"LCP",
|
||||
"Link",
|
||||
"LQM",
|
||||
"Phase",
|
||||
"TCP/IP",
|
||||
"Timer",
|
||||
"Tun",
|
||||
"Warning",
|
||||
"Error",
|
||||
@ -65,15 +63,54 @@ static const char *LogNames[] = {
|
||||
|
||||
#define MSK(n) (1<<((n)-1))
|
||||
|
||||
static u_long LogMask = MSK(LogLINK) | MSK(LogCARRIER) | MSK(LogPHASE);
|
||||
static u_long LogMask = MSK(LogPHASE);
|
||||
static u_long LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
|
||||
static int LogTunno = -1;
|
||||
static struct prompt *logprompt; /* Where to log local stuff */
|
||||
|
||||
void
|
||||
log_RegisterPrompt(struct prompt *prompt)
|
||||
{
|
||||
if (prompt) {
|
||||
prompt->lognext = logprompt;
|
||||
logprompt = prompt;
|
||||
LogMaskLocal |= prompt->logmask;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
LogSetMaskLocal(void)
|
||||
{
|
||||
struct prompt *p;
|
||||
|
||||
LogMaskLocal = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
|
||||
for (p = logprompt; p; p = p->lognext)
|
||||
LogMaskLocal |= p->logmask;
|
||||
}
|
||||
|
||||
void
|
||||
log_UnRegisterPrompt(struct prompt *prompt)
|
||||
{
|
||||
if (prompt) {
|
||||
struct prompt **p;
|
||||
|
||||
for (p = &logprompt; *p; p = &(*p)->lognext)
|
||||
if (*p == prompt) {
|
||||
*p = prompt->lognext;
|
||||
prompt->lognext = NULL;
|
||||
break;
|
||||
}
|
||||
LogSetMaskLocal();
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
syslogLevel(int lev)
|
||||
{
|
||||
switch (lev) {
|
||||
case LogDEBUG:return LOG_DEBUG;
|
||||
case LogDEBUG:
|
||||
case LogTIMER:
|
||||
return LOG_DEBUG;
|
||||
case LogWARN:
|
||||
return LOG_WARNING;
|
||||
case LogERROR:
|
||||
@ -85,53 +122,58 @@ syslogLevel(int lev)
|
||||
}
|
||||
|
||||
const char *
|
||||
LogName(int id)
|
||||
log_Name(int id)
|
||||
{
|
||||
return id < LogMIN || id > LogMAX ? "Unknown" : LogNames[id - 1];
|
||||
}
|
||||
|
||||
void
|
||||
LogKeep(int id)
|
||||
log_Keep(int id)
|
||||
{
|
||||
if (id >= LogMIN && id <= LogMAXCONF)
|
||||
LogMask |= MSK(id);
|
||||
}
|
||||
|
||||
void
|
||||
LogKeepLocal(int id)
|
||||
log_KeepLocal(int id, u_long *mask)
|
||||
{
|
||||
if (id >= LogMIN && id <= LogMAXCONF)
|
||||
if (id >= LogMIN && id <= LogMAXCONF) {
|
||||
LogMaskLocal |= MSK(id);
|
||||
*mask |= MSK(id);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogDiscard(int id)
|
||||
log_Discard(int id)
|
||||
{
|
||||
if (id >= LogMIN && id <= LogMAXCONF)
|
||||
LogMask &= ~MSK(id);
|
||||
}
|
||||
|
||||
void
|
||||
LogDiscardLocal(int id)
|
||||
log_DiscardLocal(int id, u_long *mask)
|
||||
{
|
||||
if (id >= LogMIN && id <= LogMAXCONF)
|
||||
LogMaskLocal &= ~MSK(id);
|
||||
if (id >= LogMIN && id <= LogMAXCONF) {
|
||||
*mask &= ~MSK(id);
|
||||
LogSetMaskLocal();
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogDiscardAll()
|
||||
log_DiscardAll()
|
||||
{
|
||||
LogMask = 0;
|
||||
}
|
||||
|
||||
void
|
||||
LogDiscardAllLocal()
|
||||
log_DiscardAllLocal(u_long *mask)
|
||||
{
|
||||
LogMaskLocal = 0;
|
||||
*mask = MSK(LogERROR) | MSK(LogALERT) | MSK(LogWARN);
|
||||
LogSetMaskLocal();
|
||||
}
|
||||
|
||||
int
|
||||
LogIsKept(int id)
|
||||
log_IsKept(int id)
|
||||
{
|
||||
if (id < LogMIN || id > LogMAX)
|
||||
return 0;
|
||||
@ -142,50 +184,65 @@ LogIsKept(int id)
|
||||
((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
|
||||
}
|
||||
|
||||
int
|
||||
log_IsKeptLocal(int id, u_long mask)
|
||||
{
|
||||
if (id < LogMIN || id > LogMAX)
|
||||
return 0;
|
||||
if (id > LogMAXCONF)
|
||||
return LOG_KEPT_LOCAL | LOG_KEPT_SYSLOG;
|
||||
|
||||
return ((mask & MSK(id)) ? LOG_KEPT_LOCAL : 0) |
|
||||
((LogMask & MSK(id)) ? LOG_KEPT_SYSLOG : 0);
|
||||
}
|
||||
|
||||
void
|
||||
LogOpen(const char *Name)
|
||||
log_Open(const char *Name)
|
||||
{
|
||||
openlog(Name, LOG_PID, LOG_DAEMON);
|
||||
}
|
||||
|
||||
void
|
||||
LogSetTun(int tunno)
|
||||
log_SetTun(int tunno)
|
||||
{
|
||||
LogTunno = tunno;
|
||||
}
|
||||
|
||||
void
|
||||
LogClose()
|
||||
log_Close()
|
||||
{
|
||||
closelog();
|
||||
LogTunno = -1;
|
||||
}
|
||||
|
||||
void
|
||||
LogPrintf(int lev, const char *fmt,...)
|
||||
log_Printf(int lev, const char *fmt,...)
|
||||
{
|
||||
va_list ap;
|
||||
struct prompt *prompt;
|
||||
|
||||
va_start(ap, fmt);
|
||||
if (LogIsKept(lev)) {
|
||||
if (log_IsKept(lev)) {
|
||||
static char nfmt[200];
|
||||
|
||||
if ((LogIsKept(lev) & LOG_KEPT_LOCAL) && VarTerm) {
|
||||
if ((LogIsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
|
||||
if ((log_IsKept(lev) & LOG_KEPT_LOCAL) && logprompt) {
|
||||
if ((log_IsKept(LogTUN) & LOG_KEPT_LOCAL) && LogTunno != -1)
|
||||
snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s",
|
||||
LogTunno, LogName(lev), fmt);
|
||||
LogTunno, log_Name(lev), fmt);
|
||||
else
|
||||
snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt);
|
||||
vfprintf(VarTerm, nfmt, ap);
|
||||
fflush(VarTerm);
|
||||
snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
|
||||
|
||||
for (prompt = logprompt; prompt; prompt = prompt->lognext)
|
||||
if (lev > LogMAXCONF || (prompt->logmask & MSK(lev)))
|
||||
prompt_vPrintf(prompt, nfmt, ap);
|
||||
}
|
||||
|
||||
if ((LogIsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !VarTerm)) {
|
||||
if ((LogIsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
|
||||
if ((log_IsKept(lev) & LOG_KEPT_SYSLOG) && (lev != LogWARN || !logprompt)) {
|
||||
if ((log_IsKept(LogTUN) & LOG_KEPT_SYSLOG) && LogTunno != -1)
|
||||
snprintf(nfmt, sizeof nfmt, "tun%d: %s: %s",
|
||||
LogTunno, LogName(lev), fmt);
|
||||
LogTunno, log_Name(lev), fmt);
|
||||
else
|
||||
snprintf(nfmt, sizeof nfmt, "%s: %s", LogName(lev), fmt);
|
||||
snprintf(nfmt, sizeof nfmt, "%s: %s", log_Name(lev), fmt);
|
||||
vsyslog(syslogLevel(lev), nfmt, ap);
|
||||
}
|
||||
}
|
||||
@ -193,16 +250,16 @@ LogPrintf(int lev, const char *fmt,...)
|
||||
}
|
||||
|
||||
void
|
||||
LogDumpBp(int lev, const char *hdr, const struct mbuf * bp)
|
||||
log_DumpBp(int lev, const char *hdr, const struct mbuf * bp)
|
||||
{
|
||||
if (LogIsKept(lev)) {
|
||||
if (log_IsKept(lev)) {
|
||||
char buf[50];
|
||||
char *b;
|
||||
u_char *ptr;
|
||||
int f;
|
||||
|
||||
if (hdr && *hdr)
|
||||
LogPrintf(lev, "%s\n", hdr);
|
||||
log_Printf(lev, "%s\n", hdr);
|
||||
|
||||
b = buf;
|
||||
do {
|
||||
@ -213,7 +270,7 @@ LogDumpBp(int lev, const char *hdr, const struct mbuf * bp)
|
||||
b += 3;
|
||||
if (b == buf + sizeof buf - 2) {
|
||||
strcpy(b, "\n");
|
||||
LogPrintf(lev, buf);
|
||||
log_Printf(lev, buf);
|
||||
b = buf;
|
||||
}
|
||||
}
|
||||
@ -221,26 +278,116 @@ LogDumpBp(int lev, const char *hdr, const struct mbuf * bp)
|
||||
|
||||
if (b > buf) {
|
||||
strcpy(b, "\n");
|
||||
LogPrintf(lev, buf);
|
||||
log_Printf(lev, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
LogDumpBuff(int lev, const char *hdr, const u_char * ptr, int n)
|
||||
log_DumpBuff(int lev, const char *hdr, const u_char * ptr, int n)
|
||||
{
|
||||
if (LogIsKept(lev)) {
|
||||
if (log_IsKept(lev)) {
|
||||
char buf[50];
|
||||
char *b;
|
||||
|
||||
if (hdr && *hdr)
|
||||
LogPrintf(lev, "%s\n", hdr);
|
||||
log_Printf(lev, "%s\n", hdr);
|
||||
while (n > 0) {
|
||||
b = buf;
|
||||
for (b = buf; b != buf + sizeof buf - 2 && n--; b += 3)
|
||||
sprintf(b, " %02x", (int) *ptr++);
|
||||
strcpy(b, "\n");
|
||||
LogPrintf(lev, buf);
|
||||
log_Printf(lev, buf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
log_ShowLevel(struct cmdargs const *arg)
|
||||
{
|
||||
int i;
|
||||
|
||||
prompt_Printf(arg->prompt, "Log: ");
|
||||
for (i = LogMIN; i <= LogMAX; i++)
|
||||
if (log_IsKept(i) & LOG_KEPT_SYSLOG)
|
||||
prompt_Printf(arg->prompt, " %s", log_Name(i));
|
||||
|
||||
prompt_Printf(arg->prompt, "\nLocal:");
|
||||
for (i = LogMIN; i <= LogMAX; i++)
|
||||
if (log_IsKeptLocal(i, arg->prompt->logmask) & LOG_KEPT_LOCAL)
|
||||
prompt_Printf(arg->prompt, " %s", log_Name(i));
|
||||
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
log_SetLevel(struct cmdargs const *arg)
|
||||
{
|
||||
int i, res, argc, local;
|
||||
char const *const *argv, *argp;
|
||||
|
||||
argc = arg->argc - arg->argn;
|
||||
argv = arg->argv + arg->argn;
|
||||
res = 0;
|
||||
|
||||
if (argc == 0 || strcasecmp(argv[0], "local"))
|
||||
local = 0;
|
||||
else {
|
||||
if (arg->prompt == NULL) {
|
||||
log_Printf(LogWARN, "set log local: Only available on the command line\n");
|
||||
return 1;
|
||||
}
|
||||
argc--;
|
||||
argv++;
|
||||
local = 1;
|
||||
}
|
||||
|
||||
if (argc == 0 || (argv[0][0] != '+' && argv[0][0] != '-')) {
|
||||
if (local)
|
||||
log_DiscardAllLocal(&arg->prompt->logmask);
|
||||
else
|
||||
log_DiscardAll();
|
||||
}
|
||||
|
||||
while (argc--) {
|
||||
argp = **argv == '+' || **argv == '-' ? *argv + 1 : *argv;
|
||||
for (i = LogMIN; i <= LogMAX; i++)
|
||||
if (strcasecmp(argp, log_Name(i)) == 0) {
|
||||
if (**argv == '-') {
|
||||
if (local)
|
||||
log_DiscardLocal(i, &arg->prompt->logmask);
|
||||
else
|
||||
log_Discard(i);
|
||||
} else if (local)
|
||||
log_KeepLocal(i, &arg->prompt->logmask);
|
||||
else
|
||||
log_Keep(i);
|
||||
break;
|
||||
}
|
||||
if (i > LogMAX) {
|
||||
log_Printf(LogWARN, "%s: Invalid log value\n", argp);
|
||||
res = -1;
|
||||
}
|
||||
argv++;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
|
||||
int
|
||||
log_ShowWho(struct cmdargs const *arg)
|
||||
{
|
||||
struct prompt *p;
|
||||
|
||||
for (p = logprompt; p; p = p->lognext) {
|
||||
prompt_Printf(arg->prompt, "%s (%s)", p->src.type, p->src.from);
|
||||
if (p == arg->prompt)
|
||||
prompt_Printf(arg->prompt, " *");
|
||||
if (!p->active)
|
||||
prompt_Printf(arg->prompt, " ^Z");
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,46 +23,60 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: log.h,v 1.18.2.8 1998/05/01 22:39:37 brian Exp $
|
||||
*/
|
||||
|
||||
#define LogMIN (1)
|
||||
#define LogASYNC (1) /* syslog(LOG_INFO, ....) */
|
||||
#define LogCARRIER (2)
|
||||
#define LogCCP (3)
|
||||
#define LogCHAT (4)
|
||||
#define LogCOMMAND (5)
|
||||
#define LogCONNECT (6)
|
||||
#define LogDEBUG (7) /* syslog(LOG_DEBUG, ....) */
|
||||
#define LogHDLC (8)
|
||||
#define LogID0 (9)
|
||||
#define LogIPCP (10)
|
||||
#define LogLCP (11)
|
||||
#define LogLINK (12)
|
||||
#define LogLQM (13)
|
||||
#define LogPHASE (14)
|
||||
#define LogTCPIP (15)
|
||||
#define LogTUN (16) /* If set, tun%d is output with each message */
|
||||
#define LogMAXCONF (16)
|
||||
#define LogWARN (17) /* Sent to VarTerm else syslog(LOG_WARNING, ) */
|
||||
#define LogERROR (18) /* syslog(LOG_ERR, ....), + sent to VarTerm */
|
||||
#define LogALERT (19) /* syslog(LOG_ALERT, ....) */
|
||||
#define LogMAX (19)
|
||||
#define LogCCP (2)
|
||||
#define LogCHAT (3)
|
||||
#define LogCOMMAND (4)
|
||||
#define LogCONNECT (5)
|
||||
#define LogDEBUG (6) /* syslog(LOG_DEBUG, ....) */
|
||||
#define LogHDLC (7)
|
||||
#define LogID0 (8)
|
||||
#define LogIPCP (9)
|
||||
#define LogLCP (10)
|
||||
#define LogLQM (11)
|
||||
#define LogPHASE (12)
|
||||
#define LogTCPIP (13)
|
||||
#define LogTIMER (14) /* syslog(LOG_DEBUG, ....) */
|
||||
#define LogTUN (15) /* If set, tun%d is output with each message */
|
||||
#define LogMAXCONF (15)
|
||||
#define LogWARN (16) /* Sent to VarTerm else syslog(LOG_WARNING, ) */
|
||||
#define LogERROR (17) /* syslog(LOG_ERR, ....), + sent to VarTerm */
|
||||
#define LogALERT (18) /* syslog(LOG_ALERT, ....) */
|
||||
#define LogMAX (18)
|
||||
|
||||
struct mbuf;
|
||||
struct cmdargs;
|
||||
struct prompt;
|
||||
|
||||
/* The first int arg for all of the following is one of the above values */
|
||||
extern const char *LogName(int);
|
||||
extern void LogKeep(int);
|
||||
extern void LogKeepLocal(int);
|
||||
extern void LogDiscard(int);
|
||||
extern void LogDiscardLocal(int);
|
||||
extern void LogDiscardAll(void);
|
||||
extern void LogDiscardAllLocal(void);
|
||||
#define LOG_KEPT_SYSLOG (1) /* Results of LogIsKept() */
|
||||
#define LOG_KEPT_LOCAL (2) /* Results of LogIsKept() */
|
||||
extern int LogIsKept(int);
|
||||
extern void LogOpen(const char *);
|
||||
extern void LogSetTun(int);
|
||||
extern void LogClose(void);
|
||||
extern void LogPrintf(int, const char *,...);
|
||||
extern void LogDumpBp(int, const char *, const struct mbuf *);
|
||||
extern void LogDumpBuff(int, const char *, const u_char *, int);
|
||||
extern const char *log_Name(int);
|
||||
extern void log_Keep(int);
|
||||
extern void log_KeepLocal(int, u_long *);
|
||||
extern void log_Discard(int);
|
||||
extern void log_DiscardLocal(int, u_long *);
|
||||
extern void log_DiscardAll(void);
|
||||
extern void log_DiscardAllLocal(u_long *);
|
||||
#define LOG_KEPT_SYSLOG (1) /* Results of log_IsKept() */
|
||||
#define LOG_KEPT_LOCAL (2) /* Results of log_IsKept() */
|
||||
extern int log_IsKept(int);
|
||||
extern int log_IsKeptLocal(int, u_long);
|
||||
extern void log_Open(const char *);
|
||||
extern void log_SetTun(int);
|
||||
extern void log_Close(void);
|
||||
#ifdef __GNUC__
|
||||
extern void log_Printf(int, const char *,...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
#else
|
||||
extern void log_Printf(int, const char *,...);
|
||||
#endif
|
||||
extern void log_DumpBp(int, const char *, const struct mbuf *);
|
||||
extern void log_DumpBuff(int, const char *, const u_char *, int);
|
||||
extern void log_RegisterPrompt(struct prompt *);
|
||||
extern void log_UnRegisterPrompt(struct prompt *);
|
||||
extern int log_ShowLevel(struct cmdargs const *);
|
||||
extern int log_SetLevel(struct cmdargs const *);
|
||||
extern int log_ShowWho(struct cmdargs const *);
|
||||
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lqr.c,v 1.23 1998/03/12 02:23:40 brian Exp $
|
||||
* $Id: lqr.c,v 1.22.2.30 1998/05/08 01:15:08 brian Exp $
|
||||
*
|
||||
* o LQR based on RFC1333
|
||||
*
|
||||
@ -25,36 +25,34 @@
|
||||
* o LQM policy
|
||||
* o Allow user to configure LQM method and interval.
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
|
||||
struct lqrdata MyLqrData, HisLqrData;
|
||||
struct lqrsave HisLqrSave;
|
||||
|
||||
static struct pppTimer LqrTimer;
|
||||
|
||||
static u_long lastpeerin = (u_long) - 1;
|
||||
|
||||
static int lqmmethod;
|
||||
static u_int32_t echoseq;
|
||||
static u_int32_t gotseq;
|
||||
static int lqrsendcnt;
|
||||
#include "async.h"
|
||||
#include "throughput.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#include "chat.h"
|
||||
#include "auth.h"
|
||||
#include "chap.h"
|
||||
#include "command.h"
|
||||
#include "datalink.h"
|
||||
|
||||
struct echolqr {
|
||||
u_int32_t magic;
|
||||
@ -65,43 +63,44 @@ struct echolqr {
|
||||
#define SIGNATURE 0x594e4f54
|
||||
|
||||
static void
|
||||
SendEchoReq(void)
|
||||
SendEchoReq(struct lcp *lcp)
|
||||
{
|
||||
struct fsm *fp = &LcpFsm;
|
||||
struct echolqr *lqr, lqrdata;
|
||||
struct hdlc *hdlc = &link2physical(lcp->fsm.link)->hdlc;
|
||||
struct echolqr echo;
|
||||
|
||||
if (fp->state == ST_OPENED) {
|
||||
lqr = &lqrdata;
|
||||
lqr->magic = htonl(LcpInfo.want_magic);
|
||||
lqr->signature = htonl(SIGNATURE);
|
||||
LogPrintf(LogLQM, "Send echo LQR [%d]\n", echoseq);
|
||||
lqr->sequence = htonl(echoseq++);
|
||||
FsmOutput(fp, CODE_ECHOREQ, fp->reqid++,
|
||||
(u_char *) lqr, sizeof(struct echolqr));
|
||||
}
|
||||
echo.magic = htonl(lcp->want_magic);
|
||||
echo.signature = htonl(SIGNATURE);
|
||||
echo.sequence = htonl(hdlc->lqm.echo.seq_sent);
|
||||
fsm_Output(&lcp->fsm, CODE_ECHOREQ, hdlc->lqm.echo.seq_sent++,
|
||||
(u_char *)&echo, sizeof echo);
|
||||
}
|
||||
|
||||
void
|
||||
RecvEchoLqr(struct mbuf * bp)
|
||||
lqr_RecvEcho(struct fsm *fp, struct mbuf * bp)
|
||||
{
|
||||
struct hdlc *hdlc = &link2physical(fp->link)->hdlc;
|
||||
struct echolqr *lqr;
|
||||
u_int32_t seq;
|
||||
|
||||
if (plength(bp) == sizeof(struct echolqr)) {
|
||||
if (mbuf_Length(bp) == sizeof(struct echolqr)) {
|
||||
lqr = (struct echolqr *) MBUF_CTOP(bp);
|
||||
if (htonl(lqr->signature) == SIGNATURE) {
|
||||
if (ntohl(lqr->signature) == SIGNATURE) {
|
||||
seq = ntohl(lqr->sequence);
|
||||
LogPrintf(LogLQM, "Got echo LQR [%d]\n", ntohl(lqr->sequence));
|
||||
/* careful not to update gotseq with older values */
|
||||
if ((gotseq > (u_int32_t)0 - 5 && seq < 5) ||
|
||||
(gotseq <= (u_int32_t)0 - 5 && seq > gotseq))
|
||||
gotseq = seq;
|
||||
}
|
||||
}
|
||||
/* careful not to update lqm.echo.seq_recv with older values */
|
||||
if ((hdlc->lqm.echo.seq_recv > (u_int32_t)0 - 5 && seq < 5) ||
|
||||
(hdlc->lqm.echo.seq_recv <= (u_int32_t)0 - 5 &&
|
||||
seq > hdlc->lqm.echo.seq_recv))
|
||||
hdlc->lqm.echo.seq_recv = seq;
|
||||
} else
|
||||
log_Printf(LogERROR, "lqr_RecvEcho: Got sig 0x%08x, expecting 0x%08x !\n",
|
||||
(unsigned)ntohl(lqr->signature), (unsigned)SIGNATURE);
|
||||
} else
|
||||
log_Printf(LogERROR, "lqr_RecvEcho: Got packet size %d, expecting %d !\n",
|
||||
mbuf_Length(bp), sizeof(struct echolqr));
|
||||
}
|
||||
|
||||
void
|
||||
LqrChangeOrder(struct lqrdata * src, struct lqrdata * dst)
|
||||
lqr_ChangeOrder(struct lqrdata * src, struct lqrdata * dst)
|
||||
{
|
||||
u_long *sp, *dp;
|
||||
int n;
|
||||
@ -113,169 +112,207 @@ LqrChangeOrder(struct lqrdata * src, struct lqrdata * dst)
|
||||
}
|
||||
|
||||
static void
|
||||
SendLqrReport(void *v)
|
||||
SendLqrData(struct lcp *lcp)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
|
||||
StopTimer(&LqrTimer);
|
||||
bp = mbuf_Alloc(sizeof(struct lqrdata), MB_LQR);
|
||||
hdlc_Output(lcp->fsm.link, PRI_LINK, PROTO_LQR, bp);
|
||||
}
|
||||
|
||||
if (lqmmethod & LQM_LQR) {
|
||||
if (lqrsendcnt > 5) {
|
||||
/*
|
||||
* XXX: Should implement LQM strategy
|
||||
*/
|
||||
LogPrintf(LogPHASE, "** Too many LQR packets lost **\n");
|
||||
LogPrintf(LogLQM, "LqrOutput: Too many LQR packets lost\n");
|
||||
lqmmethod = 0; /* Prevent recursion via LcpClose() */
|
||||
reconnect(RECON_TRUE);
|
||||
LcpClose();
|
||||
static void
|
||||
SendLqrReport(void *v)
|
||||
{
|
||||
struct lcp *lcp = (struct lcp *)v;
|
||||
struct physical *p = link2physical(lcp->fsm.link);
|
||||
|
||||
timer_Stop(&p->hdlc.lqm.timer);
|
||||
|
||||
if (p->hdlc.lqm.method & LQM_LQR) {
|
||||
if (p->hdlc.lqm.lqr.resent > 5) {
|
||||
/* XXX: Should implement LQM strategy */
|
||||
log_Printf(LogPHASE, "%s: ** Too many LQR packets lost **\n",
|
||||
lcp->fsm.link->name);
|
||||
log_Printf(LogLQM, "%s: Too many LQR packets lost\n",
|
||||
lcp->fsm.link->name);
|
||||
p->hdlc.lqm.method = 0;
|
||||
datalink_Down(p->dl, 0);
|
||||
} else {
|
||||
bp = mballoc(sizeof(struct lqrdata), MB_LQR);
|
||||
HdlcOutput(PRI_LINK, PROTO_LQR, bp);
|
||||
lqrsendcnt++;
|
||||
SendLqrData(lcp);
|
||||
p->hdlc.lqm.lqr.resent++;
|
||||
}
|
||||
} else if (lqmmethod & LQM_ECHO) {
|
||||
if ((echoseq > 5 && echoseq - 5 > gotseq) ||
|
||||
(echoseq <= 5 && echoseq > gotseq + 5)) {
|
||||
LogPrintf(LogPHASE, "** Too many ECHO LQR packets lost **\n");
|
||||
LogPrintf(LogLQM, "LqrOutput: Too many ECHO LQR packets lost\n");
|
||||
lqmmethod = 0; /* Prevent recursion via LcpClose() */
|
||||
reconnect(RECON_TRUE);
|
||||
LcpClose();
|
||||
} else if (p->hdlc.lqm.method & LQM_ECHO) {
|
||||
if ((p->hdlc.lqm.echo.seq_sent > 5 &&
|
||||
p->hdlc.lqm.echo.seq_sent - 5 > p->hdlc.lqm.echo.seq_recv) ||
|
||||
(p->hdlc.lqm.echo.seq_sent <= 5 &&
|
||||
p->hdlc.lqm.echo.seq_sent > p->hdlc.lqm.echo.seq_recv + 5)) {
|
||||
log_Printf(LogPHASE, "%s: ** Too many ECHO LQR packets lost **\n",
|
||||
lcp->fsm.link->name);
|
||||
log_Printf(LogLQM, "%s: Too many ECHO LQR packets lost\n",
|
||||
lcp->fsm.link->name);
|
||||
p->hdlc.lqm.method = 0;
|
||||
datalink_Down(p->dl, 0);
|
||||
} else
|
||||
SendEchoReq();
|
||||
SendEchoReq(lcp);
|
||||
}
|
||||
if (lqmmethod && LqrTimer.load)
|
||||
StartTimer(&LqrTimer);
|
||||
if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
|
||||
timer_Start(&p->hdlc.lqm.timer);
|
||||
}
|
||||
|
||||
void
|
||||
LqrInput(struct mbuf * bp)
|
||||
lqr_Input(struct physical *physical, struct mbuf *bp)
|
||||
{
|
||||
int len;
|
||||
u_char *cp;
|
||||
struct lqrdata *lqr;
|
||||
|
||||
len = plength(bp);
|
||||
if (len != sizeof(struct lqrdata)) {
|
||||
pfree(bp);
|
||||
return;
|
||||
}
|
||||
if (!Acceptable(ConfLqr)) {
|
||||
len = mbuf_Length(bp);
|
||||
if (len != sizeof(struct lqrdata))
|
||||
log_Printf(LogERROR, "lqr_Input: Got packet size %d, expecting %d !\n",
|
||||
len, sizeof(struct lqrdata));
|
||||
else if (!IsAccepted(physical->link.lcp.cfg.lqr) &&
|
||||
!(physical->hdlc.lqm.method & LQM_LQR)) {
|
||||
bp->offset -= 2;
|
||||
bp->cnt += 2;
|
||||
|
||||
cp = MBUF_CTOP(bp);
|
||||
LcpSendProtoRej(cp, bp->cnt);
|
||||
lcp_SendProtoRej(physical->hdlc.lqm.owner, MBUF_CTOP(bp), bp->cnt);
|
||||
} else {
|
||||
cp = MBUF_CTOP(bp);
|
||||
lqr = (struct lqrdata *) cp;
|
||||
if (ntohl(lqr->MagicNumber) != LcpInfo.his_magic) {
|
||||
LogPrintf(LogERROR, "LqrInput: magic %x != expecting %x\n",
|
||||
ntohl(lqr->MagicNumber), LcpInfo.his_magic);
|
||||
pfree(bp);
|
||||
return;
|
||||
}
|
||||
struct lqrdata *lqr;
|
||||
struct lcp *lcp;
|
||||
u_int32_t lastLQR;
|
||||
|
||||
/*
|
||||
* Convert byte order and save into our strage
|
||||
*/
|
||||
LqrChangeOrder(lqr, &HisLqrData);
|
||||
LqrDump("LqrInput", &HisLqrData);
|
||||
lqrsendcnt = 0; /* we have received LQR from peer */
|
||||
lqr = (struct lqrdata *)MBUF_CTOP(bp);
|
||||
lcp = physical->hdlc.lqm.owner;
|
||||
if (ntohl(lqr->MagicNumber) != physical->hdlc.lqm.owner->his_magic)
|
||||
log_Printf(LogERROR, "lqr_Input: magic %x != expecting %x\n",
|
||||
(unsigned)ntohl(lqr->MagicNumber),
|
||||
physical->hdlc.lqm.owner->his_magic);
|
||||
else {
|
||||
/*
|
||||
* Remember our PeerInLQRs, then convert byte order and save
|
||||
*/
|
||||
lastLQR = physical->hdlc.lqm.lqr.peer.PeerInLQRs;
|
||||
|
||||
/*
|
||||
* Generate an LQR response to peer we're not running LQR timer OR
|
||||
* two successive LQR's PeerInLQRs are same OR we're not going to
|
||||
* send our next one before the peers max timeout.
|
||||
*/
|
||||
if (LqrTimer.load == 0 || lastpeerin == HisLqrData.PeerInLQRs ||
|
||||
(LqrTimer.arg &&
|
||||
LqrTimer.rest * 100 / SECTICKS > (u_int32_t)LqrTimer.arg)) {
|
||||
lqmmethod |= LQM_LQR;
|
||||
SendLqrReport(LqrTimer.arg);
|
||||
lqr_ChangeOrder(lqr, &physical->hdlc.lqm.lqr.peer);
|
||||
lqr_Dump(physical->link.name, "Input", &physical->hdlc.lqm.lqr.peer);
|
||||
/* we have received an LQR from peer */
|
||||
physical->hdlc.lqm.lqr.resent = 0;
|
||||
|
||||
/*
|
||||
* Generate an LQR response if we're not running an LQR timer OR
|
||||
* two successive LQR's PeerInLQRs are the same OR we're not going to
|
||||
* send our next one before the peers max timeout.
|
||||
*/
|
||||
if (physical->hdlc.lqm.timer.load == 0 ||
|
||||
!(physical->hdlc.lqm.method & LQM_LQR) ||
|
||||
(lastLQR && lastLQR == physical->hdlc.lqm.lqr.peer.PeerInLQRs) ||
|
||||
(physical->hdlc.lqm.lqr.peer_timeout &&
|
||||
physical->hdlc.lqm.timer.rest * 100 / SECTICKS >
|
||||
physical->hdlc.lqm.lqr.peer_timeout))
|
||||
SendLqrData(physical->hdlc.lqm.owner);
|
||||
}
|
||||
lastpeerin = HisLqrData.PeerInLQRs;
|
||||
}
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* When LCP is reached to opened state, We'll start LQM activity.
|
||||
*/
|
||||
void
|
||||
StartLqm()
|
||||
|
||||
static void
|
||||
lqr_Setup(struct lcp *lcp)
|
||||
{
|
||||
struct lcpstate *lcp = &LcpInfo;
|
||||
struct physical *physical = link2physical(lcp->fsm.link);
|
||||
|
||||
lqrsendcnt = 0; /* start waiting all over for ECHOs */
|
||||
echoseq = 0;
|
||||
gotseq = 0;
|
||||
memset(&HisLqrData, '\0', sizeof HisLqrData);
|
||||
physical->hdlc.lqm.lqr.resent = 0;
|
||||
physical->hdlc.lqm.echo.seq_sent = 0;
|
||||
physical->hdlc.lqm.echo.seq_recv = 0;
|
||||
memset(&physical->hdlc.lqm.lqr.peer, '\0',
|
||||
sizeof physical->hdlc.lqm.lqr.peer);
|
||||
|
||||
lqmmethod = LQM_ECHO;
|
||||
if (Enabled(ConfLqr) && !REJECTED(lcp, TY_QUALPROTO))
|
||||
lqmmethod |= LQM_LQR;
|
||||
StopTimer(&LqrTimer);
|
||||
physical->hdlc.lqm.method = LQM_ECHO;
|
||||
if (IsEnabled(lcp->cfg.lqr) && !REJECTED(lcp, TY_QUALPROTO))
|
||||
physical->hdlc.lqm.method |= LQM_LQR;
|
||||
timer_Stop(&physical->hdlc.lqm.timer);
|
||||
|
||||
physical->hdlc.lqm.lqr.peer_timeout = lcp->his_lqrperiod;
|
||||
if (lcp->his_lqrperiod)
|
||||
LogPrintf(LogLQM, "Expecting LQR every %d.%02d secs\n",
|
||||
lcp->his_lqrperiod / 100, lcp->his_lqrperiod % 100);
|
||||
log_Printf(LogLQM, "%s: Expecting LQR every %d.%02d secs\n",
|
||||
physical->link.name, lcp->his_lqrperiod / 100,
|
||||
lcp->his_lqrperiod % 100);
|
||||
|
||||
if (lcp->want_lqrperiod) {
|
||||
LogPrintf(LogLQM, "Will send %s every %d.%02d secs\n",
|
||||
lqmmethod & LQM_LQR ? "LQR" : "ECHO LQR",
|
||||
lcp->want_lqrperiod / 100, lcp->want_lqrperiod % 100);
|
||||
LqrTimer.state = TIMER_STOPPED;
|
||||
LqrTimer.load = lcp->want_lqrperiod * SECTICKS / 100;
|
||||
LqrTimer.func = SendLqrReport;
|
||||
LqrTimer.arg = (void *)lcp->his_lqrperiod;
|
||||
SendLqrReport(LqrTimer.arg);
|
||||
log_Printf(LogLQM, "%s: Will send %s every %d.%02d secs\n",
|
||||
physical->link.name,
|
||||
physical->hdlc.lqm.method & LQM_LQR ? "LQR" : "ECHO LQR",
|
||||
lcp->want_lqrperiod / 100, lcp->want_lqrperiod % 100);
|
||||
physical->hdlc.lqm.timer.load = lcp->want_lqrperiod * SECTICKS / 100;
|
||||
physical->hdlc.lqm.timer.func = SendLqrReport;
|
||||
physical->hdlc.lqm.timer.name = "lqm";
|
||||
physical->hdlc.lqm.timer.arg = lcp;
|
||||
} else {
|
||||
LqrTimer.load = 0;
|
||||
physical->hdlc.lqm.timer.load = 0;
|
||||
if (!lcp->his_lqrperiod)
|
||||
LogPrintf(LogLQM, "LQR/ECHO LQR not negotiated\n");
|
||||
log_Printf(LogLQM, "%s: LQR/ECHO LQR not negotiated\n",
|
||||
physical->link.name);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
StopLqrTimer()
|
||||
lqr_Start(struct lcp *lcp)
|
||||
{
|
||||
StopTimer(&LqrTimer);
|
||||
struct physical *p = link2physical(lcp->fsm.link);
|
||||
|
||||
lqr_Setup(lcp);
|
||||
if (p->hdlc.lqm.timer.load)
|
||||
SendLqrReport(lcp);
|
||||
}
|
||||
|
||||
void
|
||||
StopLqr(int method)
|
||||
lqr_reStart(struct lcp *lcp)
|
||||
{
|
||||
LogPrintf(LogLQM, "StopLqr method = %x\n", method);
|
||||
struct physical *p = link2physical(lcp->fsm.link);
|
||||
|
||||
lqr_Setup(lcp);
|
||||
if (p->hdlc.lqm.timer.load)
|
||||
timer_Start(&p->hdlc.lqm.timer);
|
||||
}
|
||||
|
||||
void
|
||||
lqr_StopTimer(struct physical *physical)
|
||||
{
|
||||
timer_Stop(&physical->hdlc.lqm.timer);
|
||||
}
|
||||
|
||||
void
|
||||
lqr_Stop(struct physical *physical, int method)
|
||||
{
|
||||
if (method == LQM_LQR)
|
||||
LogPrintf(LogLQM, "Stop sending LQR, Use LCP ECHO instead.\n");
|
||||
log_Printf(LogLQM, "%s: Stop sending LQR, Use LCP ECHO instead.\n",
|
||||
physical->link.name);
|
||||
if (method == LQM_ECHO)
|
||||
LogPrintf(LogLQM, "Stop sending LCP ECHO.\n");
|
||||
lqmmethod &= ~method;
|
||||
if (lqmmethod)
|
||||
SendLqrReport(LqrTimer.arg);
|
||||
log_Printf(LogLQM, "%s: Stop sending LCP ECHO.\n",
|
||||
physical->link.name);
|
||||
physical->hdlc.lqm.method &= ~method;
|
||||
if (physical->hdlc.lqm.method)
|
||||
SendLqrReport(physical->hdlc.lqm.owner);
|
||||
else
|
||||
StopTimer(&LqrTimer);
|
||||
timer_Stop(&physical->hdlc.lqm.timer);
|
||||
}
|
||||
|
||||
void
|
||||
LqrDump(const char *message, const struct lqrdata * lqr)
|
||||
lqr_Dump(const char *link, const char *message, const struct lqrdata *lqr)
|
||||
{
|
||||
if (LogIsKept(LogLQM)) {
|
||||
LogPrintf(LogLQM, "%s:\n", message);
|
||||
LogPrintf(LogLQM, " Magic: %08x LastOutLQRs: %08x\n",
|
||||
if (log_IsKept(LogLQM)) {
|
||||
log_Printf(LogLQM, "%s: %s:\n", link, message);
|
||||
log_Printf(LogLQM, " Magic: %08x LastOutLQRs: %08x\n",
|
||||
lqr->MagicNumber, lqr->LastOutLQRs);
|
||||
LogPrintf(LogLQM, " LastOutPackets: %08x LastOutOctets: %08x\n",
|
||||
log_Printf(LogLQM, " LastOutPackets: %08x LastOutOctets: %08x\n",
|
||||
lqr->LastOutPackets, lqr->LastOutOctets);
|
||||
LogPrintf(LogLQM, " PeerInLQRs: %08x PeerInPackets: %08x\n",
|
||||
log_Printf(LogLQM, " PeerInLQRs: %08x PeerInPackets: %08x\n",
|
||||
lqr->PeerInLQRs, lqr->PeerInPackets);
|
||||
LogPrintf(LogLQM, " PeerInDiscards: %08x PeerInErrors: %08x\n",
|
||||
log_Printf(LogLQM, " PeerInDiscards: %08x PeerInErrors: %08x\n",
|
||||
lqr->PeerInDiscards, lqr->PeerInErrors);
|
||||
LogPrintf(LogLQM, " PeerInOctets: %08x PeerOutLQRs: %08x\n",
|
||||
log_Printf(LogLQM, " PeerInOctets: %08x PeerOutLQRs: %08x\n",
|
||||
lqr->PeerInOctets, lqr->PeerOutLQRs);
|
||||
LogPrintf(LogLQM, " PeerOutPackets: %08x PeerOutOctets: %08x\n",
|
||||
log_Printf(LogLQM, " PeerOutPackets: %08x PeerOutOctets: %08x\n",
|
||||
lqr->PeerOutPackets, lqr->PeerOutOctets);
|
||||
}
|
||||
}
|
||||
|
@ -15,50 +15,45 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lqr.h,v 1.11 1998/01/11 17:50:42 brian Exp $
|
||||
* $Id: lqr.h,v 1.12.2.6 1998/05/08 01:15:09 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure of LQR packet defined in RFC1333
|
||||
* Structure of LQR packet defined in RFC1989
|
||||
*/
|
||||
struct lqrdata {
|
||||
u_int32_t MagicNumber;
|
||||
u_int32_t LastOutLQRs;
|
||||
u_int32_t LastOutPackets;
|
||||
u_int32_t LastOutOctets;
|
||||
u_int32_t PeerInLQRs;
|
||||
u_int32_t PeerInPackets;
|
||||
u_int32_t PeerInDiscards;
|
||||
u_int32_t PeerInErrors;
|
||||
u_int32_t PeerInOctets;
|
||||
u_int32_t PeerOutLQRs;
|
||||
u_int32_t PeerOutPackets;
|
||||
u_int32_t PeerOutOctets;
|
||||
u_int32_t LastOutLQRs; /* most recently received PeerOutLQRs */
|
||||
u_int32_t LastOutPackets; /* most recently received PeerOutPackets */
|
||||
u_int32_t LastOutOctets; /* most recently received PeerOutOctets */
|
||||
u_int32_t PeerInLQRs; /* Peers SaveInLQRs */
|
||||
u_int32_t PeerInPackets; /* Peers SaveInPackets */
|
||||
u_int32_t PeerInDiscards; /* Peers SaveInDiscards */
|
||||
u_int32_t PeerInErrors; /* Peers SaveInErrors */
|
||||
u_int32_t PeerInOctets; /* Peers SaveInOctets */
|
||||
u_int32_t PeerOutLQRs; /* Peers OutLQRs (hdlc.h) */
|
||||
u_int32_t PeerOutPackets; /* Peers OutPackets (hdlc.h) */
|
||||
u_int32_t PeerOutOctets; /* Peers OutOctets (hdlc.h) */
|
||||
};
|
||||
|
||||
struct lqrsave {
|
||||
u_int32_t SaveInLQRs;
|
||||
u_int32_t SaveInPackets;
|
||||
u_int32_t SaveInDiscards;
|
||||
u_int32_t SaveInErrors;
|
||||
u_int32_t SaveInOctets;
|
||||
};
|
||||
|
||||
extern struct lqrdata MyLqrData, HisLqrData;
|
||||
extern struct lqrsave HisLqrSave;
|
||||
|
||||
/*
|
||||
* We support LQR and ECHO as LQM method
|
||||
*/
|
||||
#define LQM_LQR 1
|
||||
#define LQM_ECHO 2
|
||||
|
||||
extern void LqrDump(const char *, const struct lqrdata *);
|
||||
extern void LqrChangeOrder(struct lqrdata *, struct lqrdata *);
|
||||
extern void StartLqm(void);
|
||||
extern void StopLqr(int);
|
||||
extern void StopLqrTimer(void);
|
||||
extern void RecvEchoLqr(struct mbuf *);
|
||||
extern void LqrInput(struct mbuf *);
|
||||
struct mbuf;
|
||||
struct physical;
|
||||
struct lcp;
|
||||
struct fsm;
|
||||
|
||||
extern void lqr_Dump(const char *, const char *, const struct lqrdata *);
|
||||
extern void lqr_ChangeOrder(struct lqrdata *, struct lqrdata *);
|
||||
extern void lqr_Start(struct lcp *);
|
||||
extern void lqr_reStart(struct lcp *);
|
||||
extern void lqr_Stop(struct physical *, int);
|
||||
extern void lqr_StopTimer(struct physical *);
|
||||
extern void lqr_RecvEcho(struct fsm *, struct mbuf *);
|
||||
extern void lqr_Input(struct physical *, struct mbuf *);
|
||||
|
1116
usr.sbin/ppp/main.c
1116
usr.sbin/ppp/main.c
File diff suppressed because it is too large
Load Diff
@ -17,15 +17,9 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: main.h,v 1.8 1997/11/22 03:37:39 brian Exp $
|
||||
* $Id: main.h,v 1.9.2.9 1998/04/07 00:54:08 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
extern int TermMode;
|
||||
extern int tunno;
|
||||
|
||||
extern void Cleanup(int);
|
||||
extern void TtyTermMode(void);
|
||||
extern void PacketMode(int);
|
||||
extern void TtyOldMode(void);
|
||||
extern void TtyCommandMode(int);
|
||||
extern void AbortProgram(int);
|
||||
|
@ -17,33 +17,33 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: mbuf.c,v 1.12 1997/12/28 02:56:42 brian Exp $
|
||||
* $Id: mbuf.c,v 1.13.2.11 1998/05/01 19:25:19 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sysexits.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "server.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
#include "main.h"
|
||||
|
||||
static struct memmap {
|
||||
struct mbuf *queue;
|
||||
int count;
|
||||
} MemMap[MB_MAX + 2];
|
||||
} MemMap[MB_MAX + 2];
|
||||
|
||||
static int totalalloced;
|
||||
|
||||
int
|
||||
plength(struct mbuf * bp)
|
||||
mbuf_Length(struct mbuf * bp)
|
||||
{
|
||||
int len;
|
||||
|
||||
@ -53,25 +53,23 @@ plength(struct mbuf * bp)
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mballoc(int cnt, int type)
|
||||
mbuf_Alloc(int cnt, int type)
|
||||
{
|
||||
u_char *p;
|
||||
struct mbuf *bp;
|
||||
|
||||
if (type > MB_MAX)
|
||||
LogPrintf(LogERROR, "Bad mbuf type %d\n", type);
|
||||
log_Printf(LogERROR, "Bad mbuf type %d\n", type);
|
||||
bp = (struct mbuf *) malloc(sizeof(struct mbuf));
|
||||
if (bp == NULL) {
|
||||
LogPrintf(LogALERT, "failed to allocate memory: %u\n", sizeof(struct mbuf));
|
||||
ServerClose();
|
||||
exit(1);
|
||||
log_Printf(LogALERT, "failed to allocate memory: %u\n", sizeof(struct mbuf));
|
||||
AbortProgram(EX_OSERR);
|
||||
}
|
||||
memset(bp, '\0', sizeof(struct mbuf));
|
||||
p = (u_char *) malloc(cnt);
|
||||
if (p == NULL) {
|
||||
LogPrintf(LogALERT, "failed to allocate memory: %d\n", cnt);
|
||||
ServerClose();
|
||||
exit(1);
|
||||
log_Printf(LogALERT, "failed to allocate memory: %d\n", cnt);
|
||||
AbortProgram(EX_OSERR);
|
||||
}
|
||||
MemMap[type].count += cnt;
|
||||
totalalloced += cnt;
|
||||
@ -83,7 +81,7 @@ mballoc(int cnt, int type)
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbfree(struct mbuf * bp)
|
||||
mbuf_FreeSeg(struct mbuf * bp)
|
||||
{
|
||||
struct mbuf *nbp;
|
||||
|
||||
@ -99,14 +97,14 @@ mbfree(struct mbuf * bp)
|
||||
}
|
||||
|
||||
void
|
||||
pfree(struct mbuf * bp)
|
||||
mbuf_Free(struct mbuf * bp)
|
||||
{
|
||||
while (bp)
|
||||
bp = mbfree(bp);
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbread(struct mbuf * bp, u_char * ptr, int len)
|
||||
mbuf_Read(struct mbuf * bp, u_char * ptr, int len)
|
||||
{
|
||||
int nb;
|
||||
|
||||
@ -124,7 +122,7 @@ mbread(struct mbuf * bp, u_char * ptr, int len)
|
||||
#ifdef notdef
|
||||
bp = bp->next;
|
||||
#else
|
||||
bp = mbfree(bp);
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
@ -132,12 +130,12 @@ mbread(struct mbuf * bp, u_char * ptr, int len)
|
||||
}
|
||||
|
||||
void
|
||||
mbwrite(struct mbuf * bp, u_char * ptr, int cnt)
|
||||
mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt)
|
||||
{
|
||||
int plen;
|
||||
int nb;
|
||||
|
||||
plen = plength(bp);
|
||||
plen = mbuf_Length(bp);
|
||||
if (plen < cnt)
|
||||
cnt = plen;
|
||||
|
||||
@ -150,26 +148,65 @@ mbwrite(struct mbuf * bp, u_char * ptr, int cnt)
|
||||
}
|
||||
|
||||
int
|
||||
ShowMemMap(struct cmdargs const *arg)
|
||||
mbuf_Show(struct cmdargs const *arg)
|
||||
{
|
||||
/* Watch it - ~m calls us with arg == NULL */
|
||||
int i;
|
||||
static const char *mbuftype[] = {
|
||||
"async", "fsm", "hdlcout", "ipin", "echo", "lqr", "link", "vjcomp",
|
||||
"ipq", "mp" };
|
||||
|
||||
if (!VarTerm)
|
||||
return 1;
|
||||
for (i = 1; i < MB_MAX; i += 2)
|
||||
prompt_Printf(arg->prompt, "%10.10s: %04d\t%10.10s: %04d\n",
|
||||
mbuftype[i-1], MemMap[i].count, mbuftype[i], MemMap[i+1].count);
|
||||
|
||||
for (i = 0; i <= MB_MAX; i += 2)
|
||||
fprintf(VarTerm, "%d: %d %d: %d\n",
|
||||
i, MemMap[i].count, i + 1, MemMap[i + 1].count);
|
||||
if (i == MB_MAX)
|
||||
prompt_Printf(arg->prompt, "%10.10s: %04d\n",
|
||||
mbuftype[i-1], MemMap[i].count);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
LogMemory()
|
||||
mbuf_Log()
|
||||
{
|
||||
LogPrintf(LogDEBUG, "LogMemory: mem alloced: %d\n", totalalloced);
|
||||
LogPrintf(LogDEBUG, "LogMemory: 1: %d 2: %d 3: %d 4: %d\n",
|
||||
log_Printf(LogDEBUG, "mbuf_Log: mem alloced: %d\n", totalalloced);
|
||||
log_Printf(LogDEBUG, "mbuf_Log: 1: %d 2: %d 3: %d 4: %d\n",
|
||||
MemMap[1].count, MemMap[2].count, MemMap[3].count, MemMap[4].count);
|
||||
LogPrintf(LogDEBUG, "LogMemory: 5: %d 6: %d 7: %d 8: %d\n",
|
||||
log_Printf(LogDEBUG, "mbuf_Log: 5: %d 6: %d 7: %d 8: %d\n",
|
||||
MemMap[5].count, MemMap[6].count, MemMap[7].count, MemMap[8].count);
|
||||
log_Printf(LogDEBUG, "mbuf_Log: 9: %d 10: %d\n",
|
||||
MemMap[9].count, MemMap[10].count);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_Dequeue(struct mqueue *q)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
|
||||
log_Printf(LogDEBUG, "mbuf_Dequeue: queue len = %d\n", q->qlen);
|
||||
bp = q->top;
|
||||
if (bp) {
|
||||
q->top = q->top->pnext;
|
||||
q->qlen--;
|
||||
if (q->top == NULL) {
|
||||
q->last = q->top;
|
||||
if (q->qlen)
|
||||
log_Printf(LogERROR, "mbuf_Dequeue: Not zero (%d)!!!\n", q->qlen);
|
||||
}
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
void
|
||||
mbuf_Enqueue(struct mqueue *queue, struct mbuf *bp)
|
||||
{
|
||||
if (queue->last) {
|
||||
queue->last->pnext = bp;
|
||||
queue->last = bp;
|
||||
} else
|
||||
queue->last = queue->top = bp;
|
||||
queue->qlen++;
|
||||
log_Printf(LogDEBUG, "mbuf_Enqueue: len = %d\n", queue->qlen);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: mbuf.h,v 1.10 1997/12/03 10:23:50 brian Exp $
|
||||
* $Id: mbuf.h,v 1.11.2.5 1998/05/01 19:25:24 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -44,17 +44,21 @@ struct mqueue {
|
||||
#define MB_IPIN 4
|
||||
#define MB_ECHO 5
|
||||
#define MB_LQR 6
|
||||
#define MB_MODEM 7
|
||||
#define MB_LINK 7
|
||||
#define MB_VJCOMP 8
|
||||
#define MB_LOG 9
|
||||
#define MB_IPQ 10
|
||||
#define MB_MAX MB_IPQ
|
||||
#define MB_IPQ 9
|
||||
#define MB_MP 10
|
||||
#define MB_MAX MB_MP
|
||||
|
||||
extern int plength(struct mbuf *);
|
||||
extern struct mbuf *mballoc(int, int);
|
||||
extern struct mbuf *mbfree(struct mbuf *);
|
||||
extern void pfree(struct mbuf *);
|
||||
extern void mbwrite(struct mbuf *, u_char *, int);
|
||||
extern struct mbuf *mbread(struct mbuf *, u_char *, int);
|
||||
extern void LogMemory(void);
|
||||
extern int ShowMemMap(struct cmdargs const *);
|
||||
struct cmdargs;
|
||||
|
||||
extern int mbuf_Length(struct mbuf *);
|
||||
extern struct mbuf *mbuf_Alloc(int, int);
|
||||
extern struct mbuf *mbuf_FreeSeg(struct mbuf *);
|
||||
extern void mbuf_Free(struct mbuf *);
|
||||
extern void mbuf_Write(struct mbuf *, u_char *, int);
|
||||
extern struct mbuf *mbuf_Read(struct mbuf *, u_char *, int);
|
||||
extern void mbuf_Log(void);
|
||||
extern int mbuf_Show(struct cmdargs const *);
|
||||
extern void mbuf_Enqueue(struct mqueue *, struct mbuf *);
|
||||
extern struct mbuf *mbuf_Dequeue(struct mqueue *);
|
||||
|
1127
usr.sbin/ppp/modem.c
1127
usr.sbin/ppp/modem.c
File diff suppressed because it is too large
Load Diff
@ -15,27 +15,28 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: modem.h,v 1.15 1998/01/10 01:55:11 brian Exp $
|
||||
* $Id: modem.h,v 1.16.2.17 1998/05/02 21:57:49 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
extern int RawModem(void);
|
||||
extern void WriteModem(int, const char *, int);
|
||||
extern void ModemStartOutput(int);
|
||||
extern int OpenModem(void);
|
||||
extern int ModemSpeed(void);
|
||||
extern int ModemQlen(void);
|
||||
extern int DialModem(void);
|
||||
struct iovec;
|
||||
struct datalink;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
struct ccp;
|
||||
struct cmdargs;
|
||||
|
||||
extern int modem_Raw(struct physical *, struct bundle *);
|
||||
extern struct physical *modem_Create(struct datalink *, int);
|
||||
extern int modem_Open(struct physical *, struct bundle *);
|
||||
extern int modem_Speed(struct physical *);
|
||||
extern speed_t IntToSpeed(int);
|
||||
extern void ModemTimeout(void *v);
|
||||
extern void DownConnection(void);
|
||||
extern void ModemOutput(int, struct mbuf *);
|
||||
extern int ChangeParity(const char *);
|
||||
extern void HangupModem(int);
|
||||
extern int ShowModemStatus(struct cmdargs const *);
|
||||
extern void Enqueue(struct mqueue *, struct mbuf *);
|
||||
extern struct mbuf *Dequeue(struct mqueue *);
|
||||
extern void SequenceQueues(void);
|
||||
extern void ModemAddInOctets(int);
|
||||
extern void ModemAddOutOctets(int);
|
||||
extern int modem_SetParity(struct physical *, const char *);
|
||||
extern int modem_ShowStatus(struct cmdargs const *);
|
||||
extern void modem_Close(struct physical *);
|
||||
extern void modem_Offline(struct physical *);
|
||||
extern void modem_Destroy(struct physical *);
|
||||
extern struct physical *iov2modem(struct datalink *, struct iovec *, int *,
|
||||
int, int);
|
||||
extern int modem2iov(struct physical *, struct iovec *, int *, int);
|
||||
|
992
usr.sbin/ppp/mp.c
Normal file
992
usr.sbin/ppp/mp.c
Normal file
@ -0,0 +1,992 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: mp.c,v 1.1.2.29 1998/05/15 18:21:41 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <paths.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "auth.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "async.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "chat.h"
|
||||
#include "lcpproto.h"
|
||||
#include "filter.h"
|
||||
#include "mp.h"
|
||||
#include "chap.h"
|
||||
#include "datalink.h"
|
||||
#include "bundle.h"
|
||||
#include "ip.h"
|
||||
#include "prompt.h"
|
||||
#include "id.h"
|
||||
#include "arp.h"
|
||||
|
||||
void
|
||||
peerid_Init(struct peerid *peer)
|
||||
{
|
||||
peer->enddisc.class = 0;
|
||||
*peer->enddisc.address = '\0';
|
||||
peer->enddisc.len = 0;
|
||||
*peer->authname = '\0';
|
||||
}
|
||||
|
||||
int
|
||||
peerid_Equal(const struct peerid *p1, const struct peerid *p2)
|
||||
{
|
||||
return !strcmp(p1->authname, p2->authname) &&
|
||||
p1->enddisc.class == p2->enddisc.class &&
|
||||
p1->enddisc.len == p2->enddisc.len &&
|
||||
!memcmp(p1->enddisc.address, p2->enddisc.address, p1->enddisc.len);
|
||||
}
|
||||
|
||||
static u_int32_t
|
||||
inc_seq(unsigned is12bit, u_int32_t seq)
|
||||
{
|
||||
seq++;
|
||||
if (is12bit) {
|
||||
if (seq & 0xfffff000)
|
||||
seq = 0;
|
||||
} else if (seq & 0xff000000)
|
||||
seq = 0;
|
||||
return seq;
|
||||
}
|
||||
|
||||
static int
|
||||
isbefore(unsigned is12bit, u_int32_t seq1, u_int32_t seq2)
|
||||
{
|
||||
u_int32_t max = (is12bit ? 0xfff : 0xffffff) - 0x200;
|
||||
|
||||
if (seq1 > max) {
|
||||
if (seq2 < 0x200 || seq2 > seq1)
|
||||
return 1;
|
||||
} else if ((seq1 > 0x200 || seq2 <= max) && seq1 < seq2)
|
||||
return 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mp_ReadHeader(struct mp *mp, struct mbuf *m, struct mp_header *header)
|
||||
{
|
||||
if (mp->local_is12bit) {
|
||||
header->seq = ntohs(*(u_int16_t *)MBUF_CTOP(m));
|
||||
if (header->seq & 0x3000) {
|
||||
log_Printf(LogWARN, "Oops - MP header without required zero bits\n");
|
||||
return 0;
|
||||
}
|
||||
header->begin = header->seq & 0x8000 ? 1 : 0;
|
||||
header->end = header->seq & 0x4000 ? 1 : 0;
|
||||
header->seq &= 0x0fff;
|
||||
return 2;
|
||||
} else {
|
||||
header->seq = ntohl(*(u_int32_t *)MBUF_CTOP(m));
|
||||
if (header->seq & 0x3f000000) {
|
||||
log_Printf(LogWARN, "Oops - MP header without required zero bits\n");
|
||||
return 0;
|
||||
}
|
||||
header->begin = header->seq & 0x80000000 ? 1 : 0;
|
||||
header->end = header->seq & 0x40000000 ? 1 : 0;
|
||||
header->seq &= 0x00ffffff;
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mp_LayerStart(void *v, struct fsm *fp)
|
||||
{
|
||||
/* The given FSM (ccp) is about to start up ! */
|
||||
}
|
||||
|
||||
static void
|
||||
mp_LayerUp(void *v, struct fsm *fp)
|
||||
{
|
||||
/* The given fsm (ccp) is now up */
|
||||
}
|
||||
|
||||
static void
|
||||
mp_LayerDown(void *v, struct fsm *fp)
|
||||
{
|
||||
/* The given FSM (ccp) has been told to come down */
|
||||
}
|
||||
|
||||
static void
|
||||
mp_LayerFinish(void *v, struct fsm *fp)
|
||||
{
|
||||
/* The given fsm (ccp) is now down */
|
||||
if (fp->state == ST_CLOSED && fp->open_mode == OPEN_PASSIVE)
|
||||
fsm_Open(fp); /* CCP goes to ST_STOPPED */
|
||||
}
|
||||
|
||||
void
|
||||
mp_Init(struct mp *mp, struct bundle *bundle)
|
||||
{
|
||||
mp->peer_is12bit = mp->local_is12bit = 0;
|
||||
mp->peer_mrru = mp->local_mrru = 0;
|
||||
|
||||
peerid_Init(&mp->peer);
|
||||
|
||||
mp->out.seq = 0;
|
||||
mp->out.link = 0;
|
||||
mp->seq.min_in = 0;
|
||||
mp->seq.next_in = 0;
|
||||
mp->inbufs = NULL;
|
||||
mp->bundle = bundle;
|
||||
|
||||
mp->link.type = MP_LINK;
|
||||
mp->link.name = "mp";
|
||||
mp->link.len = sizeof *mp;
|
||||
|
||||
throughput_init(&mp->link.throughput);
|
||||
memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
|
||||
memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
|
||||
memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
|
||||
|
||||
mp->fsmp.LayerStart = mp_LayerStart;
|
||||
mp->fsmp.LayerUp = mp_LayerUp;
|
||||
mp->fsmp.LayerDown = mp_LayerDown;
|
||||
mp->fsmp.LayerFinish = mp_LayerFinish;
|
||||
mp->fsmp.object = mp;
|
||||
|
||||
mpserver_Init(&mp->server);
|
||||
|
||||
mp->cfg.mrru = 0;
|
||||
mp->cfg.shortseq = NEG_ENABLED|NEG_ACCEPTED;
|
||||
mp->cfg.enddisc.class = 0;
|
||||
*mp->cfg.enddisc.address = '\0';
|
||||
mp->cfg.enddisc.len = 0;
|
||||
|
||||
lcp_Init(&mp->link.lcp, mp->bundle, &mp->link, NULL);
|
||||
ccp_Init(&mp->link.ccp, mp->bundle, &mp->link, &mp->fsmp);
|
||||
}
|
||||
|
||||
int
|
||||
mp_Up(struct mp *mp, struct datalink *dl)
|
||||
{
|
||||
struct lcp *lcp = &dl->physical->link.lcp;
|
||||
|
||||
if (mp->active) {
|
||||
/* We're adding a link - do a last validation on our parameters */
|
||||
if (!peerid_Equal(&dl->peer, &mp->peer)) {
|
||||
log_Printf(LogPHASE, "%s: Inappropriate peer !\n", dl->name);
|
||||
return MP_FAILED;
|
||||
}
|
||||
if (mp->local_mrru != lcp->want_mrru ||
|
||||
mp->peer_mrru != lcp->his_mrru ||
|
||||
mp->local_is12bit != lcp->want_shortseq ||
|
||||
mp->peer_is12bit != lcp->his_shortseq) {
|
||||
log_Printf(LogPHASE, "%s: Invalid MRRU/SHORTSEQ MP parameters !\n",
|
||||
dl->name);
|
||||
return MP_FAILED;
|
||||
}
|
||||
return MP_ADDED;
|
||||
} else {
|
||||
/* First link in multilink mode */
|
||||
|
||||
mp->local_mrru = lcp->want_mrru;
|
||||
mp->peer_mrru = lcp->his_mrru;
|
||||
mp->local_is12bit = lcp->want_shortseq;
|
||||
mp->peer_is12bit = lcp->his_shortseq;
|
||||
mp->peer = dl->peer;
|
||||
|
||||
throughput_init(&mp->link.throughput);
|
||||
memset(mp->link.Queue, '\0', sizeof mp->link.Queue);
|
||||
memset(mp->link.proto_in, '\0', sizeof mp->link.proto_in);
|
||||
memset(mp->link.proto_out, '\0', sizeof mp->link.proto_out);
|
||||
|
||||
mp->out.seq = 0;
|
||||
mp->out.link = 0;
|
||||
mp->seq.min_in = 0;
|
||||
mp->seq.next_in = 0;
|
||||
|
||||
/*
|
||||
* Now we create our server socket.
|
||||
* If it already exists, join it. Otherwise, create and own it
|
||||
*/
|
||||
switch (mpserver_Open(&mp->server, &mp->peer)) {
|
||||
case MPSERVER_CONNECTED:
|
||||
log_Printf(LogPHASE, "mp: Transfer link on %s\n",
|
||||
mp->server.socket.sun_path);
|
||||
mp->server.send.dl = dl; /* Defer 'till it's safe to send */
|
||||
return MP_LINKSENT;
|
||||
case MPSERVER_FAILED:
|
||||
return MP_FAILED;
|
||||
case MPSERVER_LISTENING:
|
||||
log_Printf(LogPHASE, "mp: Listening on %s\n", mp->server.socket.sun_path);
|
||||
log_Printf(LogPHASE, " First link: %s\n", dl->name);
|
||||
|
||||
/* Re-point our IPCP layer at our MP link */
|
||||
ipcp_SetLink(&mp->bundle->ncp.ipcp, &mp->link);
|
||||
|
||||
/* Our lcp's already up 'cos of the NULL parent */
|
||||
fsm_Up(&mp->link.ccp.fsm);
|
||||
fsm_Open(&mp->link.ccp.fsm);
|
||||
|
||||
mp->active = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return MP_UP;
|
||||
}
|
||||
|
||||
void
|
||||
mp_Down(struct mp *mp)
|
||||
{
|
||||
if (mp->active) {
|
||||
struct mbuf *next;
|
||||
|
||||
/* Don't want any more of these */
|
||||
mpserver_Close(&mp->server);
|
||||
|
||||
/* CCP goes down with a bang */
|
||||
fsm_Down(&mp->link.ccp.fsm);
|
||||
fsm_Close(&mp->link.ccp.fsm);
|
||||
|
||||
/* Received fragments go in the bit-bucket */
|
||||
while (mp->inbufs) {
|
||||
next = mp->inbufs->pnext;
|
||||
mbuf_Free(mp->inbufs);
|
||||
mp->inbufs = next;
|
||||
}
|
||||
|
||||
peerid_Init(&mp->peer);
|
||||
mp->active = 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
mp_linkInit(struct mp_link *mplink)
|
||||
{
|
||||
mplink->seq = 0;
|
||||
mplink->weight = 1500;
|
||||
}
|
||||
|
||||
void
|
||||
mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
|
||||
{
|
||||
struct mp_header mh, h;
|
||||
struct mbuf *q, *last;
|
||||
int32_t seq;
|
||||
|
||||
if (mp_ReadHeader(mp, m, &mh) == 0) {
|
||||
mbuf_Free(m);
|
||||
return;
|
||||
}
|
||||
|
||||
seq = p->dl->mp.seq;
|
||||
p->dl->mp.seq = mh.seq;
|
||||
if (mp->seq.min_in == seq) {
|
||||
/*
|
||||
* We've received new data on the link that has our min (oldest) seq.
|
||||
* Figure out which link now has the smallest (oldest) seq.
|
||||
*/
|
||||
struct datalink *dl;
|
||||
|
||||
mp->seq.min_in = p->dl->mp.seq;
|
||||
for (dl = mp->bundle->links; dl; dl = dl->next)
|
||||
if (mp->seq.min_in > dl->mp.seq)
|
||||
mp->seq.min_in = dl->mp.seq;
|
||||
}
|
||||
|
||||
/*
|
||||
* Now process as many of our fragments as we can, adding our new
|
||||
* fragment in as we go, and ordering with the oldest at the top of
|
||||
* the queue.
|
||||
*/
|
||||
|
||||
if (!mp->inbufs) {
|
||||
mp->inbufs = m;
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
last = NULL;
|
||||
seq = mp->seq.next_in;
|
||||
q = mp->inbufs;
|
||||
while (q) {
|
||||
mp_ReadHeader(mp, q, &h);
|
||||
if (m && isbefore(mp->local_is12bit, mh.seq, h.seq)) {
|
||||
/* Our received fragment fits in before this one, so link it in */
|
||||
if (last)
|
||||
last->pnext = m;
|
||||
else
|
||||
mp->inbufs = m;
|
||||
m->pnext = q;
|
||||
q = m;
|
||||
h = mh;
|
||||
m = NULL;
|
||||
}
|
||||
|
||||
if (h.seq != seq) {
|
||||
/* we're missing something :-( */
|
||||
if (mp->seq.min_in > seq) {
|
||||
/* we're never gonna get it */
|
||||
struct mbuf *next;
|
||||
|
||||
/* Zap all older fragments */
|
||||
while (mp->inbufs != q) {
|
||||
log_Printf(LogDEBUG, "Drop frag\n");
|
||||
next = mp->inbufs->pnext;
|
||||
mbuf_Free(mp->inbufs);
|
||||
mp->inbufs = next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Zap everything until the next `end' fragment OR just before
|
||||
* the next `begin' fragment OR 'till seq.min_in - whichever
|
||||
* comes first.
|
||||
*/
|
||||
do {
|
||||
mp_ReadHeader(mp, mp->inbufs, &h);
|
||||
if (h.begin) {
|
||||
/* We might be able to process this ! */
|
||||
h.seq--; /* We're gonna look for fragment with h.seq+1 */
|
||||
break;
|
||||
}
|
||||
next = mp->inbufs->pnext;
|
||||
log_Printf(LogDEBUG, "Drop frag %u\n", h.seq);
|
||||
mbuf_Free(mp->inbufs);
|
||||
mp->inbufs = next;
|
||||
} while (mp->inbufs && (h.seq >= mp->seq.min_in || h.end));
|
||||
|
||||
/*
|
||||
* Continue processing things from here.
|
||||
* This deals with the possibility that we received a fragment
|
||||
* on the slowest link that invalidates some of our data (because
|
||||
* of the hole at `q'), but where there are subsequent `whole'
|
||||
* packets that have already been received.
|
||||
*/
|
||||
|
||||
mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
|
||||
last = NULL;
|
||||
q = mp->inbufs;
|
||||
} else
|
||||
/* we may still receive the missing fragment */
|
||||
break;
|
||||
} else if (h.end) {
|
||||
/* We've got something, reassemble */
|
||||
struct mbuf **frag = &q;
|
||||
int len;
|
||||
u_long first = -1;
|
||||
|
||||
do {
|
||||
*frag = mp->inbufs;
|
||||
mp->inbufs = mp->inbufs->pnext;
|
||||
len = mp_ReadHeader(mp, *frag, &h);
|
||||
if (first == -1)
|
||||
first = h.seq;
|
||||
(*frag)->offset += len;
|
||||
(*frag)->cnt -= len;
|
||||
(*frag)->pnext = NULL;
|
||||
if (frag == &q && !h.begin) {
|
||||
log_Printf(LogWARN, "Oops - MP frag %lu should have a begin flag\n",
|
||||
(u_long)h.seq);
|
||||
mbuf_Free(q);
|
||||
q = NULL;
|
||||
} else if (frag != &q && h.begin) {
|
||||
log_Printf(LogWARN, "Oops - MP frag %lu should have an end flag\n",
|
||||
(u_long)h.seq - 1);
|
||||
/*
|
||||
* Stuff our fragment back at the front of the queue and zap
|
||||
* our half-assembed packet.
|
||||
*/
|
||||
(*frag)->pnext = mp->inbufs;
|
||||
mp->inbufs = *frag;
|
||||
*frag = NULL;
|
||||
mbuf_Free(q);
|
||||
q = NULL;
|
||||
frag = &q;
|
||||
h.end = 0; /* just in case it's a whole packet */
|
||||
} else
|
||||
do
|
||||
frag = &(*frag)->next;
|
||||
while (*frag != NULL);
|
||||
} while (!h.end);
|
||||
|
||||
if (q) {
|
||||
u_short proto;
|
||||
u_char ch;
|
||||
|
||||
q = mbuf_Read(q, &ch, 1);
|
||||
proto = ch;
|
||||
if (!(proto & 1)) {
|
||||
q = mbuf_Read(q, &ch, 1);
|
||||
proto <<= 8;
|
||||
proto += ch;
|
||||
}
|
||||
if (log_IsKept(LogDEBUG))
|
||||
log_Printf(LogDEBUG, "MP: Reassembled frags %ld-%lu, length %d\n",
|
||||
first, (u_long)h.seq, mbuf_Length(q));
|
||||
hdlc_DecodePacket(mp->bundle, proto, q, &mp->link);
|
||||
}
|
||||
|
||||
mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
|
||||
last = NULL;
|
||||
q = mp->inbufs;
|
||||
} else {
|
||||
/* Look for the next fragment */
|
||||
seq = inc_seq(mp->local_is12bit, seq);
|
||||
last = q;
|
||||
q = q->pnext;
|
||||
}
|
||||
}
|
||||
|
||||
if (m) {
|
||||
/* We still have to find a home for our new fragment */
|
||||
last = NULL;
|
||||
for (q = mp->inbufs; q; last = q, q = q->pnext) {
|
||||
mp_ReadHeader(mp, q, &h);
|
||||
if (isbefore(mp->local_is12bit, mh.seq, h.seq))
|
||||
break;
|
||||
}
|
||||
/* Our received fragment fits in here */
|
||||
if (last)
|
||||
last->pnext = m;
|
||||
else
|
||||
mp->inbufs = m;
|
||||
m->pnext = q;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin,
|
||||
u_int32_t end)
|
||||
{
|
||||
struct mbuf *mo;
|
||||
|
||||
/* Stuff an MP header on the front of our packet and send it */
|
||||
mo = mbuf_Alloc(4, MB_MP);
|
||||
mo->next = m;
|
||||
if (mp->peer_is12bit) {
|
||||
u_int16_t *seq16;
|
||||
|
||||
seq16 = (u_int16_t *)MBUF_CTOP(mo);
|
||||
*seq16 = htons((begin << 15) | (end << 14) | (u_int16_t)mp->out.seq);
|
||||
mo->cnt = 2;
|
||||
} else {
|
||||
u_int32_t *seq32;
|
||||
|
||||
seq32 = (u_int32_t *)MBUF_CTOP(mo);
|
||||
*seq32 = htonl((begin << 31) | (end << 30) | (u_int32_t)mp->out.seq);
|
||||
mo->cnt = 4;
|
||||
}
|
||||
if (log_IsKept(LogDEBUG))
|
||||
log_Printf(LogDEBUG, "MP[frag %d]: Send %d bytes on link `%s'\n",
|
||||
mp->out.seq, mbuf_Length(mo), l->name);
|
||||
mp->out.seq = inc_seq(mp->peer_is12bit, mp->out.seq);
|
||||
|
||||
if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, PROTO_MP, mo))
|
||||
hdlc_Output(l, PRI_NORMAL, PROTO_MP, mo);
|
||||
}
|
||||
|
||||
int
|
||||
mp_FillQueues(struct bundle *bundle)
|
||||
{
|
||||
struct mp *mp = &bundle->ncp.mp;
|
||||
struct datalink *dl, *fdl;
|
||||
int total, add, len, thislink, nlinks;
|
||||
u_int32_t begin, end;
|
||||
struct mbuf *m, *mo;
|
||||
|
||||
thislink = nlinks = 0;
|
||||
for (fdl = NULL, dl = bundle->links; dl; dl = dl->next) {
|
||||
if (!fdl) {
|
||||
if (thislink == mp->out.link)
|
||||
fdl = dl;
|
||||
else
|
||||
thislink++;
|
||||
}
|
||||
nlinks++;
|
||||
}
|
||||
|
||||
if (!fdl) {
|
||||
fdl = bundle->links;
|
||||
if (!fdl)
|
||||
return 0;
|
||||
thislink = 0;
|
||||
}
|
||||
|
||||
total = 0;
|
||||
for (dl = fdl; nlinks > 0; dl = dl->next, nlinks--, thislink++) {
|
||||
if (!dl) {
|
||||
dl = bundle->links;
|
||||
thislink = 0;
|
||||
}
|
||||
|
||||
if (dl->state != DATALINK_OPEN)
|
||||
continue;
|
||||
|
||||
if (dl->physical->out)
|
||||
/* this link has suffered a short write. Let it continue */
|
||||
continue;
|
||||
|
||||
add = link_QueueLen(&dl->physical->link);
|
||||
total += add;
|
||||
if (add)
|
||||
/* this link has got stuff already queued. Let it continue */
|
||||
continue;
|
||||
|
||||
if (!link_QueueLen(&mp->link) && !ip_FlushPacket(&mp->link, bundle))
|
||||
/* Nothing else to send */
|
||||
break;
|
||||
|
||||
m = link_Dequeue(&mp->link);
|
||||
len = mbuf_Length(m);
|
||||
begin = 1;
|
||||
end = 0;
|
||||
|
||||
while (!end) {
|
||||
if (dl->state == DATALINK_OPEN) {
|
||||
if (len <= dl->mp.weight + LINK_MINWEIGHT) {
|
||||
/*
|
||||
* XXX: Should we remember how much of our `weight' wasn't sent
|
||||
* so that we can compensate next time ?
|
||||
*/
|
||||
mo = m;
|
||||
end = 1;
|
||||
} else {
|
||||
mo = mbuf_Alloc(dl->mp.weight, MB_MP);
|
||||
mo->cnt = dl->mp.weight;
|
||||
len -= mo->cnt;
|
||||
m = mbuf_Read(m, MBUF_CTOP(mo), mo->cnt);
|
||||
}
|
||||
mp_Output(mp, &dl->physical->link, mo, begin, end);
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
if (!end) {
|
||||
nlinks--;
|
||||
dl = dl->next;
|
||||
if (!dl) {
|
||||
dl = bundle->links;
|
||||
thislink = 0;
|
||||
} else
|
||||
thislink++;
|
||||
}
|
||||
}
|
||||
}
|
||||
mp->out.link = thislink; /* Start here next time */
|
||||
|
||||
return total;
|
||||
}
|
||||
|
||||
int
|
||||
mp_SetDatalinkWeight(struct cmdargs const *arg)
|
||||
{
|
||||
int val;
|
||||
|
||||
if (arg->argc != arg->argn+1)
|
||||
return -1;
|
||||
|
||||
val = atoi(arg->argv[arg->argn]);
|
||||
if (val < LINK_MINWEIGHT) {
|
||||
log_Printf(LogWARN, "Link weights must not be less than %d\n",
|
||||
LINK_MINWEIGHT);
|
||||
return 1;
|
||||
}
|
||||
arg->cx->mp.weight = val;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
mp_ShowStatus(struct cmdargs const *arg)
|
||||
{
|
||||
struct mp *mp = &arg->bundle->ncp.mp;
|
||||
|
||||
prompt_Printf(arg->prompt, "Multilink is %sactive\n", mp->active ? "" : "in");
|
||||
if (mp->active) {
|
||||
struct mbuf *m;
|
||||
int bufs = 0;
|
||||
|
||||
prompt_Printf(arg->prompt, "Socket: %s\n",
|
||||
mp->server.socket.sun_path);
|
||||
for (m = mp->inbufs; m; m = m->pnext)
|
||||
bufs++;
|
||||
prompt_Printf(arg->prompt, "Pending frags: %d\n", bufs);
|
||||
}
|
||||
|
||||
prompt_Printf(arg->prompt, "\nMy Side:\n");
|
||||
if (mp->active) {
|
||||
prompt_Printf(arg->prompt, " MRRU: %u\n", mp->local_mrru);
|
||||
prompt_Printf(arg->prompt, " Short Seq: %s\n",
|
||||
mp->local_is12bit ? "on" : "off");
|
||||
}
|
||||
prompt_Printf(arg->prompt, " Discriminator: %s\n",
|
||||
mp_Enddisc(mp->cfg.enddisc.class, mp->cfg.enddisc.address,
|
||||
mp->cfg.enddisc.len));
|
||||
|
||||
prompt_Printf(arg->prompt, "\nHis Side:\n");
|
||||
if (mp->active) {
|
||||
prompt_Printf(arg->prompt, " Auth Name: %s\n", mp->peer.authname);
|
||||
prompt_Printf(arg->prompt, " Next SEQ: %u\n", mp->out.seq);
|
||||
prompt_Printf(arg->prompt, " MRRU: %u\n", mp->peer_mrru);
|
||||
prompt_Printf(arg->prompt, " Short Seq: %s\n",
|
||||
mp->peer_is12bit ? "on" : "off");
|
||||
}
|
||||
prompt_Printf(arg->prompt, " Discriminator: %s\n",
|
||||
mp_Enddisc(mp->peer.enddisc.class, mp->peer.enddisc.address,
|
||||
mp->peer.enddisc.len));
|
||||
|
||||
prompt_Printf(arg->prompt, "\nDefaults:\n");
|
||||
|
||||
prompt_Printf(arg->prompt, " MRRU: ");
|
||||
if (mp->cfg.mrru)
|
||||
prompt_Printf(arg->prompt, "%d (multilink enabled)\n", mp->cfg.mrru);
|
||||
else
|
||||
prompt_Printf(arg->prompt, "disabled\n");
|
||||
prompt_Printf(arg->prompt, " Short Seq: %s\n",
|
||||
command_ShowNegval(mp->cfg.shortseq));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const char *
|
||||
mp_Enddisc(u_char c, const char *address, int len)
|
||||
{
|
||||
static char result[100];
|
||||
int f, header;
|
||||
|
||||
switch (c) {
|
||||
case ENDDISC_NULL:
|
||||
sprintf(result, "Null Class");
|
||||
break;
|
||||
|
||||
case ENDDISC_LOCAL:
|
||||
snprintf(result, sizeof result, "Local Addr: %.*s", len, address);
|
||||
break;
|
||||
|
||||
case ENDDISC_IP:
|
||||
if (len == 4)
|
||||
snprintf(result, sizeof result, "IP %s",
|
||||
inet_ntoa(*(const struct in_addr *)address));
|
||||
else
|
||||
sprintf(result, "IP[%d] ???", len);
|
||||
break;
|
||||
|
||||
case ENDDISC_MAC:
|
||||
if (len == 6) {
|
||||
const u_char *m = (const u_char *)address;
|
||||
snprintf(result, sizeof result, "MAC %02x:%02x:%02x:%02x:%02x:%02x",
|
||||
m[0], m[1], m[2], m[3], m[4], m[5]);
|
||||
} else
|
||||
sprintf(result, "MAC[%d] ???", len);
|
||||
break;
|
||||
|
||||
case ENDDISC_MAGIC:
|
||||
sprintf(result, "Magic: 0x");
|
||||
header = strlen(result);
|
||||
if (len > sizeof result - header - 1)
|
||||
len = sizeof result - header - 1;
|
||||
for (f = 0; f < len; f++)
|
||||
sprintf(result + header + 2 * f, "%02x", address[f]);
|
||||
break;
|
||||
|
||||
case ENDDISC_PSN:
|
||||
snprintf(result, sizeof result, "PSN: %.*s", len, address);
|
||||
break;
|
||||
|
||||
default:
|
||||
sprintf(result, "%d: ", (int)c);
|
||||
header = strlen(result);
|
||||
if (len > sizeof result - header - 1)
|
||||
len = sizeof result - header - 1;
|
||||
for (f = 0; f < len; f++)
|
||||
sprintf(result + header + 2 * f, "%02x", address[f]);
|
||||
break;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
mp_SetEnddisc(struct cmdargs const *arg)
|
||||
{
|
||||
struct mp *mp = &arg->bundle->ncp.mp;
|
||||
struct in_addr addr;
|
||||
|
||||
if (bundle_Phase(arg->bundle) != PHASE_DEAD) {
|
||||
log_Printf(LogWARN, "set enddisc: Only available at phase DEAD\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (arg->argc == arg->argn) {
|
||||
mp->cfg.enddisc.class = 0;
|
||||
*mp->cfg.enddisc.address = '\0';
|
||||
mp->cfg.enddisc.len = 0;
|
||||
} else if (arg->argc > arg->argn) {
|
||||
if (!strcasecmp(arg->argv[arg->argn], "label")) {
|
||||
mp->cfg.enddisc.class = ENDDISC_LOCAL;
|
||||
strcpy(mp->cfg.enddisc.address, arg->bundle->cfg.label);
|
||||
mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address);
|
||||
} else if (!strcasecmp(arg->argv[arg->argn], "ip")) {
|
||||
if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY)
|
||||
addr = arg->bundle->ncp.ipcp.cfg.my_range.ipaddr;
|
||||
else
|
||||
addr = arg->bundle->ncp.ipcp.my_ip;
|
||||
memcpy(mp->cfg.enddisc.address, &addr.s_addr, sizeof addr.s_addr);
|
||||
mp->cfg.enddisc.class = ENDDISC_IP;
|
||||
mp->cfg.enddisc.len = sizeof arg->bundle->ncp.ipcp.my_ip.s_addr;
|
||||
} else if (!strcasecmp(arg->argv[arg->argn], "mac")) {
|
||||
struct sockaddr_dl hwaddr;
|
||||
int s;
|
||||
|
||||
if (arg->bundle->ncp.ipcp.my_ip.s_addr == INADDR_ANY)
|
||||
addr = arg->bundle->ncp.ipcp.cfg.my_range.ipaddr;
|
||||
else
|
||||
addr = arg->bundle->ncp.ipcp.my_ip;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
log_Printf(LogERROR, "set enddisc: socket(): %s\n", strerror(errno));
|
||||
return 2;
|
||||
}
|
||||
if (get_ether_addr(s, addr, &hwaddr)) {
|
||||
mp->cfg.enddisc.class = ENDDISC_MAC;
|
||||
memcpy(mp->cfg.enddisc.address, hwaddr.sdl_data + hwaddr.sdl_nlen,
|
||||
hwaddr.sdl_alen);
|
||||
mp->cfg.enddisc.len = hwaddr.sdl_alen;
|
||||
} else {
|
||||
log_Printf(LogWARN, "set enddisc: Can't locate MAC address for %s\n",
|
||||
inet_ntoa(addr));
|
||||
close(s);
|
||||
return 4;
|
||||
}
|
||||
close(s);
|
||||
} else if (!strcasecmp(arg->argv[arg->argn], "magic")) {
|
||||
int f;
|
||||
|
||||
randinit();
|
||||
for (f = 0; f < 20; f += sizeof(long))
|
||||
*(long *)(mp->cfg.enddisc.address + f) = random();
|
||||
mp->cfg.enddisc.class = ENDDISC_MAGIC;
|
||||
mp->cfg.enddisc.len = 20;
|
||||
} else if (!strcasecmp(arg->argv[arg->argn], "psn")) {
|
||||
if (arg->argc > arg->argn+1) {
|
||||
mp->cfg.enddisc.class = ENDDISC_PSN;
|
||||
strcpy(mp->cfg.enddisc.address, arg->argv[arg->argn+1]);
|
||||
mp->cfg.enddisc.len = strlen(mp->cfg.enddisc.address);
|
||||
} else {
|
||||
log_Printf(LogWARN, "PSN endpoint requires additional data\n");
|
||||
return 5;
|
||||
}
|
||||
} else {
|
||||
log_Printf(LogWARN, "%s: Unrecognised endpoint type\n",
|
||||
arg->argv[arg->argn]);
|
||||
return 6;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpserver_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
||||
int *n)
|
||||
{
|
||||
struct mpserver *s = descriptor2mpserver(d);
|
||||
|
||||
if (s->send.dl != NULL) {
|
||||
/* We've connect()ed */
|
||||
if (!link_QueueLen(&s->send.dl->physical->link) &&
|
||||
!s->send.dl->physical->out) {
|
||||
/* Only send if we've transmitted all our data (i.e. the ConfigAck) */
|
||||
datalink_RemoveFromSet(s->send.dl, r, w, e);
|
||||
bundle_SendDatalink(s->send.dl, s->fd, &s->socket);
|
||||
s->send.dl = NULL;
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
} else
|
||||
/* Never read from a datalink that's on death row ! */
|
||||
datalink_RemoveFromSet(s->send.dl, r, NULL, NULL);
|
||||
} else if (r && s->fd >= 0) {
|
||||
if (*n < s->fd + 1)
|
||||
*n = s->fd + 1;
|
||||
FD_SET(s->fd, r);
|
||||
log_Printf(LogTIMER, "mp: fdset(r) %d\n", s->fd);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
mpserver_IsSet(struct descriptor *d, const fd_set *fdset)
|
||||
{
|
||||
struct mpserver *s = descriptor2mpserver(d);
|
||||
return s->fd >= 0 && FD_ISSET(s->fd, fdset);
|
||||
}
|
||||
|
||||
static void
|
||||
mpserver_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
struct mpserver *s = descriptor2mpserver(d);
|
||||
struct sockaddr in;
|
||||
int fd, size;
|
||||
|
||||
size = sizeof in;
|
||||
fd = accept(s->fd, &in, &size);
|
||||
if (fd < 0) {
|
||||
log_Printf(LogERROR, "mpserver_Read: accept(): %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
if (in.sa_family == AF_LOCAL)
|
||||
bundle_ReceiveDatalink(bundle, fd, (struct sockaddr_un *)&in);
|
||||
|
||||
close(fd);
|
||||
}
|
||||
|
||||
static void
|
||||
mpserver_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
/* We never want to write here ! */
|
||||
log_Printf(LogERROR, "mpserver_Write: Internal error: Bad call !\n");
|
||||
}
|
||||
|
||||
void
|
||||
mpserver_Init(struct mpserver *s)
|
||||
{
|
||||
s->desc.type = MPSERVER_DESCRIPTOR;
|
||||
s->desc.next = NULL;
|
||||
s->desc.UpdateSet = mpserver_UpdateSet;
|
||||
s->desc.IsSet = mpserver_IsSet;
|
||||
s->desc.Read = mpserver_Read;
|
||||
s->desc.Write = mpserver_Write;
|
||||
s->send.dl = NULL;
|
||||
s->fd = -1;
|
||||
memset(&s->socket, '\0', sizeof s->socket);
|
||||
}
|
||||
|
||||
int
|
||||
mpserver_Open(struct mpserver *s, struct peerid *peer)
|
||||
{
|
||||
int f, l;
|
||||
mode_t mask;
|
||||
|
||||
if (s->fd != -1) {
|
||||
log_Printf(LogERROR, "Internal error ! mpserver already open\n");
|
||||
mpserver_Close(s);
|
||||
}
|
||||
|
||||
l = snprintf(s->socket.sun_path, sizeof s->socket.sun_path, "%sppp-%s-%02x-",
|
||||
_PATH_VARRUN, peer->authname, peer->enddisc.class);
|
||||
|
||||
for (f = 0; f < peer->enddisc.len && l < sizeof s->socket.sun_path - 2; f++) {
|
||||
snprintf(s->socket.sun_path + l, sizeof s->socket.sun_path - l,
|
||||
"%02x", *(u_char *)(peer->enddisc.address+f));
|
||||
l += 2;
|
||||
}
|
||||
|
||||
s->socket.sun_family = AF_LOCAL;
|
||||
s->socket.sun_len = sizeof s->socket;
|
||||
s->fd = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (s->fd < 0) {
|
||||
log_Printf(LogERROR, "mpserver: socket: %s\n", strerror(errno));
|
||||
return MPSERVER_FAILED;
|
||||
}
|
||||
|
||||
setsockopt(s->fd, SOL_SOCKET, SO_REUSEADDR, (struct sockaddr *)&s->socket,
|
||||
sizeof s->socket);
|
||||
mask = umask(0177);
|
||||
if (ID0bind_un(s->fd, &s->socket) < 0) {
|
||||
if (errno != EADDRINUSE) {
|
||||
log_Printf(LogPHASE, "mpserver: can't create bundle socket %s (%s)\n",
|
||||
s->socket.sun_path, strerror(errno));
|
||||
umask(mask);
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
return MPSERVER_FAILED;
|
||||
}
|
||||
umask(mask);
|
||||
if (ID0connect_un(s->fd, &s->socket) < 0) {
|
||||
log_Printf(LogPHASE, "mpserver: can't connect to bundle socket %s (%s)\n",
|
||||
s->socket.sun_path, strerror(errno));
|
||||
if (errno == ECONNREFUSED)
|
||||
log_Printf(LogPHASE, " Has the previous server died badly ?\n");
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
return MPSERVER_FAILED;
|
||||
}
|
||||
|
||||
/* Donate our link to the other guy */
|
||||
return MPSERVER_CONNECTED;
|
||||
}
|
||||
|
||||
/* Listen for other ppp invocations that want to donate links */
|
||||
if (listen(s->fd, 5) != 0) {
|
||||
log_Printf(LogERROR, "mpserver: Unable to listen to socket"
|
||||
" - BUNDLE overload?\n");
|
||||
mpserver_Close(s);
|
||||
}
|
||||
|
||||
return MPSERVER_LISTENING;
|
||||
}
|
||||
|
||||
void
|
||||
mpserver_Close(struct mpserver *s)
|
||||
{
|
||||
if (s->send.dl != NULL) {
|
||||
bundle_SendDatalink(s->send.dl, s->fd, &s->socket);
|
||||
s->send.dl = NULL;
|
||||
close(s->fd);
|
||||
s->fd = -1;
|
||||
} else if (s->fd >= 0) {
|
||||
close(s->fd);
|
||||
if (ID0unlink(s->socket.sun_path) == -1)
|
||||
log_Printf(LogERROR, "%s: Failed to remove: %s\n", s->socket.sun_path,
|
||||
strerror(errno));
|
||||
memset(&s->socket, '\0', sizeof s->socket);
|
||||
s->fd = -1;
|
||||
}
|
||||
}
|
134
usr.sbin/ppp/mp.h
Normal file
134
usr.sbin/ppp/mp.h
Normal file
@ -0,0 +1,134 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: mp.h,v 1.1.2.12 1998/05/03 22:13:13 brian Exp $
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
struct cmdargs;
|
||||
struct datalink;
|
||||
|
||||
#define ENDDISC_NULL 0
|
||||
#define ENDDISC_LOCAL 1
|
||||
#define ENDDISC_IP 2
|
||||
#define ENDDISC_MAC 3
|
||||
#define ENDDISC_MAGIC 4
|
||||
#define ENDDISC_PSN 5
|
||||
|
||||
#define MP_LINKSENT 0 /* We attached the link to another ppp */
|
||||
#define MP_UP 1 /* We've started MP */
|
||||
#define MP_ADDED 2 /* We've added the link to our MP */
|
||||
#define MP_FAILED 3 /* No go */
|
||||
|
||||
#define MPSERVER_CONNECTED 0
|
||||
#define MPSERVER_LISTENING 1
|
||||
#define MPSERVER_FAILED 2
|
||||
|
||||
struct enddisc {
|
||||
u_char class;
|
||||
char address[50];
|
||||
int len;
|
||||
};
|
||||
|
||||
struct peerid {
|
||||
struct enddisc enddisc; /* Peers endpoint discriminator */
|
||||
char authname[50]; /* Peers name (authenticated) */
|
||||
};
|
||||
|
||||
struct mpserver {
|
||||
struct descriptor desc;
|
||||
int fd; /* listen()ing or connect()ing here */
|
||||
struct sockaddr_un socket; /* On this socket */
|
||||
|
||||
struct {
|
||||
struct datalink *dl; /* Send this datalink */
|
||||
} send; /* (in UpdateSet()) */
|
||||
};
|
||||
|
||||
struct mp {
|
||||
struct link link;
|
||||
|
||||
unsigned active : 1;
|
||||
unsigned peer_is12bit : 1; /* 12/24bit seq nos */
|
||||
unsigned local_is12bit : 1;
|
||||
u_short peer_mrru;
|
||||
u_short local_mrru;
|
||||
|
||||
struct peerid peer; /* Who are we talking to */
|
||||
struct mpserver server; /* Our ``sharing'' socket */
|
||||
|
||||
struct {
|
||||
u_int32_t seq; /* next outgoing seq */
|
||||
int link; /* Next link to send on */
|
||||
} out;
|
||||
|
||||
struct {
|
||||
u_int32_t min_in; /* minimum received incoming seq */
|
||||
u_int32_t next_in; /* next incoming seq to process */
|
||||
} seq;
|
||||
|
||||
struct {
|
||||
u_short mrru; /* Max Reconstructed Receive Unit */
|
||||
unsigned shortseq : 2; /* I want short Sequence Numbers */
|
||||
struct enddisc enddisc; /* endpoint discriminator */
|
||||
} cfg;
|
||||
|
||||
struct mbuf *inbufs; /* Received fragments */
|
||||
struct fsm_parent fsmp; /* Our callback functions */
|
||||
struct bundle *bundle; /* Parent */
|
||||
};
|
||||
|
||||
struct mp_link {
|
||||
u_int32_t seq; /* 12 or 24 bit incoming seq */
|
||||
int weight; /* bytes to send with each write */
|
||||
};
|
||||
|
||||
struct mp_header {
|
||||
unsigned begin : 1;
|
||||
unsigned end : 1;
|
||||
u_int32_t seq;
|
||||
};
|
||||
|
||||
#define descriptor2mpserver(d) \
|
||||
((d)->type == MPSERVER_DESCRIPTOR ? (struct mpserver *)(d) : NULL)
|
||||
#define mpserver_IsOpen(s) ((s)->fd != -1)
|
||||
|
||||
extern void peerid_Init(struct peerid *);
|
||||
extern int peerid_Equal(const struct peerid *, const struct peerid *);
|
||||
extern void mpserver_Init(struct mpserver *);
|
||||
extern int mpserver_Open(struct mpserver *, struct peerid *);
|
||||
extern void mpserver_Close(struct mpserver *);
|
||||
extern void mp_Init(struct mp *, struct bundle *);
|
||||
extern void mp_linkInit(struct mp_link *);
|
||||
extern int mp_Up(struct mp *, struct datalink *);
|
||||
extern void mp_Down(struct mp *);
|
||||
extern void mp_Input(struct mp *, struct mbuf *, struct physical *);
|
||||
extern int mp_FillQueues(struct bundle *);
|
||||
extern int mp_SetDatalinkWeight(struct cmdargs const *);
|
||||
extern int mp_ShowStatus(struct cmdargs const *);
|
||||
extern const char *mp_Enddisc(u_char, const char *, int);
|
||||
extern int mp_SetEnddisc(struct cmdargs const *);
|
@ -2,26 +2,25 @@
|
||||
* The code in this file was written by Eivind Eklund <perhaps@yes.no>,
|
||||
* who places it in the public domain without restriction.
|
||||
*
|
||||
* $Id: alias_cmd.c,v 1.11 1997/12/24 10:28:37 brian Exp $
|
||||
* $Id: alias_cmd.c,v 1.12.2.8 1998/05/01 19:23:43 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <limits.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "alias_cmd.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
|
||||
|
||||
static int StrToAddr(const char *, struct in_addr *);
|
||||
@ -30,13 +29,12 @@ static int StrToAddrAndPort(const char *, struct in_addr *, u_short *, const cha
|
||||
|
||||
|
||||
int
|
||||
AliasRedirectPort(struct cmdargs const *arg)
|
||||
alias_RedirectPort(struct cmdargs const *arg)
|
||||
{
|
||||
if (!(mode & MODE_ALIAS)) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "Alias not enabled\n");
|
||||
if (!alias_IsEnabled()) {
|
||||
prompt_Printf(arg->prompt, "Alias not enabled\n");
|
||||
return 1;
|
||||
} else if (arg->argc == 3) {
|
||||
} else if (arg->argc == arg->argn+3) {
|
||||
char proto_constant;
|
||||
const char *proto;
|
||||
u_short local_port;
|
||||
@ -46,45 +44,44 @@ AliasRedirectPort(struct cmdargs const *arg)
|
||||
struct in_addr null_addr;
|
||||
struct alias_link *link;
|
||||
|
||||
proto = arg->argv[0];
|
||||
proto = arg->argv[arg->argn];
|
||||
if (strcmp(proto, "tcp") == 0) {
|
||||
proto_constant = IPPROTO_TCP;
|
||||
} else if (strcmp(proto, "udp") == 0) {
|
||||
proto_constant = IPPROTO_UDP;
|
||||
} else {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: protocol must be tcp or udp\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: protocol must be"
|
||||
" tcp or udp\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
|
||||
error = StrToAddrAndPort(arg->argv[1], &local_addr, &local_port, proto);
|
||||
error = StrToAddrAndPort(arg->argv[arg->argn+1], &local_addr, &local_port,
|
||||
proto);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: error reading local addr:port\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: error reading"
|
||||
" local addr:port\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
error = StrToPort(arg->argv[2], &alias_port, proto);
|
||||
error = StrToPort(arg->argv[arg->argn+2], &alias_port, proto);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "port redirect: error reading alias port\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "port redirect: error reading alias port\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
null_addr.s_addr = 0;
|
||||
null_addr.s_addr = INADDR_ANY;
|
||||
|
||||
link = VarPacketAliasRedirectPort(local_addr, local_port,
|
||||
link = (*PacketAlias.RedirectPort)(local_addr, local_port,
|
||||
null_addr, 0,
|
||||
null_addr, alias_port,
|
||||
proto_constant);
|
||||
|
||||
if (link == NULL && VarTerm)
|
||||
fprintf(VarTerm, "port redirect: error returned by packed"
|
||||
if (link == NULL)
|
||||
prompt_Printf(arg->prompt, "port redirect: error returned by packed"
|
||||
" aliasing engine (code=%d)\n", error);
|
||||
} else
|
||||
return -1;
|
||||
@ -94,36 +91,35 @@ AliasRedirectPort(struct cmdargs const *arg)
|
||||
|
||||
|
||||
int
|
||||
AliasRedirectAddr(struct cmdargs const *arg)
|
||||
alias_RedirectAddr(struct cmdargs const *arg)
|
||||
{
|
||||
if (!(mode & MODE_ALIAS)) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "alias not enabled\n");
|
||||
if (!alias_IsEnabled()) {
|
||||
prompt_Printf(arg->prompt, "alias not enabled\n");
|
||||
return 1;
|
||||
} else if (arg->argc == 2) {
|
||||
} else if (arg->argc == arg->argn+2) {
|
||||
int error;
|
||||
struct in_addr local_addr;
|
||||
struct in_addr alias_addr;
|
||||
struct alias_link *link;
|
||||
|
||||
error = StrToAddr(arg->argv[0], &local_addr);
|
||||
error = StrToAddr(arg->argv[arg->argn], &local_addr);
|
||||
if (error) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "address redirect: invalid local address\n");
|
||||
prompt_Printf(arg->prompt, "address redirect: invalid local address\n");
|
||||
return 1;
|
||||
}
|
||||
error = StrToAddr(arg->argv[1], &alias_addr);
|
||||
error = StrToAddr(arg->argv[arg->argn+1], &alias_addr);
|
||||
if (error) {
|
||||
if (VarTerm) {
|
||||
fprintf(VarTerm, "address redirect: invalid alias address\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
}
|
||||
prompt_Printf(arg->prompt, "address redirect: invalid alias address\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
return 1;
|
||||
}
|
||||
link = VarPacketAliasRedirectAddr(local_addr, alias_addr);
|
||||
if (link == NULL && VarTerm) {
|
||||
fprintf(VarTerm, "address redirect: packet aliasing engine error\n");
|
||||
fprintf(VarTerm, "Usage: alias %s %s\n", arg->cmd->name, arg->cmd->syntax);
|
||||
link = (*PacketAlias.RedirectAddr)(local_addr, alias_addr);
|
||||
if (link == NULL) {
|
||||
prompt_Printf(arg->prompt, "address redirect: packet aliasing"
|
||||
" engine error\n");
|
||||
prompt_Printf(arg->prompt, "Usage: alias %s %s\n", arg->cmd->name,
|
||||
arg->cmd->syntax);
|
||||
}
|
||||
} else
|
||||
return -1;
|
||||
@ -142,7 +138,7 @@ StrToAddr(const char *str, struct in_addr *addr)
|
||||
|
||||
hp = gethostbyname(str);
|
||||
if (!hp) {
|
||||
LogPrintf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
|
||||
log_Printf(LogWARN, "StrToAddr: Unknown host %s.\n", str);
|
||||
return -1;
|
||||
}
|
||||
*addr = *((struct in_addr *) hp->h_addr);
|
||||
@ -164,7 +160,7 @@ StrToPort(const char *str, u_short *port, const char *proto)
|
||||
}
|
||||
sp = getservbyname(str, proto);
|
||||
if (!sp) {
|
||||
LogPrintf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
|
||||
log_Printf(LogWARN, "StrToAddr: Unknown port or service %s/%s.\n",
|
||||
str, proto);
|
||||
return -1;
|
||||
}
|
||||
@ -181,7 +177,7 @@ StrToAddrAndPort(const char *str, struct in_addr *addr, u_short *port, const cha
|
||||
|
||||
colon = strchr(str, ':');
|
||||
if (!colon) {
|
||||
LogPrintf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
|
||||
log_Printf(LogWARN, "StrToAddrAndPort: %s is missing port number.\n", str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
@ -2,8 +2,10 @@
|
||||
* The code in this file was written by Eivind Eklund <perhaps@yes.no>,
|
||||
* who places it in the public domain without restriction.
|
||||
*
|
||||
* $Id: alias_cmd.h,v 1.6 1997/12/21 14:28:24 brian Exp $
|
||||
* $Id: alias_cmd.h,v 1.7.2.2 1998/05/01 19:23:44 brian Exp $
|
||||
*/
|
||||
|
||||
extern int AliasRedirectPort(struct cmdargs const *);
|
||||
extern int AliasRedirectAddr(struct cmdargs const *);
|
||||
struct cmdargs;
|
||||
|
||||
extern int alias_RedirectPort(struct cmdargs const *);
|
||||
extern int alias_RedirectAddr(struct cmdargs const *);
|
||||
|
@ -1,400 +0,0 @@
|
||||
/*
|
||||
* PPP OS Layer Interface Module
|
||||
*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the Internet Initiative Japan, Inc. The name of the
|
||||
* IIJ 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.
|
||||
*
|
||||
* $Id: os.c,v 1.42 1998/01/21 02:15:23 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "ipcp.h"
|
||||
#include "os.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "arp.h"
|
||||
#include "systems.h"
|
||||
#include "route.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
|
||||
char *IfDevName;
|
||||
|
||||
static struct ifaliasreq ifra;
|
||||
static struct ifreq ifrq;
|
||||
static struct in_addr oldmine, oldhis;
|
||||
static int linkup;
|
||||
|
||||
enum set_method { SET_UP, SET_DOWN, SET_TRY };
|
||||
|
||||
static int
|
||||
SetIpDevice(struct in_addr myaddr,
|
||||
struct in_addr hisaddr,
|
||||
struct in_addr netmask,
|
||||
enum set_method how)
|
||||
{
|
||||
struct sockaddr_in *sock_in;
|
||||
int s;
|
||||
u_long mask, addr;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
if (how == SET_DOWN) {
|
||||
if (Enabled(ConfProxy))
|
||||
cifproxyarp(s, oldhis);
|
||||
if (oldmine.s_addr == 0 && oldhis.s_addr == 0) {
|
||||
close(s);
|
||||
return (0);
|
||||
}
|
||||
memset(&ifra.ifra_addr, '\0', sizeof ifra.ifra_addr);
|
||||
memset(&ifra.ifra_broadaddr, '\0', sizeof ifra.ifra_broadaddr);
|
||||
memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask);
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
|
||||
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCDIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
oldmine.s_addr = oldhis.s_addr = 0;
|
||||
} else {
|
||||
/* If given addresses are alreay set, then ignore this request */
|
||||
if (oldmine.s_addr == myaddr.s_addr && oldhis.s_addr == hisaddr.s_addr) {
|
||||
close(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If different address has been set, then delete it first.
|
||||
*/
|
||||
if (oldmine.s_addr || oldhis.s_addr) {
|
||||
memset(&ifra.ifra_addr, '\0', sizeof ifra.ifra_addr);
|
||||
memset(&ifra.ifra_broadaddr, '\0', sizeof ifra.ifra_broadaddr);
|
||||
memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask);
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
|
||||
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCDIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/* Set interface address */
|
||||
sock_in = (struct sockaddr_in *) & (ifra.ifra_addr);
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr = myaddr;
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
|
||||
/* Set destination address */
|
||||
sock_in = (struct sockaddr_in *) & (ifra.ifra_broadaddr);
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr = hisaddr;
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
|
||||
addr = ntohl(myaddr.s_addr);
|
||||
if (IN_CLASSA(addr))
|
||||
mask = IN_CLASSA_NET;
|
||||
else if (IN_CLASSB(addr))
|
||||
mask = IN_CLASSB_NET;
|
||||
else
|
||||
mask = IN_CLASSC_NET;
|
||||
|
||||
/*
|
||||
* if subnet mask is given, use it instead of class mask.
|
||||
*/
|
||||
if (netmask.s_addr && (ntohl(netmask.s_addr) & mask) == mask)
|
||||
mask = ntohl(netmask.s_addr);
|
||||
|
||||
sock_in = (struct sockaddr_in *) & (ifra.ifra_mask);
|
||||
sock_in->sin_family = AF_INET;
|
||||
sock_in->sin_addr.s_addr = htonl(mask);
|
||||
sock_in->sin_len = sizeof *sock_in;
|
||||
|
||||
if (ID0ioctl(s, SIOCAIFADDR, &ifra) < 0) {
|
||||
if (how != SET_TRY)
|
||||
LogPrintf(LogERROR, "SetIpDevice: ioctl(SIOCAIFADDR): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
oldhis.s_addr = hisaddr.s_addr;
|
||||
oldmine.s_addr = myaddr.s_addr;
|
||||
if (Enabled(ConfProxy))
|
||||
sifproxyarp(s, hisaddr);
|
||||
}
|
||||
close(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
CleanInterface(const char *name)
|
||||
{
|
||||
int s;
|
||||
|
||||
s = ID0socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "SetIpDevice: socket(): %s\n", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
strncpy(ifrq.ifr_name, name, sizeof ifrq.ifr_name - 1);
|
||||
ifrq.ifr_name[sizeof ifrq.ifr_name - 1] = '\0';
|
||||
while (ID0ioctl(s, SIOCGIFADDR, &ifrq) == 0) {
|
||||
memset(&ifra.ifra_mask, '\0', sizeof ifra.ifra_mask);
|
||||
ifra.ifra_addr = ifrq.ifr_addr;
|
||||
if (ID0ioctl(s, SIOCGIFDSTADDR, &ifrq) < 0) {
|
||||
if (ifra.ifra_addr.sa_family == AF_INET)
|
||||
LogPrintf(LogERROR, "tun_configure: Can't get dst for %s on %s !\n",
|
||||
inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
|
||||
name);
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
ifra.ifra_broadaddr = ifrq.ifr_dstaddr;
|
||||
if (ID0ioctl(s, SIOCDIFADDR, &ifra) < 0) {
|
||||
if (ifra.ifra_addr.sa_family == AF_INET)
|
||||
LogPrintf(LogERROR, "tun_configure: Can't delete %s address on %s !\n",
|
||||
inet_ntoa(((struct sockaddr_in *)&ifra.ifra_addr)->sin_addr),
|
||||
name);
|
||||
close(s);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
close(s);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int
|
||||
OsTrySetIpaddress(struct in_addr myaddr, struct in_addr hisaddr)
|
||||
{
|
||||
return (SetIpDevice(myaddr, hisaddr, ifnetmask, SET_TRY));
|
||||
}
|
||||
|
||||
int
|
||||
OsSetIpaddress(struct in_addr myaddr, struct in_addr hisaddr)
|
||||
{
|
||||
return (SetIpDevice(myaddr, hisaddr, ifnetmask, SET_UP));
|
||||
}
|
||||
|
||||
static struct in_addr peer_addr;
|
||||
|
||||
void
|
||||
OsLinkup()
|
||||
{
|
||||
char *s;
|
||||
|
||||
if (linkup == 0) {
|
||||
reconnectState = RECON_UNKNOWN;
|
||||
if (mode & MODE_BACKGROUND && BGFiledes[1] != -1) {
|
||||
char c = EX_NORMAL;
|
||||
|
||||
if (write(BGFiledes[1], &c, 1) == 1)
|
||||
LogPrintf(LogPHASE, "Parent notified of success.\n");
|
||||
else
|
||||
LogPrintf(LogPHASE, "Failed to notify parent of success.\n");
|
||||
close(BGFiledes[1]);
|
||||
BGFiledes[1] = -1;
|
||||
}
|
||||
peer_addr = IpcpInfo.his_ipaddr;
|
||||
s = (char *) inet_ntoa(peer_addr);
|
||||
if (LogIsKept(LogLINK))
|
||||
LogPrintf(LogLINK, "OsLinkup: %s\n", s);
|
||||
else
|
||||
LogPrintf(LogLCP, "OsLinkup: %s\n", s);
|
||||
|
||||
if (SelectSystem(inet_ntoa(IpcpInfo.want_ipaddr), LINKUPFILE) < 0) {
|
||||
if (GetLabel()) {
|
||||
if (SelectSystem(GetLabel(), LINKUPFILE) < 0)
|
||||
SelectSystem("MYADDR", LINKUPFILE);
|
||||
} else
|
||||
SelectSystem("MYADDR", LINKUPFILE);
|
||||
}
|
||||
linkup = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
OsLinkIsUp()
|
||||
{
|
||||
return linkup;
|
||||
}
|
||||
|
||||
void
|
||||
OsLinkdown()
|
||||
{
|
||||
char *s;
|
||||
int Level;
|
||||
|
||||
if (linkup) {
|
||||
s = (char *) inet_ntoa(peer_addr);
|
||||
Level = LogIsKept(LogLINK) ? LogLINK : LogIPCP;
|
||||
LogPrintf(Level, "OsLinkdown: %s\n", s);
|
||||
|
||||
FsmDown(&IpcpFsm); /* IPCP must come down */
|
||||
FsmDown(&CcpFsm); /* CCP must come down */
|
||||
|
||||
linkup = 0;
|
||||
if (SelectSystem(s, LINKDOWNFILE) < 0) {
|
||||
if (GetLabel()) {
|
||||
if (SelectSystem(GetLabel(), LINKDOWNFILE) < 0)
|
||||
SelectSystem("MYADDR", LINKDOWNFILE);
|
||||
} else
|
||||
SelectSystem("MYADDR", LINKDOWNFILE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
OsInterfaceDown(int final)
|
||||
{
|
||||
struct in_addr zeroaddr;
|
||||
int s;
|
||||
|
||||
OsLinkdown();
|
||||
if (!final && (mode & MODE_DAEMON)) /* We still want interface alive */
|
||||
return (0);
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "OsInterfaceDown: socket: %s\n", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
ifrq.ifr_flags &= ~IFF_UP;
|
||||
if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
|
||||
LogPrintf(LogERROR, "OsInterfaceDown: ioctl(SIOCSIFFLAGS): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
zeroaddr.s_addr = 0;
|
||||
SetIpDevice(zeroaddr, zeroaddr, zeroaddr, SET_DOWN);
|
||||
|
||||
close(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open tunnel device and returns its descriptor
|
||||
*/
|
||||
|
||||
#define MAX_TUN 256
|
||||
/* MAX_TUN is set at an arbitrarily large value *
|
||||
* as the loop aborts when it reaches the first *
|
||||
* 'Device not configured' (ENXIO), or the third *
|
||||
* 'No such file or directory' (ENOENT) error. */
|
||||
int
|
||||
OpenTunnel(int *ptun)
|
||||
{
|
||||
int s;
|
||||
char ifname[IFNAMSIZ];
|
||||
static char devname[14]; /* sufficient room for "/dev/tun65535" */
|
||||
unsigned unit, enoentcount = 0;
|
||||
int err;
|
||||
|
||||
err = ENOENT;
|
||||
for (unit = 0; unit <= MAX_TUN; unit++) {
|
||||
snprintf(devname, sizeof devname, "/dev/tun%d", unit);
|
||||
tun_out = ID0open(devname, O_RDWR);
|
||||
if (tun_out >= 0)
|
||||
break;
|
||||
if (errno == ENXIO) {
|
||||
unit = MAX_TUN;
|
||||
err = errno;
|
||||
} else if (errno == ENOENT) {
|
||||
enoentcount++;
|
||||
if (enoentcount > 2)
|
||||
unit = MAX_TUN;
|
||||
} else
|
||||
err = errno;
|
||||
}
|
||||
if (unit > MAX_TUN) {
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "No tunnel device is available (%s).\n", strerror(err));
|
||||
return -1;
|
||||
}
|
||||
*ptun = unit;
|
||||
|
||||
LogSetTun(unit);
|
||||
|
||||
/*
|
||||
* At first, name the interface.
|
||||
*/
|
||||
strncpy(ifname, devname + 5, IFNAMSIZ - 1);
|
||||
|
||||
memset(&ifra, '\0', sizeof ifra);
|
||||
memset(&ifrq, '\0', sizeof ifrq);
|
||||
|
||||
strncpy(ifrq.ifr_name, ifname, IFNAMSIZ - 1);
|
||||
strncpy(ifra.ifra_name, ifname, IFNAMSIZ - 1);
|
||||
|
||||
s = socket(AF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "OpenTunnel: socket(): %s\n", strerror(errno));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Now, bring up the interface.
|
||||
*/
|
||||
if (ioctl(s, SIOCGIFFLAGS, &ifrq) < 0) {
|
||||
LogPrintf(LogERROR, "OpenTunnel: ioctl(SIOCGIFFLAGS): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
ifrq.ifr_flags |= IFF_UP;
|
||||
if (ID0ioctl(s, SIOCSIFFLAGS, &ifrq) < 0) {
|
||||
LogPrintf(LogERROR, "OpenTunnel: ioctl(SIOCSIFFLAGS): %s\n",
|
||||
strerror(errno));
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
tun_in = tun_out;
|
||||
IfDevName = devname + 5;
|
||||
if (GetIfIndex(IfDevName) < 0) {
|
||||
LogPrintf(LogERROR, "OpenTunnel: Can't find ifindex.\n");
|
||||
close(s);
|
||||
return (-1);
|
||||
}
|
||||
if (VarTerm)
|
||||
fprintf(VarTerm, "Using interface: %s\n", IfDevName);
|
||||
LogPrintf(LogPHASE, "Using interface: %s\n", IfDevName);
|
||||
close(s);
|
||||
return (0);
|
||||
}
|
@ -1,32 +0,0 @@
|
||||
/*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the Internet Initiative Japan. The name of the
|
||||
* IIJ 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.
|
||||
*
|
||||
* $Id: os.h,v 1.13 1997/12/13 02:37:30 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
extern char *IfDevName;
|
||||
|
||||
extern int OsSetIpaddress(struct in_addr, struct in_addr);
|
||||
extern int OsTrySetIpaddress(struct in_addr, struct in_addr);
|
||||
extern int OsInterfaceDown(int);
|
||||
extern int OpenTunnel(int *);
|
||||
extern void OsLinkup(void);
|
||||
extern int OsLinkIsUp(void);
|
||||
extern void OsLinkdown(void);
|
||||
extern int CleanInterface(const char *);
|
@ -18,81 +18,78 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pap.c,v 1.21 1998/02/19 02:10:13 brian Exp $
|
||||
* $Id: pap.c,v 1.20.2.28 1998/05/01 19:25:30 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <pwd.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#ifdef __OpenBSD__
|
||||
#include <util.h>
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
#include <utmp.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "auth.h"
|
||||
#include "pap.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcpproto.h"
|
||||
#include "phase.h"
|
||||
#include "auth.h"
|
||||
#include "id.h"
|
||||
#include "async.h"
|
||||
#include "throughput.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "chat.h"
|
||||
#include "chap.h"
|
||||
#include "datalink.h"
|
||||
|
||||
static const char *papcodes[] = { "???", "REQUEST", "ACK", "NAK" };
|
||||
|
||||
static void
|
||||
SendPapChallenge(int papid)
|
||||
void
|
||||
pap_SendChallenge(struct authinfo *auth, int papid, struct physical *physical)
|
||||
{
|
||||
struct fsmheader lh;
|
||||
struct mbuf *bp;
|
||||
u_char *cp;
|
||||
int namelen, keylen, plen;
|
||||
|
||||
namelen = strlen(VarAuthName);
|
||||
keylen = strlen(VarAuthKey);
|
||||
namelen = strlen(physical->dl->bundle->cfg.auth.name);
|
||||
keylen = strlen(physical->dl->bundle->cfg.auth.key);
|
||||
plen = namelen + keylen + 2;
|
||||
LogPrintf(LogDEBUG, "SendPapChallenge: namelen = %d, keylen = %d\n",
|
||||
log_Printf(LogDEBUG, "pap_SendChallenge: namelen = %d, keylen = %d\n",
|
||||
namelen, keylen);
|
||||
if (LogIsKept(LogDEBUG))
|
||||
LogPrintf(LogPHASE, "PAP: %s (%s)\n", VarAuthName, VarAuthKey);
|
||||
else
|
||||
LogPrintf(LogPHASE, "PAP: %s\n", VarAuthName);
|
||||
log_Printf(LogPHASE, "PAP: %s\n", physical->dl->bundle->cfg.auth.name);
|
||||
lh.code = PAP_REQUEST;
|
||||
lh.id = papid;
|
||||
lh.length = htons(plen + sizeof(struct fsmheader));
|
||||
bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
|
||||
bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
|
||||
memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
|
||||
cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
|
||||
*cp++ = namelen;
|
||||
memcpy(cp, VarAuthName, namelen);
|
||||
memcpy(cp, physical->dl->bundle->cfg.auth.name, namelen);
|
||||
cp += namelen;
|
||||
*cp++ = keylen;
|
||||
memcpy(cp, VarAuthKey, keylen);
|
||||
memcpy(cp, physical->dl->bundle->cfg.auth.key, keylen);
|
||||
|
||||
HdlcOutput(PRI_LINK, PROTO_PAP, bp);
|
||||
hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
|
||||
}
|
||||
|
||||
struct authinfo AuthPapInfo = {
|
||||
SendPapChallenge,
|
||||
};
|
||||
|
||||
static void
|
||||
SendPapCode(int id, int code, const char *message)
|
||||
SendPapCode(int id, int code, const char *message, struct physical *physical)
|
||||
{
|
||||
struct fsmheader lh;
|
||||
struct mbuf *bp;
|
||||
@ -104,20 +101,21 @@ SendPapCode(int id, int code, const char *message)
|
||||
mlen = strlen(message);
|
||||
plen = mlen + 1;
|
||||
lh.length = htons(plen + sizeof(struct fsmheader));
|
||||
bp = mballoc(plen + sizeof(struct fsmheader), MB_FSM);
|
||||
bp = mbuf_Alloc(plen + sizeof(struct fsmheader), MB_FSM);
|
||||
memcpy(MBUF_CTOP(bp), &lh, sizeof(struct fsmheader));
|
||||
cp = MBUF_CTOP(bp) + sizeof(struct fsmheader);
|
||||
*cp++ = mlen;
|
||||
memcpy(cp, message, mlen);
|
||||
LogPrintf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
|
||||
HdlcOutput(PRI_LINK, PROTO_PAP, bp);
|
||||
log_Printf(LogPHASE, "PapOutput: %s\n", papcodes[code]);
|
||||
hdlc_Output(&physical->link, PRI_LINK, PROTO_PAP, bp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Validate given username and passwrd against with secret table
|
||||
*/
|
||||
static int
|
||||
PapValidate(u_char * name, u_char * key)
|
||||
PapValidate(struct bundle *bundle, u_char *name, u_char *key,
|
||||
struct physical *physical)
|
||||
{
|
||||
int nlen, klen;
|
||||
|
||||
@ -125,31 +123,17 @@ PapValidate(u_char * name, u_char * key)
|
||||
klen = *key;
|
||||
*key++ = 0;
|
||||
key[klen] = 0;
|
||||
LogPrintf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
|
||||
log_Printf(LogDEBUG, "PapValidate: name %s (%d), key %s (%d)\n",
|
||||
name, nlen, key, klen);
|
||||
|
||||
#ifndef NOPASSWDAUTH
|
||||
if (Enabled(ConfPasswdAuth)) {
|
||||
struct passwd *pwd;
|
||||
int result;
|
||||
|
||||
LogPrintf(LogLCP, "Using PasswdAuth\n");
|
||||
result = (pwd = getpwnam(name)) &&
|
||||
!strcmp(crypt(key, pwd->pw_passwd), pwd->pw_passwd);
|
||||
endpwent();
|
||||
return result;
|
||||
}
|
||||
#endif
|
||||
|
||||
return (AuthValidate(SECRETFILE, name, key));
|
||||
return auth_Validate(bundle, name, key, physical);
|
||||
}
|
||||
|
||||
void
|
||||
PapInput(struct mbuf * bp)
|
||||
pap_Input(struct bundle *bundle, struct mbuf *bp, struct physical *physical)
|
||||
{
|
||||
int len = plength(bp);
|
||||
int len = mbuf_Length(bp);
|
||||
struct fsmheader *php;
|
||||
struct lcpstate *lcp = &LcpInfo;
|
||||
u_char *cp;
|
||||
|
||||
if (len >= sizeof(struct fsmheader)) {
|
||||
@ -157,60 +141,57 @@ PapInput(struct mbuf * bp)
|
||||
if (len >= ntohs(php->length)) {
|
||||
if (php->code < PAP_REQUEST || php->code > PAP_NAK)
|
||||
php->code = 0;
|
||||
LogPrintf(LogPHASE, "PapInput: %s\n", papcodes[php->code]);
|
||||
log_Printf(LogPHASE, "pap_Input: %s\n", papcodes[php->code]);
|
||||
|
||||
switch (php->code) {
|
||||
case PAP_REQUEST:
|
||||
cp = (u_char *) (php + 1);
|
||||
if (PapValidate(cp, cp + *cp + 1)) {
|
||||
SendPapCode(php->id, PAP_ACK, "Greetings!!");
|
||||
lcp->auth_ineed = 0;
|
||||
if (lcp->auth_iwait == 0) {
|
||||
if ((mode & MODE_DIRECT) && isatty(modem) && Enabled(ConfUtmp)) {
|
||||
if (Utmp)
|
||||
LogPrintf(LogERROR, "Oops, already logged in on %s\n",
|
||||
VarBaseDevice);
|
||||
else {
|
||||
struct utmp ut;
|
||||
memset(&ut, 0, sizeof ut);
|
||||
time(&ut.ut_time);
|
||||
strncpy(ut.ut_name, cp+1, sizeof ut.ut_name);
|
||||
strncpy(ut.ut_line, VarBaseDevice, sizeof ut.ut_line - 1);
|
||||
ID0login(&ut);
|
||||
Utmp = 1;
|
||||
}
|
||||
}
|
||||
NewPhase(PHASE_NETWORK);
|
||||
}
|
||||
if (PapValidate(bundle, cp, cp + *cp + 1, physical)) {
|
||||
datalink_GotAuthname(physical->dl, cp+1, *cp);
|
||||
SendPapCode(php->id, PAP_ACK, "Greetings!!", physical);
|
||||
physical->link.lcp.auth_ineed = 0;
|
||||
if (Enabled(bundle, OPT_UTMP))
|
||||
physical_Login(physical, cp + 1);
|
||||
|
||||
if (physical->link.lcp.auth_iwait == 0)
|
||||
/*
|
||||
* Either I didn't need to authenticate, or I've already been
|
||||
* told that I got the answer right.
|
||||
*/
|
||||
datalink_AuthOk(physical->dl);
|
||||
|
||||
} else {
|
||||
SendPapCode(php->id, PAP_NAK, "Login incorrect");
|
||||
reconnect(RECON_FALSE);
|
||||
LcpClose();
|
||||
SendPapCode(php->id, PAP_NAK, "Login incorrect", physical);
|
||||
datalink_AuthNotOk(physical->dl);
|
||||
}
|
||||
break;
|
||||
case PAP_ACK:
|
||||
StopAuthTimer(&AuthPapInfo);
|
||||
auth_StopTimer(&physical->dl->pap);
|
||||
cp = (u_char *) (php + 1);
|
||||
len = *cp++;
|
||||
cp[len] = 0;
|
||||
LogPrintf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
|
||||
if (lcp->auth_iwait == PROTO_PAP) {
|
||||
lcp->auth_iwait = 0;
|
||||
if (lcp->auth_ineed == 0)
|
||||
NewPhase(PHASE_NETWORK);
|
||||
log_Printf(LogPHASE, "Received PAP_ACK (%s)\n", cp);
|
||||
if (physical->link.lcp.auth_iwait == PROTO_PAP) {
|
||||
physical->link.lcp.auth_iwait = 0;
|
||||
if (physical->link.lcp.auth_ineed == 0)
|
||||
/*
|
||||
* We've succeeded in our ``login''
|
||||
* If we're not expecting the peer to authenticate (or he already
|
||||
* has), proceed to network phase.
|
||||
*/
|
||||
datalink_AuthOk(physical->dl);
|
||||
}
|
||||
break;
|
||||
case PAP_NAK:
|
||||
StopAuthTimer(&AuthPapInfo);
|
||||
auth_StopTimer(&physical->dl->pap);
|
||||
cp = (u_char *) (php + 1);
|
||||
len = *cp++;
|
||||
cp[len] = 0;
|
||||
LogPrintf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
|
||||
reconnect(RECON_FALSE);
|
||||
LcpClose();
|
||||
log_Printf(LogPHASE, "Received PAP_NAK (%s)\n", cp);
|
||||
datalink_AuthNotOk(physical->dl);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
|
@ -15,7 +15,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pap.h,v 1.4 1997/10/26 01:03:29 brian Exp $
|
||||
* $Id: pap.h,v 1.5.2.5 1998/05/01 19:25:32 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -24,6 +24,10 @@
|
||||
#define PAP_ACK 2
|
||||
#define PAP_NAK 3
|
||||
|
||||
extern struct authinfo AuthPapInfo;
|
||||
struct mbuf;
|
||||
struct physical;
|
||||
struct authinfo;
|
||||
struct bundle;
|
||||
|
||||
extern void PapInput(struct mbuf *);
|
||||
extern void pap_Input(struct bundle *, struct mbuf *, struct physical *);
|
||||
extern void pap_SendChallenge(struct authinfo *, int, struct physical *);
|
||||
|
@ -1,105 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 1997 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "lcp.h"
|
||||
#include "lcpproto.h"
|
||||
#include "timer.h"
|
||||
#include "auth.h"
|
||||
#include "pap.h"
|
||||
#include "chap.h"
|
||||
#include "defs.h"
|
||||
#include "ipcp.h"
|
||||
#include "ccp.h"
|
||||
#include "main.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "phase.h"
|
||||
|
||||
int phase = 0; /* Curent phase */
|
||||
|
||||
static const char *PhaseNames[] = {
|
||||
"Dead", "Establish", "Authenticate", "Network", "Terminate"
|
||||
};
|
||||
|
||||
static const char *
|
||||
Auth2Nam(u_short auth)
|
||||
{
|
||||
switch (auth) {
|
||||
case PROTO_PAP:
|
||||
return "PAP";
|
||||
case PROTO_CHAP:
|
||||
return "CHAP";
|
||||
case 0:
|
||||
return "none";
|
||||
}
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
void
|
||||
NewPhase(int new)
|
||||
{
|
||||
struct lcpstate *lcp = &LcpInfo;
|
||||
|
||||
phase = new;
|
||||
LogPrintf(LogPHASE, "NewPhase: %s\n", PhaseNames[phase]);
|
||||
switch (phase) {
|
||||
case PHASE_AUTHENTICATE:
|
||||
lcp->auth_ineed = lcp->want_auth;
|
||||
lcp->auth_iwait = lcp->his_auth;
|
||||
if (lcp->his_auth || lcp->want_auth) {
|
||||
LogPrintf(LogPHASE, " his = %s, mine = %s\n",
|
||||
Auth2Nam(lcp->his_auth), Auth2Nam(lcp->want_auth));
|
||||
if (lcp->his_auth == PROTO_PAP)
|
||||
StartAuthChallenge(&AuthPapInfo);
|
||||
if (lcp->want_auth == PROTO_CHAP)
|
||||
StartAuthChallenge(&AuthChapInfo);
|
||||
} else
|
||||
NewPhase(PHASE_NETWORK);
|
||||
break;
|
||||
case PHASE_NETWORK:
|
||||
IpcpUp();
|
||||
IpcpOpen();
|
||||
CcpUp();
|
||||
CcpOpen();
|
||||
break;
|
||||
case PHASE_DEAD:
|
||||
if (mode & MODE_DIRECT)
|
||||
Cleanup(EX_DEAD);
|
||||
if (mode & MODE_BACKGROUND && reconnectState != RECON_TRUE)
|
||||
Cleanup(EX_DEAD);
|
||||
break;
|
||||
}
|
||||
}
|
@ -1,31 +0,0 @@
|
||||
/*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the Internet Initiative Japan. The name of the
|
||||
* IIJ 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.
|
||||
*
|
||||
* $Id: phase.h,v 1.8 1997/10/26 01:03:32 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#define PHASE_DEAD 0 /* Link is dead */
|
||||
#define PHASE_ESTABLISH 1 /* Establishing link */
|
||||
#define PHASE_AUTHENTICATE 2 /* Being authenticated */
|
||||
#define PHASE_NETWORK 3
|
||||
#define PHASE_TERMINATE 4 /* Terminating link */
|
||||
|
||||
extern int phase; /* Curent phase */
|
||||
|
||||
extern void NewPhase(int);
|
230
usr.sbin/ppp/physical.c
Normal file
230
usr.sbin/ppp/physical.c
Normal file
@ -0,0 +1,230 @@
|
||||
/*
|
||||
* Written by Eivind Eklund <eivind@yes.no>
|
||||
* for Yes Interactive
|
||||
*
|
||||
* Copyright (C) 1998, Yes Interactive. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in any form is permitted. Redistribution in
|
||||
* source form should include the above copyright and this set of
|
||||
* conditions, because large sections american law seems to have been
|
||||
* created by a bunch of jerks on drugs that are now illegal, forcing
|
||||
* me to include this copyright-stuff instead of placing this in the
|
||||
* public domain. The name of of 'Yes Interactive' or 'Eivind Eklund'
|
||||
* 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.
|
||||
*
|
||||
* $Id: physical.c,v 1.1.2.34 1998/05/21 01:12:20 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/tty.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "mbuf.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "async.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
|
||||
/* External calls - should possibly be moved inline */
|
||||
extern int IntToSpeed(int);
|
||||
|
||||
|
||||
int
|
||||
physical_GetFD(struct physical *phys) {
|
||||
return phys->fd;
|
||||
}
|
||||
|
||||
int
|
||||
physical_IsATTY(struct physical *phys) {
|
||||
return isatty(phys->fd);
|
||||
}
|
||||
|
||||
int
|
||||
physical_IsSync(struct physical *phys) {
|
||||
return phys->cfg.speed == 0;
|
||||
}
|
||||
|
||||
const char *physical_GetDevice(struct physical *phys)
|
||||
{
|
||||
return phys->name.full;
|
||||
}
|
||||
|
||||
void
|
||||
physical_SetDeviceList(struct physical *p, int argc, const char *const *argv)
|
||||
{
|
||||
int f, pos;
|
||||
|
||||
p->cfg.devlist[sizeof p->cfg.devlist - 1] = '\0';
|
||||
for (f = 0, pos = 0; f < argc && pos < sizeof p->cfg.devlist - 1; f++) {
|
||||
if (pos)
|
||||
p->cfg.devlist[pos++] = ' ';
|
||||
strncpy(p->cfg.devlist + pos, argv[f], sizeof p->cfg.devlist - pos - 1);
|
||||
pos += strlen(p->cfg.devlist + pos);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
physical_SetSpeed(struct physical *phys, int speed) {
|
||||
if (IntToSpeed(speed) != B0) {
|
||||
phys->cfg.speed = speed;
|
||||
return 1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
physical_SetSync(struct physical *phys) {
|
||||
phys->cfg.speed = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
physical_SetRtsCts(struct physical *phys, int enable) {
|
||||
phys->cfg.rts_cts = enable ? 1 : 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Encapsulation for a read on the FD. Avoids some exposure, and
|
||||
concentrates control. */
|
||||
ssize_t
|
||||
physical_Read(struct physical *phys, void *buf, size_t nbytes) {
|
||||
return read(phys->fd, buf, nbytes);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
|
||||
return write(phys->fd, buf, nbytes);
|
||||
}
|
||||
|
||||
int
|
||||
physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
||||
int *n, int force)
|
||||
{
|
||||
struct physical *p = descriptor2physical(d);
|
||||
int sets;
|
||||
|
||||
sets = 0;
|
||||
if (p->fd >= 0) {
|
||||
if (r) {
|
||||
FD_SET(p->fd, r);
|
||||
log_Printf(LogTIMER, "%s: fdset(r) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
if (e) {
|
||||
FD_SET(p->fd, e);
|
||||
log_Printf(LogTIMER, "%s: fdset(e) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
if (w && (force || link_QueueLen(&p->link))) {
|
||||
FD_SET(p->fd, w);
|
||||
log_Printf(LogTIMER, "%s: fdset(w) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
if (sets && *n < p->fd + 1)
|
||||
*n = p->fd + 1;
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
int
|
||||
physical_RemoveFromSet(struct physical *p, fd_set *r, fd_set *w, fd_set *e)
|
||||
{
|
||||
int sets;
|
||||
|
||||
sets = 0;
|
||||
if (p->fd >= 0) {
|
||||
if (r && FD_ISSET(p->fd, r)) {
|
||||
FD_CLR(p->fd, r);
|
||||
log_Printf(LogTIMER, "%s: fdunset(r) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
if (e && FD_ISSET(p->fd, e)) {
|
||||
FD_CLR(p->fd, e);
|
||||
log_Printf(LogTIMER, "%s: fdunset(e) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
if (w && FD_ISSET(p->fd, w)) {
|
||||
FD_CLR(p->fd, w);
|
||||
log_Printf(LogTIMER, "%s: fdunset(w) %d\n", p->link.name, p->fd);
|
||||
sets++;
|
||||
}
|
||||
}
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
int
|
||||
physical_IsSet(struct descriptor *d, const fd_set *fdset)
|
||||
{
|
||||
struct physical *p = descriptor2physical(d);
|
||||
return p->fd >= 0 && FD_ISSET(p->fd, fdset);
|
||||
}
|
||||
|
||||
void
|
||||
physical_Login(struct physical *phys, const char *name)
|
||||
{
|
||||
if (phys->type == PHYS_DIRECT && physical_IsATTY(phys)) {
|
||||
if (phys->Utmp)
|
||||
log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base);
|
||||
else {
|
||||
struct utmp ut;
|
||||
const char *connstr;
|
||||
|
||||
memset(&ut, 0, sizeof ut);
|
||||
time(&ut.ut_time);
|
||||
strncpy(ut.ut_name, name, sizeof ut.ut_name);
|
||||
strncpy(ut.ut_line, phys->name.base, sizeof ut.ut_line);
|
||||
if ((connstr = getenv("CONNECT")))
|
||||
/* mgetty sets this to the connection speed */
|
||||
strncpy(ut.ut_host, connstr, sizeof ut.ut_host);
|
||||
ID0login(&ut);
|
||||
phys->Utmp = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
physical_Logout(struct physical *phys)
|
||||
{
|
||||
if (phys->Utmp) {
|
||||
ID0logout(phys->name.base);
|
||||
phys->Utmp = 0;
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
physical_SetMode(struct physical *p, int mode)
|
||||
{
|
||||
if (p->type & (PHYS_DIRECT|PHYS_DEDICATED)
|
||||
|| mode & (PHYS_DIRECT|PHYS_DEDICATED)) {
|
||||
log_Printf(LogWARN, "%s: Cannot change mode %s to %s\n", p->link.name,
|
||||
mode2Nam(p->type), mode2Nam(mode));
|
||||
return 0;
|
||||
}
|
||||
p->type = mode;
|
||||
return 1;
|
||||
}
|
101
usr.sbin/ppp/physical.h
Normal file
101
usr.sbin/ppp/physical.h
Normal file
@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Written by Eivind Eklund <eivind@yes.no>
|
||||
* for Yes Interactive
|
||||
*
|
||||
* Copyright (C) 1998, Yes Interactive. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in any form is permitted. Redistribution in
|
||||
* source form should include the above copyright and this set of
|
||||
* conditions, because large sections american law seems to have been
|
||||
* created by a bunch of jerks on drugs that are now illegal, forcing
|
||||
* me to include this copyright-stuff instead of placing this in the
|
||||
* public domain. The name of of 'Yes Interactive' or 'Eivind Eklund'
|
||||
* 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.
|
||||
*
|
||||
* $Id: physical.h,v 1.1.2.26 1998/05/15 23:58:26 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
struct bundle;
|
||||
|
||||
struct physical {
|
||||
struct link link;
|
||||
struct descriptor desc;
|
||||
int type; /* What sort of PHYS_* link are we ? */
|
||||
struct async async; /* Our async state */
|
||||
struct hdlc hdlc; /* Our hdlc state */
|
||||
int fd; /* File descriptor for this device */
|
||||
int mbits; /* Current DCD status */
|
||||
unsigned dev_is_modem : 1; /* Is the device an actual modem?
|
||||
Faked for sync devices, though...
|
||||
(Possibly this should be
|
||||
dev_is_not_tcp?) XXX-ML */
|
||||
|
||||
struct mbuf *out; /* mbuf that suffered a short write */
|
||||
int connect_count;
|
||||
struct datalink *dl; /* my owner */
|
||||
|
||||
struct {
|
||||
char full[40];
|
||||
char *base;
|
||||
} name;
|
||||
|
||||
unsigned Utmp : 1; /* Are we in utmp ? */
|
||||
|
||||
/* XXX-ML Most of the below is device specific, and probably do not
|
||||
belong in the generic physical struct. It comes from modem.c. */
|
||||
|
||||
struct {
|
||||
unsigned rts_cts : 1; /* Is rts/cts enabled? */
|
||||
unsigned parity; /* What parity is enabled? (TTY flags) */
|
||||
unsigned speed; /* Modem speed */
|
||||
char devlist[LINE_LEN]; /* Comma-separated list of devices */
|
||||
} cfg;
|
||||
|
||||
struct termios ios; /* To be able to reset from raw mode */
|
||||
|
||||
struct pppTimer Timer; /* CD checks */
|
||||
};
|
||||
|
||||
#define field2phys(fp, name) \
|
||||
((struct physical *)((char *)fp - (int)(&((struct physical *)0)->name)))
|
||||
|
||||
#define link2physical(l) \
|
||||
((l)->type == PHYSICAL_LINK ? field2phys(l, link) : NULL)
|
||||
|
||||
#define descriptor2physical(d) \
|
||||
((d)->type == PHYSICAL_DESCRIPTOR ? field2phys(d, desc) : NULL)
|
||||
|
||||
extern int physical_GetFD(struct physical *);
|
||||
extern int physical_IsATTY(struct physical *);
|
||||
extern int physical_IsSync(struct physical *);
|
||||
extern const char *physical_GetDevice(struct physical *);
|
||||
extern void physical_SetDeviceList(struct physical *, int, const char *const *);
|
||||
extern int physical_SetSpeed(struct physical *, int);
|
||||
|
||||
/*
|
||||
* XXX-ML I'm not certain this is the right way to handle this, but we
|
||||
* can solve that later.
|
||||
*/
|
||||
extern void physical_SetSync(struct physical *);
|
||||
|
||||
/*
|
||||
* Can this be set? (Might not be a relevant attribute for this
|
||||
* device, for instance)
|
||||
*/
|
||||
extern int physical_SetRtsCts(struct physical *, int);
|
||||
|
||||
extern ssize_t physical_Read(struct physical *, void *, size_t);
|
||||
extern ssize_t physical_Write(struct physical *, const void *, size_t);
|
||||
extern int physical_UpdateSet(struct descriptor *, fd_set *, fd_set *,
|
||||
fd_set *, int *, int);
|
||||
extern int physical_IsSet(struct descriptor *, const fd_set *);
|
||||
extern void physical_Login(struct physical *, const char *);
|
||||
extern void physical_Logout(struct physical *);
|
||||
extern int physical_RemoveFromSet(struct physical *, fd_set *, fd_set *,
|
||||
fd_set *);
|
||||
extern int physical_SetMode(struct physical *, int);
|
1801
usr.sbin/ppp/ppp.8
1801
usr.sbin/ppp/ppp.8
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -26,26 +26,20 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pred.c,v 1.19 1997/12/21 12:11:08 brian Exp $
|
||||
* $Id: pred.c,v 1.20.2.12 1998/05/01 19:25:40 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcpproto.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "pred.h"
|
||||
@ -56,16 +50,16 @@
|
||||
* A better hash function would result in additional compression,
|
||||
* at the expense of time.
|
||||
*/
|
||||
#define IHASH(x) do {iHash = (iHash << 4) ^ (x);} while(0)
|
||||
#define OHASH(x) do {oHash = (oHash << 4) ^ (x);} while(0)
|
||||
#define HASH(state, x) state->hash = (state->hash << 4) ^ (x)
|
||||
#define GUESS_TABLE_SIZE 65536
|
||||
|
||||
static unsigned short int iHash, oHash;
|
||||
static unsigned char *InputGuessTable;
|
||||
static unsigned char *OutputGuessTable;
|
||||
struct pred1_state {
|
||||
u_short hash;
|
||||
u_char dict[GUESS_TABLE_SIZE];
|
||||
};
|
||||
|
||||
static int
|
||||
compress(u_char * source, u_char * dest, int len)
|
||||
compress(struct pred1_state *state, u_char *source, u_char *dest, int len)
|
||||
{
|
||||
int i, bitmask;
|
||||
unsigned char *flagdest, flags, *orgdest;
|
||||
@ -75,13 +69,13 @@ compress(u_char * source, u_char * dest, int len)
|
||||
flagdest = dest++;
|
||||
flags = 0; /* All guess wrong initially */
|
||||
for (bitmask = 1, i = 0; i < 8 && len; i++, bitmask <<= 1) {
|
||||
if (OutputGuessTable[oHash] == *source) {
|
||||
if (state->dict[state->hash] == *source) {
|
||||
flags |= bitmask; /* Guess was right - don't output */
|
||||
} else {
|
||||
OutputGuessTable[oHash] = *source;
|
||||
state->dict[state->hash] = *source;
|
||||
*dest++ = *source; /* Guess wrong, output char */
|
||||
}
|
||||
OHASH(*source++);
|
||||
HASH(state, *source++);
|
||||
len--;
|
||||
}
|
||||
*flagdest = flags;
|
||||
@ -90,19 +84,17 @@ compress(u_char * source, u_char * dest, int len)
|
||||
}
|
||||
|
||||
static void
|
||||
SyncTable(u_char * source, u_char * dest, int len)
|
||||
SyncTable(struct pred1_state *state, u_char * source, u_char * dest, int len)
|
||||
{
|
||||
|
||||
while (len--) {
|
||||
if (InputGuessTable[iHash] != *source) {
|
||||
InputGuessTable[iHash] = *source;
|
||||
}
|
||||
IHASH(*dest++ = *source++);
|
||||
if (state->dict[state->hash] != *source)
|
||||
state->dict[state->hash] = *source;
|
||||
HASH(state, *dest++ = *source++);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
decompress(u_char * source, u_char * dest, int len)
|
||||
decompress(struct pred1_state *state, u_char * source, u_char * dest, int len)
|
||||
{
|
||||
int i, bitmask;
|
||||
unsigned char flags, *orgdest;
|
||||
@ -113,157 +105,151 @@ decompress(u_char * source, u_char * dest, int len)
|
||||
len--;
|
||||
for (i = 0, bitmask = 1; i < 8; i++, bitmask <<= 1) {
|
||||
if (flags & bitmask) {
|
||||
*dest = InputGuessTable[iHash]; /* Guess correct */
|
||||
*dest = state->dict[state->hash]; /* Guess correct */
|
||||
} else {
|
||||
if (!len)
|
||||
break; /* we seem to be really done -- cabo */
|
||||
InputGuessTable[iHash] = *source; /* Guess wrong */
|
||||
state->dict[state->hash] = *source; /* Guess wrong */
|
||||
*dest = *source++; /* Read from source */
|
||||
len--;
|
||||
}
|
||||
IHASH(*dest++);
|
||||
HASH(state, *dest++);
|
||||
}
|
||||
}
|
||||
return (dest - orgdest);
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1TermInput(void)
|
||||
Pred1Term(void *v)
|
||||
{
|
||||
if (InputGuessTable != NULL) {
|
||||
free(InputGuessTable);
|
||||
InputGuessTable = NULL;
|
||||
}
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
free(state);
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1TermOutput(void)
|
||||
Pred1ResetInput(void *v)
|
||||
{
|
||||
if (OutputGuessTable != NULL) {
|
||||
free(OutputGuessTable);
|
||||
OutputGuessTable = NULL;
|
||||
}
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
state->hash = 0;
|
||||
memset(state->dict, '\0', sizeof state->dict);
|
||||
log_Printf(LogCCP, "Predictor1: Input channel reset\n");
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1ResetInput(void)
|
||||
Pred1ResetOutput(void *v)
|
||||
{
|
||||
iHash = 0;
|
||||
memset(InputGuessTable, '\0', GUESS_TABLE_SIZE);
|
||||
LogPrintf(LogCCP, "Predictor1: Input channel reset\n");
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
state->hash = 0;
|
||||
memset(state->dict, '\0', sizeof state->dict);
|
||||
log_Printf(LogCCP, "Predictor1: Output channel reset\n");
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1ResetOutput(void)
|
||||
static void *
|
||||
Pred1InitInput(struct lcp_opt *o)
|
||||
{
|
||||
oHash = 0;
|
||||
memset(OutputGuessTable, '\0', GUESS_TABLE_SIZE);
|
||||
LogPrintf(LogCCP, "Predictor1: Output channel reset\n");
|
||||
struct pred1_state *state;
|
||||
state = (struct pred1_state *)malloc(sizeof(struct pred1_state));
|
||||
if (state != NULL)
|
||||
Pred1ResetInput(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
static void *
|
||||
Pred1InitOutput(struct lcp_opt *o)
|
||||
{
|
||||
struct pred1_state *state;
|
||||
state = (struct pred1_state *)malloc(sizeof(struct pred1_state));
|
||||
if (state != NULL)
|
||||
Pred1ResetOutput(state);
|
||||
return state;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1InitInput(void)
|
||||
{
|
||||
if (InputGuessTable == NULL)
|
||||
if ((InputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL)
|
||||
return 0;
|
||||
Pred1ResetInput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1InitOutput(void)
|
||||
{
|
||||
if (OutputGuessTable == NULL)
|
||||
if ((OutputGuessTable = malloc(GUESS_TABLE_SIZE)) == NULL)
|
||||
return 0;
|
||||
Pred1ResetOutput();
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1Output(int pri, u_short proto, struct mbuf * bp)
|
||||
Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *bp)
|
||||
{
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
struct mbuf *mwp;
|
||||
u_char *cp, *wp, *hp;
|
||||
int orglen, len;
|
||||
u_char bufp[MAX_MTU + 2];
|
||||
u_short fcs;
|
||||
|
||||
orglen = plength(bp) + 2; /* add count of proto */
|
||||
mwp = mballoc((orglen + 2) / 8 * 9 + 12, MB_HDLCOUT);
|
||||
orglen = mbuf_Length(bp) + 2; /* add count of proto */
|
||||
mwp = mbuf_Alloc((orglen + 2) / 8 * 9 + 12, MB_HDLCOUT);
|
||||
hp = wp = MBUF_CTOP(mwp);
|
||||
cp = bufp;
|
||||
*wp++ = *cp++ = orglen >> 8;
|
||||
*wp++ = *cp++ = orglen & 0377;
|
||||
*cp++ = proto >> 8;
|
||||
*cp++ = proto & 0377;
|
||||
mbread(bp, cp, orglen - 2);
|
||||
fcs = HdlcFcs(INITFCS, bufp, 2 + orglen);
|
||||
mbuf_Read(bp, cp, orglen - 2);
|
||||
fcs = hdlc_Fcs(INITFCS, bufp, 2 + orglen);
|
||||
fcs = ~fcs;
|
||||
|
||||
len = compress(bufp + 2, wp, orglen);
|
||||
LogPrintf(LogDEBUG, "Pred1Output: orglen (%d) --> len (%d)\n", orglen, len);
|
||||
CcpInfo.uncompout += orglen;
|
||||
len = compress(state, bufp + 2, wp, orglen);
|
||||
log_Printf(LogDEBUG, "Pred1Output: orglen (%d) --> len (%d)\n", orglen, len);
|
||||
ccp->uncompout += orglen;
|
||||
if (len < orglen) {
|
||||
*hp |= 0x80;
|
||||
wp += len;
|
||||
CcpInfo.compout += len;
|
||||
ccp->compout += len;
|
||||
} else {
|
||||
memcpy(wp, bufp + 2, orglen);
|
||||
wp += orglen;
|
||||
CcpInfo.compout += orglen;
|
||||
ccp->compout += orglen;
|
||||
}
|
||||
|
||||
*wp++ = fcs & 0377;
|
||||
*wp++ = fcs >> 8;
|
||||
mwp->cnt = wp - MBUF_CTOP(mwp);
|
||||
HdlcOutput(PRI_NORMAL, PROTO_COMPD, mwp);
|
||||
hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mwp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
Pred1Input(u_short *proto, struct mbuf *bp)
|
||||
Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
||||
{
|
||||
struct pred1_state *state = (struct pred1_state *)v;
|
||||
u_char *cp, *pp;
|
||||
int len, olen, len1;
|
||||
struct mbuf *wp;
|
||||
u_char *bufp;
|
||||
u_short fcs;
|
||||
|
||||
wp = mballoc(MAX_MTU + 2, MB_IPIN);
|
||||
wp = mbuf_Alloc(MAX_MTU + 2, MB_IPIN);
|
||||
cp = MBUF_CTOP(bp);
|
||||
olen = plength(bp);
|
||||
olen = mbuf_Length(bp);
|
||||
pp = bufp = MBUF_CTOP(wp);
|
||||
*pp++ = *cp & 0177;
|
||||
len = *cp++ << 8;
|
||||
*pp++ = *cp;
|
||||
len += *cp++;
|
||||
CcpInfo.uncompin += len & 0x7fff;
|
||||
ccp->uncompin += len & 0x7fff;
|
||||
if (len & 0x8000) {
|
||||
len1 = decompress(cp, pp, olen - 4);
|
||||
CcpInfo.compin += olen;
|
||||
len1 = decompress(state, cp, pp, olen - 4);
|
||||
ccp->compin += olen;
|
||||
len &= 0x7fff;
|
||||
if (len != len1) { /* Error is detected. Send reset request */
|
||||
LogPrintf(LogCCP, "Pred1: Length error\n");
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
pfree(bp);
|
||||
pfree(wp);
|
||||
log_Printf(LogCCP, "Pred1: Length error\n");
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
mbuf_Free(bp);
|
||||
mbuf_Free(wp);
|
||||
return NULL;
|
||||
}
|
||||
cp += olen - 4;
|
||||
pp += len1;
|
||||
} else {
|
||||
CcpInfo.compin += len;
|
||||
SyncTable(cp, pp, len);
|
||||
ccp->compin += len;
|
||||
SyncTable(state, cp, pp, len);
|
||||
cp += len;
|
||||
pp += len;
|
||||
}
|
||||
*pp++ = *cp++; /* CRC */
|
||||
*pp++ = *cp++;
|
||||
fcs = HdlcFcs(INITFCS, bufp, wp->cnt = pp - bufp);
|
||||
fcs = hdlc_Fcs(INITFCS, bufp, wp->cnt = pp - bufp);
|
||||
if (fcs != GOODFCS)
|
||||
LogPrintf(LogDEBUG, "Pred1Input: fcs = 0x%04x (%s), len = 0x%x,"
|
||||
log_Printf(LogDEBUG, "Pred1Input: fcs = 0x%04x (%s), len = 0x%x,"
|
||||
" olen = 0x%x\n", fcs, (fcs == GOODFCS) ? "good" : "bad",
|
||||
len, olen);
|
||||
if (fcs == GOODFCS) {
|
||||
@ -279,19 +265,19 @@ Pred1Input(u_short *proto, struct mbuf *bp)
|
||||
wp->cnt -= 2;
|
||||
*proto = (*proto << 8) | *pp++;
|
||||
}
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
return wp;
|
||||
} else {
|
||||
LogDumpBp(LogHDLC, "Bad FCS", wp);
|
||||
CcpSendResetReq(&CcpFsm);
|
||||
pfree(wp);
|
||||
log_DumpBp(LogHDLC, "Bad FCS", wp);
|
||||
ccp_SendResetReq(&ccp->fsm);
|
||||
mbuf_Free(wp);
|
||||
}
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1DictSetup(u_short proto, struct mbuf * bp)
|
||||
Pred1DictSetup(void *v, struct ccp *ccp, u_short proto, struct mbuf * bp)
|
||||
{
|
||||
}
|
||||
|
||||
@ -302,40 +288,44 @@ Pred1DispOpts(struct lcp_opt *o)
|
||||
}
|
||||
|
||||
static void
|
||||
Pred1GetOpts(struct lcp_opt *o)
|
||||
Pred1InitOptsOutput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
o->id = TY_PRED1;
|
||||
o->len = 2;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1SetOpts(struct lcp_opt *o)
|
||||
Pred1SetOptsOutput(struct lcp_opt *o)
|
||||
{
|
||||
if (o->id != TY_PRED1 || o->len != 2) {
|
||||
Pred1GetOpts(o);
|
||||
if (o->len != 2) {
|
||||
o->len = 2;
|
||||
return MODE_NAK;
|
||||
}
|
||||
return MODE_ACK;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1SetOptsInput(struct lcp_opt *o, const struct ccp_config *cfg)
|
||||
{
|
||||
return Pred1SetOptsOutput(o);
|
||||
}
|
||||
|
||||
const struct ccp_algorithm Pred1Algorithm = {
|
||||
TY_PRED1,
|
||||
ConfPred1,
|
||||
CCP_NEG_PRED1,
|
||||
Pred1DispOpts,
|
||||
{
|
||||
Pred1GetOpts,
|
||||
Pred1SetOpts,
|
||||
Pred1SetOptsInput,
|
||||
Pred1InitInput,
|
||||
Pred1TermInput,
|
||||
Pred1Term,
|
||||
Pred1ResetInput,
|
||||
Pred1Input,
|
||||
Pred1DictSetup
|
||||
},
|
||||
{
|
||||
Pred1GetOpts,
|
||||
Pred1SetOpts,
|
||||
Pred1InitOptsOutput,
|
||||
Pred1SetOptsOutput,
|
||||
Pred1InitOutput,
|
||||
Pred1TermOutput,
|
||||
Pred1Term,
|
||||
Pred1ResetOutput,
|
||||
Pred1Output
|
||||
},
|
||||
|
522
usr.sbin/ppp/prompt.c
Normal file
522
usr.sbin/ppp/prompt.c
Normal file
@ -0,0 +1,522 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: prompt.c,v 1.1.2.30 1998/05/10 22:20:17 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/fcntl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "auth.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "async.h"
|
||||
#include "mbuf.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "chat.h"
|
||||
#include "chap.h"
|
||||
#include "datalink.h"
|
||||
#include "server.h"
|
||||
|
||||
static void
|
||||
prompt_Display(struct prompt *p)
|
||||
{
|
||||
static char shostname[MAXHOSTNAMELEN];
|
||||
const char *pconnect, *pauth;
|
||||
|
||||
if (p->TermMode || !p->needprompt)
|
||||
return;
|
||||
|
||||
p->needprompt = 0;
|
||||
|
||||
if (p->nonewline)
|
||||
p->nonewline = 0;
|
||||
else
|
||||
fprintf(p->Term, "\n");
|
||||
|
||||
if (p->auth == LOCAL_AUTH)
|
||||
pauth = " ON ";
|
||||
else
|
||||
pauth = " on ";
|
||||
|
||||
if (p->bundle->ncp.ipcp.fsm.state == ST_OPENED)
|
||||
pconnect = "PPP";
|
||||
else if (bundle_Phase(p->bundle) == PHASE_NETWORK)
|
||||
pconnect = "PPp";
|
||||
else if (bundle_Phase(p->bundle) == PHASE_AUTHENTICATE)
|
||||
pconnect = "Ppp";
|
||||
else
|
||||
pconnect = "ppp";
|
||||
|
||||
if (*shostname == '\0') {
|
||||
char *dot;
|
||||
|
||||
if (gethostname(shostname, sizeof shostname))
|
||||
strcpy(shostname, "localhost");
|
||||
else if ((dot = strchr(shostname, '.')))
|
||||
*dot = '\0';
|
||||
}
|
||||
|
||||
fprintf(p->Term, "%s%s%s> ", pconnect, pauth, shostname);
|
||||
fflush(p->Term);
|
||||
}
|
||||
|
||||
static int
|
||||
prompt_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
|
||||
{
|
||||
struct prompt *p = descriptor2prompt(d);
|
||||
int sets;
|
||||
|
||||
sets = 0;
|
||||
|
||||
if (!p->active)
|
||||
return sets;
|
||||
|
||||
if (p->fd_in >= 0) {
|
||||
if (r) {
|
||||
FD_SET(p->fd_in, r);
|
||||
log_Printf(LogTIMER, "prompt %s: fdset(r) %d\n", p->src.from, p->fd_in);
|
||||
sets++;
|
||||
}
|
||||
if (e) {
|
||||
FD_SET(p->fd_in, e);
|
||||
log_Printf(LogTIMER, "prompt %s: fdset(e) %d\n", p->src.from, p->fd_in);
|
||||
sets++;
|
||||
}
|
||||
if (sets && *n < p->fd_in + 1)
|
||||
*n = p->fd_in + 1;
|
||||
}
|
||||
|
||||
prompt_Display(p);
|
||||
|
||||
return sets;
|
||||
}
|
||||
|
||||
static int
|
||||
prompt_IsSet(struct descriptor *d, const fd_set *fdset)
|
||||
{
|
||||
struct prompt *p = descriptor2prompt(d);
|
||||
return p->fd_in >= 0 && FD_ISSET(p->fd_in, fdset);
|
||||
}
|
||||
|
||||
|
||||
static void
|
||||
prompt_ShowHelp(struct prompt *p)
|
||||
{
|
||||
prompt_Printf(p, "The following commands are available:\r\n");
|
||||
prompt_Printf(p, " ~p\tEnter Packet mode\r\n");
|
||||
prompt_Printf(p, " ~-\tDecrease log level\r\n");
|
||||
prompt_Printf(p, " ~+\tIncrease log level\r\n");
|
||||
prompt_Printf(p, " ~t\tShow timers\r\n");
|
||||
prompt_Printf(p, " ~m\tShow memory map\r\n");
|
||||
prompt_Printf(p, " ~.\tTerminate program\r\n");
|
||||
prompt_Printf(p, " ~?\tThis help\r\n");
|
||||
}
|
||||
|
||||
static void
|
||||
prompt_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
struct prompt *p = descriptor2prompt(d);
|
||||
int n;
|
||||
char ch;
|
||||
static int ttystate;
|
||||
char linebuff[LINE_LEN];
|
||||
|
||||
if (p->TermMode == NULL) {
|
||||
n = read(p->fd_in, linebuff, sizeof linebuff - 1);
|
||||
if (n > 0) {
|
||||
if (linebuff[n-1] == '\n')
|
||||
linebuff[--n] = '\0';
|
||||
else
|
||||
linebuff[n] = '\0';
|
||||
p->nonewline = 1; /* Maybe command_Decode does a prompt */
|
||||
prompt_Required(p);
|
||||
if (n)
|
||||
command_Decode(bundle, linebuff, n, p, p->src.from);
|
||||
} else if (n <= 0) {
|
||||
log_Printf(LogPHASE, "Client connection closed.\n");
|
||||
prompt_Destroy(p, 0);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
switch (p->TermMode->state) {
|
||||
case DATALINK_CLOSED:
|
||||
prompt_Printf(p, "Link lost, terminal mode.\n");
|
||||
prompt_TtyCommandMode(p);
|
||||
p->nonewline = 0;
|
||||
prompt_Required(p);
|
||||
return;
|
||||
|
||||
case DATALINK_READY:
|
||||
break;
|
||||
|
||||
case DATALINK_OPEN:
|
||||
prompt_Printf(p, "\nPacket mode detected.\n");
|
||||
prompt_TtyCommandMode(p);
|
||||
p->nonewline = 0;
|
||||
/* We'll get a prompt because of our status change */
|
||||
/* Fall through */
|
||||
|
||||
default:
|
||||
/* Wait 'till we're in a state we care about */
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* We are in terminal mode, decode special sequences
|
||||
*/
|
||||
n = read(p->fd_in, &ch, 1);
|
||||
log_Printf(LogDEBUG, "Got %d bytes (reading from the terminal)\n", n);
|
||||
|
||||
if (n > 0) {
|
||||
switch (ttystate) {
|
||||
case 0:
|
||||
if (ch == '~')
|
||||
ttystate++;
|
||||
else
|
||||
if (physical_Write(p->TermMode->physical, &ch, n) < 0) {
|
||||
log_Printf(LogERROR, "error writing to modem: %s\n", strerror(errno));
|
||||
prompt_TtyCommandMode(p);
|
||||
}
|
||||
break;
|
||||
case 1:
|
||||
switch (ch) {
|
||||
case '?':
|
||||
prompt_ShowHelp(p);
|
||||
break;
|
||||
case 'p':
|
||||
datalink_Up(p->TermMode, 0, 1);
|
||||
prompt_Printf(p, "\nPacket mode.\n");
|
||||
prompt_TtyCommandMode(p);
|
||||
break;
|
||||
case '.':
|
||||
prompt_TtyCommandMode(p);
|
||||
p->nonewline = 0;
|
||||
prompt_Required(p);
|
||||
break;
|
||||
case 't':
|
||||
timer_Show(0, p);
|
||||
break;
|
||||
case 'm':
|
||||
mbuf_Show(NULL);
|
||||
break;
|
||||
default:
|
||||
if (physical_Write(p->TermMode->physical, &ch, n) < 0) {
|
||||
log_Printf(LogERROR, "error writing to modem: %s\n", strerror(errno));
|
||||
prompt_TtyCommandMode(p);
|
||||
}
|
||||
break;
|
||||
}
|
||||
ttystate = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
prompt_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
/* We never want to write here ! */
|
||||
log_Printf(LogERROR, "prompt_Write: Internal error: Bad call !\n");
|
||||
}
|
||||
|
||||
struct prompt *
|
||||
prompt_Create(struct server *s, struct bundle *bundle, int fd)
|
||||
{
|
||||
struct prompt *p = (struct prompt *)malloc(sizeof(struct prompt));
|
||||
|
||||
if (p != NULL) {
|
||||
p->desc.type = PROMPT_DESCRIPTOR;
|
||||
p->desc.next = NULL;
|
||||
p->desc.UpdateSet = prompt_UpdateSet;
|
||||
p->desc.IsSet = prompt_IsSet;
|
||||
p->desc.Read = prompt_Read;
|
||||
p->desc.Write = prompt_Write;
|
||||
|
||||
if (fd == PROMPT_STD) {
|
||||
p->fd_in = STDIN_FILENO;
|
||||
p->fd_out = STDOUT_FILENO;
|
||||
p->Term = stdout;
|
||||
p->owner = NULL;
|
||||
p->auth = LOCAL_AUTH;
|
||||
p->src.type = "Controller";
|
||||
strncpy(p->src.from, ttyname(p->fd_out), sizeof p->src.from - 1);
|
||||
p->src.from[sizeof p->src.from - 1] = '\0';
|
||||
tcgetattr(p->fd_in, &p->oldtio); /* Save original tty mode */
|
||||
} else {
|
||||
p->fd_in = p->fd_out = fd;
|
||||
p->Term = fdopen(fd, "a+");
|
||||
p->owner = s;
|
||||
p->auth = *s->passwd ? LOCAL_NO_AUTH : LOCAL_AUTH;
|
||||
p->src.type = "unknown";
|
||||
*p->src.from = '\0';
|
||||
}
|
||||
p->TermMode = NULL;
|
||||
p->nonewline = 1;
|
||||
p->needprompt = 1;
|
||||
p->active = 1;
|
||||
p->bundle = bundle;
|
||||
if (p->bundle)
|
||||
bundle_RegisterDescriptor(p->bundle, &p->desc);
|
||||
log_RegisterPrompt(p);
|
||||
log_DiscardAllLocal(&p->logmask);
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
void
|
||||
prompt_Destroy(struct prompt *p, int verbose)
|
||||
{
|
||||
if (p->Term != stdout) {
|
||||
fclose(p->Term);
|
||||
close(p->fd_in);
|
||||
if (p->fd_out != p->fd_in)
|
||||
close(p->fd_out);
|
||||
if (verbose)
|
||||
log_Printf(LogPHASE, "Client connection dropped.\n");
|
||||
} else
|
||||
prompt_TtyOldMode(p);
|
||||
|
||||
log_UnRegisterPrompt(p);
|
||||
bundle_UnRegisterDescriptor(p->bundle, &p->desc);
|
||||
free(p);
|
||||
}
|
||||
|
||||
void
|
||||
prompt_Printf(struct prompt *p, const char *fmt,...)
|
||||
{
|
||||
if (p && p->active) {
|
||||
va_list ap;
|
||||
va_start(ap, fmt);
|
||||
vfprintf(p->Term, fmt, ap);
|
||||
fflush(p->Term);
|
||||
va_end(ap);
|
||||
p->nonewline = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prompt_vPrintf(struct prompt *p, const char *fmt, va_list ap)
|
||||
{
|
||||
if (p && p->active) {
|
||||
vfprintf(p->Term, fmt, ap);
|
||||
fflush(p->Term);
|
||||
p->nonewline = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prompt_TtyInit(struct prompt *p)
|
||||
{
|
||||
int stat, fd = p ? p->fd_in : STDIN_FILENO;
|
||||
struct termios newtio;
|
||||
|
||||
stat = fcntl(fd, F_GETFL, 0);
|
||||
if (stat > 0) {
|
||||
stat |= O_NONBLOCK;
|
||||
fcntl(fd, F_SETFL, stat);
|
||||
}
|
||||
|
||||
if (p)
|
||||
newtio = p->oldtio;
|
||||
else
|
||||
tcgetattr(fd, &newtio);
|
||||
|
||||
newtio.c_lflag &= ~(ECHO | ISIG | ICANON);
|
||||
newtio.c_iflag = 0;
|
||||
newtio.c_oflag &= ~OPOST;
|
||||
newtio.c_cc[VEOF] = _POSIX_VDISABLE;
|
||||
if (!p)
|
||||
newtio.c_cc[VINTR] = _POSIX_VDISABLE;
|
||||
newtio.c_cc[VMIN] = 1;
|
||||
newtio.c_cc[VTIME] = 0;
|
||||
newtio.c_cflag |= CS8;
|
||||
tcsetattr(fd, TCSANOW, &newtio);
|
||||
if (p)
|
||||
p->comtio = newtio;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set tty into command mode. We allow canonical input and echo processing.
|
||||
*/
|
||||
void
|
||||
prompt_TtyCommandMode(struct prompt *p)
|
||||
{
|
||||
struct termios newtio;
|
||||
int stat;
|
||||
|
||||
tcgetattr(p->fd_in, &newtio);
|
||||
newtio.c_lflag |= (ECHO | ISIG | ICANON);
|
||||
newtio.c_iflag = p->oldtio.c_iflag;
|
||||
newtio.c_oflag |= OPOST;
|
||||
tcsetattr(p->fd_in, TCSADRAIN, &newtio);
|
||||
|
||||
stat = fcntl(p->fd_in, F_GETFL, 0);
|
||||
if (stat > 0) {
|
||||
stat |= O_NONBLOCK;
|
||||
fcntl(p->fd_in, F_SETFL, stat);
|
||||
}
|
||||
|
||||
p->TermMode = NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set tty into terminal mode which is used while we invoke term command.
|
||||
*/
|
||||
void
|
||||
prompt_TtyTermMode(struct prompt *p, struct datalink *dl)
|
||||
{
|
||||
int stat;
|
||||
|
||||
prompt_Printf(p, "Entering terminal mode on %s.\n", dl->name);
|
||||
prompt_Printf(p, "Type `~?' for help.\n");
|
||||
|
||||
if (p->Term == stdout)
|
||||
tcsetattr(p->fd_in, TCSADRAIN, &p->comtio);
|
||||
|
||||
stat = fcntl(p->fd_in, F_GETFL, 0);
|
||||
if (stat > 0) {
|
||||
stat &= ~O_NONBLOCK;
|
||||
fcntl(p->fd_in, F_SETFL, stat);
|
||||
}
|
||||
p->TermMode = dl;
|
||||
}
|
||||
|
||||
void
|
||||
prompt_TtyOldMode(struct prompt *p)
|
||||
{
|
||||
int stat;
|
||||
|
||||
stat = fcntl(p->fd_in, F_GETFL, 0);
|
||||
if (stat > 0) {
|
||||
stat &= ~O_NONBLOCK;
|
||||
fcntl(p->fd_in, F_SETFL, stat);
|
||||
}
|
||||
|
||||
if (p->Term == stdout)
|
||||
tcsetattr(p->fd_in, TCSADRAIN, &p->oldtio);
|
||||
}
|
||||
|
||||
pid_t
|
||||
prompt_pgrp(struct prompt *p)
|
||||
{
|
||||
return tcgetpgrp(p->fd_in);
|
||||
}
|
||||
|
||||
int
|
||||
PasswdCommand(struct cmdargs const *arg)
|
||||
{
|
||||
const char *pass;
|
||||
|
||||
if (!arg->prompt) {
|
||||
log_Printf(LogWARN, "passwd: Cannot specify without a prompt\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg->prompt->owner == NULL) {
|
||||
log_Printf(LogWARN, "passwd: Not required\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (arg->argc == arg->argn)
|
||||
pass = "";
|
||||
else if (arg->argc > arg->argn+1)
|
||||
return -1;
|
||||
else
|
||||
pass = arg->argv[arg->argn];
|
||||
|
||||
if (!strcmp(arg->prompt->owner->passwd, pass))
|
||||
arg->prompt->auth = LOCAL_AUTH;
|
||||
else
|
||||
arg->prompt->auth = LOCAL_NO_AUTH;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct pppTimer bgtimer;
|
||||
|
||||
static void
|
||||
prompt_TimedContinue(void *v)
|
||||
{
|
||||
prompt_Continue((struct prompt *)v);
|
||||
}
|
||||
|
||||
void
|
||||
prompt_Continue(struct prompt *p)
|
||||
{
|
||||
timer_Stop(&bgtimer);
|
||||
if (getpgrp() == prompt_pgrp(p)) {
|
||||
prompt_TtyCommandMode(p);
|
||||
p->nonewline = 1;
|
||||
prompt_Required(p);
|
||||
p->active = 1;
|
||||
} else if (!p->owner) {
|
||||
bgtimer.func = prompt_TimedContinue;
|
||||
bgtimer.name = "prompt bg";
|
||||
bgtimer.load = SECTICKS;
|
||||
bgtimer.arg = p;
|
||||
timer_Start(&bgtimer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
prompt_Suspend(struct prompt *p)
|
||||
{
|
||||
if (getpgrp() == prompt_pgrp(p)) {
|
||||
prompt_TtyOldMode(p);
|
||||
p->active = 0;
|
||||
}
|
||||
}
|
90
usr.sbin/ppp/prompt.h
Normal file
90
usr.sbin/ppp/prompt.h
Normal file
@ -0,0 +1,90 @@
|
||||
/*-
|
||||
* Copyright (c) 1998 Brian Somers <brian@Awfulhak.org>
|
||||
* 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.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR 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 AUTHOR 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.
|
||||
*
|
||||
* $Id: prompt.h,v 1.1.2.9 1998/05/01 19:25:44 brian Exp $
|
||||
*/
|
||||
|
||||
#define LOCAL_AUTH 0x01
|
||||
#define LOCAL_NO_AUTH 0x02
|
||||
#define LOCAL_DENY 0x03
|
||||
#define LOCAL_CX 0x04 /* OR'd value - require a context */
|
||||
#define LOCAL_CX_OPT 0x08 /* OR'd value - optional context */
|
||||
|
||||
struct server;
|
||||
struct datalink;
|
||||
struct bundle;
|
||||
struct cmdargs;
|
||||
|
||||
struct prompt {
|
||||
struct descriptor desc;
|
||||
int fd_in, fd_out;
|
||||
struct datalink *TermMode; /* The modem we're talking directly to */
|
||||
FILE *Term; /* sits on top of fd_out */
|
||||
u_char auth; /* Local Authorized status */
|
||||
struct server *owner; /* who created me */
|
||||
struct bundle *bundle; /* who I'm controlling */
|
||||
unsigned nonewline : 1; /* need a newline before our prompt ? */
|
||||
unsigned needprompt : 1; /* Show a prompt at the next UpdateSet() */
|
||||
unsigned active : 1; /* Is the prompt active (^Z) */
|
||||
|
||||
struct {
|
||||
const char *type; /* Type of connection */
|
||||
char from[40]; /* Source of connection */
|
||||
} src;
|
||||
|
||||
struct prompt *lognext; /* Maintained in log.c */
|
||||
u_long logmask; /* Maintained in log.c */
|
||||
|
||||
struct termios oldtio; /* Original tty mode */
|
||||
struct termios comtio; /* Command level tty mode */
|
||||
};
|
||||
|
||||
#define descriptor2prompt(d) \
|
||||
((d)->type == PROMPT_DESCRIPTOR ? (struct prompt *)(d) : NULL)
|
||||
|
||||
#define PROMPT_STD (-1)
|
||||
extern struct prompt *prompt_Create(struct server *, struct bundle *, int);
|
||||
extern void prompt_Destroy(struct prompt *, int);
|
||||
extern void prompt_Required(struct prompt *);
|
||||
#ifdef __GNUC__
|
||||
extern void prompt_Printf(struct prompt *, const char *, ...)
|
||||
__attribute__ ((format (printf, 2, 3)));
|
||||
#else
|
||||
extern void prompt_Printf(struct prompt *, const char *, ...);
|
||||
#endif
|
||||
extern void prompt_vPrintf(struct prompt *, const char *, _BSD_VA_LIST_);
|
||||
#define PROMPT_DONT_WANT_INT 1
|
||||
#define PROMPT_WANT_INT 0
|
||||
extern void prompt_TtyInit(struct prompt *);
|
||||
extern void prompt_TtyCommandMode(struct prompt *);
|
||||
extern void prompt_TtyTermMode(struct prompt *, struct datalink *);
|
||||
extern void prompt_TtyOldMode(struct prompt *);
|
||||
extern pid_t prompt_pgrp(struct prompt *);
|
||||
extern int PasswdCommand(struct cmdargs const *);
|
||||
extern void prompt_Suspend(struct prompt *);
|
||||
extern void prompt_Continue(struct prompt *);
|
||||
#define prompt_IsTermMode(p, dl) ((p)->TermMode == (dl) ? 1 : 0)
|
||||
#define prompt_IsController(p) (!(p) || (p)->owner ? 0 : 1)
|
||||
#define prompt_Required(p) ((p)->needprompt = 1)
|
@ -17,12 +17,11 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: route.c,v 1.43 1998/03/13 01:36:10 brian Exp $
|
||||
* $Id: route.c,v 1.42.2.25 1998/05/16 21:19:00 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/route.h>
|
||||
@ -30,155 +29,42 @@
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <machine/endian.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <unistd.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "defs.h"
|
||||
#include "vars.h"
|
||||
#include "id.h"
|
||||
#include "os.h"
|
||||
#include "ipcp.h"
|
||||
#include "iplist.h"
|
||||
#include "timer.h"
|
||||
#include "throughput.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "route.h"
|
||||
|
||||
static int IfIndex;
|
||||
|
||||
struct rtmsg {
|
||||
struct rt_msghdr m_rtm;
|
||||
char m_space[64];
|
||||
};
|
||||
|
||||
static int seqno;
|
||||
|
||||
void
|
||||
OsSetRoute(int cmd,
|
||||
struct in_addr dst,
|
||||
struct in_addr gateway,
|
||||
struct in_addr mask,
|
||||
int bang)
|
||||
{
|
||||
struct rtmsg rtmes;
|
||||
int s, nb, wb;
|
||||
char *cp;
|
||||
const char *cmdstr;
|
||||
struct sockaddr_in rtdata;
|
||||
|
||||
if (bang)
|
||||
cmdstr = (cmd == RTM_ADD ? "Add!" : "Delete!");
|
||||
else
|
||||
cmdstr = (cmd == RTM_ADD ? "Add" : "Delete");
|
||||
s = ID0socket(PF_ROUTE, SOCK_RAW, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "OsSetRoute: socket(): %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
memset(&rtmes, '\0', sizeof rtmes);
|
||||
rtmes.m_rtm.rtm_version = RTM_VERSION;
|
||||
rtmes.m_rtm.rtm_type = cmd;
|
||||
rtmes.m_rtm.rtm_addrs = RTA_DST;
|
||||
rtmes.m_rtm.rtm_seq = ++seqno;
|
||||
rtmes.m_rtm.rtm_pid = getpid();
|
||||
rtmes.m_rtm.rtm_flags = RTF_UP | RTF_GATEWAY | RTF_STATIC;
|
||||
|
||||
memset(&rtdata, '\0', sizeof rtdata);
|
||||
rtdata.sin_len = 16;
|
||||
rtdata.sin_family = AF_INET;
|
||||
rtdata.sin_port = 0;
|
||||
rtdata.sin_addr = dst;
|
||||
|
||||
cp = rtmes.m_space;
|
||||
memcpy(cp, &rtdata, 16);
|
||||
cp += 16;
|
||||
if (cmd == RTM_ADD) {
|
||||
if (gateway.s_addr == INADDR_ANY) {
|
||||
/* Add a route through the interface */
|
||||
struct sockaddr_dl dl;
|
||||
const char *iname;
|
||||
int ilen;
|
||||
|
||||
iname = Index2Nam(IfIndex);
|
||||
ilen = strlen(iname);
|
||||
dl.sdl_len = sizeof dl - sizeof dl.sdl_data + ilen;
|
||||
dl.sdl_family = AF_LINK;
|
||||
dl.sdl_index = IfIndex;
|
||||
dl.sdl_type = 0;
|
||||
dl.sdl_nlen = ilen;
|
||||
dl.sdl_alen = 0;
|
||||
dl.sdl_slen = 0;
|
||||
strncpy(dl.sdl_data, iname, sizeof dl.sdl_data);
|
||||
|
||||
memcpy(cp, &dl, dl.sdl_len);
|
||||
cp += dl.sdl_len;
|
||||
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
|
||||
} else {
|
||||
rtdata.sin_addr = gateway;
|
||||
memcpy(cp, &rtdata, 16);
|
||||
cp += 16;
|
||||
rtmes.m_rtm.rtm_addrs |= RTA_GATEWAY;
|
||||
}
|
||||
}
|
||||
|
||||
if (dst.s_addr == INADDR_ANY)
|
||||
mask.s_addr = INADDR_ANY;
|
||||
|
||||
if (cmd == RTM_ADD || dst.s_addr == INADDR_ANY) {
|
||||
rtdata.sin_addr = mask;
|
||||
memcpy(cp, &rtdata, 16);
|
||||
cp += 16;
|
||||
rtmes.m_rtm.rtm_addrs |= RTA_NETMASK;
|
||||
}
|
||||
|
||||
nb = cp - (char *) &rtmes;
|
||||
rtmes.m_rtm.rtm_msglen = nb;
|
||||
wb = ID0write(s, &rtmes, nb);
|
||||
if (wb < 0) {
|
||||
LogPrintf(LogTCPIP, "OsSetRoute failure:\n");
|
||||
LogPrintf(LogTCPIP, "OsSetRoute: Cmd = %s\n", cmdstr);
|
||||
LogPrintf(LogTCPIP, "OsSetRoute: Dst = %s\n", inet_ntoa(dst));
|
||||
LogPrintf(LogTCPIP, "OsSetRoute: Gateway = %s\n", inet_ntoa(gateway));
|
||||
LogPrintf(LogTCPIP, "OsSetRoute: Mask = %s\n", inet_ntoa(mask));
|
||||
failed:
|
||||
if (cmd == RTM_ADD && (rtmes.m_rtm.rtm_errno == EEXIST ||
|
||||
(rtmes.m_rtm.rtm_errno == 0 && errno == EEXIST))) {
|
||||
if (!bang)
|
||||
LogPrintf(LogWARN, "Add route failed: %s already exists\n",
|
||||
inet_ntoa(dst));
|
||||
else {
|
||||
rtmes.m_rtm.rtm_type = cmd = RTM_CHANGE;
|
||||
if ((wb = ID0write(s, &rtmes, nb)) < 0)
|
||||
goto failed;
|
||||
}
|
||||
} else if (cmd == RTM_DELETE &&
|
||||
(rtmes.m_rtm.rtm_errno == ESRCH ||
|
||||
(rtmes.m_rtm.rtm_errno == 0 && errno == ESRCH))) {
|
||||
if (!bang)
|
||||
LogPrintf(LogWARN, "Del route failed: %s: Non-existent\n",
|
||||
inet_ntoa(dst));
|
||||
} else if (rtmes.m_rtm.rtm_errno == 0)
|
||||
LogPrintf(LogWARN, "%s route failed: %s: errno: %s\n", cmdstr,
|
||||
inet_ntoa(dst), strerror(errno));
|
||||
else
|
||||
LogPrintf(LogWARN, "%s route failed: %s: %s\n",
|
||||
cmdstr, inet_ntoa(dst), strerror(rtmes.m_rtm.rtm_errno));
|
||||
}
|
||||
LogPrintf(LogDEBUG, "wrote %d: cmd = %s, dst = %x, gateway = %x\n",
|
||||
wb, cmdstr, dst.s_addr, gateway.s_addr);
|
||||
close(s);
|
||||
}
|
||||
#include "prompt.h"
|
||||
|
||||
static void
|
||||
p_sockaddr(struct sockaddr *phost, struct sockaddr *pmask, int width)
|
||||
p_sockaddr(struct prompt *prompt, struct sockaddr *phost,
|
||||
struct sockaddr *pmask, int width)
|
||||
{
|
||||
char buf[29];
|
||||
struct sockaddr_in *ihost = (struct sockaddr_in *)phost;
|
||||
@ -238,7 +124,7 @@ p_sockaddr(struct sockaddr *phost, struct sockaddr *pmask, int width)
|
||||
strcpy(buf, "??:??:??:??:??:??");
|
||||
} else
|
||||
sprintf(buf, "<IFT type %d>", dl->sdl_type);
|
||||
} else if (dl->sdl_slen)
|
||||
} else if (dl->sdl_slen)
|
||||
sprintf(buf, "<slen %d?>", dl->sdl_slen);
|
||||
else
|
||||
sprintf(buf, "link#%d", dl->sdl_index);
|
||||
@ -249,7 +135,7 @@ p_sockaddr(struct sockaddr *phost, struct sockaddr *pmask, int width)
|
||||
break;
|
||||
}
|
||||
|
||||
fprintf(VarTerm, "%-*s ", width-1, buf);
|
||||
prompt_Printf(prompt, "%-*s ", width-1, buf);
|
||||
}
|
||||
|
||||
static struct bits {
|
||||
@ -290,21 +176,19 @@ static struct bits {
|
||||
#endif
|
||||
|
||||
static void
|
||||
p_flags(u_long f, int max)
|
||||
p_flags(struct prompt *prompt, u_long f, int max)
|
||||
{
|
||||
if (VarTerm) {
|
||||
char name[33], *flags;
|
||||
register struct bits *p = bits;
|
||||
char name[33], *flags;
|
||||
register struct bits *p = bits;
|
||||
|
||||
if (max > sizeof name - 1)
|
||||
max = sizeof name - 1;
|
||||
if (max > sizeof name - 1)
|
||||
max = sizeof name - 1;
|
||||
|
||||
for (flags = name; p->b_mask && flags - name < max; p++)
|
||||
if (p->b_mask & f)
|
||||
*flags++ = p->b_val;
|
||||
*flags = '\0';
|
||||
fprintf(VarTerm, "%-*.*s", max, max, name);
|
||||
}
|
||||
for (flags = name; p->b_mask && flags - name < max; p++)
|
||||
if (p->b_mask & f)
|
||||
*flags++ = p->b_val;
|
||||
*flags = '\0';
|
||||
prompt_Printf(prompt, "%-*.*s", max, max, name);
|
||||
}
|
||||
|
||||
const char *
|
||||
@ -328,7 +212,7 @@ Index2Nam(int idx)
|
||||
mib[5] = 0;
|
||||
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "Index2Nam: sysctl: estimate: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "Index2Nam: sysctl: estimate: %s\n", strerror(errno));
|
||||
return "???";
|
||||
}
|
||||
if ((buf = malloc(needed)) == NULL)
|
||||
@ -352,7 +236,7 @@ Index2Nam(int idx)
|
||||
else
|
||||
ifs = (char **)malloc(sizeof(char *) * have);
|
||||
if (!ifs) {
|
||||
LogPrintf(LogDEBUG, "Index2Nam: %s\n", strerror(errno));
|
||||
log_Printf(LogDEBUG, "Index2Nam: %s\n", strerror(errno));
|
||||
nifs = 0;
|
||||
return "???";
|
||||
}
|
||||
@ -365,20 +249,20 @@ Index2Nam(int idx)
|
||||
if (nifs < ifm->ifm_index)
|
||||
nifs = ifm->ifm_index;
|
||||
}
|
||||
} else if (LogIsKept(LogDEBUG))
|
||||
LogPrintf(LogDEBUG, "Skipping out-of-range interface %d!\n",
|
||||
} else if (log_IsKept(LogDEBUG))
|
||||
log_Printf(LogDEBUG, "Skipping out-of-range interface %d!\n",
|
||||
ifm->ifm_index);
|
||||
}
|
||||
free(buf);
|
||||
}
|
||||
|
||||
if (LogIsKept(LogDEBUG) && !debug_done) {
|
||||
if (log_IsKept(LogDEBUG) && !debug_done) {
|
||||
int f;
|
||||
|
||||
LogPrintf(LogDEBUG, "Found the following interfaces:\n");
|
||||
log_Printf(LogDEBUG, "Found the following interfaces:\n");
|
||||
for (f = 0; f < nifs; f++)
|
||||
if (ifs[f] != NULL)
|
||||
LogPrintf(LogDEBUG, " Index %d, name \"%s\"\n", f+1, ifs[f]);
|
||||
log_Printf(LogDEBUG, " Index %d, name \"%s\"\n", f+1, ifs[f]);
|
||||
debug_done = 1;
|
||||
}
|
||||
|
||||
@ -389,7 +273,7 @@ Index2Nam(int idx)
|
||||
}
|
||||
|
||||
int
|
||||
ShowRoute(struct cmdargs const *arg)
|
||||
route_Show(struct cmdargs const *arg)
|
||||
{
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr *sa_dst, *sa_gw, *sa_mask;
|
||||
@ -397,9 +281,6 @@ ShowRoute(struct cmdargs const *arg)
|
||||
size_t needed;
|
||||
int mib[6];
|
||||
|
||||
if (!VarTerm)
|
||||
return 1;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
mib[1] = PF_ROUTE;
|
||||
mib[2] = 0;
|
||||
@ -407,7 +288,7 @@ ShowRoute(struct cmdargs const *arg)
|
||||
mib[4] = NET_RT_DUMP;
|
||||
mib[5] = 0;
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "ShowRoute: sysctl: estimate: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "route_Show: sysctl: estimate: %s\n", strerror(errno));
|
||||
return (1);
|
||||
}
|
||||
if (needed < 0)
|
||||
@ -416,13 +297,14 @@ ShowRoute(struct cmdargs const *arg)
|
||||
if (sp == NULL)
|
||||
return (1);
|
||||
if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "ShowRoute: sysctl: getroute: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "route_Show: sysctl: getroute: %s\n", strerror(errno));
|
||||
free(sp);
|
||||
return (1);
|
||||
}
|
||||
ep = sp + needed;
|
||||
|
||||
fprintf(VarTerm, "%-20s%-20sFlags Netif\n", "Destination", "Gateway");
|
||||
prompt_Printf(arg->prompt, "%-20s%-20sFlags Netif\n",
|
||||
"Destination", "Gateway");
|
||||
for (cp = sp; cp < ep; cp += rtm->rtm_msglen) {
|
||||
rtm = (struct rt_msghdr *) cp;
|
||||
wp = (char *)(rtm+1);
|
||||
@ -445,11 +327,11 @@ ShowRoute(struct cmdargs const *arg)
|
||||
} else
|
||||
sa_mask = NULL;
|
||||
|
||||
p_sockaddr(sa_dst, sa_mask, 20);
|
||||
p_sockaddr(sa_gw, NULL, 20);
|
||||
p_sockaddr(arg->prompt, sa_dst, sa_mask, 20);
|
||||
p_sockaddr(arg->prompt, sa_gw, NULL, 20);
|
||||
|
||||
p_flags(rtm->rtm_flags, 6);
|
||||
fprintf(VarTerm, " %s\n", Index2Nam(rtm->rtm_index));
|
||||
p_flags(arg->prompt, rtm->rtm_flags, 6);
|
||||
prompt_Printf(arg->prompt, " %s\n", Index2Nam(rtm->rtm_index));
|
||||
}
|
||||
free(sp);
|
||||
return 0;
|
||||
@ -459,7 +341,7 @@ ShowRoute(struct cmdargs const *arg)
|
||||
* Delete routes associated with our interface
|
||||
*/
|
||||
void
|
||||
DeleteIfRoutes(int all)
|
||||
route_IfDelete(struct bundle *bundle, int all)
|
||||
{
|
||||
struct rt_msghdr *rtm;
|
||||
struct sockaddr *sa;
|
||||
@ -469,7 +351,7 @@ DeleteIfRoutes(int all)
|
||||
char *sp, *cp, *ep;
|
||||
int mib[6];
|
||||
|
||||
LogPrintf(LogDEBUG, "DeleteIfRoutes (%d)\n", IfIndex);
|
||||
log_Printf(LogDEBUG, "route_IfDelete (%d)\n", bundle->ifp.Index);
|
||||
sa_none.s_addr = INADDR_ANY;
|
||||
|
||||
mib[0] = CTL_NET;
|
||||
@ -479,7 +361,7 @@ DeleteIfRoutes(int all)
|
||||
mib[4] = NET_RT_DUMP;
|
||||
mib[5] = 0;
|
||||
if (sysctl(mib, 6, NULL, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "DeleteIfRoutes: sysctl: estimate: %s\n",
|
||||
log_Printf(LogERROR, "route_IfDelete: sysctl: estimate: %s\n",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
@ -491,7 +373,7 @@ DeleteIfRoutes(int all)
|
||||
return;
|
||||
|
||||
if (sysctl(mib, 6, sp, &needed, NULL, 0) < 0) {
|
||||
LogPrintf(LogERROR, "DeleteIfRoutes: sysctl: getroute: %s\n",
|
||||
log_Printf(LogERROR, "route_IfDelete: sysctl: getroute: %s\n",
|
||||
strerror(errno));
|
||||
free(sp);
|
||||
return;
|
||||
@ -503,7 +385,8 @@ DeleteIfRoutes(int all)
|
||||
* We do 2 passes. The first deletes all cloned routes. The second
|
||||
* deletes all non-cloned routes. This is necessary to avoid
|
||||
* potential errors from trying to delete route X after route Y where
|
||||
* route X was cloned from route Y (which is no longer there).
|
||||
* route X was cloned from route Y (and is no longer there 'cos it
|
||||
* may have gone with route Y).
|
||||
*/
|
||||
if (RTF_WASCLONED == 0 && pass == 0)
|
||||
/* So we can't tell ! */
|
||||
@ -511,25 +394,25 @@ DeleteIfRoutes(int all)
|
||||
for (cp = sp; cp < ep; cp += rtm->rtm_msglen) {
|
||||
rtm = (struct rt_msghdr *) cp;
|
||||
sa = (struct sockaddr *) (rtm + 1);
|
||||
LogPrintf(LogDEBUG, "DeleteIfRoutes: addrs: %x, Netif: %d (%s),"
|
||||
log_Printf(LogDEBUG, "route_IfDelete: addrs: %x, Netif: %d (%s),"
|
||||
" flags: %x, dst: %s ?\n", rtm->rtm_addrs, rtm->rtm_index,
|
||||
Index2Nam(rtm->rtm_index), rtm->rtm_flags,
|
||||
inet_ntoa(((struct sockaddr_in *) sa)->sin_addr));
|
||||
if (rtm->rtm_addrs & RTA_DST && rtm->rtm_addrs & RTA_GATEWAY &&
|
||||
rtm->rtm_index == IfIndex &&
|
||||
rtm->rtm_index == bundle->ifp.Index &&
|
||||
(all || (rtm->rtm_flags & RTF_GATEWAY))) {
|
||||
sa_dst.s_addr = ((struct sockaddr_in *)sa)->sin_addr.s_addr;
|
||||
sa = (struct sockaddr *)((char *)sa + sa->sa_len);
|
||||
if (sa->sa_family == AF_INET || sa->sa_family == AF_LINK) {
|
||||
if ((pass == 0 && (rtm->rtm_flags & RTF_WASCLONED)) ||
|
||||
(pass == 1 && !(rtm->rtm_flags & RTF_WASCLONED))) {
|
||||
LogPrintf(LogDEBUG, "DeleteIfRoutes: Remove it (pass %d)\n", pass);
|
||||
OsSetRoute(RTM_DELETE, sa_dst, sa_none, sa_none, 0);
|
||||
log_Printf(LogDEBUG, "route_IfDelete: Remove it (pass %d)\n", pass);
|
||||
bundle_SetRoute(bundle, RTM_DELETE, sa_dst, sa_none, sa_none, 0);
|
||||
} else
|
||||
LogPrintf(LogDEBUG, "DeleteIfRoutes: Skip it (pass %d)\n", pass);
|
||||
log_Printf(LogDEBUG, "route_IfDelete: Skip it (pass %d)\n", pass);
|
||||
} else
|
||||
LogPrintf(LogDEBUG,
|
||||
"DeleteIfRoutes: Can't remove routes of %d family !\n",
|
||||
log_Printf(LogDEBUG,
|
||||
"route_IfDelete: Can't remove routes of %d family !\n",
|
||||
sa->sa_family);
|
||||
}
|
||||
}
|
||||
@ -546,33 +429,133 @@ GetIfIndex(char *name)
|
||||
idx = 1;
|
||||
while (strcmp(got = Index2Nam(idx), "???"))
|
||||
if (!strcmp(got, name))
|
||||
return IfIndex = idx;
|
||||
return idx;
|
||||
else
|
||||
idx++;
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct in_addr
|
||||
ChooseHisAddr(const struct in_addr gw)
|
||||
void
|
||||
route_Change(struct bundle *bundle, struct sticky_route *r,
|
||||
struct in_addr me, struct in_addr peer)
|
||||
{
|
||||
struct in_addr try;
|
||||
int f;
|
||||
struct in_addr none, del;
|
||||
|
||||
for (f = 0; f < DefHisChoice.nItems; f++) {
|
||||
try = iplist_next(&DefHisChoice);
|
||||
LogPrintf(LogDEBUG, "ChooseHisAddr: Check item %d (%s)\n",
|
||||
f, inet_ntoa(try));
|
||||
if (OsTrySetIpaddress(gw, try) == 0) {
|
||||
LogPrintf(LogIPCP, "ChooseHisAddr: Selected IP address %s\n",
|
||||
inet_ntoa(try));
|
||||
none.s_addr = INADDR_ANY;
|
||||
for (; r; r = r->next) {
|
||||
if ((r->type & ROUTE_DSTMYADDR) && r->dst.s_addr != me.s_addr) {
|
||||
del.s_addr = r->dst.s_addr & r->mask.s_addr;
|
||||
bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1);
|
||||
r->dst = me;
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
r->gw = peer;
|
||||
} else if ((r->type & ROUTE_DSTHISADDR) && r->dst.s_addr != peer.s_addr) {
|
||||
del.s_addr = r->dst.s_addr & r->mask.s_addr;
|
||||
bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1);
|
||||
r->dst = peer;
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
r->gw = peer;
|
||||
} else if ((r->type & ROUTE_GWHISADDR) && r->gw.s_addr != peer.s_addr)
|
||||
r->gw = peer;
|
||||
bundle_SetRoute(bundle, RTM_ADD, r->dst, r->gw, r->mask, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
route_Clean(struct bundle *bundle, struct sticky_route *r)
|
||||
{
|
||||
struct in_addr none, del;
|
||||
|
||||
none.s_addr = INADDR_ANY;
|
||||
for (; r; r = r->next) {
|
||||
del.s_addr = r->dst.s_addr & r->mask.s_addr;
|
||||
bundle_SetRoute(bundle, RTM_DELETE, del, none, none, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
route_Add(struct sticky_route **rp, int type, struct in_addr dst,
|
||||
struct in_addr mask, struct in_addr gw)
|
||||
{
|
||||
if (type != ROUTE_STATIC) {
|
||||
struct sticky_route *r;
|
||||
int dsttype = type & ROUTE_DSTANY;
|
||||
|
||||
r = NULL;
|
||||
while (*rp) {
|
||||
if ((dsttype && dsttype == ((*rp)->type & ROUTE_DSTANY)) ||
|
||||
(!dsttype && (*rp)->dst.s_addr == dst.s_addr)) {
|
||||
r = *rp;
|
||||
*rp = r->next;
|
||||
} else
|
||||
rp = &(*rp)->next;
|
||||
}
|
||||
|
||||
if (!r)
|
||||
r = (struct sticky_route *)malloc(sizeof(struct sticky_route));
|
||||
r->type = type;
|
||||
r->next = NULL;
|
||||
r->dst = dst;
|
||||
r->mask = mask;
|
||||
r->gw = gw;
|
||||
*rp = r;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
route_Delete(struct sticky_route **rp, int type, struct in_addr dst)
|
||||
{
|
||||
struct sticky_route *r;
|
||||
int dsttype = type & ROUTE_DSTANY;
|
||||
|
||||
for (; *rp; rp = &(*rp)->next) {
|
||||
if ((dsttype && dsttype == ((*rp)->type & ROUTE_DSTANY)) ||
|
||||
(!dsttype && dst.s_addr == ((*rp)->dst.s_addr & (*rp)->mask.s_addr))) {
|
||||
r = *rp;
|
||||
*rp = r->next;
|
||||
free(r);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (f == DefHisChoice.nItems) {
|
||||
LogPrintf(LogDEBUG, "ChooseHisAddr: All addresses in use !\n");
|
||||
try.s_addr = INADDR_ANY;
|
||||
}
|
||||
|
||||
return try;
|
||||
}
|
||||
|
||||
void
|
||||
route_DeleteAll(struct sticky_route **rp)
|
||||
{
|
||||
struct sticky_route *r, *rn;
|
||||
|
||||
for (r = *rp; r; r = rn) {
|
||||
rn = r->next;
|
||||
free(r);
|
||||
}
|
||||
*rp = NULL;
|
||||
}
|
||||
|
||||
void
|
||||
route_ShowSticky(struct prompt *p, struct sticky_route *r)
|
||||
{
|
||||
int def;
|
||||
|
||||
prompt_Printf(p, "Sticky routes:\n");
|
||||
for (; r; r = r->next) {
|
||||
def = r->dst.s_addr == INADDR_ANY && r->mask.s_addr == INADDR_ANY;
|
||||
|
||||
prompt_Printf(p, " add ");
|
||||
if (r->type & ROUTE_DSTMYADDR)
|
||||
prompt_Printf(p, "MYADDR");
|
||||
else if (r->type & ROUTE_DSTHISADDR)
|
||||
prompt_Printf(p, "HISADDR");
|
||||
else if (!def)
|
||||
prompt_Printf(p, "%s", inet_ntoa(r->dst));
|
||||
|
||||
if (def)
|
||||
prompt_Printf(p, "default ");
|
||||
else
|
||||
prompt_Printf(p, " %s ", inet_ntoa(r->mask));
|
||||
|
||||
if (r->type & ROUTE_GWHISADDR)
|
||||
prompt_Printf(p, "HISADDR\n");
|
||||
else
|
||||
prompt_Printf(p, "%s\n", inet_ntoa(r->gw));
|
||||
}
|
||||
}
|
||||
|
@ -17,13 +17,37 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: route.h,v 1.9 1997/12/30 02:45:48 brian Exp $
|
||||
* $Id: route.h,v 1.10.2.6 1998/05/05 23:30:13 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
struct bundle;
|
||||
struct cmdargs;
|
||||
|
||||
#define ROUTE_STATIC 0
|
||||
#define ROUTE_DSTMYADDR 1
|
||||
#define ROUTE_DSTHISADDR 2
|
||||
#define ROUTE_DSTANY 3
|
||||
#define ROUTE_GWHISADDR 4 /* May be ORd with DST_MYADDR */
|
||||
|
||||
struct sticky_route {
|
||||
int type; /* ROUTE_* value (not _STATIC) */
|
||||
struct sticky_route *next; /* next in list */
|
||||
|
||||
struct in_addr dst;
|
||||
struct in_addr mask;
|
||||
struct in_addr gw;
|
||||
};
|
||||
|
||||
extern int GetIfIndex(char *);
|
||||
extern int ShowRoute(struct cmdargs const *);
|
||||
extern void OsSetRoute(int, struct in_addr, struct in_addr, struct in_addr,int);
|
||||
extern void DeleteIfRoutes(int);
|
||||
extern struct in_addr ChooseHisAddr(const struct in_addr);
|
||||
extern int route_Show(struct cmdargs const *);
|
||||
extern void route_IfDelete(struct bundle *, int);
|
||||
extern const char *Index2Nam(int);
|
||||
extern void route_Change(struct bundle *, struct sticky_route *,
|
||||
struct in_addr, struct in_addr);
|
||||
extern void route_Add(struct sticky_route **, int, struct in_addr,
|
||||
struct in_addr, struct in_addr);
|
||||
extern void route_Delete(struct sticky_route **, int, struct in_addr);
|
||||
extern void route_DeleteAll(struct sticky_route **);
|
||||
extern void route_Clean(struct bundle *, struct sticky_route *);
|
||||
extern void route_ShowSticky(struct prompt *, struct sticky_route *);
|
||||
|
@ -23,113 +23,213 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: server.c,v 1.16 1998/01/21 02:15:27 brian Exp $
|
||||
* $Id: server.c,v 1.16.2.19 1998/05/10 22:20:20 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/un.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "loadalias.h"
|
||||
#include "defs.h"
|
||||
#include "vars.h"
|
||||
#include "descriptor.h"
|
||||
#include "server.h"
|
||||
#include "id.h"
|
||||
#include "prompt.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "throughput.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "bundle.h"
|
||||
|
||||
int server = -1;
|
||||
static int
|
||||
server_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
|
||||
{
|
||||
struct server *s = descriptor2server(d);
|
||||
|
||||
static struct sockaddr_un ifsun;
|
||||
static char *rm;
|
||||
if (r && s->fd >= 0) {
|
||||
if (*n < s->fd + 1)
|
||||
*n = s->fd + 1;
|
||||
FD_SET(s->fd, r);
|
||||
log_Printf(LogTIMER, "server: fdset(r) %d\n", s->fd);
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
server_IsSet(struct descriptor *d, const fd_set *fdset)
|
||||
{
|
||||
struct server *s = descriptor2server(d);
|
||||
return s->fd >= 0 && FD_ISSET(s->fd, fdset);
|
||||
}
|
||||
|
||||
#define IN_SIZE sizeof(struct sockaddr_in)
|
||||
#define UN_SIZE sizeof(struct sockaddr_in)
|
||||
#define ADDRSZ (IN_SIZE > UN_SIZE ? IN_SIZE : UN_SIZE)
|
||||
|
||||
static void
|
||||
server_Read(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
struct server *s = descriptor2server(d);
|
||||
char hisaddr[ADDRSZ];
|
||||
struct sockaddr *sa = (struct sockaddr *)hisaddr;
|
||||
struct sockaddr_in *in = (struct sockaddr_in *)hisaddr;
|
||||
int ssize = ADDRSZ, wfd;
|
||||
struct prompt *p;
|
||||
|
||||
wfd = accept(s->fd, sa, &ssize);
|
||||
if (wfd < 0) {
|
||||
log_Printf(LogERROR, "server_Read: accept(): %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
|
||||
switch (sa->sa_family) {
|
||||
case AF_LOCAL:
|
||||
log_Printf(LogPHASE, "Connected to local client.\n");
|
||||
break;
|
||||
|
||||
case AF_INET:
|
||||
if (ntohs(in->sin_port) < 1024) {
|
||||
log_Printf(LogALERT, "Rejected client connection from %s:%u"
|
||||
"(invalid port number) !\n",
|
||||
inet_ntoa(in->sin_addr), ntohs(in->sin_port));
|
||||
close(wfd);
|
||||
return;
|
||||
}
|
||||
log_Printf(LogPHASE, "Connected to client from %s:%u\n",
|
||||
inet_ntoa(in->sin_addr), in->sin_port);
|
||||
break;
|
||||
|
||||
default:
|
||||
write(wfd, "Unrecognised access !\n", 22);
|
||||
close(wfd);
|
||||
return;
|
||||
}
|
||||
|
||||
if ((p = prompt_Create(s, bundle, wfd)) == NULL) {
|
||||
write(wfd, "Connection refused.\n", 20);
|
||||
close(wfd);
|
||||
} else {
|
||||
switch (sa->sa_family) {
|
||||
case AF_LOCAL:
|
||||
p->src.type = "local";
|
||||
strncpy(p->src.from, s->rm, sizeof p->src.from - 1);
|
||||
p->src.from[sizeof p->src.from - 1] = '\0';
|
||||
break;
|
||||
case AF_INET:
|
||||
p->src.type = "tcp";
|
||||
snprintf(p->src.from, sizeof p->src.from, "%s:%u",
|
||||
inet_ntoa(in->sin_addr), in->sin_port);
|
||||
break;
|
||||
}
|
||||
prompt_TtyCommandMode(p);
|
||||
prompt_Required(p);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
server_Write(struct descriptor *d, struct bundle *bundle, const fd_set *fdset)
|
||||
{
|
||||
/* We never want to write here ! */
|
||||
log_Printf(LogERROR, "server_Write: Internal error: Bad call !\n");
|
||||
}
|
||||
|
||||
struct server server = {
|
||||
{
|
||||
SERVER_DESCRIPTOR,
|
||||
NULL,
|
||||
server_UpdateSet,
|
||||
server_IsSet,
|
||||
server_Read,
|
||||
server_Write
|
||||
},
|
||||
-1
|
||||
};
|
||||
|
||||
int
|
||||
ServerLocalOpen(const char *name, mode_t mask)
|
||||
server_LocalOpen(struct bundle *bundle, const char *name, mode_t mask)
|
||||
{
|
||||
int s;
|
||||
|
||||
if (VarLocalAuth == LOCAL_DENY) {
|
||||
LogPrintf(LogWARN, "Local: Can't open socket %s: No password "
|
||||
"in ppp.secret\n", name);
|
||||
return 1;
|
||||
if (server.rm && !strcmp(server.rm, name)) {
|
||||
if (chmod(server.rm, mask))
|
||||
log_Printf(LogERROR, "Local: chmod: %s\n", strerror(errno));
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (mode & MODE_INTER) {
|
||||
LogPrintf(LogWARN, "Local: Can't open socket in interactive mode\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
memset(&ifsun, '\0', sizeof ifsun);
|
||||
ifsun.sun_len = strlen(name);
|
||||
if (ifsun.sun_len > sizeof ifsun.sun_path - 1) {
|
||||
LogPrintf(LogERROR, "Local: %s: Path too long\n", name);
|
||||
memset(&server.ifsun, '\0', sizeof server.ifsun);
|
||||
server.ifsun.sun_len = strlen(name);
|
||||
if (server.ifsun.sun_len > sizeof server.ifsun.sun_path - 1) {
|
||||
log_Printf(LogERROR, "Local: %s: Path too long\n", name);
|
||||
return 2;
|
||||
}
|
||||
ifsun.sun_family = AF_LOCAL;
|
||||
strcpy(ifsun.sun_path, name);
|
||||
server.ifsun.sun_family = AF_LOCAL;
|
||||
strcpy(server.ifsun.sun_path, name);
|
||||
|
||||
s = ID0socket(PF_LOCAL, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "Local: socket: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "Local: socket: %s\n", strerror(errno));
|
||||
return 3;
|
||||
}
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
|
||||
if (mask != (mode_t)-1)
|
||||
mask = umask(mask);
|
||||
if (bind(s, (struct sockaddr *)&ifsun, sizeof ifsun) < 0) {
|
||||
if (bind(s, (struct sockaddr *)&server.ifsun, sizeof server.ifsun) < 0) {
|
||||
if (mask != (mode_t)-1)
|
||||
umask(mask);
|
||||
LogPrintf(LogERROR, "Local: bind: %s\n", strerror(errno));
|
||||
if (errno == EADDRINUSE && VarTerm)
|
||||
fprintf(VarTerm, "Wait for a while, then try again.\n");
|
||||
log_Printf(LogWARN, "Local: bind: %s\n", strerror(errno));
|
||||
close(s);
|
||||
return 4;
|
||||
}
|
||||
if (mask != (mode_t)-1)
|
||||
umask(mask);
|
||||
if (listen(s, 5) != 0) {
|
||||
LogPrintf(LogERROR, "Local: Unable to listen to socket - OS overload?\n");
|
||||
log_Printf(LogERROR, "Local: Unable to listen to socket - BUNDLE overload?\n");
|
||||
close(s);
|
||||
ID0unlink(name);
|
||||
return 5;
|
||||
}
|
||||
ServerClose();
|
||||
server = s;
|
||||
rm = ifsun.sun_path;
|
||||
LogPrintf(LogPHASE, "Listening at local socket %s.\n", name);
|
||||
server_Close(bundle);
|
||||
server.fd = s;
|
||||
server.rm = server.ifsun.sun_path;
|
||||
log_Printf(LogPHASE, "Listening at local socket %s.\n", name);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
ServerTcpOpen(int port)
|
||||
server_TcpOpen(struct bundle *bundle, int port)
|
||||
{
|
||||
struct sockaddr_in ifsin;
|
||||
int s;
|
||||
|
||||
if (VarLocalAuth == LOCAL_DENY) {
|
||||
LogPrintf(LogWARN, "Tcp: Can't open socket %d: No password "
|
||||
"in ppp.secret\n", port);
|
||||
return 6;
|
||||
}
|
||||
|
||||
if (mode & MODE_INTER) {
|
||||
LogPrintf(LogWARN, "Tcp: Can't open socket in interactive mode\n");
|
||||
return 6;
|
||||
}
|
||||
if (server.port == port)
|
||||
return 0;
|
||||
|
||||
s = ID0socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
LogPrintf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
|
||||
log_Printf(LogERROR, "Tcp: socket: %s\n", strerror(errno));
|
||||
return 7;
|
||||
}
|
||||
memset(&ifsin, '\0', sizeof ifsin);
|
||||
@ -138,32 +238,36 @@ ServerTcpOpen(int port)
|
||||
ifsin.sin_port = htons(port);
|
||||
setsockopt(s, SOL_SOCKET, SO_REUSEADDR, &s, sizeof s);
|
||||
if (bind(s, (struct sockaddr *)&ifsin, sizeof ifsin) < 0) {
|
||||
LogPrintf(LogERROR, "Tcp: bind: %s\n", strerror(errno));
|
||||
if (errno == EADDRINUSE && VarTerm)
|
||||
fprintf(VarTerm, "Wait for a while, then try again.\n");
|
||||
log_Printf(LogWARN, "Tcp: bind: %s\n", strerror(errno));
|
||||
close(s);
|
||||
return 8;
|
||||
}
|
||||
if (listen(s, 5) != 0) {
|
||||
LogPrintf(LogERROR, "Tcp: Unable to listen to socket - OS overload?\n");
|
||||
log_Printf(LogERROR, "Tcp: Unable to listen to socket - BUNDLE overload?\n");
|
||||
close(s);
|
||||
return 9;
|
||||
}
|
||||
ServerClose();
|
||||
server = s;
|
||||
LogPrintf(LogPHASE, "Listening at port %d.\n", port);
|
||||
server_Close(bundle);
|
||||
server.fd = s;
|
||||
server.port = port;
|
||||
log_Printf(LogPHASE, "Listening at port %d.\n", port);
|
||||
return 0;
|
||||
}
|
||||
|
||||
void
|
||||
ServerClose()
|
||||
int
|
||||
server_Close(struct bundle *bundle)
|
||||
{
|
||||
if (server >= 0) {
|
||||
close(server);
|
||||
if (rm) {
|
||||
ID0unlink(rm);
|
||||
rm = 0;
|
||||
if (server.fd >= 0) {
|
||||
close(server.fd);
|
||||
if (server.rm) {
|
||||
ID0unlink(server.rm);
|
||||
server.rm = NULL;
|
||||
}
|
||||
server.fd = -1;
|
||||
server.port = 0;
|
||||
/* Drop associated prompts */
|
||||
bundle_DelPromptDescriptors(bundle, &server);
|
||||
return 1;
|
||||
}
|
||||
server = -1;
|
||||
return 0;
|
||||
}
|
||||
|
@ -23,11 +23,27 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: server.h,v 1.4.2.5 1998/05/01 19:25:52 brian Exp $
|
||||
*/
|
||||
|
||||
extern int server;
|
||||
struct bundle;
|
||||
|
||||
extern int ServerLocalOpen(const char *, mode_t);
|
||||
extern int ServerTcpOpen(int);
|
||||
extern void ServerClose(void);
|
||||
struct server {
|
||||
struct descriptor desc;
|
||||
int fd;
|
||||
char passwd[50];
|
||||
|
||||
struct sockaddr_un ifsun; /* local socket */
|
||||
char *rm; /* Points to local socket path */
|
||||
|
||||
u_short port; /* tcp socket */
|
||||
};
|
||||
|
||||
#define descriptor2server(d) \
|
||||
((d)->type == SERVER_DESCRIPTOR ? (struct server *)(d) : NULL)
|
||||
|
||||
extern struct server server;
|
||||
|
||||
extern int server_LocalOpen(struct bundle *, const char *, mode_t);
|
||||
extern int server_TcpOpen(struct bundle *, int);
|
||||
extern int server_Close(struct bundle *);
|
||||
|
@ -23,15 +23,13 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: sig.c,v 1.11 1997/12/21 12:11:08 brian Exp $
|
||||
* $Id: sig.c,v 1.11.2.5 1998/05/01 19:25:56 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <signal.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "sig.h"
|
||||
|
||||
@ -54,13 +52,13 @@ signal_recorder(int sig)
|
||||
*/
|
||||
|
||||
sig_type
|
||||
pending_signal(int sig, sig_type fn)
|
||||
sig_signal(int sig, sig_type fn)
|
||||
{
|
||||
sig_type Result;
|
||||
|
||||
if (sig <= 0 || sig > NSIG) {
|
||||
/* Oops - we must be a bit out of date (too many sigs ?) */
|
||||
LogPrintf(LogALERT, "Eeek! %s:%s: I must be out of date!\n",
|
||||
log_Printf(LogALERT, "Eeek! %s:%d: I must be out of date!\n",
|
||||
__FILE__, __LINE__);
|
||||
return signal(sig, fn);
|
||||
}
|
||||
@ -80,7 +78,7 @@ pending_signal(int sig, sig_type fn)
|
||||
/* Call the handlers for any pending signals */
|
||||
|
||||
void
|
||||
handle_signals()
|
||||
sig_Handle()
|
||||
{
|
||||
int sig;
|
||||
int got;
|
||||
|
@ -23,13 +23,13 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: sig.h,v 1.11.2.1 1998/05/01 19:25:57 brian Exp $
|
||||
*/
|
||||
|
||||
typedef void (*sig_type)(int);
|
||||
|
||||
/* Call this instead of signal() */
|
||||
extern sig_type pending_signal(int, sig_type);
|
||||
extern sig_type sig_signal(int, sig_type);
|
||||
|
||||
/* Call this when you want things to *actually* happen */
|
||||
extern void handle_signals(void);
|
||||
extern void sig_Handle(void);
|
||||
|
@ -17,41 +17,43 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: slcompress.c,v 1.14 1997/11/22 03:37:50 brian Exp $
|
||||
* $Id: slcompress.c,v 1.15.2.11 1998/05/01 19:25:59 brian Exp $
|
||||
*
|
||||
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
|
||||
* - Initial distribution.
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "slcompress.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
|
||||
static struct slstat {
|
||||
int sls_packets; /* outbound packets */
|
||||
int sls_compressed; /* outbound compressed packets */
|
||||
int sls_searches; /* searches for connection state */
|
||||
int sls_misses; /* times couldn't find conn. state */
|
||||
int sls_uncompressedin; /* inbound uncompressed packets */
|
||||
int sls_compressedin; /* inbound compressed packets */
|
||||
int sls_errorin; /* inbound unknown type packets */
|
||||
int sls_tossed; /* inbound packets tossed because of error */
|
||||
} slstat;
|
||||
|
||||
#define INCR(counter) slstat.counter++;
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "throughput.h"
|
||||
#include "iplist.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
|
||||
void
|
||||
sl_compress_init(struct slcompress * comp, int max_state)
|
||||
@ -129,7 +131,8 @@ sl_compress_init(struct slcompress * comp, int max_state)
|
||||
u_char
|
||||
sl_compress_tcp(struct mbuf * m,
|
||||
struct ip * ip,
|
||||
struct slcompress * comp,
|
||||
struct slcompress *comp,
|
||||
struct slstat *slstat,
|
||||
int compress_cid)
|
||||
{
|
||||
register struct cstate *cs = comp->last_cs->cs_next;
|
||||
@ -147,15 +150,15 @@ sl_compress_tcp(struct mbuf * m,
|
||||
* the caller has already made sure the packet is IP proto TCP).
|
||||
*/
|
||||
if ((ip->ip_off & htons(0x3fff)) || m->cnt < 40) {
|
||||
LogPrintf(LogDEBUG, "??? 1 ip_off = %x, cnt = %d\n",
|
||||
log_Printf(LogDEBUG, "??? 1 ip_off = %x, cnt = %d\n",
|
||||
ip->ip_off, m->cnt);
|
||||
LogDumpBp(LogDEBUG, "", m);
|
||||
log_DumpBp(LogDEBUG, "", m);
|
||||
return (TYPE_IP);
|
||||
}
|
||||
th = (struct tcphdr *) & ((int *) ip)[hlen];
|
||||
if ((th->th_flags & (TH_SYN | TH_FIN | TH_RST | TH_ACK)) != TH_ACK) {
|
||||
LogPrintf(LogDEBUG, "??? 2 th_flags = %x\n", th->th_flags);
|
||||
LogDumpBp(LogDEBUG, "", m);
|
||||
log_Printf(LogDEBUG, "??? 2 th_flags = %x\n", th->th_flags);
|
||||
log_DumpBp(LogDEBUG, "", m);
|
||||
return (TYPE_IP);
|
||||
}
|
||||
|
||||
@ -166,10 +169,10 @@ sl_compress_tcp(struct mbuf * m,
|
||||
* 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]) {
|
||||
slstat->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.
|
||||
@ -187,10 +190,10 @@ sl_compress_tcp(struct mbuf * m,
|
||||
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])
|
||||
slstat->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);
|
||||
|
||||
@ -201,7 +204,7 @@ sl_compress_tcp(struct mbuf * m,
|
||||
* state points to the newest and we only need to set last_cs to update
|
||||
* the lru linkage.
|
||||
*/
|
||||
INCR(sls_misses)
|
||||
slstat->sls_misses++;
|
||||
comp->last_cs = lcs;
|
||||
#define THOFFSET(th) (th->th_off)
|
||||
hlen += th->th_off;
|
||||
@ -382,8 +385,8 @@ sl_compress_tcp(struct mbuf * m,
|
||||
*cp++ = deltaA >> 8;
|
||||
*cp++ = deltaA;
|
||||
memcpy(cp, new_seq, deltaS);
|
||||
INCR(sls_compressed)
|
||||
return (TYPE_COMPRESSED_TCP);
|
||||
slstat->sls_compressed++;
|
||||
return (TYPE_COMPRESSED_TCP);
|
||||
|
||||
/*
|
||||
* Update connection state cs & send uncompressed packet ('uncompressed'
|
||||
@ -399,10 +402,8 @@ sl_compress_tcp(struct mbuf * m,
|
||||
|
||||
|
||||
int
|
||||
sl_uncompress_tcp(u_char ** bufp,
|
||||
int len,
|
||||
u_int type,
|
||||
struct slcompress * comp)
|
||||
sl_uncompress_tcp(u_char ** bufp, int len, u_int type,
|
||||
struct slcompress *comp, struct slstat *slstat)
|
||||
{
|
||||
register u_char *cp;
|
||||
register u_int hlen, changes;
|
||||
@ -414,7 +415,7 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
|
||||
case TYPE_UNCOMPRESSED_TCP:
|
||||
ip = (struct ip *) * bufp;
|
||||
if (ip->ip_p >= MAX_STATES)
|
||||
if (ip->ip_p >= MAX_VJ_STATES)
|
||||
goto bad;
|
||||
cs = &comp->rstate[comp->last_recv = ip->ip_p];
|
||||
comp->flags &= ~SLF_TOSS;
|
||||
@ -434,8 +435,8 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
memcpy(&cs->cs_ip, ip, hlen);
|
||||
cs->cs_ip.ip_sum = 0;
|
||||
cs->cs_hlen = hlen;
|
||||
INCR(sls_uncompressedin)
|
||||
return (len);
|
||||
slstat->sls_uncompressedin++;
|
||||
return (len);
|
||||
|
||||
default:
|
||||
goto bad;
|
||||
@ -444,17 +445,17 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
break;
|
||||
}
|
||||
/* We've got a compressed packet. */
|
||||
INCR(sls_compressedin)
|
||||
cp = *bufp;
|
||||
slstat->sls_compressedin++;
|
||||
cp = *bufp;
|
||||
changes = *cp++;
|
||||
LogPrintf(LogDEBUG, "compressed: changes = %02x\n", changes);
|
||||
log_Printf(LogDEBUG, "compressed: changes = %02x\n", changes);
|
||||
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 || comp->last_recv == 255)
|
||||
if (*cp >= MAX_VJ_STATES || comp->last_recv == 255)
|
||||
goto bad;
|
||||
|
||||
comp->flags &= ~SLF_TOSS;
|
||||
@ -467,8 +468,8 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
* the packet.
|
||||
*/
|
||||
if (comp->flags & SLF_TOSS) {
|
||||
INCR(sls_tossed)
|
||||
return (0);
|
||||
slstat->sls_tossed++;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
cs = &comp->rstate[comp->last_recv];
|
||||
@ -507,7 +508,7 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
if (changes & NEW_A)
|
||||
DECODEL(th->th_ack)
|
||||
if (changes & NEW_S) {
|
||||
LogPrintf(LogDEBUG, "NEW_S: %02x, %02x, %02x\n",
|
||||
log_Printf(LogDEBUG, "NEW_S: %02x, %02x, %02x\n",
|
||||
*cp, cp[1], cp[2]);
|
||||
DECODEL(th->th_seq)
|
||||
}
|
||||
@ -518,8 +519,8 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
} else
|
||||
cs->cs_ip.ip_id = htons(ntohs(cs->cs_ip.ip_id) + 1);
|
||||
|
||||
LogPrintf(LogDEBUG, "Uncompress: id = %04x, seq = %08x\n",
|
||||
cs->cs_ip.ip_id, ntohl(th->th_seq));
|
||||
log_Printf(LogDEBUG, "Uncompress: id = %04x, seq = %08lx\n",
|
||||
cs->cs_ip.ip_id, (u_long)ntohl(th->th_seq));
|
||||
|
||||
/*
|
||||
* At this point, cp points to the first byte of data in the packet. If
|
||||
@ -565,23 +566,25 @@ sl_uncompress_tcp(u_char ** bufp,
|
||||
return (len);
|
||||
bad:
|
||||
comp->flags |= SLF_TOSS;
|
||||
INCR(sls_errorin)
|
||||
return (0);
|
||||
slstat->sls_errorin++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
int
|
||||
ReportCompress(struct cmdargs const *arg)
|
||||
sl_Show(struct cmdargs const *arg)
|
||||
{
|
||||
if (!VarTerm)
|
||||
return 1;
|
||||
|
||||
fprintf(VarTerm, "Out: %d (compress) / %d (total)",
|
||||
slstat.sls_compressed, slstat.sls_packets);
|
||||
fprintf(VarTerm, " %d (miss) / %d (search)\n",
|
||||
slstat.sls_misses, slstat.sls_searches);
|
||||
fprintf(VarTerm, "In: %d (compress), %d (uncompress)",
|
||||
slstat.sls_compressedin, slstat.sls_uncompressedin);
|
||||
fprintf(VarTerm, " %d (error), %d (tossed)\n",
|
||||
slstat.sls_errorin, slstat.sls_tossed);
|
||||
prompt_Printf(arg->prompt, "VJ compression statistics:\n");
|
||||
prompt_Printf(arg->prompt, " Out: %d (compress) / %d (total)",
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_compressed,
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_packets);
|
||||
prompt_Printf(arg->prompt, " %d (miss) / %d (search)\n",
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_misses,
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_searches);
|
||||
prompt_Printf(arg->prompt, " In: %d (compress), %d (uncompress)",
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_compressedin,
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_uncompressedin);
|
||||
prompt_Printf(arg->prompt, " %d (error), %d (tossed)\n",
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_errorin,
|
||||
arg->bundle->ncp.ipcp.vj.slstat.sls_tossed);
|
||||
return 0;
|
||||
}
|
||||
|
@ -1,8 +1,6 @@
|
||||
/*
|
||||
* Definitions for tcp compression routines.
|
||||
*
|
||||
* $Header: /home/ncvs/src/usr.sbin/ppp/slcompress.h,v 1.9 1997/10/26 01:03:46 brian Exp $
|
||||
*
|
||||
* Copyright (c) 1989 Regents of the University of California.
|
||||
* All rights reserved.
|
||||
*
|
||||
@ -18,14 +16,16 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: slcompress.h,v 1.9 1997/10/26 01:03:46 brian Exp $
|
||||
* $Id: slcompress.h,v 1.10.2.5 1998/05/01 19:26:00 brian Exp $
|
||||
*
|
||||
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
|
||||
* - Initial distribution.
|
||||
*/
|
||||
|
||||
#define MAX_STATES 16 /* must be > 2 and < 256 */
|
||||
#define MAX_HDR 128 /* XXX 4bsd-ism: should really be 128 */
|
||||
#define MIN_VJ_STATES 3
|
||||
#define MAX_VJ_STATES 255
|
||||
#define DEF_VJ_STATES 16 /* must be > 2 and < 256 */
|
||||
#define MAX_HDR 128
|
||||
|
||||
/*
|
||||
* Compressed packet format:
|
||||
@ -120,15 +120,30 @@ struct slcompress {
|
||||
u_char last_recv; /* last rcvd conn. id */
|
||||
u_char last_xmit; /* last sent conn. id */
|
||||
u_short flags;
|
||||
struct cstate tstate[MAX_STATES]; /* xmit connection states */
|
||||
struct cstate rstate[MAX_STATES]; /* receive connection states */
|
||||
struct cstate tstate[MAX_VJ_STATES]; /* xmit connection states */
|
||||
struct cstate rstate[MAX_VJ_STATES]; /* receive connection states */
|
||||
};
|
||||
|
||||
struct slstat {
|
||||
int sls_packets; /* outbound packets */
|
||||
int sls_compressed; /* outbound compressed packets */
|
||||
int sls_searches; /* searches for connection state */
|
||||
int sls_misses; /* times couldn't find conn. state */
|
||||
int sls_uncompressedin; /* inbound uncompressed packets */
|
||||
int sls_compressedin; /* inbound compressed packets */
|
||||
int sls_errorin; /* inbound unknown type packets */
|
||||
int sls_tossed; /* inbound packets tossed because of error */
|
||||
};
|
||||
|
||||
/* flag values */
|
||||
#define SLF_TOSS 1 /* tossing rcvd frames because of input err */
|
||||
|
||||
struct mbuf;
|
||||
struct cmdargs;
|
||||
|
||||
extern void sl_compress_init(struct slcompress *, int);
|
||||
extern u_char sl_compress_tcp
|
||||
(struct mbuf *, struct ip *, struct slcompress *, int);
|
||||
extern int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *);
|
||||
extern int ReportCompress(struct cmdargs const *);
|
||||
extern u_char sl_compress_tcp(struct mbuf *, struct ip *, struct slcompress *,
|
||||
struct slstat *, int);
|
||||
extern int sl_uncompress_tcp(u_char **, int, u_int, struct slcompress *,
|
||||
struct slstat *);
|
||||
extern int sl_Show(struct cmdargs const *);
|
||||
|
@ -17,12 +17,11 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: systems.c,v 1.34 1997/12/24 09:29:17 brian Exp $
|
||||
* $Id: systems.c,v 1.35.2.10 1998/05/15 23:58:29 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <pwd.h>
|
||||
@ -32,16 +31,9 @@
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "loadalias.h"
|
||||
#include "pathnames.h"
|
||||
#include "vars.h"
|
||||
#include "server.h"
|
||||
#include "systems.h"
|
||||
|
||||
#define issep(ch) ((ch) == ' ' || (ch) == '\t')
|
||||
@ -55,7 +47,7 @@ OpenSecret(const char *file)
|
||||
snprintf(line, sizeof line, "%s/%s", _PATH_PPP, file);
|
||||
fp = ID0fopen(line, "r");
|
||||
if (fp == NULL)
|
||||
LogPrintf(LogWARN, "OpenSecret: Can't open %s.\n", line);
|
||||
log_Printf(LogWARN, "OpenSecret: Can't open %s.\n", line);
|
||||
return (fp);
|
||||
}
|
||||
|
||||
@ -164,18 +156,22 @@ DecodeCtrlCommand(char *line, char *arg)
|
||||
return CTRL_UNKNOWN;
|
||||
}
|
||||
|
||||
/* Initialised in system_IsValid(), set in ReadSystem(), used by system_IsValid() */
|
||||
static int modeok;
|
||||
static int userok;
|
||||
static int modereq;
|
||||
|
||||
int
|
||||
AllowUsers(struct cmdargs const *arg)
|
||||
{
|
||||
/* arg->bundle may be NULL (see system_IsValid()) ! */
|
||||
int f;
|
||||
char *user;
|
||||
|
||||
userok = 0;
|
||||
user = getlogin();
|
||||
if (user && *user)
|
||||
for (f = 0; f < arg->argc; f++)
|
||||
for (f = arg->argn; f < arg->argc; f++)
|
||||
if (!strcmp("*", arg->argv[f]) || !strcmp(user, arg->argv[f])) {
|
||||
userok = 1;
|
||||
break;
|
||||
@ -184,57 +180,82 @@ AllowUsers(struct cmdargs const *arg)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct {
|
||||
int mode;
|
||||
const char *name;
|
||||
} modes[] = {
|
||||
{ MODE_INTER, "interactive" },
|
||||
{ MODE_AUTO, "auto" },
|
||||
{ MODE_DIRECT, "direct" },
|
||||
{ MODE_DEDICATED, "dedicated" },
|
||||
{ MODE_DDIAL, "ddial" },
|
||||
{ MODE_BACKGROUND, "background" },
|
||||
{ ~0, "*" },
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
static int modeok;
|
||||
|
||||
int
|
||||
AllowModes(struct cmdargs const *arg)
|
||||
{
|
||||
int f;
|
||||
int m;
|
||||
int allowed;
|
||||
/* arg->bundle may be NULL (see system_IsValid()) ! */
|
||||
int f, mode, allowed;
|
||||
|
||||
allowed = 0;
|
||||
for (f = 0; f < arg->argc; f++) {
|
||||
for (m = 0; modes[m].mode; m++)
|
||||
if (!strcasecmp(modes[m].name, arg->argv[f])) {
|
||||
allowed |= modes[m].mode;
|
||||
break;
|
||||
}
|
||||
if (modes[m].mode == 0)
|
||||
LogPrintf(LogWARN, "allow modes: %s: Invalid mode\n", arg->argv[f]);
|
||||
for (f = arg->argn; f < arg->argc; f++) {
|
||||
mode = Nam2mode(arg->argv[f]);
|
||||
if (mode == PHYS_NONE || mode == PHYS_ALL)
|
||||
log_Printf(LogWARN, "allow modes: %s: Invalid mode\n", arg->argv[f]);
|
||||
else
|
||||
allowed |= mode;
|
||||
}
|
||||
|
||||
modeok = (mode | allowed) == allowed ? 1 : 0;
|
||||
modeok = modereq & allowed ? 1 : 0;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
strip(char *line)
|
||||
{
|
||||
int len;
|
||||
|
||||
len = strlen(line);
|
||||
while (len && (line[len-1] == '\n' || line[len-1] == '\r' ||
|
||||
issep(line[len-1])))
|
||||
line[--len] = '\0';
|
||||
|
||||
while (issep(*line))
|
||||
line++;
|
||||
|
||||
if (*line == '#')
|
||||
*line = '\0';
|
||||
|
||||
return line;
|
||||
}
|
||||
|
||||
static int
|
||||
ReadSystem(const char *name, const char *file, int doexec)
|
||||
xgets(char *buf, int buflen, FILE *fp)
|
||||
{
|
||||
int len, n;
|
||||
|
||||
n = 0;
|
||||
while (fgets(buf, buflen-1, fp)) {
|
||||
n++;
|
||||
buf[buflen-1] = '\0';
|
||||
len = strlen(buf);
|
||||
while (len && (buf[len-1] == '\n' || buf[len-1] == '\r'))
|
||||
buf[--len] = '\0';
|
||||
if (len && buf[len-1] == '\\') {
|
||||
buf += len - 1;
|
||||
buflen -= len - 1;
|
||||
if (!buflen) /* No buffer space */
|
||||
break;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
return n;
|
||||
}
|
||||
|
||||
static int
|
||||
ReadSystem(struct bundle *bundle, const char *name, const char *file,
|
||||
int doexec, struct prompt *prompt)
|
||||
{
|
||||
FILE *fp;
|
||||
char *cp, *wp;
|
||||
int n, len;
|
||||
u_char olauth;
|
||||
char line[LINE_LEN];
|
||||
char filename[MAXPATHLEN];
|
||||
int linenum;
|
||||
int argc;
|
||||
char **argv;
|
||||
int allowcmd;
|
||||
int indent;
|
||||
char arg[LINE_LEN];
|
||||
|
||||
if (*file == '/')
|
||||
snprintf(filename, sizeof filename, "%s", file);
|
||||
@ -242,73 +263,70 @@ ReadSystem(const char *name, const char *file, int doexec)
|
||||
snprintf(filename, sizeof filename, "%s/%s", _PATH_PPP, file);
|
||||
fp = ID0fopen(filename, "r");
|
||||
if (fp == NULL) {
|
||||
LogPrintf(LogDEBUG, "ReadSystem: Can't open %s.\n", filename);
|
||||
log_Printf(LogDEBUG, "ReadSystem: Can't open %s.\n", filename);
|
||||
return (-1);
|
||||
}
|
||||
LogPrintf(LogDEBUG, "ReadSystem: Checking %s (%s).\n", name, filename);
|
||||
log_Printf(LogDEBUG, "ReadSystem: Checking %s (%s).\n", name, filename);
|
||||
|
||||
linenum = 0;
|
||||
while (fgets(line, sizeof line, fp)) {
|
||||
linenum++;
|
||||
cp = line;
|
||||
while ((n = xgets(line, sizeof line, fp))) {
|
||||
linenum += n;
|
||||
if (issep(*line))
|
||||
continue;
|
||||
|
||||
cp = strip(line);
|
||||
|
||||
switch (*cp) {
|
||||
case '#': /* comment */
|
||||
case '\0': /* empty/comment */
|
||||
break;
|
||||
case ' ':
|
||||
case '\t':
|
||||
|
||||
case '!':
|
||||
switch (DecodeCtrlCommand(cp+1, arg)) {
|
||||
case CTRL_INCLUDE:
|
||||
log_Printf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg);
|
||||
n = ReadSystem(bundle, name, arg, doexec, prompt);
|
||||
log_Printf(LogCOMMAND, "%s: Done include of \"%s\"\n", filename, arg);
|
||||
if (!n)
|
||||
return 0; /* got it */
|
||||
break;
|
||||
default:
|
||||
log_Printf(LogWARN, "%s: %s: Invalid command\n", filename, cp);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
wp = strpbrk(cp, ":\n");
|
||||
if (wp == NULL) {
|
||||
LogPrintf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n",
|
||||
wp = strchr(cp, ':');
|
||||
if (wp == NULL || wp[1] != '\0') {
|
||||
log_Printf(LogWARN, "Bad rule in %s (line %d) - missing colon.\n",
|
||||
filename, linenum);
|
||||
ServerClose();
|
||||
exit(1);
|
||||
continue;
|
||||
}
|
||||
*wp = '\0';
|
||||
if (*cp == '!') {
|
||||
char arg[LINE_LEN];
|
||||
switch (DecodeCtrlCommand(cp+1, arg)) {
|
||||
case CTRL_INCLUDE:
|
||||
LogPrintf(LogCOMMAND, "%s: Including \"%s\"\n", filename, arg);
|
||||
n = ReadSystem(name, arg, doexec);
|
||||
LogPrintf(LogCOMMAND, "%s: Done include of \"%s\"\n", filename, arg);
|
||||
if (!n)
|
||||
return 0; /* got it */
|
||||
break;
|
||||
default:
|
||||
LogPrintf(LogWARN, "%s: %s: Invalid command\n", filename, cp);
|
||||
break;
|
||||
cp = strip(cp); /* lose any spaces between the label and the ':' */
|
||||
|
||||
if (strcmp(cp, name) == 0) {
|
||||
/* We're in business */
|
||||
while ((n = xgets(line, sizeof line, fp))) {
|
||||
linenum += n;
|
||||
indent = issep(*line);
|
||||
cp = strip(line);
|
||||
|
||||
if (*cp == '\0') /* empty / comment */
|
||||
continue;
|
||||
|
||||
if (!indent) /* start of next section */
|
||||
break;
|
||||
|
||||
len = strlen(cp);
|
||||
command_Interpret(cp, len, &argc, &argv);
|
||||
allowcmd = argc > 0 && !strcasecmp(*argv, "allow");
|
||||
if ((!doexec && allowcmd) || (doexec && !allowcmd))
|
||||
command_Run(bundle, argc, (char const *const *)argv, prompt, name);
|
||||
}
|
||||
} else if (strcmp(cp, name) == 0) {
|
||||
while (fgets(line, sizeof line, fp)) {
|
||||
cp = line;
|
||||
if (issep(*cp)) {
|
||||
n = strspn(cp, " \t");
|
||||
cp += n;
|
||||
len = strlen(cp);
|
||||
if (!len || *cp == '#')
|
||||
continue;
|
||||
if (cp[len-1] == '\n')
|
||||
cp[--len] = '\0';
|
||||
if (!len)
|
||||
continue;
|
||||
InterpretCommand(cp, len, &argc, &argv);
|
||||
allowcmd = argc > 0 && !strcasecmp(*argv, "allow");
|
||||
if ((!doexec && allowcmd) || (doexec && !allowcmd)) {
|
||||
olauth = VarLocalAuth;
|
||||
if (VarLocalAuth == LOCAL_NO_AUTH)
|
||||
VarLocalAuth = LOCAL_AUTH;
|
||||
RunCommand(argc, (char const *const *)argv, name);
|
||||
VarLocalAuth = olauth;
|
||||
}
|
||||
} else if (*cp == '#' || *cp == '\n' || *cp == '\0') {
|
||||
continue;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
fclose(fp);
|
||||
return (0);
|
||||
|
||||
fclose(fp); /* everything read - get out */
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
}
|
||||
@ -318,49 +336,28 @@ ReadSystem(const char *name, const char *file, int doexec)
|
||||
}
|
||||
|
||||
int
|
||||
ValidSystem(const char *name)
|
||||
system_IsValid(const char *name, struct prompt *prompt, int mode)
|
||||
{
|
||||
/*
|
||||
* Note: The ReadSystem() calls only result in calls to the Allow*
|
||||
* functions. arg->bundle will be set to NULL for these commands !
|
||||
*/
|
||||
if (ID0realuid() == 0)
|
||||
return userok = modeok = 1;
|
||||
userok = 0;
|
||||
modeok = 1;
|
||||
ReadSystem("default", CONFFILE, 0);
|
||||
modereq = mode;
|
||||
ReadSystem(NULL, "default", CONFFILE, 0, prompt);
|
||||
if (name != NULL)
|
||||
ReadSystem(name, CONFFILE, 0);
|
||||
ReadSystem(NULL, name, CONFFILE, 0, prompt);
|
||||
return userok && modeok;
|
||||
}
|
||||
|
||||
int
|
||||
SelectSystem(const char *name, const char *file)
|
||||
system_Select(struct bundle *bundle, const char *name, const char *file,
|
||||
struct prompt *prompt)
|
||||
{
|
||||
userok = modeok = 1;
|
||||
return ReadSystem(name, file, 1);
|
||||
}
|
||||
|
||||
int
|
||||
LoadCommand(struct cmdargs const *arg)
|
||||
{
|
||||
const char *name;
|
||||
|
||||
if (arg->argc > 0)
|
||||
name = *arg->argv;
|
||||
else
|
||||
name = "default";
|
||||
|
||||
if (!ValidSystem(name)) {
|
||||
LogPrintf(LogERROR, "%s: Label not allowed\n", name);
|
||||
return 1;
|
||||
} else if (SelectSystem(name, CONFFILE) < 0) {
|
||||
LogPrintf(LogWARN, "%s: label not found.\n", name);
|
||||
return -1;
|
||||
} else
|
||||
SetLabel(arg->argc ? name : NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
SaveCommand(struct cmdargs const *arg)
|
||||
{
|
||||
LogPrintf(LogWARN, "save command is not implemented (yet).\n");
|
||||
return 1;
|
||||
modereq = PHYS_ALL;
|
||||
return ReadSystem(bundle, name, file, 1, prompt);
|
||||
}
|
||||
|
@ -17,12 +17,17 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: systems.h,v 1.9 1997/11/11 22:58:14 brian Exp $
|
||||
* $Id: systems.h,v 1.10.2.6 1998/05/15 23:58:30 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
extern int SelectSystem(const char *, const char *);
|
||||
extern int ValidSystem(const char *);
|
||||
struct prompt;
|
||||
struct bundle;
|
||||
struct cmdargs;
|
||||
|
||||
extern int system_Select(struct bundle *bundle, const char *, const char *,
|
||||
struct prompt *);
|
||||
extern int system_IsValid(const char *, struct prompt *, int);
|
||||
extern FILE *OpenSecret(const char *);
|
||||
extern void CloseSecret(FILE *);
|
||||
extern int AllowUsers(struct cmdargs const *);
|
||||
|
@ -23,23 +23,21 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: throughput.c,v 1.4.4.9 1998/05/01 19:26:04 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <time.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "throughput.h"
|
||||
#include "defs.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
|
||||
void
|
||||
throughput_init(struct pppThroughput *t)
|
||||
@ -50,26 +48,33 @@ throughput_init(struct pppThroughput *t)
|
||||
for (f = 0; f < SAMPLE_PERIOD; f++)
|
||||
t->SampleOctets[f] = 0;
|
||||
t->OctetsPerSecond = t->BestOctetsPerSecond = t->nSample = 0;
|
||||
memset(&t->Timer, '\0', sizeof t->Timer);
|
||||
t->Timer.name = "throughput";
|
||||
t->uptime = 0;
|
||||
t->rolling = 0;
|
||||
throughput_stop(t);
|
||||
}
|
||||
|
||||
void
|
||||
throughput_disp(struct pppThroughput *t, FILE *f)
|
||||
throughput_disp(struct pppThroughput *t, struct prompt *prompt)
|
||||
{
|
||||
int secs_up;
|
||||
|
||||
secs_up = t->uptime ? time(NULL) - t->uptime : 0;
|
||||
fprintf(f, "Connect time: %d secs\n", secs_up);
|
||||
prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
|
||||
if (secs_up == 0)
|
||||
secs_up = 1;
|
||||
fprintf(f, "%ld octets in, %ld octets out\n", t->OctetsIn, t->OctetsOut);
|
||||
if (Enabled(ConfThroughput)) {
|
||||
fprintf(f, " overall %5ld bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
fprintf(f, " currently %5d bytes/sec\n", t->OctetsPerSecond);
|
||||
fprintf(f, " peak %5d bytes/sec\n", t->BestOctetsPerSecond);
|
||||
prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
|
||||
t->OctetsIn, t->OctetsOut);
|
||||
if (t->rolling) {
|
||||
prompt_Printf(prompt, " overall %5ld bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
prompt_Printf(prompt, " currently %5d bytes/sec\n", t->OctetsPerSecond);
|
||||
prompt_Printf(prompt, " peak %5d bytes/sec\n",
|
||||
t->BestOctetsPerSecond);
|
||||
} else
|
||||
fprintf(f, "Overall %ld bytes/sec\n", (t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
prompt_Printf(prompt, "Overall %ld bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
}
|
||||
|
||||
|
||||
@ -81,18 +86,18 @@ throughput_log(struct pppThroughput *t, int level, const char *title)
|
||||
|
||||
secs_up = t->uptime ? time(NULL) - t->uptime : 0;
|
||||
if (title)
|
||||
LogPrintf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
|
||||
log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
|
||||
" out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
|
||||
else
|
||||
LogPrintf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
|
||||
log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
|
||||
secs_up, t->OctetsIn, t->OctetsOut);
|
||||
if (secs_up == 0)
|
||||
secs_up = 1;
|
||||
if (Enabled(ConfThroughput))
|
||||
LogPrintf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
|
||||
if (t->rolling)
|
||||
log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond);
|
||||
else
|
||||
LogPrintf(level, " total %ld bytes/sec\n",
|
||||
log_Printf(level, " total %ld bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
}
|
||||
}
|
||||
@ -103,8 +108,7 @@ throughput_sampler(void *v)
|
||||
struct pppThroughput *t = (struct pppThroughput *)v;
|
||||
u_long old;
|
||||
|
||||
StopTimer(&t->Timer);
|
||||
t->Timer.state = TIMER_STOPPED;
|
||||
timer_Stop(&t->Timer);
|
||||
|
||||
old = t->SampleOctets[t->nSample];
|
||||
t->SampleOctets[t->nSample] = t->OctetsIn + t->OctetsOut;
|
||||
@ -114,28 +118,29 @@ throughput_sampler(void *v)
|
||||
if (++t->nSample == SAMPLE_PERIOD)
|
||||
t->nSample = 0;
|
||||
|
||||
StartTimer(&t->Timer);
|
||||
timer_Start(&t->Timer);
|
||||
}
|
||||
|
||||
void
|
||||
throughput_start(struct pppThroughput *t)
|
||||
throughput_start(struct pppThroughput *t, const char *name, int rolling)
|
||||
{
|
||||
timer_Stop(&t->Timer);
|
||||
throughput_init(t);
|
||||
t->rolling = rolling ? 1 : 0;
|
||||
time(&t->uptime);
|
||||
if (Enabled(ConfThroughput)) {
|
||||
t->Timer.state = TIMER_STOPPED;
|
||||
if (t->rolling) {
|
||||
t->Timer.load = SECTICKS;
|
||||
t->Timer.func = throughput_sampler;
|
||||
t->Timer.name = name;
|
||||
t->Timer.arg = t;
|
||||
StartTimer(&t->Timer);
|
||||
timer_Start(&t->Timer);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
throughput_stop(struct pppThroughput *t)
|
||||
{
|
||||
if (Enabled(ConfThroughput))
|
||||
StopTimer(&t->Timer);
|
||||
timer_Stop(&t->Timer);
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: throughput.h,v 1.2.4.4 1998/04/16 00:26:19 brian Exp $
|
||||
*/
|
||||
|
||||
#define SAMPLE_PERIOD 5
|
||||
@ -36,13 +36,14 @@ struct pppThroughput {
|
||||
int OctetsPerSecond;
|
||||
int BestOctetsPerSecond;
|
||||
int nSample;
|
||||
unsigned rolling : 1;
|
||||
struct pppTimer Timer;
|
||||
};
|
||||
|
||||
extern void throughput_init(struct pppThroughput *);
|
||||
extern void throughput_disp(struct pppThroughput *, FILE *);
|
||||
extern void throughput_disp(struct pppThroughput *, struct prompt *);
|
||||
extern void throughput_log(struct pppThroughput *, int, const char *);
|
||||
extern void throughput_start(struct pppThroughput *);
|
||||
extern void throughput_start(struct pppThroughput *, const char *, int);
|
||||
extern void throughput_stop(struct pppThroughput *);
|
||||
extern void throughput_addin(struct pppThroughput *, int);
|
||||
extern void throughput_addout(struct pppThroughput *, int);
|
||||
|
@ -17,67 +17,68 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: timer.c,v 1.26 1997/12/29 22:23:52 brian Exp $
|
||||
* $Id: timer.c,v 1.27.2.11 1998/05/08 01:15:18 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#include <signal.h>
|
||||
#ifdef SIGALRM
|
||||
#include <errno.h>
|
||||
#endif
|
||||
#include <signal.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "sig.h"
|
||||
#include "timer.h"
|
||||
#include "descriptor.h"
|
||||
#include "prompt.h"
|
||||
|
||||
static struct pppTimer *TimerList = NULL;
|
||||
|
||||
static void StopTimerNoBlock(struct pppTimer *);
|
||||
static void InitTimerService(void);
|
||||
|
||||
void
|
||||
StopTimer(struct pppTimer * tp)
|
||||
static const char *
|
||||
tState2Nam(u_int state)
|
||||
{
|
||||
#ifdef SIGALRM
|
||||
int omask;
|
||||
static const char *StateNames[] = { "stopped", "running", "expired" };
|
||||
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
#endif
|
||||
StopTimerNoBlock(tp);
|
||||
#ifdef SIGALRM
|
||||
sigsetmask(omask);
|
||||
#endif
|
||||
if (state >= sizeof StateNames / sizeof StateNames[0])
|
||||
return "unknown";
|
||||
return StateNames[state];
|
||||
}
|
||||
|
||||
void
|
||||
StartTimer(struct pppTimer * tp)
|
||||
timer_Stop(struct pppTimer * tp)
|
||||
{
|
||||
struct pppTimer *t, *pt;
|
||||
u_long ticks = 0;
|
||||
|
||||
#ifdef SIGALRM
|
||||
int omask;
|
||||
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
#endif
|
||||
StopTimerNoBlock(tp);
|
||||
sigsetmask(omask);
|
||||
}
|
||||
|
||||
if (tp->state != TIMER_STOPPED) {
|
||||
void
|
||||
timer_Start(struct pppTimer * tp)
|
||||
{
|
||||
struct pppTimer *t, *pt;
|
||||
u_long ticks = 0;
|
||||
int omask;
|
||||
|
||||
omask = sigblock(sigmask(SIGALRM));
|
||||
|
||||
if (tp->state != TIMER_STOPPED)
|
||||
StopTimerNoBlock(tp);
|
||||
}
|
||||
|
||||
if (tp->load == 0) {
|
||||
LogPrintf(LogDEBUG, "timer %x has 0 load!\n", tp);
|
||||
log_Printf(LogTIMER, "%s timer[%p] has 0 load!\n", tp->name, tp);
|
||||
sigsetmask(omask);
|
||||
return;
|
||||
}
|
||||
pt = NULL;
|
||||
for (t = TimerList; t; t = t->next) {
|
||||
LogPrintf(LogDEBUG, "StartTimer: %x(%d): ticks: %d, rest: %d\n",
|
||||
t, t->state, ticks, t->rest);
|
||||
if (ticks + t->rest >= tp->load)
|
||||
break;
|
||||
ticks += t->rest;
|
||||
@ -86,8 +87,13 @@ StartTimer(struct pppTimer * tp)
|
||||
|
||||
tp->state = TIMER_RUNNING;
|
||||
tp->rest = tp->load - ticks;
|
||||
LogPrintf(LogDEBUG, "StartTimer: Inserting %x before %x, rest = %d\n",
|
||||
tp, t, tp->rest);
|
||||
|
||||
if (t)
|
||||
log_Printf(LogTIMER, "timer_Start: Inserting %s timer[%p] before %s "
|
||||
"timer[%p], delta = %ld\n", tp->name, tp, t->name, t, tp->rest);
|
||||
else
|
||||
log_Printf(LogTIMER, "timer_Start: Inserting %s timer[%p]\n", tp->name, tp);
|
||||
|
||||
/* Insert given *tp just before *t */
|
||||
tp->next = t;
|
||||
if (pt) {
|
||||
@ -99,9 +105,7 @@ StartTimer(struct pppTimer * tp)
|
||||
if (t)
|
||||
t->rest -= tp->rest;
|
||||
|
||||
#ifdef SIGALRM
|
||||
sigsetmask(omask);
|
||||
#endif
|
||||
}
|
||||
|
||||
static void
|
||||
@ -110,12 +114,10 @@ StopTimerNoBlock(struct pppTimer * tp)
|
||||
struct pppTimer *t, *pt;
|
||||
|
||||
/*
|
||||
* A Running Timer should be removing TimerList, But STOPPED/EXPIRED is
|
||||
* already removing TimerList. So just marked as TIMER_STOPPED. Do not
|
||||
* change tp->enext!! (Might be Called by expired proc)
|
||||
* A RUNNING timer must be removed from TimerList (->next list).
|
||||
* A STOPPED timer isn't in any list, but may have a bogus [e]next field.
|
||||
* An EXPIRED timer is in the ->enext list.
|
||||
*/
|
||||
LogPrintf(LogDEBUG, "StopTimer: %x, next = %x state=%x\n",
|
||||
tp, tp->next, tp->state);
|
||||
if (tp->state != TIMER_RUNNING) {
|
||||
tp->next = NULL;
|
||||
tp->state = TIMER_STOPPED;
|
||||
@ -130,24 +132,30 @@ StopTimerNoBlock(struct pppTimer * tp)
|
||||
} else {
|
||||
TimerList = t->next;
|
||||
if (TimerList == NULL) /* Last one ? */
|
||||
TermTimerService(); /* Terminate Timer Service */
|
||||
timer_TermService(); /* Terminate Timer Service */
|
||||
}
|
||||
if (t->next)
|
||||
t->next->rest += tp->rest;
|
||||
} else
|
||||
LogPrintf(LogERROR, "Oops, timer not found!!\n");
|
||||
log_Printf(LogERROR, "Oops, %s timer not found!!\n", tp->name);
|
||||
|
||||
tp->next = NULL;
|
||||
tp->state = TIMER_STOPPED;
|
||||
}
|
||||
|
||||
static void
|
||||
TimerService()
|
||||
TimerService(void)
|
||||
{
|
||||
struct pppTimer *tp, *exp, *wt;
|
||||
|
||||
if (LogIsKept(LogDEBUG))
|
||||
ShowTimers();
|
||||
if (log_IsKept(LogTIMER)) {
|
||||
static time_t t;
|
||||
time_t n = time(NULL); /* Only show timers every second */
|
||||
|
||||
if (n > t)
|
||||
timer_Show(LogTIMER, NULL);
|
||||
t = n;
|
||||
}
|
||||
tp = TimerList;
|
||||
if (tp) {
|
||||
tp->rest--;
|
||||
@ -162,22 +170,19 @@ TimerService()
|
||||
wt = tp->next;
|
||||
tp->enext = exp;
|
||||
exp = tp;
|
||||
LogPrintf(LogDEBUG, "TimerService: Add %x to exp\n", tp);
|
||||
tp = wt;
|
||||
} while (tp && (tp->rest == 0));
|
||||
|
||||
TimerList = tp;
|
||||
if (TimerList == NULL) /* No timers ? */
|
||||
TermTimerService(); /* Terminate Timer Service */
|
||||
LogPrintf(LogDEBUG, "TimerService: next is %x(%d)\n",
|
||||
TimerList, TimerList ? TimerList->rest : 0);
|
||||
timer_TermService(); /* Terminate Timer Service */
|
||||
|
||||
/*
|
||||
* Process all expired timers.
|
||||
*/
|
||||
while (exp) {
|
||||
#ifdef notdef
|
||||
StopTimer(exp);
|
||||
timer_Stop(exp);
|
||||
#endif
|
||||
if (exp->func)
|
||||
(*exp->func) (exp->arg);
|
||||
@ -193,73 +198,31 @@ TimerService()
|
||||
}
|
||||
|
||||
void
|
||||
ShowTimers()
|
||||
timer_Show(int LogLevel, struct prompt *prompt)
|
||||
{
|
||||
struct pppTimer *pt;
|
||||
int rest = 0;
|
||||
|
||||
LogPrintf(LogDEBUG, "---- Begin of Timer Service List---\n");
|
||||
for (pt = TimerList; pt; pt = pt->next)
|
||||
LogPrintf(LogDEBUG, "%x: load = %d, rest = %d, state =%x\n",
|
||||
pt, pt->load, pt->rest, pt->state);
|
||||
LogPrintf(LogDEBUG, "---- End of Timer Service List ---\n");
|
||||
}
|
||||
#define SECS(val) ((val) / SECTICKS)
|
||||
#define HSECS(val) (((val) % SECTICKS) * 100 / SECTICKS)
|
||||
#define DISP \
|
||||
"%s timer[%p]: freq = %ld.%02lds, next = %d.%02ds, state = %s\n", \
|
||||
pt->name, pt, SECS(pt->load), HSECS(pt->load), SECS(rest), \
|
||||
HSECS(rest), tState2Nam(pt->state)
|
||||
|
||||
#ifdef SIGALRM
|
||||
if (!prompt)
|
||||
log_Printf(LogLevel, "---- Begin of Timer Service List---\n");
|
||||
|
||||
static void
|
||||
nointr_dosleep(u_int sec, u_int usec)
|
||||
{
|
||||
struct timeval to, st, et;
|
||||
|
||||
gettimeofday(&st, NULL);
|
||||
et.tv_sec = st.tv_sec + sec;
|
||||
et.tv_usec = st.tv_usec + usec;
|
||||
to.tv_sec = sec;
|
||||
to.tv_usec = usec;
|
||||
for (;;) {
|
||||
if (select(0, NULL, NULL, NULL, &to) == 0 ||
|
||||
errno != EINTR) {
|
||||
break;
|
||||
} else {
|
||||
gettimeofday(&to, NULL);
|
||||
if (to.tv_sec > et.tv_sec + 1 ||
|
||||
(to.tv_sec == et.tv_sec + 1 && to.tv_usec > et.tv_usec) ||
|
||||
to.tv_sec < st.tv_sec ||
|
||||
(to.tv_sec == st.tv_sec && to.tv_usec < st.tv_usec)) {
|
||||
LogPrintf(LogWARN, "Clock adjusted between %d and %d seconds "
|
||||
"during sleep !\n",
|
||||
to.tv_sec - st.tv_sec, sec + to.tv_sec - st.tv_sec);
|
||||
st.tv_sec = to.tv_sec;
|
||||
st.tv_usec = to.tv_usec;
|
||||
et.tv_sec = st.tv_sec + sec;
|
||||
et.tv_usec = st.tv_usec + usec;
|
||||
to.tv_sec = sec;
|
||||
to.tv_usec = usec;
|
||||
} else if (to.tv_sec > et.tv_sec ||
|
||||
(to.tv_sec == et.tv_sec && to.tv_usec >= et.tv_usec)) {
|
||||
break;
|
||||
} else {
|
||||
to.tv_sec = et.tv_sec - to.tv_sec;
|
||||
if (et.tv_usec < to.tv_usec) {
|
||||
to.tv_sec--;
|
||||
to.tv_usec = 1000000 + et.tv_usec - to.tv_usec;
|
||||
} else
|
||||
to.tv_usec = et.tv_usec - to.tv_usec;
|
||||
}
|
||||
}
|
||||
for (pt = TimerList; pt; pt = pt->next) {
|
||||
rest += pt->rest;
|
||||
if (prompt)
|
||||
prompt_Printf(prompt, DISP);
|
||||
else
|
||||
log_Printf(LogLevel, DISP);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
nointr_sleep(u_int sec)
|
||||
{
|
||||
nointr_dosleep(sec, 0);
|
||||
}
|
||||
|
||||
void
|
||||
nointr_usleep(u_int usec)
|
||||
{
|
||||
nointr_dosleep(0, usec);
|
||||
if (!prompt)
|
||||
log_Printf(LogLevel, "---- End of Timer Service List ---\n");
|
||||
}
|
||||
|
||||
static void
|
||||
@ -267,23 +230,21 @@ InitTimerService()
|
||||
{
|
||||
struct itimerval itimer;
|
||||
|
||||
pending_signal(SIGALRM, (void (*) (int)) TimerService);
|
||||
sig_signal(SIGALRM, (void (*) (int)) TimerService);
|
||||
itimer.it_interval.tv_sec = itimer.it_value.tv_sec = 0;
|
||||
itimer.it_interval.tv_usec = itimer.it_value.tv_usec = TICKUNIT;
|
||||
if (setitimer(ITIMER_REAL, &itimer, NULL) == -1)
|
||||
LogPrintf(LogERROR, "Unable to set itimer.\n");
|
||||
log_Printf(LogERROR, "Unable to set itimer.\n");
|
||||
}
|
||||
|
||||
void
|
||||
TermTimerService(void)
|
||||
timer_TermService(void)
|
||||
{
|
||||
struct itimerval itimer;
|
||||
|
||||
itimer.it_interval.tv_usec = itimer.it_interval.tv_sec = 0;
|
||||
itimer.it_value.tv_usec = itimer.it_value.tv_sec = 0;
|
||||
if (setitimer(ITIMER_REAL, &itimer, NULL) == -1)
|
||||
LogPrintf(LogERROR, "Unable to set itimer.\n");
|
||||
pending_signal(SIGALRM, SIG_IGN);
|
||||
log_Printf(LogERROR, "Unable to set itimer.\n");
|
||||
sig_signal(SIGALRM, SIG_IGN);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -15,16 +15,17 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: timer.h,v 1.4 1997/12/28 21:55:05 brian Exp $
|
||||
* $Id: timer.h,v 1.5.4.5 1998/05/08 01:15:19 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
#define TICKUNIT 100000 /* Unit in usec */
|
||||
#define SECTICKS (1000000/TICKUNIT)
|
||||
#define TICKUNIT 100000 /* usec's per Unit */
|
||||
#define SECTICKS (1000000/TICKUNIT) /* Units per second */
|
||||
|
||||
struct pppTimer {
|
||||
int state;
|
||||
const char *name;
|
||||
u_long rest; /* Ticks to expire */
|
||||
u_long load; /* Initial load value */
|
||||
void (*func)(void *); /* Function called when timer is expired */
|
||||
@ -37,12 +38,9 @@ struct pppTimer {
|
||||
#define TIMER_RUNNING 1
|
||||
#define TIMER_EXPIRED 2
|
||||
|
||||
extern void StartTimer(struct pppTimer *);
|
||||
extern void StopTimer(struct pppTimer *);
|
||||
extern void TermTimerService(void);
|
||||
extern void ShowTimers(void);
|
||||
struct prompt;
|
||||
|
||||
#ifdef SIGALRM
|
||||
extern void nointr_sleep(u_int);
|
||||
extern void nointr_usleep(u_int);
|
||||
#endif
|
||||
extern void timer_Start(struct pppTimer *);
|
||||
extern void timer_Stop(struct pppTimer *);
|
||||
extern void timer_TermService(void);
|
||||
extern void timer_Show(int LogLevel, struct prompt *);
|
||||
|
@ -23,44 +23,54 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: tun.c,v 1.5 1998/01/11 17:53:27 brian Exp $
|
||||
* $Id: tun.c,v 1.6.4.18 1998/05/06 23:50:22 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_tun.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "defs.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "fsm.h"
|
||||
#include "throughput.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "tun.h"
|
||||
|
||||
void
|
||||
tun_configure(int mtu, int speed)
|
||||
tun_configure(struct bundle *bundle, int mtu)
|
||||
{
|
||||
struct tuninfo info;
|
||||
|
||||
info.type = 23;
|
||||
info.mtu = mtu;
|
||||
if (VarPrefMTU != 0 && VarPrefMTU < mtu)
|
||||
info.mtu = VarPrefMTU;
|
||||
info.baudrate = speed;
|
||||
info.baudrate = bundle->ifp.Speed;
|
||||
#ifdef __OpenBSD__
|
||||
info.flags = IFF_UP|IFF_POINTOPOINT;
|
||||
#endif
|
||||
if (ioctl(tun_out, TUNSIFINFO, &info) < 0)
|
||||
LogPrintf(LogERROR, "tun_configure: ioctl(TUNSIFINFO): %s\n",
|
||||
if (ioctl(bundle->dev.fd, TUNSIFINFO, &info) < 0)
|
||||
log_Printf(LogERROR, "tun_configure: ioctl(TUNSIFINFO): %s\n",
|
||||
strerror(errno));
|
||||
}
|
||||
|
@ -23,7 +23,7 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: tun.h,v 1.3.4.3 1998/05/06 23:50:25 brian Exp $
|
||||
*/
|
||||
|
||||
struct tun_data {
|
||||
@ -41,4 +41,6 @@ struct tun_data {
|
||||
#define tun_check_header(f,proto) (1)
|
||||
#endif
|
||||
|
||||
extern void tun_configure(int, int);
|
||||
struct bundle;
|
||||
|
||||
extern void tun_configure(struct bundle *, int);
|
||||
|
@ -1,192 +0,0 @@
|
||||
/*
|
||||
* PPP configuration variables
|
||||
*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the Internet Initiative Japan, Inc. The name of the
|
||||
* IIJ 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.
|
||||
*
|
||||
* $Id: vars.c,v 1.44 1998/01/20 22:47:48 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "hdlc.h"
|
||||
#include "termios.h"
|
||||
#include "loadalias.h"
|
||||
#include "vars.h"
|
||||
#include "auth.h"
|
||||
|
||||
char VarVersion[] = "PPP Version 1.65";
|
||||
char VarLocalVersion[] = "$Date: 1998/01/20 22:47:48 $";
|
||||
int Utmp = 0;
|
||||
int ipKeepAlive = 0;
|
||||
int reconnectState = RECON_UNKNOWN;
|
||||
int reconnectCount = 0;
|
||||
|
||||
/*
|
||||
* Order of conf option is important. See vars.h.
|
||||
*/
|
||||
struct confdesc pppConfs[] = {
|
||||
{"acfcomp", CONF_ENABLE, CONF_ACCEPT},
|
||||
{"chap", CONF_DISABLE, CONF_ACCEPT},
|
||||
{"deflate", CONF_ENABLE, CONF_ACCEPT},
|
||||
{"lqr", CONF_DISABLE, CONF_ACCEPT},
|
||||
{"pap", CONF_DISABLE, CONF_ACCEPT},
|
||||
{"pppd-deflate", CONF_DISABLE, CONF_DENY},
|
||||
{"pred1", CONF_ENABLE, CONF_ACCEPT},
|
||||
{"protocomp", CONF_ENABLE, CONF_ACCEPT},
|
||||
{"vjcomp", CONF_ENABLE, CONF_ACCEPT},
|
||||
{"msext", CONF_DISABLE, CONF_NONE},
|
||||
{"passwdauth", CONF_DISABLE, CONF_NONE},
|
||||
{"proxy", CONF_DISABLE, CONF_NONE},
|
||||
{"throughput", CONF_DISABLE, CONF_NONE},
|
||||
{"utmp", CONF_ENABLE, CONF_NONE},
|
||||
{NULL},
|
||||
};
|
||||
|
||||
struct pppvars pppVars = {
|
||||
DEF_MRU, DEF_MTU, 0, MODEM_SPEED, CS8, MODEM_CTSRTS, 180, 30, 3,
|
||||
RECONNECT_TIMER, RECONNECT_TRIES, REDIAL_PERIOD,
|
||||
NEXT_REDIAL_PERIOD, 1, 1, MODEM_DEV, "", BASE_MODEM_DEV,
|
||||
1, LOCAL_NO_AUTH, 0
|
||||
};
|
||||
|
||||
int
|
||||
DisplayCommand(struct cmdargs const *arg)
|
||||
{
|
||||
struct confdesc *vp;
|
||||
|
||||
if (!VarTerm)
|
||||
return 1;
|
||||
|
||||
fprintf(VarTerm, "Current configuration option settings..\n\n");
|
||||
fprintf(VarTerm, "Name\t\tMy Side\t\tHis Side\n");
|
||||
fprintf(VarTerm, "----------------------------------------\n");
|
||||
for (vp = pppConfs; vp->name; vp++)
|
||||
fprintf(VarTerm, "%-10s\t%s\t\t%s\n", vp->name,
|
||||
(vp->myside == CONF_ENABLE) ? "enable" :
|
||||
(vp->myside == CONF_DISABLE ? "disable" : "N/A"),
|
||||
(vp->hisside == CONF_ACCEPT) ? "accept" :
|
||||
(vp->hisside == CONF_DENY ? "deny" : "N/A"));
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
ConfigCommand(struct cmdargs const *arg, int mine, int val)
|
||||
{
|
||||
struct confdesc *vp;
|
||||
int err;
|
||||
int narg = 0;
|
||||
|
||||
if (arg->argc < 1)
|
||||
return -1;
|
||||
|
||||
err = 0;
|
||||
do {
|
||||
for (vp = pppConfs; vp->name; vp++)
|
||||
if (strcasecmp(vp->name, arg->argv[narg]) == 0) {
|
||||
if (mine) {
|
||||
if (vp->myside == CONF_NONE) {
|
||||
LogPrintf(LogWARN, "Config: %s cannot be enabled or disabled\n",
|
||||
vp->name);
|
||||
err++;
|
||||
} else
|
||||
vp->myside = val;
|
||||
} else {
|
||||
if (vp->hisside == CONF_NONE) {
|
||||
LogPrintf(LogWARN, "Config: %s cannot be accepted or denied\n",
|
||||
vp->name);
|
||||
err++;
|
||||
} else
|
||||
vp->hisside = val;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (!vp->name) {
|
||||
LogPrintf(LogWARN, "Config: %s: No such key word\n", arg->argv[narg]);
|
||||
err++;
|
||||
}
|
||||
} while (++narg < arg->argc);
|
||||
|
||||
return err;
|
||||
}
|
||||
|
||||
int
|
||||
EnableCommand(struct cmdargs const *arg)
|
||||
{
|
||||
return ConfigCommand(arg, 1, CONF_ENABLE);
|
||||
}
|
||||
|
||||
int
|
||||
DisableCommand(struct cmdargs const *arg)
|
||||
{
|
||||
return ConfigCommand(arg, 1, CONF_DISABLE);
|
||||
}
|
||||
|
||||
int
|
||||
AcceptCommand(struct cmdargs const *arg)
|
||||
{
|
||||
return ConfigCommand(arg, 0, CONF_ACCEPT);
|
||||
}
|
||||
|
||||
int
|
||||
DenyCommand(struct cmdargs const *arg)
|
||||
{
|
||||
return ConfigCommand(arg, 0, CONF_DENY);
|
||||
}
|
||||
|
||||
int
|
||||
LocalAuthCommand(struct cmdargs const *arg)
|
||||
{
|
||||
const char *pass;
|
||||
if (arg->argc == 0)
|
||||
pass = "";
|
||||
else if (arg->argc > 1)
|
||||
return -1;
|
||||
else
|
||||
pass = *arg->argv;
|
||||
|
||||
if (VarHaveLocalAuthKey)
|
||||
VarLocalAuth = strcmp(VarLocalAuthKey, pass) ? LOCAL_NO_AUTH : LOCAL_AUTH;
|
||||
else
|
||||
switch (LocalAuthValidate(SECRETFILE, VarShortHost, pass)) {
|
||||
case INVALID:
|
||||
VarLocalAuth = LOCAL_NO_AUTH;
|
||||
break;
|
||||
case VALID:
|
||||
VarLocalAuth = LOCAL_AUTH;
|
||||
break;
|
||||
case NOT_FOUND:
|
||||
VarLocalAuth = LOCAL_AUTH;
|
||||
LogPrintf(LogWARN, "WARNING: No Entry for this system\n");
|
||||
break;
|
||||
default:
|
||||
VarLocalAuth = LOCAL_NO_AUTH;
|
||||
LogPrintf(LogERROR, "LocalAuthCommand: Ooops?\n");
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
@ -1,205 +0,0 @@
|
||||
/*
|
||||
* Written by Toshiharu OHNO (tony-o@iij.ad.jp)
|
||||
*
|
||||
* Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
|
||||
*
|
||||
* Redistribution and use in source and binary forms are permitted
|
||||
* provided that the above copyright notice and this paragraph are
|
||||
* duplicated in all such forms and that any documentation,
|
||||
* advertising materials, and other materials related to such
|
||||
* distribution and use acknowledge that the software was developed
|
||||
* by the Internet Initiative Japan. The name of the
|
||||
* IIJ 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.
|
||||
*
|
||||
* $Id: vars.h,v 1.41 1998/01/20 22:47:48 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
struct confdesc {
|
||||
const char *name;
|
||||
int myside, hisside;
|
||||
};
|
||||
|
||||
#define CONF_NONE -1
|
||||
#define CONF_DISABLE 0
|
||||
#define CONF_ENABLE 1
|
||||
|
||||
#define CONF_DENY 0
|
||||
#define CONF_ACCEPT 1
|
||||
|
||||
#define ConfAcfcomp 0
|
||||
#define ConfChap 1
|
||||
#define ConfDeflate 2
|
||||
#define ConfLqr 3
|
||||
#define ConfPap 4
|
||||
#define ConfPppdDeflate 5
|
||||
#define ConfPred1 6
|
||||
#define ConfProtocomp 7
|
||||
#define ConfVjcomp 8
|
||||
|
||||
#define ConfMSExt 9
|
||||
#define ConfPasswdAuth 10
|
||||
#define ConfProxy 11
|
||||
#define ConfThroughput 12
|
||||
#define ConfUtmp 13
|
||||
#define MAXCONFS 14
|
||||
|
||||
#define Enabled(x) (pppConfs[x].myside & CONF_ENABLE)
|
||||
#define Acceptable(x) (pppConfs[x].hisside & CONF_ACCEPT)
|
||||
|
||||
extern struct confdesc pppConfs[MAXCONFS + 1];
|
||||
|
||||
struct pppvars {
|
||||
u_short var_mru; /* Initial MRU value */
|
||||
u_short pref_mtu; /* Preferred MTU value */
|
||||
int var_accmap; /* Initial ACCMAP value */
|
||||
int modem_speed; /* Current modem speed */
|
||||
int modem_parity; /* Parity setting */
|
||||
int modem_ctsrts; /* Use CTS/RTS on modem port? (boolean) */
|
||||
int idle_timeout; /* Idle timeout value */
|
||||
int lqr_timeout; /* LQR timeout value */
|
||||
int retry_timeout; /* Retry timeout value */
|
||||
int reconnect_timer; /* Timeout before reconnect on carrier loss */
|
||||
int reconnect_tries; /* Attempt reconnect on carrier loss */
|
||||
int redial_timeout; /* Redial timeout value */
|
||||
int redial_next_timeout; /* Redial next timeout value */
|
||||
int dial_tries; /* Dial attempts before giving up, 0 == inf */
|
||||
int loopback; /* Turn around packets addressed to me */
|
||||
char modem_devlist[LINE_LEN]; /* Comma-separated list of devices */
|
||||
char modem_dev[40]; /* Name of device / host:port */
|
||||
const char *base_modem_dev; /* Pointer to base of modem_dev */
|
||||
int open_mode; /* Delay before first LCP REQ (-1 = passive) */
|
||||
#define LOCAL_AUTH 0x01
|
||||
#define LOCAL_NO_AUTH 0x02
|
||||
#define LOCAL_DENY 0x03
|
||||
u_char lauth; /* Local Authorized status */
|
||||
FILE *termfp; /* The terminal */
|
||||
#define DIALUP_REQ 0x01
|
||||
#define DIALUP_DONE 0x02
|
||||
char dial_script[SCRIPT_LEN]; /* Dial script */
|
||||
char login_script[SCRIPT_LEN]; /* Login script */
|
||||
char auth_key[50]; /* PAP/CHAP key */
|
||||
char auth_name[50]; /* PAP/CHAP system name */
|
||||
char local_auth_key[50]; /* Local auth passwd */
|
||||
int have_local_auth_key; /* Local auth passwd specified ? */
|
||||
#ifdef HAVE_DES
|
||||
int use_MSChap; /* Use MSCHAP encryption */
|
||||
#endif
|
||||
char phone_numbers[200]; /* Telephone Numbers */
|
||||
char phone_copy[200]; /* copy for strsep() */
|
||||
char *next_phone; /* Next phone from the list */
|
||||
char *alt_phone; /* Next phone from the list */
|
||||
char shostname[MAXHOSTNAMELEN]; /* Local short Host Name */
|
||||
char hangup_script[SCRIPT_LEN]; /* Hangup script before modem is closed */
|
||||
struct aliasHandlers handler; /* Alias function pointers */
|
||||
};
|
||||
|
||||
#define VarAccmap pppVars.var_accmap
|
||||
#define VarMRU pppVars.var_mru
|
||||
#define VarPrefMTU pppVars.pref_mtu
|
||||
#define VarDevice pppVars.modem_dev
|
||||
#define VarDeviceList pppVars.modem_devlist
|
||||
#define VarBaseDevice pppVars.base_modem_dev
|
||||
#define VarSpeed pppVars.modem_speed
|
||||
#define VarParity pppVars.modem_parity
|
||||
#define VarCtsRts pppVars.modem_ctsrts
|
||||
#define VarOpenMode pppVars.open_mode
|
||||
#define VarLocalAuth pppVars.lauth
|
||||
#define VarDialScript pppVars.dial_script
|
||||
#define VarHangupScript pppVars.hangup_script
|
||||
#define VarLoginScript pppVars.login_script
|
||||
#define VarIdleTimeout pppVars.idle_timeout
|
||||
#define VarLqrTimeout pppVars.lqr_timeout
|
||||
#define VarRetryTimeout pppVars.retry_timeout
|
||||
#define VarAuthKey pppVars.auth_key
|
||||
#define VarAuthName pppVars.auth_name
|
||||
#define VarLocalAuthKey pppVars.local_auth_key
|
||||
#define VarHaveLocalAuthKey pppVars.have_local_auth_key
|
||||
#ifdef HAVE_DES
|
||||
#define VarMSChap pppVars.use_MSChap
|
||||
#endif
|
||||
#define VarPhoneList pppVars.phone_numbers
|
||||
#define VarPhoneCopy pppVars.phone_copy
|
||||
#define VarNextPhone pppVars.next_phone
|
||||
#define VarAltPhone pppVars.alt_phone
|
||||
#define VarShortHost pppVars.shostname
|
||||
#define VarReconnectTimer pppVars.reconnect_timer
|
||||
#define VarReconnectTries pppVars.reconnect_tries
|
||||
#define VarRedialTimeout pppVars.redial_timeout
|
||||
#define VarRedialNextTimeout pppVars.redial_next_timeout
|
||||
#define VarDialTries pppVars.dial_tries
|
||||
#define VarLoopback pppVars.loopback
|
||||
#define VarTerm pppVars.termfp
|
||||
|
||||
#define VarAliasHandlers pppVars.handler
|
||||
#define VarPacketAliasGetFragment (*pppVars.handler.PacketAliasGetFragment)
|
||||
#define VarPacketAliasGetFragment (*pppVars.handler.PacketAliasGetFragment)
|
||||
#define VarPacketAliasInit (*pppVars.handler.PacketAliasInit)
|
||||
#define VarPacketAliasIn (*pppVars.handler.PacketAliasIn)
|
||||
#define VarPacketAliasOut (*pppVars.handler.PacketAliasOut)
|
||||
#define VarPacketAliasRedirectAddr (*pppVars.handler.PacketAliasRedirectAddr)
|
||||
#define VarPacketAliasRedirectPort (*pppVars.handler.PacketAliasRedirectPort)
|
||||
#define VarPacketAliasSaveFragment (*pppVars.handler.PacketAliasSaveFragment)
|
||||
#define VarPacketAliasSetAddress (*pppVars.handler.PacketAliasSetAddress)
|
||||
#define VarPacketAliasSetMode (*pppVars.handler.PacketAliasSetMode)
|
||||
#define VarPacketAliasFragmentIn (*pppVars.handler.PacketAliasFragmentIn)
|
||||
|
||||
#define DEV_IS_SYNC (VarSpeed == 0)
|
||||
|
||||
extern struct pppvars pppVars;
|
||||
extern char VarVersion[];
|
||||
extern char VarLocalVersion[];
|
||||
|
||||
extern int Utmp; /* Are we in /etc/utmp ? */
|
||||
extern int ipKeepAlive;
|
||||
extern int reconnectState;
|
||||
extern int reconnectCount;
|
||||
|
||||
#define RECON_TRUE (1)
|
||||
#define RECON_FALSE (2)
|
||||
#define RECON_UNKNOWN (3)
|
||||
#define RECON_ENVOKED (4)
|
||||
#define reconnect(x) \
|
||||
do \
|
||||
if (reconnectState == RECON_UNKNOWN) { \
|
||||
reconnectState = x; \
|
||||
if (x == RECON_FALSE) \
|
||||
reconnectCount = 0; \
|
||||
} \
|
||||
while(0)
|
||||
|
||||
|
||||
/*
|
||||
* This is the logic behind the reconnect variables:
|
||||
* We have four reconnect "states". We start off not requiring anything
|
||||
* from the reconnect code (reconnectState == RECON_UNKNOWN). If the
|
||||
* line is brought down (via LcpClose() or LcpDown()), we have to decide
|
||||
* whether to set to RECON_TRUE or RECON_FALSE. It's only here that we
|
||||
* know the correct action. Once we've decided, we don't want that
|
||||
* decision to be overridden (hence the above reconnect() macro) - If we
|
||||
* call LcpClose, the ModemTimeout() still gets to "notice" that the line
|
||||
* is down. When it "notice"s, it should only set RECON_TRUE if a decision
|
||||
* hasn't already been made.
|
||||
*
|
||||
* In main.c, when we notice we have RECON_TRUE, we must only action
|
||||
* it once. The fourth "state" is where we're bringing the line up,
|
||||
* but if we call LcpClose for any reason (failed PAP/CHAP etc) we
|
||||
* don't want to set to RECON_{TRUE,FALSE}.
|
||||
*
|
||||
* If we get a connection or give up dialing, we go back to RECON_UNKNOWN.
|
||||
* If we get give up dialing or reconnecting or if we chose to down the
|
||||
* connection, we set reconnectCount back to zero.
|
||||
*
|
||||
*/
|
||||
|
||||
extern int EnableCommand(struct cmdargs const *);
|
||||
extern int DisableCommand(struct cmdargs const *);
|
||||
extern int AcceptCommand(struct cmdargs const *);
|
||||
extern int DenyCommand(struct cmdargs const *);
|
||||
extern int LocalAuthCommand(struct cmdargs const *);
|
||||
extern int DisplayCommand(struct cmdargs const *);
|
@ -17,7 +17,7 @@
|
||||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: vjcomp.c,v 1.15 1998/01/11 17:50:46 brian Exp $
|
||||
* $Id: vjcomp.c,v 1.16.2.17 1998/05/04 03:00:09 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
@ -25,44 +25,49 @@
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/ip.h>
|
||||
#include <sys/un.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "slcompress.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "defs.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "ipcp.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "mp.h"
|
||||
#include "bundle.h"
|
||||
#include "vjcomp.h"
|
||||
|
||||
#define MAX_VJHEADER 16 /* Maximum size of compressed header */
|
||||
|
||||
static struct slcompress cslc;
|
||||
|
||||
void
|
||||
VjInit(int max_state)
|
||||
{
|
||||
sl_compress_init(&cslc, max_state);
|
||||
}
|
||||
|
||||
void
|
||||
SendPppFrame(struct mbuf * bp)
|
||||
vj_SendFrame(struct link *l, struct mbuf * bp, struct bundle *bundle)
|
||||
{
|
||||
int type;
|
||||
u_short proto;
|
||||
u_short cproto = IpcpInfo.his_compproto >> 16;
|
||||
u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16;
|
||||
|
||||
LogPrintf(LogDEBUG, "SendPppFrame: proto = %x\n", IpcpInfo.his_compproto);
|
||||
log_Printf(LogDEBUG, "vj_SendFrame: COMPPROTO = %x\n",
|
||||
bundle->ncp.ipcp.peer_compproto);
|
||||
if (((struct ip *) MBUF_CTOP(bp))->ip_p == IPPROTO_TCP
|
||||
&& cproto == PROTO_VJCOMP) {
|
||||
type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp), &cslc,
|
||||
IpcpInfo.his_compproto & 0xff);
|
||||
LogPrintf(LogDEBUG, "SendPppFrame: type = %x\n", type);
|
||||
type = sl_compress_tcp(bp, (struct ip *)MBUF_CTOP(bp),
|
||||
&bundle->ncp.ipcp.vj.cslc,
|
||||
&bundle->ncp.ipcp.vj.slstat,
|
||||
bundle->ncp.ipcp.peer_compproto & 0xff);
|
||||
log_Printf(LogDEBUG, "vj_SendFrame: type = %x\n", type);
|
||||
switch (type) {
|
||||
case TYPE_IP:
|
||||
proto = PROTO_IP;
|
||||
@ -74,24 +79,26 @@ SendPppFrame(struct mbuf * bp)
|
||||
proto = PROTO_VJCOMP;
|
||||
break;
|
||||
default:
|
||||
LogPrintf(LogERROR, "Unknown frame type %x\n", type);
|
||||
pfree(bp);
|
||||
log_Printf(LogERROR, "Unknown frame type %x\n", type);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
proto = PROTO_IP;
|
||||
HdlcOutput(PRI_NORMAL, proto, bp);
|
||||
|
||||
if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, proto, bp))
|
||||
hdlc_Output(l, PRI_NORMAL, proto, bp);
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
VjUncompressTcp(struct mbuf * bp, u_char type)
|
||||
VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
|
||||
{
|
||||
u_char *bufp;
|
||||
int len, olen, rlen;
|
||||
struct mbuf *nbp;
|
||||
u_char work[MAX_HDR + MAX_VJHEADER]; /* enough to hold TCP/IP header */
|
||||
|
||||
olen = len = plength(bp);
|
||||
olen = len = mbuf_Length(bp);
|
||||
if (type == TYPE_UNCOMPRESSED_TCP) {
|
||||
|
||||
/*
|
||||
@ -99,9 +106,9 @@ VjUncompressTcp(struct mbuf * bp, u_char type)
|
||||
* space for uncompression job.
|
||||
*/
|
||||
bufp = MBUF_CTOP(bp);
|
||||
len = sl_uncompress_tcp(&bufp, len, type, &cslc);
|
||||
len = sl_uncompress_tcp(&bufp, len, type, &ipcp->vj.cslc, &ipcp->vj.slstat);
|
||||
if (len <= 0) {
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
return (bp);
|
||||
@ -116,27 +123,27 @@ VjUncompressTcp(struct mbuf * bp, u_char type)
|
||||
len = MAX_VJHEADER;
|
||||
rlen = len;
|
||||
bufp = work + MAX_HDR;
|
||||
bp = mbread(bp, bufp, rlen);
|
||||
len = sl_uncompress_tcp(&bufp, olen, type, &cslc);
|
||||
bp = mbuf_Read(bp, bufp, rlen);
|
||||
len = sl_uncompress_tcp(&bufp, olen, type, &ipcp->vj.cslc, &ipcp->vj.slstat);
|
||||
if (len <= 0) {
|
||||
pfree(bp);
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
len -= olen;
|
||||
len += rlen;
|
||||
nbp = mballoc(len, MB_VJCOMP);
|
||||
nbp = mbuf_Alloc(len, MB_VJCOMP);
|
||||
memcpy(MBUF_CTOP(nbp), bufp, len);
|
||||
nbp->next = bp;
|
||||
return (nbp);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
VjCompInput(struct mbuf * bp, int proto)
|
||||
vj_Input(struct ipcp *ipcp, struct mbuf *bp, int proto)
|
||||
{
|
||||
u_char type;
|
||||
|
||||
LogPrintf(LogDEBUG, "VjCompInput: proto %02x\n", proto);
|
||||
LogDumpBp(LogDEBUG, "Raw packet info:", bp);
|
||||
log_Printf(LogDEBUG, "vj_Input: proto %02x\n", proto);
|
||||
log_DumpBp(LogDEBUG, "Raw packet info:", bp);
|
||||
|
||||
switch (proto) {
|
||||
case PROTO_VJCOMP:
|
||||
@ -146,10 +153,10 @@ VjCompInput(struct mbuf * bp, int proto)
|
||||
type = TYPE_UNCOMPRESSED_TCP;
|
||||
break;
|
||||
default:
|
||||
LogPrintf(LogERROR, "VjCompInput...???\n");
|
||||
log_Printf(LogERROR, "vj_Input...???\n");
|
||||
return (bp);
|
||||
}
|
||||
bp = VjUncompressTcp(bp, type);
|
||||
bp = VjUncompressTcp(ipcp, bp, type);
|
||||
return (bp);
|
||||
}
|
||||
|
||||
@ -158,7 +165,10 @@ vj2asc(u_int32_t val)
|
||||
{
|
||||
static char asc[50];
|
||||
|
||||
sprintf(asc, "%d VJ slots %s slot compression",
|
||||
(int)((val>>8)&15)+1, val & 1 ? "with" : "without");
|
||||
if (val)
|
||||
snprintf(asc, sizeof asc, "%d VJ slots %s slot compression",
|
||||
(int)((val>>8)&15)+1, val & 1 ? "with" : "without");
|
||||
else
|
||||
strcpy(asc, "VJ disabled");
|
||||
return asc;
|
||||
}
|
||||
|
@ -23,10 +23,14 @@
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: vjcomp.h,v 1.4 1997/12/21 12:11:10 brian Exp $
|
||||
* $Id: vjcomp.h,v 1.5.4.6 1998/05/01 19:26:12 brian Exp $
|
||||
*/
|
||||
|
||||
extern void VjInit(int);
|
||||
extern void SendPppFrame(struct mbuf *);
|
||||
extern struct mbuf *VjCompInput(struct mbuf *, int);
|
||||
struct mbuf;
|
||||
struct link;
|
||||
struct ipcp;
|
||||
struct bundle;
|
||||
|
||||
extern void vj_SendFrame(struct link *, struct mbuf *, struct bundle *);
|
||||
extern struct mbuf *vj_Input(struct ipcp *, struct mbuf *, int);
|
||||
extern const char *vj2asc(u_int32_t);
|
||||
|
Loading…
Reference in New Issue
Block a user