MFMP: Make ppp multilink capable.

See the file README.changes, and re-read the man page.
This commit is contained in:
Brian Somers 1998-05-21 21:49:08 +00:00
commit d91d286164
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=36285
95 changed files with 16579 additions and 9263 deletions

View File

@ -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

View 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.

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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

View File

@ -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 *);

View File

@ -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--;
}
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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

File diff suppressed because it is too large Load Diff

170
usr.sbin/ppp/bundle.h Normal file
View 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 *);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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];

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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

View File

@ -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

File diff suppressed because it is too large Load Diff

130
usr.sbin/ppp/datalink.h Normal file
View 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);

View File

@ -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,

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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))

View File

@ -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;
}

View File

@ -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

View File

@ -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);

View File

@ -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);
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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);

File diff suppressed because it is too large Load Diff

View File

@ -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 *);

View File

@ -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++;

File diff suppressed because it is too large Load Diff

View File

@ -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 *);

View File

@ -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
View 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
View 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 *);

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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);
}
}

View File

@ -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 *);

File diff suppressed because it is too large Load Diff

View File

@ -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);

View File

@ -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);
}

View File

@ -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 *);

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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
View 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 *);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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;
}
}

View File

@ -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
View 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
View 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);

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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
View 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
View 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)

View File

@ -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));
}
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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);
}

View File

@ -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 *);

View File

@ -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

View File

@ -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);

View File

@ -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

View File

@ -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 *);

View File

@ -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));
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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 *);

View File

@ -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;
}

View File

@ -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);