o Redesign the layering mechanism and make the aliasing code part of
the layering. We now ``stack'' layers as soon as we open the device (when we figure out what we're dealing with). A static set of `dispatch' routines are also declared for dealing with incoming packets after they've been `pulled' up through the stacked layers. Physical devices are now assigned handlers based on the device type when they're opened. For the moment there are three device types; ttys, execs and tcps. o Increment version number to 2.2 o Make an entry in [uw]tmp for non-tty -direct invocations (after pap/chap authentication). o Make throughput counters quad_t's o Account for the absolute number of mbuf malloc()s and free()s in ``show mem''. o ``show modem'' becomes ``show physical''.
This commit is contained in:
parent
46be34b902
commit
5d9e610366
|
@ -1,13 +1,14 @@
|
|||
# $Id: Makefile,v 1.51 1999/01/28 01:56:30 brian Exp $
|
||||
# $Id: Makefile,v 1.52 1999/01/28 15:16:38 brian Exp $
|
||||
|
||||
MAINTAINER=brian@FreeBSD.org
|
||||
|
||||
PROG= ppp
|
||||
SRCS= arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c command.c \
|
||||
datalink.c deflate.c defs.c filter.c fsm.c hdlc.c id.c iface.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 probe.c prompt.c route.c server.c \
|
||||
sig.c slcompress.c systems.c throughput.c timer.c tun.c vjcomp.c
|
||||
SRCS= acf.c arp.c async.c auth.c bundle.c cbcp.c ccp.c chap.c chat.c \
|
||||
command.c datalink.c deflate.c defs.c exec.c filter.c fsm.c hdlc.c \
|
||||
id.c iface.c ip.c ipcp.c iplist.c lcp.c link.c log.c lqr.c main.c \
|
||||
mbuf.c mp.c pap.c physical.c pred.c probe.c prompt.c proto.c route.c \
|
||||
server.c sig.c slcompress.c sync.c systems.c tcp.c throughput.c \
|
||||
timer.c tty.c tun.c vjcomp.c
|
||||
CFLAGS+=-Wall
|
||||
LDADD+= -lcrypt -lmd -lutil -lz
|
||||
DPADD+= ${LIBCRYPT} ${LIBMD} ${LIBUTIL} ${LIBZ}
|
||||
|
|
|
@ -83,3 +83,5 @@ o Ppp now accepts M$CHAP (as well as normal CHAP) by default. If this
|
|||
o The ``set device'' command now expects each device to be specified as an
|
||||
argument rather than concatentating all arguments and splitting based
|
||||
on commas and spaces.
|
||||
o The ``show modem'' command is depricated and has been changed to
|
||||
``show physical''.
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "layer.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "log.h"
|
||||
#include "mbuf.h"
|
||||
#include "acf.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "throughput.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
|
||||
int
|
||||
acf_WrapperOctets(struct lcp *lcp, u_short proto)
|
||||
{
|
||||
return (proto == PROTO_LCP || lcp->his_acfcomp == 0) ? 2 : 0;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
acf_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
const u_char cp[2] = { HDLC_ADDR, HDLC_UI };
|
||||
|
||||
if (*proto == PROTO_LCP || l->lcp.his_acfcomp == 0)
|
||||
bp = mbuf_Prepend(bp, cp, 2, 0);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
acf_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
u_char cp[2];
|
||||
|
||||
if (!p) {
|
||||
log_Printf(LogERROR, "Can't Pull an acf packet from a logical link\n");
|
||||
return bp;
|
||||
}
|
||||
|
||||
if (mbuf_View(bp, cp, 2) == 2) {
|
||||
if (!p->link.lcp.want_acfcomp) {
|
||||
/* We expect the packet not to be compressed */
|
||||
bp = mbuf_Read(bp, cp, 2);
|
||||
if (cp[0] != HDLC_ADDR) {
|
||||
p->hdlc.lqm.SaveInErrors++;
|
||||
p->hdlc.stats.badaddr++;
|
||||
log_Printf(LogDEBUG, "acf_LayerPull: addr 0x%02x\n", cp[0]);
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
if (cp[1] != HDLC_UI) {
|
||||
p->hdlc.lqm.SaveInErrors++;
|
||||
p->hdlc.stats.badcommand++;
|
||||
log_Printf(LogDEBUG, "acf_LayerPull: control 0x%02x\n", cp[1]);
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
} else if (cp[0] == HDLC_ADDR && cp[1] == HDLC_UI) {
|
||||
/*
|
||||
* We can receive compressed packets, but the peer still sends
|
||||
* uncompressed packets (or maybe this is a PROTO_LCP packet) !
|
||||
*/
|
||||
bp = mbuf_Read(bp, cp, 2);
|
||||
}
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct layer acflayer = { LAYER_ACF, "acf", acf_LayerPush, acf_LayerPull };
|
|
@ -0,0 +1,33 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
struct lcp;
|
||||
|
||||
extern int acf_WrapperOctets(struct lcp *, u_short);
|
||||
|
||||
extern struct layer acflayer;
|
|
@ -2,7 +2,7 @@
|
|||
* 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.22 1999/03/25 23:36:23 brian Exp $
|
||||
* $Id: alias_cmd.c,v 1.23 1999/04/26 08:54:32 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -24,6 +24,8 @@
|
|||
#else
|
||||
#include "alias.h"
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "proto.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
|
@ -304,3 +306,96 @@ alias_Pptp(struct cmdargs const *arg)
|
|||
PacketAliasPptp(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_PadMbuf(struct mbuf *bp, int type)
|
||||
{
|
||||
struct mbuf **last;
|
||||
int len;
|
||||
|
||||
for (last = &bp, len = 0; *last != NULL; last = &(*last)->next)
|
||||
len += (*last)->cnt;
|
||||
|
||||
len = MAX_MRU - len;
|
||||
*last = mbuf_Alloc(len, type);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
if (!bundle->AliasEnabled || *proto != PROTO_IP)
|
||||
return bp;
|
||||
|
||||
bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPQ));
|
||||
PacketAliasOut(MBUF_CTOP(bp), bp->cnt);
|
||||
bp->cnt = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
struct ip *pip, *piip;
|
||||
int ret;
|
||||
struct mbuf **last;
|
||||
char *fptr;
|
||||
|
||||
if (!bundle->AliasEnabled || *proto != PROTO_IP)
|
||||
return bp;
|
||||
|
||||
bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPIN));
|
||||
pip = (struct ip *)MBUF_CTOP(bp);
|
||||
piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
|
||||
|
||||
if (pip->ip_p == IPPROTO_IGMP ||
|
||||
(pip->ip_p == IPPROTO_IPIP && IN_CLASSD(ntohl(piip->ip_dst.s_addr))))
|
||||
return bp;
|
||||
|
||||
ret = PacketAliasIn(MBUF_CTOP(bp), bp->cnt);
|
||||
|
||||
bp->cnt = ntohs(pip->ip_len);
|
||||
if (bp->cnt > MAX_MRU) {
|
||||
log_Printf(LogWARN, "alias_LayerPull: Problem with IP header length\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case PKT_ALIAS_OK:
|
||||
break;
|
||||
|
||||
case PKT_ALIAS_UNRESOLVED_FRAGMENT:
|
||||
/* Save the data for later */
|
||||
fptr = malloc(bp->cnt);
|
||||
mbuf_Read(bp, fptr, bp->cnt);
|
||||
PacketAliasSaveFragment(fptr);
|
||||
break;
|
||||
|
||||
case PKT_ALIAS_FOUND_HEADER_FRAGMENT:
|
||||
/* Fetch all the saved fragments and chain them on the end of `bp' */
|
||||
last = &bp->pnext;
|
||||
while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) {
|
||||
PacketAliasFragmentIn(MBUF_CTOP(bp), fptr);
|
||||
*last = mbuf_Alloc(ntohs(((struct ip *)fptr)->ip_len), MB_IPIN);
|
||||
memcpy(MBUF_CTOP(*last), fptr, (*last)->cnt);
|
||||
free(fptr);
|
||||
last = &(*last)->pnext;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct layer aliaslayer =
|
||||
{ LAYER_ALIAS, "alias", alias_LayerPush, alias_LayerPull };
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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.9 1999/03/07 15:02:37 brian Exp $
|
||||
* $Id: alias_cmd.h,v 1.10 1999/03/07 18:13:44 brian Exp $
|
||||
*/
|
||||
|
||||
struct cmdargs;
|
||||
|
@ -11,3 +11,5 @@ extern int alias_RedirectPort(struct cmdargs const *);
|
|||
extern int alias_RedirectAddr(struct cmdargs const *);
|
||||
extern int alias_ProxyRule(struct cmdargs const *);
|
||||
extern int alias_Pptp(struct cmdargs const *);
|
||||
|
||||
extern struct layer aliaslayer;
|
||||
|
|
|
@ -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.32 1999/01/28 01:56:30 brian Exp $
|
||||
* $Id: arp.c,v 1.33 1999/04/26 08:54:24 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -42,8 +42,10 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: async.c,v 1.17 1998/06/16 19:40:34 brian Exp $
|
||||
* $Id: async.c,v 1.18 1999/04/11 08:51:04 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
@ -25,6 +25,7 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
@ -33,7 +34,7 @@
|
|||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "async.h"
|
||||
#include "throughput.h"
|
||||
#include "ccp.h"
|
||||
|
@ -61,10 +62,10 @@ async_SetLinkParams(struct async *async, struct lcp *lcp)
|
|||
}
|
||||
|
||||
/*
|
||||
* Encode into async HDLC byte code if necessary
|
||||
* Encode into async HDLC byte code
|
||||
*/
|
||||
static void
|
||||
HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto)
|
||||
async_Encode(struct async *async, u_char **cp, u_char c, int proto)
|
||||
{
|
||||
u_char *wp;
|
||||
|
||||
|
@ -82,39 +83,44 @@ HdlcPutByte(struct async *async, u_char **cp, u_char c, int proto)
|
|||
*cp = wp;
|
||||
}
|
||||
|
||||
void
|
||||
async_Output(int pri, struct mbuf *bp, int proto, struct physical *physical)
|
||||
static struct mbuf *
|
||||
async_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
u_char *cp, *sp, *ep;
|
||||
struct mbuf *wp;
|
||||
int cnt;
|
||||
|
||||
if (mbuf_Length(bp) > HDLCSIZE) {
|
||||
if (!p || mbuf_Length(bp) > HDLCSIZE) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
cp = physical->async.xbuff;
|
||||
|
||||
cp = p->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(&physical->async, &cp, *sp++, proto);
|
||||
async_Encode(&p->async, &cp, *sp++, *proto);
|
||||
if (cp >= ep) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
wp = wp->next;
|
||||
}
|
||||
*cp++ = HDLC_SYN;
|
||||
|
||||
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);
|
||||
cnt = cp - p->async.xbuff;
|
||||
mbuf_Free(bp);
|
||||
bp = mbuf_Alloc(cnt, MB_ASYNC);
|
||||
memcpy(MBUF_CTOP(bp), p->async.xbuff, cnt);
|
||||
|
||||
log_DumpBp(LogASYNC, "WriteModem", bp);
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
|
@ -160,25 +166,34 @@ async_Decode(struct async *async, u_char c)
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
async_Input(struct bundle *bundle, u_char *buff, int cnt,
|
||||
struct physical *physical)
|
||||
static struct mbuf *
|
||||
async_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
struct mbuf *bp;
|
||||
struct mbuf *nbp, **last;
|
||||
struct physical *p = link2physical(l);
|
||||
u_char *ch;
|
||||
size_t cnt;
|
||||
|
||||
link_AddInOctets(&physical->link, cnt);
|
||||
|
||||
if (physical_IsSync(physical)) {
|
||||
bp = mbuf_Alloc(cnt, MB_ASYNC);
|
||||
memcpy(MBUF_CTOP(bp), buff, cnt);
|
||||
bp->cnt = cnt;
|
||||
hdlc_Input(bundle, bp, physical);
|
||||
} else {
|
||||
while (cnt > 0) {
|
||||
bp = async_Decode(&physical->async, *buff++);
|
||||
if (bp)
|
||||
hdlc_Input(bundle, bp, physical);
|
||||
cnt--;
|
||||
}
|
||||
if (!p) {
|
||||
log_Printf(LogERROR, "Can't Pull an async packet from a logical link\n");
|
||||
return bp;
|
||||
}
|
||||
|
||||
last = &nbp;
|
||||
|
||||
while (bp) {
|
||||
ch = MBUF_CTOP(bp);
|
||||
for (cnt = bp->cnt; cnt; cnt--) {
|
||||
*last = async_Decode(&p->async, *ch++);
|
||||
if (*last != NULL)
|
||||
last = &(*last)->pnext;
|
||||
}
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
}
|
||||
|
||||
return nbp;
|
||||
}
|
||||
|
||||
struct layer asynclayer =
|
||||
{ LAYER_ASYNC, "async", async_LayerPush, async_LayerPull };
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: async.h,v 1.3 1998/05/21 21:43:57 brian Exp $
|
||||
* $Id: async.h,v 1.4 1998/06/27 12:03:48 brian Exp $
|
||||
*/
|
||||
|
||||
#define HDLCSIZE (MAX_MRU*2+6)
|
||||
|
@ -48,5 +48,5 @@ 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 *);
|
||||
|
||||
extern struct layer asynclayer;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: auth.c,v 1.42 1999/02/26 21:28:06 brian Exp $
|
||||
* $Id: auth.c,v 1.43 1999/03/31 14:21:44 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Implement check against with registered IP addresses.
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
|
@ -52,7 +53,7 @@
|
|||
#include "link.h"
|
||||
#include "descriptor.h"
|
||||
#include "chat.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "filter.h"
|
||||
#include "mp.h"
|
||||
#ifndef NORADIUS
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: bundle.c,v 1.50 1999/03/25 11:37:51 brian Exp $
|
||||
* $Id: bundle.c,v 1.51 1999/04/26 08:54:33 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -49,13 +49,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef NOALIAS
|
||||
#ifdef __FreeBSD__
|
||||
#include <alias.h>
|
||||
#else
|
||||
#include "alias.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
@ -82,9 +76,8 @@
|
|||
#include "bundle.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
#include "modem.h"
|
||||
#include "auth.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "chap.h"
|
||||
#include "tun.h"
|
||||
#include "prompt.h"
|
||||
|
@ -349,11 +342,11 @@ bundle_LayerUp(void *v, struct fsm *fp)
|
|||
bundle->ifSpeed = 0;
|
||||
for (dl = bundle->links; dl; dl = dl->next)
|
||||
if (dl->state == DATALINK_OPEN)
|
||||
bundle->ifSpeed += modem_Speed(dl->physical);
|
||||
bundle->ifSpeed += physical_GetSpeed(dl->physical);
|
||||
tun_configure(bundle, bundle->ncp.mp.peer_mrru);
|
||||
bundle->autoload.running = 1;
|
||||
} else {
|
||||
bundle->ifSpeed = modem_Speed(p);
|
||||
bundle->ifSpeed = physical_GetSpeed(p);
|
||||
tun_configure(bundle, fsm2lcp(fp)->his_mru);
|
||||
}
|
||||
} else if (fp->proto == PROTO_IPCP) {
|
||||
|
@ -389,7 +382,7 @@ bundle_LayerDown(void *v, struct fsm *fp)
|
|||
if (fp == &dl->physical->link.lcp.fsm)
|
||||
lost = dl;
|
||||
else if (dl->state == DATALINK_OPEN)
|
||||
bundle->ifSpeed += modem_Speed(dl->physical);
|
||||
bundle->ifSpeed += physical_GetSpeed(dl->physical);
|
||||
|
||||
if (bundle->ifSpeed)
|
||||
/* Don't configure down to a speed of 0 */
|
||||
|
@ -639,11 +632,8 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
|
|||
if (Enabled(bundle, OPT_LOOPBACK)) {
|
||||
pri = PacketCheck(bundle, tun.data, n, &bundle->filter.in);
|
||||
if (pri >= 0) {
|
||||
struct mbuf *bp;
|
||||
|
||||
bp = mbuf_Alloc(n, MB_IPIN);
|
||||
memcpy(MBUF_CTOP(bp), tun.data, n);
|
||||
ip_Input(bundle, bp);
|
||||
n += sizeof tun - sizeof tun.data;
|
||||
write(bundle->dev.fd, &tun, n);
|
||||
log_Printf(LogDEBUG, "Looped back packet addressed to myself\n");
|
||||
}
|
||||
return;
|
||||
|
@ -675,15 +665,8 @@ bundle_DescriptorRead(struct descriptor *d, struct bundle *bundle,
|
|||
}
|
||||
|
||||
pri = PacketCheck(bundle, tun.data, n, &bundle->filter.out);
|
||||
if (pri >= 0) {
|
||||
#ifndef NOALIAS
|
||||
if (bundle->AliasEnabled) {
|
||||
PacketAliasOut(tun.data, sizeof tun.data);
|
||||
n = ntohs(((struct ip *)tun.data)->ip_len);
|
||||
}
|
||||
#endif
|
||||
if (pri >= 0)
|
||||
ip_Enqueue(&bundle->ncp.ipcp, pri, tun.data, n);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1194,7 +1177,7 @@ bundle_FillQueues(struct bundle *bundle)
|
|||
if (dl->state == DATALINK_OPEN) {
|
||||
add = link_QueueLen(&dl->physical->link);
|
||||
if (add == 0 && dl->physical->out == NULL)
|
||||
add = ip_FlushPacket(&dl->physical->link, bundle);
|
||||
add = ip_PushPacket(&dl->physical->link, bundle);
|
||||
total += add;
|
||||
}
|
||||
}
|
||||
|
@ -1211,7 +1194,7 @@ bundle_ShowLinks(struct cmdargs const *arg)
|
|||
prompt_Printf(arg->prompt, "Name: %s [%s, %s]",
|
||||
dl->name, mode2Nam(dl->physical->type), datalink_State(dl));
|
||||
if (dl->physical->link.throughput.rolling && dl->state == DATALINK_OPEN)
|
||||
prompt_Printf(arg->prompt, " weight %d, %d bytes/sec",
|
||||
prompt_Printf(arg->prompt, " weight %d, %Ld bytes/sec",
|
||||
dl->mp.weight,
|
||||
dl->physical->link.throughput.OctetsPerSecond);
|
||||
prompt_Printf(arg->prompt, "\n");
|
||||
|
@ -1704,10 +1687,10 @@ bundle_setsid(struct bundle *bundle, int holdsession)
|
|||
break;
|
||||
default:
|
||||
close(fds[0]);
|
||||
/* Give away all our modem locks (to the final process) */
|
||||
/* Give away all our physical locks (to the final process) */
|
||||
for (dl = bundle->links; dl; dl = dl->next)
|
||||
if (dl->state != DATALINK_CLOSED)
|
||||
modem_ChangedPid(dl->physical, pid);
|
||||
physical_ChangedPid(dl->physical, pid);
|
||||
write(fds[1], "!", 1); /* done */
|
||||
close(fds[1]);
|
||||
exit(0);
|
||||
|
@ -1716,10 +1699,10 @@ bundle_setsid(struct bundle *bundle, int holdsession)
|
|||
break;
|
||||
default:
|
||||
close(fds[0]);
|
||||
/* Give away all our modem locks (to the intermediate process) */
|
||||
/* Give away all our physical locks (to the intermediate process) */
|
||||
for (dl = bundle->links; dl; dl = dl->next)
|
||||
if (dl->state != DATALINK_CLOSED)
|
||||
modem_ChangedPid(dl->physical, pid);
|
||||
physical_ChangedPid(dl->physical, pid);
|
||||
write(fds[1], "!", 1); /* done */
|
||||
close(fds[1]);
|
||||
if (holdsession) {
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: cbcp.c,v 1.10 1999/02/26 21:28:07 brian Exp $
|
||||
* $Id: cbcp.c,v 1.11 1999/03/29 08:21:26 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -33,6 +33,7 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
|
@ -47,7 +48,7 @@
|
|||
#include "link.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "cbcp.h"
|
||||
#include "mp.h"
|
||||
#include "chat.h"
|
||||
|
@ -201,7 +202,8 @@ cbcp_Output(struct cbcp *cbcp, u_char code, struct cbcp_data *data)
|
|||
head->length = htons(sizeof *head + data->length);
|
||||
memcpy(MBUF_CTOP(bp) + sizeof *head, data, data->length);
|
||||
log_DumpBp(LogDEBUG, "cbcp_Output", bp);
|
||||
hdlc_Output(&cbcp->p->link, PRI_LINK, PROTO_CBCP, bp);
|
||||
link_PushPacket(&cbcp->p->link, bp, cbcp->p->dl->bundle,
|
||||
PRI_LINK, PROTO_CBCP);
|
||||
}
|
||||
|
||||
static const char *
|
||||
|
@ -600,26 +602,33 @@ cbcp_SendAck(struct cbcp *cbcp)
|
|||
cbcp_NewPhase(cbcp, CBCP_ACKSENT); /* Wait for an ACK */
|
||||
}
|
||||
|
||||
void
|
||||
cbcp_Input(struct physical *p, struct mbuf *bp)
|
||||
extern struct mbuf *
|
||||
cbcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct cbcp_header *head;
|
||||
struct cbcp_data *data;
|
||||
struct cbcp *cbcp = &p->dl->cbcp;
|
||||
int len;
|
||||
|
||||
if (p == NULL) {
|
||||
log_Printf(LogERROR, "cbcp_Input: Not a physical link - dropped\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
bp = mbuf_Contiguous(bp);
|
||||
len = mbuf_Length(bp);
|
||||
if (len < sizeof(struct cbcp_header)) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
head = (struct cbcp_header *)MBUF_CTOP(bp);
|
||||
if (ntohs(head->length) != len) {
|
||||
log_Printf(LogWARN, "Corrupt CBCP packet (code %d, length %d not %d)"
|
||||
" - ignored\n", head->code, ntohs(head->length), len);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* XXX check the id */
|
||||
|
@ -706,6 +715,7 @@ cbcp_Input(struct physical *p, struct mbuf *bp)
|
|||
}
|
||||
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
* $Id: cbcp.h,v 1.1 1998/08/07 18:44:16 brian Exp $
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
|
@ -60,6 +60,6 @@ struct cbcp {
|
|||
|
||||
extern void cbcp_Init(struct cbcp *, struct physical *);
|
||||
extern void cbcp_Up(struct cbcp *);
|
||||
extern void cbcp_Input(struct physical *, struct mbuf *);
|
||||
extern struct mbuf *cbcp_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
extern void cbcp_Down(struct cbcp *);
|
||||
extern void cbcp_ReceiveTerminateReq(struct physical *);
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ccp.c,v 1.45 1999/03/31 14:21:44 brian Exp $
|
||||
* $Id: ccp.c,v 1.46 1999/05/02 14:33:39 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Support other compression protocols
|
||||
|
@ -33,13 +33,14 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "pred.h"
|
||||
|
@ -144,11 +145,13 @@ ccp_ReportStatus(struct cmdargs const *arg)
|
|||
|
||||
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);
|
||||
if (ccp->fsm.state == ST_OPENED) {
|
||||
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, max %u Config"
|
||||
|
@ -529,18 +532,19 @@ CcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ccp_Input(struct ccp *ccp, struct bundle *bundle, struct mbuf *bp)
|
||||
extern struct mbuf *
|
||||
ccp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
/* Got PROTO_CCP from link */
|
||||
if (bundle_Phase(bundle) == PHASE_NETWORK)
|
||||
fsm_Input(&ccp->fsm, bp);
|
||||
fsm_Input(&l->ccp.fsm, bp);
|
||||
else {
|
||||
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));
|
||||
l->ccp.fsm.link->name, bundle_PhaseName(bundle));
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -571,42 +575,40 @@ CcpRecvResetAck(struct fsm *fp, u_char id)
|
|||
(*algorithm[ccp->in.algorithm]->i.Reset)(ccp->in.state);
|
||||
}
|
||||
|
||||
int
|
||||
ccp_Compress(struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
struct mbuf *m)
|
||||
static struct mbuf *
|
||||
ccp_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
/*
|
||||
* 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;
|
||||
if (PROTO_COMPRESSIBLE(*proto) && l->ccp.fsm.state == ST_OPENED &&
|
||||
l->ccp.out.state != NULL)
|
||||
return (*algorithm[l->ccp.out.algorithm]->o.Write)
|
||||
(l->ccp.out.state, &l->ccp, l, pri, proto, bp);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
ccp_Decompress(struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
||||
static struct mbuf *
|
||||
ccp_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp, u_short *proto)
|
||||
{
|
||||
/*
|
||||
* 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 (l->ccp.fsm.state == ST_OPENED) {
|
||||
if (*proto == PROTO_COMPD || *proto == PROTO_ICOMPD) {
|
||||
/* Decompress incoming data */
|
||||
if (ccp->reset_sent != -1)
|
||||
if (l->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);
|
||||
fsm_Output(&l->ccp.fsm, CODE_RESETREQ, l->ccp.reset_sent, NULL, 0);
|
||||
else if (l->ccp.in.state != NULL)
|
||||
return (*algorithm[l->ccp.in.algorithm]->i.Read)
|
||||
(l->ccp.in.state, &l->ccp, proto, bp);
|
||||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
} else if (PROTO_COMPRESSIBLE(*proto) && ccp->in.state != NULL)
|
||||
} else if (PROTO_COMPRESSIBLE(*proto) && l->ccp.in.state != NULL)
|
||||
/* Add incoming Network Layer traffic to our dictionary */
|
||||
(*algorithm[ccp->in.algorithm]->i.DictSetup)
|
||||
(ccp->in.state, ccp, *proto, bp);
|
||||
(*algorithm[l->ccp.in.algorithm]->i.DictSetup)
|
||||
(l->ccp.in.state, &l->ccp, *proto, bp);
|
||||
}
|
||||
|
||||
return bp;
|
||||
|
@ -638,3 +640,5 @@ ccp_SetOpenMode(struct ccp *ccp)
|
|||
|
||||
return 0; /* No CCP at all */
|
||||
}
|
||||
|
||||
struct layer ccplayer = { LAYER_CCP, "ccp", ccp_LayerPush, ccp_LayerPull };
|
||||
|
|
|
@ -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.19 1998/06/30 23:04:12 brian Exp $
|
||||
* $Id: ccp.h,v 1.20 1999/02/26 21:28:07 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -109,8 +109,8 @@ struct ccp_algorithm {
|
|||
void *(*Init)(struct lcp_opt *);
|
||||
void (*Term)(void *);
|
||||
void (*Reset)(void *);
|
||||
int (*Write)(void *, struct ccp *, struct link *, int, u_short,
|
||||
struct mbuf *);
|
||||
struct mbuf *(*Write)(void *, struct ccp *, struct link *, int, u_short *,
|
||||
struct mbuf *);
|
||||
} o;
|
||||
};
|
||||
|
||||
|
@ -119,10 +119,10 @@ extern void ccp_Init(struct ccp *, struct bundle *, struct link *,
|
|||
extern void ccp_Setup(struct ccp *);
|
||||
|
||||
extern void ccp_SendResetReq(struct fsm *);
|
||||
extern void ccp_Input(struct ccp *, struct bundle *, struct mbuf *);
|
||||
extern struct mbuf *ccp_Input(struct bundle *, struct link *, 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 *);
|
||||
extern int ccp_SetOpenMode(struct ccp *);
|
||||
|
||||
extern struct layer ccplayer;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.c,v 1.48 1999/04/01 11:05:22 brian Exp $
|
||||
* $Id: chap.c,v 1.49 1999/04/21 08:03:51 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -41,12 +41,13 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
|
@ -101,7 +102,8 @@ ChapOutput(struct physical *physical, u_int code, u_int id,
|
|||
log_Printf(LogPHASE, "Chap Output: %s\n", chapcodes[code]);
|
||||
else
|
||||
log_Printf(LogPHASE, "Chap Output: %s (%s)\n", chapcodes[code], text);
|
||||
hdlc_Output(&physical->link, PRI_LINK, PROTO_CHAP, bp);
|
||||
link_PushPacket(&physical->link, bp, physical->dl->bundle,
|
||||
PRI_LINK, PROTO_CHAP);
|
||||
}
|
||||
|
||||
static char *
|
||||
|
@ -532,9 +534,10 @@ chap_ReInit(struct chap *chap)
|
|||
chap_Cleanup(chap, SIGTERM);
|
||||
}
|
||||
|
||||
void
|
||||
chap_Input(struct physical *p, struct mbuf *bp)
|
||||
struct mbuf *
|
||||
chap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct chap *chap = &p->dl->chap;
|
||||
char *name, *key, *ans;
|
||||
int len, nlen;
|
||||
|
@ -543,11 +546,17 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
int lanman;
|
||||
#endif
|
||||
|
||||
if (bundle_Phase(p->dl->bundle) != PHASE_NETWORK &&
|
||||
bundle_Phase(p->dl->bundle) != PHASE_AUTHENTICATE) {
|
||||
if (p == NULL) {
|
||||
log_Printf(LogERROR, "chap_Input: Not a physical link - dropped\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bundle_Phase(bundle) != PHASE_NETWORK &&
|
||||
bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
|
||||
log_Printf(LogPHASE, "Unexpected chap input - dropped !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((bp = auth_ReadHeader(&chap->auth, bp)) == NULL &&
|
||||
|
@ -562,13 +571,13 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
|
||||
if (chap->auth.in.hdr.code != CHAP_CHALLENGE &&
|
||||
chap->auth.id != chap->auth.in.hdr.id &&
|
||||
Enabled(p->dl->bundle, OPT_IDCHECK)) {
|
||||
Enabled(bundle, OPT_IDCHECK)) {
|
||||
/* Wrong conversation dude ! */
|
||||
log_Printf(LogPHASE, "Chap Input: %s dropped (got id %d, not %d)\n",
|
||||
chapcodes[chap->auth.in.hdr.code], chap->auth.in.hdr.id,
|
||||
chap->auth.id);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
chap->auth.id = chap->auth.in.hdr.id; /* We respond with this id */
|
||||
|
||||
|
@ -582,7 +591,7 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
if (len < 0) {
|
||||
log_Printf(LogERROR, "Chap Input: Truncated challenge !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
*chap->challenge.peer = alen;
|
||||
bp = mbuf_Read(bp, chap->challenge.peer + 1, alen);
|
||||
|
@ -601,12 +610,12 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
if (len < 0) {
|
||||
log_Printf(LogERROR, "Chap Input: Truncated response !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
if ((ans = malloc(alen + 2)) == NULL) {
|
||||
log_Printf(LogERROR, "Chap Input: Out of memory !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
*ans = chap->auth.id;
|
||||
bp = mbuf_Read(bp, ans + 1, alen);
|
||||
|
@ -623,7 +632,7 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
if ((ans = malloc(len + 1)) == NULL) {
|
||||
log_Printf(LogERROR, "Chap Input: Out of memory !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
bp = mbuf_Read(bp, ans, len);
|
||||
ans[len] = '\0';
|
||||
|
@ -665,12 +674,12 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
|
||||
switch (chap->auth.in.hdr.code) {
|
||||
case CHAP_CHALLENGE:
|
||||
if (*p->dl->bundle->cfg.auth.key == '!')
|
||||
chap_StartChild(chap, p->dl->bundle->cfg.auth.key + 1,
|
||||
p->dl->bundle->cfg.auth.name);
|
||||
if (*bundle->cfg.auth.key == '!')
|
||||
chap_StartChild(chap, bundle->cfg.auth.key + 1,
|
||||
bundle->cfg.auth.name);
|
||||
else
|
||||
chap_Respond(chap, p->dl->bundle->cfg.auth.name,
|
||||
p->dl->bundle->cfg.auth.key, p->link.lcp.his_authtype
|
||||
chap_Respond(chap, bundle->cfg.auth.name,
|
||||
bundle->cfg.auth.key, p->link.lcp.his_authtype
|
||||
#ifdef HAVE_DES
|
||||
, lanman
|
||||
#endif
|
||||
|
@ -681,17 +690,17 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
name = chap->auth.in.name;
|
||||
nlen = strlen(name);
|
||||
#ifndef NORADIUS
|
||||
if (*p->dl->bundle->radius.cfg.file) {
|
||||
if (*bundle->radius.cfg.file) {
|
||||
end = chap->challenge.local[*chap->challenge.local+1];
|
||||
chap->challenge.local[*chap->challenge.local+1] = '\0';
|
||||
radius_Authenticate(&p->dl->bundle->radius, &chap->auth,
|
||||
radius_Authenticate(&bundle->radius, &chap->auth,
|
||||
chap->auth.in.name, ans,
|
||||
chap->challenge.local + 1);
|
||||
chap->challenge.local[*chap->challenge.local+1] = end;
|
||||
} else
|
||||
#endif
|
||||
{
|
||||
key = auth_GetSecret(p->dl->bundle, name, nlen, p);
|
||||
key = auth_GetSecret(bundle, name, nlen, p);
|
||||
if (key) {
|
||||
char *myans;
|
||||
#ifdef HAVE_DES
|
||||
|
@ -760,4 +769,5 @@ chap_Input(struct physical *p, struct mbuf *bp)
|
|||
}
|
||||
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: chap.h,v 1.14 1999/02/18 19:45:06 brian Exp $
|
||||
* $Id: chap.h,v 1.15 1999/04/21 08:03:51 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -55,4 +55,4 @@ struct chap {
|
|||
|
||||
extern void chap_Init(struct chap *, struct physical *);
|
||||
extern void chap_ReInit(struct chap *);
|
||||
extern void chap_Input(struct physical *, struct mbuf *);
|
||||
extern struct mbuf *chap_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: chat.c,v 1.53 1999/01/28 01:56:31 brian Exp $
|
||||
* $Id: chat.c,v 1.54 1999/02/12 00:52:29 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -42,6 +42,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
@ -73,7 +74,6 @@
|
|||
#include "bundle.h"
|
||||
|
||||
#define BUFLEFT(c) (sizeof (c)->buf - ((c)->bufend - (c)->buf))
|
||||
#define issep(c) ((c) == '\t' || (c) == ' ')
|
||||
|
||||
static void ExecStr(struct physical *, char *, char *, int);
|
||||
static char *ExpandString(struct chat *, const char *, char *, int, int);
|
||||
|
@ -301,9 +301,9 @@ chat_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e, int *n)
|
|||
*/
|
||||
|
||||
if (c->state == CHAT_EXPECT)
|
||||
return physical_UpdateSet(&c->physical->desc, r, NULL, e, n, 1);
|
||||
return physical_doUpdateSet(&c->physical->desc, r, NULL, e, n, 1);
|
||||
else
|
||||
return physical_UpdateSet(&c->physical->desc, NULL, w, e, n, 1);
|
||||
return physical_doUpdateSet(&c->physical->desc, NULL, w, e, n, 1);
|
||||
}
|
||||
|
||||
static int
|
||||
|
@ -566,61 +566,6 @@ chat_Destroy(struct chat *c)
|
|||
c->abort.num = 0;
|
||||
}
|
||||
|
||||
static char *
|
||||
findblank(char *p, int instring)
|
||||
{
|
||||
if (instring) {
|
||||
while (*p) {
|
||||
if (*p == '\\') {
|
||||
strcpy(p, p + 1);
|
||||
if (!*p)
|
||||
break;
|
||||
} else if (*p == '"')
|
||||
return (p);
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
while (*p) {
|
||||
if (issep(*p))
|
||||
return (p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
MakeArgs(char *script, char **pvect, int maxargs)
|
||||
{
|
||||
int nargs, nb;
|
||||
int instring;
|
||||
|
||||
nargs = 0;
|
||||
while (*script) {
|
||||
nb = strspn(script, " \t");
|
||||
script += nb;
|
||||
if (*script) {
|
||||
if (*script == '"') {
|
||||
instring = 1;
|
||||
script++;
|
||||
if (*script == '\0')
|
||||
break; /* Shouldn't return here. Need to null
|
||||
* terminate below */
|
||||
} else
|
||||
instring = 0;
|
||||
if (nargs >= maxargs - 1)
|
||||
break;
|
||||
*pvect++ = script;
|
||||
nargs++;
|
||||
script = findblank(script, instring);
|
||||
if (*script)
|
||||
*script++ = '\0';
|
||||
}
|
||||
}
|
||||
*pvect = NULL;
|
||||
return nargs;
|
||||
}
|
||||
|
||||
/*
|
||||
* \c don't add a cr
|
||||
* \d Sleep a little (delay 2 seconds
|
||||
|
@ -743,7 +688,7 @@ ExecStr(struct physical *physical, char *command, char *out, int olen)
|
|||
close(fids[0]);
|
||||
timer_TermService();
|
||||
fids[1] = fcntl(fids[1], F_DUPFD, 4);
|
||||
dup2(physical_GetFD(physical), STDIN_FILENO);
|
||||
dup2(physical->fd, STDIN_FILENO);
|
||||
dup2(STDIN_FILENO, STDOUT_FILENO);
|
||||
dup2(fids[1], STDERR_FILENO);
|
||||
close(3);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* 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 $
|
||||
* $Id: chat.h,v 1.10 1998/05/21 21:44:39 brian Exp $
|
||||
*/
|
||||
|
||||
#define CHAT_EXPECT 0
|
||||
|
@ -79,4 +79,3 @@ struct chat {
|
|||
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 ! */
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: command.c,v 1.190 1999/03/25 23:36:23 brian Exp $
|
||||
* $Id: command.c,v 1.191 1999/04/26 08:54:33 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
|
@ -48,6 +48,7 @@
|
|||
#include "alias.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
@ -61,7 +62,6 @@
|
|||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "ipcp.h"
|
||||
#include "modem.h"
|
||||
#ifndef NOALIAS
|
||||
#include "alias_cmd.h"
|
||||
#endif
|
||||
|
@ -120,6 +120,8 @@
|
|||
#define VAR_RECVPIPE 28
|
||||
#define VAR_RADIUS 29
|
||||
#define VAR_CD 30
|
||||
#define VAR_PARITY 31
|
||||
#define VAR_CRTSCTS 32
|
||||
|
||||
/* ``accept|deny|disable|enable'' masks */
|
||||
#define NEG_HISMASK (1)
|
||||
|
@ -140,8 +142,8 @@
|
|||
#define NEG_VJCOMP 51
|
||||
#define NEG_DNS 52
|
||||
|
||||
const char Version[] = "2.11";
|
||||
const char VersionDate[] = "$Date: 1999/03/25 23:36:23 $";
|
||||
const char Version[] = "2.2";
|
||||
const char VersionDate[] = "$Date: 1999/04/26 08:54:33 $";
|
||||
|
||||
static int ShowCommand(struct cmdargs const *);
|
||||
static int TerminalCommand(struct cmdargs const *);
|
||||
|
@ -622,7 +624,8 @@ static struct cmdtab const Commands[] = {
|
|||
{"bg", "!bg", BgShellCommand, LOCAL_AUTH,
|
||||
"Run a background command", "[!]bg command"},
|
||||
{"clear", NULL, ClearCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"Clear throughput statistics", "clear ipcp|modem [current|overall|peak]..."},
|
||||
"Clear throughput statistics",
|
||||
"clear ipcp|physical [current|overall|peak]..."},
|
||||
{"clone", NULL, CloneCommand, LOCAL_AUTH | LOCAL_CX,
|
||||
"Clone a link", "clone newname..."},
|
||||
{"close", NULL, CloseCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
|
@ -638,7 +641,7 @@ static struct cmdtab const Commands[] = {
|
|||
{"disable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"Disable option", "disable option .."},
|
||||
{"down", NULL, DownCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"Generate a down event", "down"},
|
||||
"Generate a down event", "down [ccp|lcp]"},
|
||||
{"enable", NULL, NegotiateCommand, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"Enable option", "enable option .."},
|
||||
{"iface", "interface", RunListCommand, LOCAL_AUTH,
|
||||
|
@ -764,8 +767,8 @@ static struct cmdtab const ShowCommands[] = {
|
|||
"log levels", "show log"},
|
||||
{"mem", NULL, mbuf_Show, LOCAL_AUTH,
|
||||
"mbuf allocations", "show mem"},
|
||||
{"modem", NULL, modem_ShowStatus, LOCAL_AUTH | LOCAL_CX,
|
||||
"(low-level) link info", "show modem"},
|
||||
{"physical", NULL, physical_ShowStatus, LOCAL_AUTH | LOCAL_CX,
|
||||
"(low-level) link info", "show physical"},
|
||||
{"mp", "multilink", mp_ShowStatus, LOCAL_AUTH,
|
||||
"multilink setup", "show mp"},
|
||||
{"proto", NULL, ShowProtocolStats, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
|
@ -1249,13 +1252,6 @@ SetServer(struct cmdargs const *arg)
|
|||
return res;
|
||||
}
|
||||
|
||||
static int
|
||||
SetModemParity(struct cmdargs const *arg)
|
||||
{
|
||||
return arg->argc > arg->argn ? modem_SetParity(arg->cx->physical,
|
||||
arg->argv[arg->argn]) : -1;
|
||||
}
|
||||
|
||||
static int
|
||||
SetEscape(struct cmdargs const *arg)
|
||||
{
|
||||
|
@ -1738,26 +1734,31 @@ SetVariable(struct cmdargs const *arg)
|
|||
cx->physical->cfg.cd.required = 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_PARITY:
|
||||
if (arg->argc == arg->argn + 1)
|
||||
return physical_SetParity(arg->cx->physical, argp);
|
||||
else {
|
||||
err = "Parity value must be odd, even or none\n";
|
||||
log_Printf(LogWARN, err);
|
||||
}
|
||||
break;
|
||||
|
||||
case VAR_CRTSCTS:
|
||||
if (strcasecmp(argp, "on") == 0)
|
||||
physical_SetRtsCts(arg->cx->physical, 1);
|
||||
else if (strcasecmp(argp, "off") == 0)
|
||||
physical_SetRtsCts(arg->cx->physical, 0);
|
||||
else {
|
||||
err = "RTS/CTS value must be on or off\n";
|
||||
log_Printf(LogWARN, err);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return err ? 1 : 0;
|
||||
}
|
||||
|
||||
static int
|
||||
SetCtsRts(struct cmdargs const *arg)
|
||||
{
|
||||
if (arg->argc == arg->argn+1) {
|
||||
if (strcmp(arg->argv[arg->argn], "on") == 0)
|
||||
physical_SetRtsCts(arg->cx->physical, 1);
|
||||
else if (strcmp(arg->argv[arg->argn], "off") == 0)
|
||||
physical_SetRtsCts(arg->cx->physical, 0);
|
||||
else
|
||||
return -1;
|
||||
return 0;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static struct cmdtab const SetCommands[] = {
|
||||
{"accmap", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"accmap value", "set accmap hex-value", (const void *)VAR_ACCMAP},
|
||||
|
@ -1783,13 +1784,14 @@ static struct cmdtab const SetCommands[] = {
|
|||
(const void *)VAR_CHAPRETRY},
|
||||
{"choked", NULL, SetVariable, LOCAL_AUTH,
|
||||
"choked timeout", "set choked [secs]", (const void *)VAR_CHOKED},
|
||||
{"ctsrts", "crtscts", SetCtsRts, LOCAL_AUTH | LOCAL_CX,
|
||||
"Use hardware flow control", "set ctsrts [on|off]"},
|
||||
{"ctsrts", "crtscts", SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"Use hardware flow control", "set ctsrts [on|off]",
|
||||
(const char *)VAR_CRTSCTS},
|
||||
{"deflate", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX_OPT,
|
||||
"deflate window sizes", "set deflate out-winsize in-winsize",
|
||||
(const void *) VAR_WINSIZE},
|
||||
{"device", "line", SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"modem device name", "set device|line device-name[,device-name]",
|
||||
"physical device name", "set device|line device-name[,device-name]",
|
||||
(const void *) VAR_DEVICE},
|
||||
{"dial", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX,
|
||||
"dialing script", "set dial chat-script", (const void *) VAR_DIAL},
|
||||
|
@ -1832,8 +1834,8 @@ static struct cmdtab const SetCommands[] = {
|
|||
"set openmode active|passive [secs]", (const void *)VAR_OPENMODE},
|
||||
{"papretry", "papretries", SetVariable, LOCAL_AUTH | LOCAL_CX, "PAP retries",
|
||||
"set papretry value [attempts]", (const void *)VAR_PAPRETRY},
|
||||
{"parity", NULL, SetModemParity, LOCAL_AUTH | LOCAL_CX,
|
||||
"modem parity", "set parity [odd|even|none]"},
|
||||
{"parity", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "serial parity",
|
||||
"set parity [odd|even|none]", (const void *)VAR_PARITY},
|
||||
{"phone", NULL, SetVariable, LOCAL_AUTH | LOCAL_CX, "telephone number(s)",
|
||||
"set phone phone1[:phone2[...]]", (const void *)VAR_PHONE},
|
||||
{"proctitle", "title", SetProcTitle, LOCAL_AUTH,
|
||||
|
@ -1853,7 +1855,7 @@ static struct cmdtab const SetCommands[] = {
|
|||
{"server", "socket", SetServer, LOCAL_AUTH,
|
||||
"server port", "set server|socket TcpPort|LocalName|none password [mask]"},
|
||||
{"speed", NULL, SetModemSpeed, LOCAL_AUTH | LOCAL_CX,
|
||||
"modem speed", "set speed value"},
|
||||
"physical speed", "set speed value|sync"},
|
||||
{"stopped", NULL, SetStoppedTimeout, LOCAL_AUTH | LOCAL_CX,
|
||||
"STOPPED timeouts", "set stopped [LCPseconds [CCPseconds]]"},
|
||||
{"timeout", NULL, SetVariable, LOCAL_AUTH, "Idle timeout",
|
||||
|
@ -1977,7 +1979,11 @@ AliasEnable(struct cmdargs const *arg)
|
|||
{
|
||||
if (arg->argc == arg->argn+1) {
|
||||
if (strcasecmp(arg->argv[arg->argn], "yes") == 0) {
|
||||
arg->bundle->AliasEnabled = 1;
|
||||
if (!arg->bundle->AliasEnabled) {
|
||||
if (arg->bundle->ncp.ipcp.fsm.state == ST_OPENED)
|
||||
PacketAliasSetAddress(arg->bundle->ncp.ipcp.my_ip);
|
||||
arg->bundle->AliasEnabled = 1;
|
||||
}
|
||||
return 0;
|
||||
} else if (strcasecmp(arg->argv[arg->argn], "no") == 0) {
|
||||
arg->bundle->AliasEnabled = 0;
|
||||
|
@ -2373,12 +2379,12 @@ ClearCommand(struct cmdargs const *arg)
|
|||
if (arg->argc < arg->argn + 1)
|
||||
return -1;
|
||||
|
||||
if (strcasecmp(arg->argv[arg->argn], "modem") == 0) {
|
||||
if (strcasecmp(arg->argv[arg->argn], "physical") == 0) {
|
||||
cx = arg->cx;
|
||||
if (!cx)
|
||||
cx = bundle2datalink(arg->bundle, NULL);
|
||||
if (!cx) {
|
||||
log_Printf(LogWARN, "A link must be specified for ``clear modem''\n");
|
||||
log_Printf(LogWARN, "A link must be specified for ``clear physical''\n");
|
||||
return 1;
|
||||
}
|
||||
t = &cx->physical->link.throughput;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: datalink.c,v 1.36 1999/04/05 21:52:10 brian Exp $
|
||||
* $Id: datalink.c,v 1.37 1999/04/06 14:48:10 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -39,6 +39,7 @@
|
|||
#include <sys/uio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
@ -64,9 +65,8 @@
|
|||
#include "bundle.h"
|
||||
#include "chat.h"
|
||||
#include "auth.h"
|
||||
#include "modem.h"
|
||||
#include "prompt.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "pap.h"
|
||||
#include "chap.h"
|
||||
#include "command.h"
|
||||
|
@ -114,13 +114,13 @@ static void
|
|||
datalink_HangupDone(struct datalink *dl)
|
||||
{
|
||||
if (dl->physical->type == PHYS_DEDICATED && !dl->bundle->CleaningUp &&
|
||||
physical_GetFD(dl->physical) != -1) {
|
||||
/* Don't close our modem if the link is dedicated */
|
||||
dl->physical->fd != -1) {
|
||||
/* Don't close our device if the link is dedicated */
|
||||
datalink_LoginDone(dl);
|
||||
return;
|
||||
}
|
||||
|
||||
modem_Close(dl->physical);
|
||||
physical_Close(dl->physical);
|
||||
dl->phone.chosen = "N/A";
|
||||
|
||||
if (dl->cbcp.required) {
|
||||
|
@ -202,18 +202,18 @@ datalink_LoginDone(struct datalink *dl)
|
|||
dl->dial.tries = -1;
|
||||
dl->dial.incs = 0;
|
||||
datalink_NewState(dl, DATALINK_READY);
|
||||
} else if (modem_Raw(dl->physical, dl->bundle) < 0) {
|
||||
} else if (!physical_Raw(dl->physical)) {
|
||||
dl->dial.tries = 0;
|
||||
log_Printf(LogWARN, "datalink_LoginDone: Not connected.\n");
|
||||
if (dl->script.run) {
|
||||
datalink_NewState(dl, DATALINK_HANGUP);
|
||||
modem_Offline(dl->physical);
|
||||
physical_Offline(dl->physical);
|
||||
chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL);
|
||||
} else {
|
||||
timer_Stop(&dl->physical->Timer);
|
||||
if (dl->physical->type == PHYS_DEDICATED)
|
||||
/* force a redial timeout */
|
||||
modem_Close(dl->physical);
|
||||
physical_Close(dl->physical);
|
||||
datalink_HangupDone(dl);
|
||||
}
|
||||
} else {
|
||||
|
@ -260,7 +260,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
|||
if (dl->dial.timer.state != TIMER_RUNNING) {
|
||||
if (--dl->dial.tries < 0)
|
||||
dl->dial.tries = 0;
|
||||
if (modem_Open(dl->physical, dl->bundle) >= 0) {
|
||||
if (physical_Open(dl->physical, dl->bundle) >= 0) {
|
||||
log_WritePrompts(dl, "%s: Entering terminal mode on %s\r\n"
|
||||
"Type `~?' for help\r\n", dl->name,
|
||||
dl->physical->name.full);
|
||||
|
@ -279,10 +279,10 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
|||
} else {
|
||||
if (!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) &&
|
||||
dl->cfg.dial.max)
|
||||
log_Printf(LogCHAT, "Failed to open modem (attempt %u of %d)\n",
|
||||
log_Printf(LogCHAT, "Failed to open device (attempt %u of %d)\n",
|
||||
dl->cfg.dial.max - dl->dial.tries, dl->cfg.dial.max);
|
||||
else
|
||||
log_Printf(LogCHAT, "Failed to open modem\n");
|
||||
log_Printf(LogCHAT, "Failed to open device\n");
|
||||
|
||||
if (dl->bundle->CleaningUp ||
|
||||
(!(dl->physical->type & (PHYS_DDIAL|PHYS_DEDICATED)) &&
|
||||
|
@ -338,7 +338,7 @@ datalink_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
|||
case DATALINK_DIAL:
|
||||
case DATALINK_LOGIN:
|
||||
datalink_NewState(dl, DATALINK_HANGUP);
|
||||
modem_Offline(dl->physical); /* Is this required ? */
|
||||
physical_Offline(dl->physical); /* Is this required ? */
|
||||
chat_Init(&dl->chat, dl->physical, dl->cfg.script.hangup, 1, NULL);
|
||||
return datalink_UpdateSet(d, r, w, e, n);
|
||||
}
|
||||
|
@ -466,7 +466,7 @@ datalink_ComeDown(struct datalink *dl, int how)
|
|||
timer_Stop(&dl->physical->Timer);
|
||||
datalink_NewState(dl, DATALINK_READY);
|
||||
} else if (dl->state != DATALINK_CLOSED && dl->state != DATALINK_HANGUP) {
|
||||
modem_Offline(dl->physical);
|
||||
physical_Offline(dl->physical);
|
||||
chat_Destroy(&dl->chat);
|
||||
if (dl->script.run && dl->state != DATALINK_OPENING) {
|
||||
datalink_NewState(dl, DATALINK_HANGUP);
|
||||
|
@ -764,7 +764,7 @@ datalink_Create(const char *name, struct bundle *bundle, int type)
|
|||
dl->fsmp.LayerFinish = datalink_LayerFinish;
|
||||
dl->fsmp.object = dl;
|
||||
|
||||
if ((dl->physical = modem_Create(dl, type)) == NULL) {
|
||||
if ((dl->physical = physical_Create(dl, type)) == NULL) {
|
||||
free(dl->name);
|
||||
free(dl);
|
||||
return NULL;
|
||||
|
@ -815,7 +815,7 @@ datalink_Clone(struct datalink *odl, const char *name)
|
|||
memcpy(&dl->fsmp, &odl->fsmp, sizeof dl->fsmp);
|
||||
dl->fsmp.object = dl;
|
||||
|
||||
if ((dl->physical = modem_Create(dl, PHYS_INTERACTIVE)) == NULL) {
|
||||
if ((dl->physical = physical_Create(dl, PHYS_INTERACTIVE)) == NULL) {
|
||||
free(dl->name);
|
||||
free(dl);
|
||||
return NULL;
|
||||
|
@ -862,7 +862,7 @@ datalink_Destroy(struct datalink *dl)
|
|||
|
||||
timer_Stop(&dl->dial.timer);
|
||||
result = dl->next;
|
||||
modem_Destroy(dl->physical);
|
||||
physical_Destroy(dl->physical);
|
||||
free(dl->name);
|
||||
free(dl);
|
||||
|
||||
|
@ -1251,7 +1251,7 @@ iov2datalink(struct bundle *bundle, struct iovec *iov, int *niov, int maxiov,
|
|||
dl->fsmp.LayerFinish = datalink_LayerFinish;
|
||||
dl->fsmp.object = dl;
|
||||
|
||||
dl->physical = iov2modem(dl, iov, niov, maxiov, fd);
|
||||
dl->physical = iov2physical(dl, iov, niov, maxiov, fd);
|
||||
|
||||
if (!dl->physical) {
|
||||
free(dl->name);
|
||||
|
@ -1306,7 +1306,7 @@ datalink2iov(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
|
|||
dl ? realloc(dl->name, DATALINK_MAXNAME) : malloc(DATALINK_MAXNAME);
|
||||
iov[(*niov)++].iov_len = DATALINK_MAXNAME;
|
||||
|
||||
link_fd = modem2iov(dl ? dl->physical : NULL, iov, niov, maxiov, newpid);
|
||||
link_fd = physical2iov(dl ? dl->physical : NULL, iov, niov, maxiov, newpid);
|
||||
|
||||
if (link_fd == -1 && dl) {
|
||||
free(dl->name);
|
||||
|
|
|
@ -23,13 +23,14 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: deflate.c,v 1.11 1998/08/07 18:42:48 brian Exp $
|
||||
* $Id: deflate.c,v 1.12 1999/03/11 01:49:15 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <termios.h>
|
||||
#include <zlib.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
@ -54,7 +55,7 @@ struct deflate_state {
|
|||
static char garbage[10];
|
||||
static u_char EMPTY_BLOCK[4] = { 0x00, 0x00, 0xff, 0xff };
|
||||
|
||||
#define DEFLATE_CHUNK_LEN 1024 /* Allocate mbufs this size */
|
||||
#define DEFLATE_CHUNK_LEN 1600 /* Allocate mbufs this size */
|
||||
|
||||
static void
|
||||
DeflateResetOutput(void *v)
|
||||
|
@ -67,8 +68,8 @@ DeflateResetOutput(void *v)
|
|||
log_Printf(LogCCP, "Deflate: Output channel reset\n");
|
||||
}
|
||||
|
||||
static int
|
||||
DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
static struct mbuf *
|
||||
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;
|
||||
|
@ -77,19 +78,19 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
struct mbuf *mo_head, *mo, *mi_head, *mi;
|
||||
|
||||
ilen = mbuf_Length(mp);
|
||||
log_Printf(LogDEBUG, "DeflateOutput: Proto %02x (%d bytes)\n", proto, ilen);
|
||||
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 = mbuf_Alloc(2, MB_HDLCOUT);
|
||||
mi->next = mp;
|
||||
rp = MBUF_CTOP(mi);
|
||||
if (proto < 0x100) { /* Compress the protocol */
|
||||
rp[0] = proto & 0377;
|
||||
if (*proto < 0x100) { /* Compress the protocol */
|
||||
rp[0] = *proto & 0377;
|
||||
mi->cnt = 1;
|
||||
} else { /* Don't compress the protocol */
|
||||
rp[0] = proto >> 8;
|
||||
rp[1] = proto & 0377;
|
||||
rp[0] = *proto >> 8;
|
||||
rp[1] = *proto & 0377;
|
||||
mi->cnt = 2;
|
||||
}
|
||||
|
||||
|
@ -119,7 +120,7 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
mbuf_Free(mo_head);
|
||||
mbuf_FreeSeg(mi_head);
|
||||
state->seqno--;
|
||||
return 1; /* packet dropped */
|
||||
return mp; /* Our dictionary's probably dead now :-( */
|
||||
}
|
||||
|
||||
if (flush == Z_SYNC_FLUSH && state->cx.avail_out != 0)
|
||||
|
@ -154,10 +155,10 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
mbuf_Free(mo_head);
|
||||
mbuf_FreeSeg(mi_head);
|
||||
log_Printf(LogDEBUG, "DeflateOutput: %d => %d: Uncompressible (0x%04x)\n",
|
||||
ilen, olen, proto);
|
||||
ilen, olen, *proto);
|
||||
ccp->uncompout += ilen;
|
||||
ccp->compout += ilen; /* We measure this stuff too */
|
||||
return 0;
|
||||
return mp;
|
||||
}
|
||||
|
||||
mbuf_Free(mi_head);
|
||||
|
@ -179,10 +180,10 @@ DeflateOutput(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
ccp->compout += olen;
|
||||
|
||||
log_Printf(LogDEBUG, "DeflateOutput: %d => %d bytes, proto 0x%04x\n",
|
||||
ilen, olen, proto);
|
||||
ilen, olen, *proto);
|
||||
|
||||
hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mo_head);
|
||||
return 1;
|
||||
*proto = ccp_Proto(ccp);
|
||||
return mo_head;
|
||||
}
|
||||
|
||||
static void
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: defs.c,v 1.18 1999/02/25 20:05:55 brian Exp $
|
||||
* $Id: defs.c,v 1.19 1999/04/26 08:54:24 brian Exp $
|
||||
*/
|
||||
|
||||
|
||||
|
@ -37,6 +37,7 @@
|
|||
#include <errno.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#if !defined(__FreeBSD__) || __FreeBSD__ < 3
|
||||
#include <time.h>
|
||||
#endif
|
||||
|
@ -44,6 +45,8 @@
|
|||
|
||||
#include "defs.h"
|
||||
|
||||
#define issep(c) ((c) == '\t' || (c) == ' ')
|
||||
|
||||
void
|
||||
randinit()
|
||||
{
|
||||
|
@ -151,3 +154,166 @@ GetIpAddr(const char *cp)
|
|||
|
||||
return ipaddr;
|
||||
}
|
||||
|
||||
static const struct speeds {
|
||||
int nspeed;
|
||||
speed_t speed;
|
||||
} speeds[] = {
|
||||
#ifdef B50
|
||||
{ 50, B50, },
|
||||
#endif
|
||||
#ifdef B75
|
||||
{ 75, B75, },
|
||||
#endif
|
||||
#ifdef B110
|
||||
{ 110, B110, },
|
||||
#endif
|
||||
#ifdef B134
|
||||
{ 134, B134, },
|
||||
#endif
|
||||
#ifdef B150
|
||||
{ 150, B150, },
|
||||
#endif
|
||||
#ifdef B200
|
||||
{ 200, B200, },
|
||||
#endif
|
||||
#ifdef B300
|
||||
{ 300, B300, },
|
||||
#endif
|
||||
#ifdef B600
|
||||
{ 600, B600, },
|
||||
#endif
|
||||
#ifdef B1200
|
||||
{ 1200, B1200, },
|
||||
#endif
|
||||
#ifdef B1800
|
||||
{ 1800, B1800, },
|
||||
#endif
|
||||
#ifdef B2400
|
||||
{ 2400, B2400, },
|
||||
#endif
|
||||
#ifdef B4800
|
||||
{ 4800, B4800, },
|
||||
#endif
|
||||
#ifdef B9600
|
||||
{ 9600, B9600, },
|
||||
#endif
|
||||
#ifdef B19200
|
||||
{ 19200, B19200, },
|
||||
#endif
|
||||
#ifdef B38400
|
||||
{ 38400, B38400, },
|
||||
#endif
|
||||
#ifndef _POSIX_SOURCE
|
||||
#ifdef B7200
|
||||
{ 7200, B7200, },
|
||||
#endif
|
||||
#ifdef B14400
|
||||
{ 14400, B14400, },
|
||||
#endif
|
||||
#ifdef B28800
|
||||
{ 28800, B28800, },
|
||||
#endif
|
||||
#ifdef B57600
|
||||
{ 57600, B57600, },
|
||||
#endif
|
||||
#ifdef B76800
|
||||
{ 76800, B76800, },
|
||||
#endif
|
||||
#ifdef B115200
|
||||
{ 115200, B115200, },
|
||||
#endif
|
||||
#ifdef B230400
|
||||
{ 230400, B230400, },
|
||||
#endif
|
||||
#ifdef EXTA
|
||||
{ 19200, EXTA, },
|
||||
#endif
|
||||
#ifdef EXTB
|
||||
{ 38400, EXTB, },
|
||||
#endif
|
||||
#endif /* _POSIX_SOURCE */
|
||||
{ 0, 0 }
|
||||
};
|
||||
|
||||
int
|
||||
SpeedToInt(speed_t speed)
|
||||
{
|
||||
const struct speeds *sp;
|
||||
|
||||
for (sp = speeds; sp->nspeed; sp++) {
|
||||
if (sp->speed == speed) {
|
||||
return sp->nspeed;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
speed_t
|
||||
IntToSpeed(int nspeed)
|
||||
{
|
||||
const struct speeds *sp;
|
||||
|
||||
for (sp = speeds; sp->nspeed; sp++) {
|
||||
if (sp->nspeed == nspeed) {
|
||||
return sp->speed;
|
||||
}
|
||||
}
|
||||
return B0;
|
||||
}
|
||||
|
||||
static char *
|
||||
findblank(char *p, int instring)
|
||||
{
|
||||
if (instring) {
|
||||
while (*p) {
|
||||
if (*p == '\\') {
|
||||
memmove(p, p + 1, strlen(p + 1));
|
||||
if (!*p)
|
||||
break;
|
||||
} else if (*p == '"')
|
||||
return (p);
|
||||
p++;
|
||||
}
|
||||
} else {
|
||||
while (*p) {
|
||||
if (issep(*p))
|
||||
return (p);
|
||||
p++;
|
||||
}
|
||||
}
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
MakeArgs(char *script, char **pvect, int maxargs)
|
||||
{
|
||||
int nargs, nb;
|
||||
int instring;
|
||||
|
||||
nargs = 0;
|
||||
while (*script) {
|
||||
nb = strspn(script, " \t");
|
||||
script += nb;
|
||||
if (*script) {
|
||||
if (*script == '"') {
|
||||
instring = 1;
|
||||
script++;
|
||||
if (*script == '\0')
|
||||
break; /* Shouldn't return here. Need to null
|
||||
* terminate below */
|
||||
} else
|
||||
instring = 0;
|
||||
if (nargs >= maxargs - 1)
|
||||
break;
|
||||
*pvect++ = script;
|
||||
nargs++;
|
||||
script = findblank(script, instring);
|
||||
if (*script)
|
||||
*script++ = '\0';
|
||||
}
|
||||
}
|
||||
*pvect = NULL;
|
||||
return nargs;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: defs.h,v 1.41 1999/02/26 21:28:10 brian Exp $
|
||||
* $Id: defs.h,v 1.42 1999/04/27 00:23:54 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -96,3 +96,6 @@ extern ssize_t fullread(int, void *, size_t);
|
|||
extern const char *mode2Nam(int);
|
||||
extern int Nam2mode(const char *);
|
||||
extern struct in_addr GetIpAddr(const char *);
|
||||
extern int SpeedToInt(speed_t);
|
||||
extern speed_t IntToSpeed(int);
|
||||
extern int MakeArgs(char *, char **, int);
|
||||
|
|
|
@ -0,0 +1,160 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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 <sys/socket.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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "sync.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "async.h"
|
||||
#include "slcompress.h"
|
||||
#include "iplist.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#ifndef NORADIUS
|
||||
#include "radius.h"
|
||||
#endif
|
||||
#include "chat.h"
|
||||
#include "command.h"
|
||||
#include "bundle.h"
|
||||
#include "prompt.h"
|
||||
#include "auth.h"
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "exec.h"
|
||||
|
||||
static int
|
||||
exec_Open(struct physical *p)
|
||||
{
|
||||
if (*p->name.full == '!') {
|
||||
int fids[2];
|
||||
|
||||
if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fids) < 0)
|
||||
log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
|
||||
strerror(errno));
|
||||
else {
|
||||
int stat, argc;
|
||||
pid_t pid;
|
||||
char *argv[MAXARGS];
|
||||
|
||||
stat = fcntl(fids[0], F_GETFL, 0);
|
||||
if (stat > 0) {
|
||||
stat |= O_NONBLOCK;
|
||||
fcntl(fids[0], F_SETFL, stat);
|
||||
}
|
||||
switch ((pid = fork())) {
|
||||
case -1:
|
||||
log_Printf(LogPHASE, "Unable to create pipe for line exec: %s\n",
|
||||
strerror(errno));
|
||||
break;
|
||||
|
||||
case 0:
|
||||
close(fids[0]);
|
||||
timer_TermService();
|
||||
setuid(geteuid());
|
||||
|
||||
switch (fork()) {
|
||||
case 0:
|
||||
break;
|
||||
|
||||
case -1:
|
||||
log_Printf(LogPHASE, "Unable to fork to drop parent: %s\n",
|
||||
strerror(errno));
|
||||
default:
|
||||
_exit(127);
|
||||
}
|
||||
|
||||
fids[1] = fcntl(fids[1], F_DUPFD, 3);
|
||||
dup2(fids[1], STDIN_FILENO);
|
||||
dup2(fids[1], STDOUT_FILENO);
|
||||
dup2(fids[1], STDERR_FILENO);
|
||||
|
||||
argc = MakeArgs(p->name.base, argv, VECSIZE(argv));
|
||||
command_Expand(argv, argc, (char const *const *)argv,
|
||||
p->dl->bundle, 0);
|
||||
execvp(*argv, argv);
|
||||
fprintf(stderr, "execvp failed: %s: %s\r\n", *argv, strerror(errno));
|
||||
_exit(127);
|
||||
break;
|
||||
|
||||
default:
|
||||
close(fids[1]);
|
||||
p->fd = fids[0];
|
||||
waitpid(pid, &stat, 0);
|
||||
log_Printf(LogDEBUG, "Using descriptor %d for child\n", p->fd);
|
||||
physical_SetupStack(p, 1);
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct device execdevice = {
|
||||
EXEC_DEVICE,
|
||||
"exec",
|
||||
exec_Open,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
extern const struct device execdevice;
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: filter.c,v 1.26 1998/10/22 02:32:48 brian Exp $
|
||||
* $Id: filter.c,v 1.27 1999/01/28 01:56:31 brian Exp $
|
||||
*
|
||||
* TODO: Shoud send ICMP error message when we discard packets.
|
||||
*/
|
||||
|
@ -35,6 +35,7 @@
|
|||
#include <strings.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: fsm.c,v 1.40 1999/03/01 02:52:39 brian Exp $
|
||||
* $Id: fsm.c,v 1.41 1999/03/29 08:21:26 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -31,6 +31,7 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "ua.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
|
@ -55,7 +56,7 @@
|
|||
#include "bundle.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
|
||||
static void FsmSendConfigReq(struct fsm *);
|
||||
static void FsmSendTerminateReq(struct fsm *);
|
||||
|
@ -87,7 +88,7 @@ static const struct fsmcodedesc {
|
|||
{ FsmRecvDiscReq, 0, 0, "DiscardReq" },
|
||||
{ FsmRecvIdent, 0, 0, "Ident" },
|
||||
{ FsmRecvTimeRemain,0, 0, "TimeRemain" },
|
||||
{ FsmRecvResetReq, 0, 0, "ResetReqt" },
|
||||
{ FsmRecvResetReq, 0, 0, "ResetReq" },
|
||||
{ FsmRecvResetAck, 0, 1, "ResetAck" }
|
||||
};
|
||||
|
||||
|
@ -140,7 +141,7 @@ fsm_Init(struct fsm *fp, const char *name, u_short proto, int mincode,
|
|||
fp->state = fp->min_code > CODE_TERMACK ? ST_OPENED : ST_INITIAL;
|
||||
fp->reqid = 1;
|
||||
fp->restart = 1;
|
||||
fp->more.reqs = fp->more.naks = fp->more.rejs = 1;
|
||||
fp->more.reqs = fp->more.naks = fp->more.rejs = 3;
|
||||
memset(&fp->FsmTimer, '\0', sizeof fp->FsmTimer);
|
||||
memset(&fp->OpenTimer, '\0', sizeof fp->OpenTimer);
|
||||
memset(&fp->StoppedTimer, '\0', sizeof fp->StoppedTimer);
|
||||
|
@ -204,7 +205,7 @@ fsm_Output(struct fsm *fp, u_int code, u_int id, u_char *ptr, int count)
|
|||
if (count)
|
||||
memcpy(MBUF_CTOP(bp) + sizeof(struct fsmheader), ptr, count);
|
||||
log_DumpBp(LogDEBUG, "fsm_Output", bp);
|
||||
hdlc_Output(fp->link, PRI_LINK, fp->proto, bp);
|
||||
link_PushPacket(fp->link, bp, fp->bundle, PRI_LINK, fp->proto);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -468,13 +469,13 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
|
|||
if (fp->proto == PROTO_CCP && fp->link->lcp.fsm.state == ST_OPENED) {
|
||||
/*
|
||||
* ccp_SetOpenMode() leaves us in initial if we're disabling
|
||||
* & denying everything. This is a bit smelly, we know that
|
||||
* ``bp'' really has ``fsmheader'' in front of it, and CCP_PROTO
|
||||
* in front of that. CCP_PROTO isn't compressed either 'cos it
|
||||
* doesn't begin with 0x00....
|
||||
* & denying everything.
|
||||
*
|
||||
* this is a bit smelly... we know that bp has a leading fsmheader.
|
||||
*/
|
||||
bp->offset -= sizeof(struct fsmheader) + 2;
|
||||
bp->cnt += sizeof(struct fsmheader) + 2;
|
||||
bp = mbuf_Prepend(bp, lhp, sizeof *lhp, 2);
|
||||
bp = proto_Prepend(bp, fp->proto, 0, 0);
|
||||
bp = mbuf_Contiguous(bp);
|
||||
lcp_SendProtoRej(&fp->link->lcp, MBUF_CTOP(bp), bp->cnt);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
|
@ -501,6 +502,8 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
|
|||
break;
|
||||
}
|
||||
|
||||
bp = mbuf_Contiguous(bp);
|
||||
|
||||
dec.ackend = dec.ack;
|
||||
dec.nakend = dec.nak;
|
||||
dec.rejend = dec.rej;
|
||||
|
@ -576,7 +579,6 @@ FsmRecvConfigReq(struct fsm *fp, struct fsmheader *lhp, struct mbuf *bp)
|
|||
}
|
||||
|
||||
if (dec.nakend != dec.nak && --fp->more.naks <= 0) {
|
||||
fsm_Close(fp);
|
||||
log_Printf(LogPHASE, "%s: Too many %s NAKs sent - abandoning negotiation\n",
|
||||
fp->link->name, fp->name);
|
||||
fsm_Close(fp);
|
||||
|
@ -961,7 +963,7 @@ void
|
|||
fsm_Input(struct fsm *fp, struct mbuf *bp)
|
||||
{
|
||||
int len;
|
||||
struct fsmheader *lhp;
|
||||
struct fsmheader lh;
|
||||
const struct fsmcodedesc *codep;
|
||||
|
||||
len = mbuf_Length(bp);
|
||||
|
@ -969,41 +971,41 @@ fsm_Input(struct fsm *fp, struct mbuf *bp)
|
|||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
lhp = (struct fsmheader *) MBUF_CTOP(bp);
|
||||
if (lhp->code < fp->min_code || lhp->code > fp->max_code ||
|
||||
lhp->code > sizeof FsmCodes / sizeof *FsmCodes) {
|
||||
bp = mbuf_Read(bp, &lh, sizeof lh);
|
||||
if (lh.code < fp->min_code || lh.code > fp->max_code ||
|
||||
lh.code > sizeof FsmCodes / sizeof *FsmCodes) {
|
||||
/*
|
||||
* Use a private id. This is really a response-type packet, but we
|
||||
* MUST send a unique id for each REQ....
|
||||
*/
|
||||
static u_char id;
|
||||
|
||||
bp = mbuf_Prepend(bp, &lh, sizeof lh, 0);
|
||||
bp = mbuf_Contiguous(bp);
|
||||
fsm_Output(fp, CODE_CODEREJ, id++, MBUF_CTOP(bp), bp->cnt);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
bp->offset += sizeof(struct fsmheader);
|
||||
bp->cnt -= sizeof(struct fsmheader);
|
||||
|
||||
codep = FsmCodes + lhp->code - 1;
|
||||
if (lhp->id != fp->reqid && codep->check_reqid &&
|
||||
codep = FsmCodes + lh.code - 1;
|
||||
if (lh.id != fp->reqid && codep->check_reqid &&
|
||||
Enabled(fp->bundle, OPT_IDCHECK)) {
|
||||
log_Printf(fp->LogLevel, "%s: Recv%s(%d), dropped (expected %d)\n",
|
||||
fp->link->name, codep->name, lhp->id, fp->reqid);
|
||||
fp->link->name, codep->name, lh.id, fp->reqid);
|
||||
return;
|
||||
}
|
||||
|
||||
log_Printf(fp->LogLevel, "%s: Recv%s(%d) state = %s\n",
|
||||
fp->link->name, codep->name, lhp->id, State2Nam(fp->state));
|
||||
fp->link->name, codep->name, lh.id, State2Nam(fp->state));
|
||||
|
||||
if (log_IsKept(LogDEBUG))
|
||||
mbuf_Log();
|
||||
|
||||
if (codep->inc_reqid && (lhp->id == fp->reqid ||
|
||||
if (codep->inc_reqid && (lh.id == fp->reqid ||
|
||||
(!Enabled(fp->bundle, OPT_IDCHECK) && codep->check_reqid)))
|
||||
fp->reqid++; /* That's the end of that ``exchange''.... */
|
||||
|
||||
(*codep->recv)(fp, lhp, bp);
|
||||
(*codep->recv)(fp, &lh, bp);
|
||||
|
||||
if (log_IsKept(LogDEBUG))
|
||||
mbuf_Log();
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: hdlc.c,v 1.40 1999/03/29 08:21:26 brian Exp $
|
||||
* $Id: hdlc.c,v 1.41 1999/04/03 11:54:00 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "layer.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
|
@ -39,7 +40,7 @@
|
|||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
#include "slcompress.h"
|
||||
|
@ -112,12 +113,15 @@ hdlc_Init(struct hdlc *hdlc, struct lcp *lcp)
|
|||
* HDLC FCS computation. Read RFC 1171 Appendix B and CCITT X.25 section
|
||||
* 2.27 for further details.
|
||||
*/
|
||||
inline u_short
|
||||
hdlc_Fcs(u_short fcs, u_char * cp, int len)
|
||||
u_short
|
||||
hdlc_Fcs(u_char *cp, size_t len)
|
||||
{
|
||||
u_short fcs = INITFCS;
|
||||
|
||||
while (len--)
|
||||
fcs = (fcs >> 8) ^ fcstab[(fcs ^ *cp++) & 0xff];
|
||||
return (fcs);
|
||||
|
||||
return fcs;
|
||||
}
|
||||
|
||||
static inline u_short
|
||||
|
@ -140,107 +144,41 @@ HdlcFcsBuf(u_short fcs, struct mbuf *m)
|
|||
return (fcs);
|
||||
}
|
||||
|
||||
void
|
||||
hdlc_Output(struct link *l, int pri, u_short proto, struct mbuf *bp)
|
||||
int
|
||||
hdlc_WrapperOctets(struct lcp *lcp, u_short proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct mbuf *mhp, *mfcs;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
hdlc_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
struct mbuf *last;
|
||||
u_char *cp;
|
||||
u_short fcs;
|
||||
|
||||
if (!p || physical_IsSync(p))
|
||||
mfcs = NULL;
|
||||
else
|
||||
mfcs = mbuf_Alloc(2, MB_HDLCOUT);
|
||||
fcs = HdlcFcsBuf(INITFCS, bp);
|
||||
fcs = ~fcs;
|
||||
|
||||
mhp = mbuf_Alloc(4, MB_HDLCOUT);
|
||||
mhp->cnt = 0;
|
||||
cp = MBUF_CTOP(mhp);
|
||||
if (p && (proto == PROTO_LCP || l->lcp.his_acfcomp == 0)) {
|
||||
*cp++ = HDLC_ADDR;
|
||||
*cp++ = HDLC_UI;
|
||||
mhp->cnt += 2;
|
||||
}
|
||||
for (last = bp; last->next; last = last->next)
|
||||
;
|
||||
|
||||
/*
|
||||
* If possible, compress protocol field.
|
||||
*/
|
||||
if (l->lcp.his_protocomp && (proto & 0xff00) == 0) {
|
||||
*cp++ = proto;
|
||||
mhp->cnt++;
|
||||
if (last->size - last->offset - last->cnt >= 2) {
|
||||
cp = MBUF_CTOP(last) + last->cnt;
|
||||
last->cnt += 2;
|
||||
} else {
|
||||
*cp++ = proto >> 8;
|
||||
*cp = proto & 0377;
|
||||
mhp->cnt += 2;
|
||||
struct mbuf *tail = mbuf_Alloc(2, MB_HDLCOUT);
|
||||
last->next = tail;
|
||||
cp = MBUF_CTOP(tail);
|
||||
}
|
||||
|
||||
mhp->next = bp = mbuf_Contiguous(bp);
|
||||
*cp++ = fcs & 0377; /* Low byte first (nothing like consistency) */
|
||||
*cp++ = fcs >> 8;
|
||||
|
||||
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;
|
||||
}
|
||||
log_DumpBp(LogHDLC, "hdlc_Output", bp);
|
||||
|
||||
bp->next = mfcs; /* Tack mfcs onto the end */
|
||||
|
||||
p->hdlc.lqm.OutOctets += mbuf_Length(mhp) + 1;
|
||||
p->hdlc.lqm.OutPackets++;
|
||||
|
||||
if (proto == PROTO_LQR) {
|
||||
/* 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 = ++p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output", &lqr);
|
||||
} else {
|
||||
lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output (again)", &lqr);
|
||||
}
|
||||
lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
|
||||
}
|
||||
|
||||
if (mfcs) {
|
||||
mfcs->cnt = 0;
|
||||
fcs = HdlcFcsBuf(INITFCS, mhp);
|
||||
fcs = ~fcs;
|
||||
cp = MBUF_CTOP(mfcs);
|
||||
*cp++ = fcs & 0377; /* Low byte first!! */
|
||||
*cp++ = fcs >> 8;
|
||||
mfcs->cnt = 2;
|
||||
}
|
||||
|
||||
log_DumpBp(LogHDLC, "hdlc_Output", 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
|
||||
async_Output(pri, mhp, proto, p);
|
||||
return bp;
|
||||
}
|
||||
|
||||
/* Check out the latest ``Assigned numbers'' rfc (rfc1700.txt) */
|
||||
|
@ -369,192 +307,45 @@ hdlc_Protocol2Nam(u_short proto)
|
|||
return "unrecognised protocol";
|
||||
}
|
||||
|
||||
void
|
||||
hdlc_DecodePacket(struct bundle *bundle, u_short proto, struct mbuf * bp,
|
||||
struct link *l)
|
||||
static struct mbuf *
|
||||
hdlc_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
u_char *cp;
|
||||
const char *type;
|
||||
u_short fcs;
|
||||
int len;
|
||||
|
||||
log_Printf(LogDEBUG, "DecodePacket: proto = 0x%04x\n", proto);
|
||||
|
||||
/* decompress everything. CCP needs uncompressed data too */
|
||||
if ((bp = ccp_Decompress(&l->ccp, &proto, bp)) == NULL)
|
||||
return;
|
||||
|
||||
switch (proto) {
|
||||
case PROTO_LCP:
|
||||
lcp_Input(&l->lcp, bp);
|
||||
break;
|
||||
case PROTO_PAP:
|
||||
if (p)
|
||||
pap_Input(p, bp);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: PAP: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_CBCP:
|
||||
if (p)
|
||||
cbcp_Input(p, bp);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: CBCP: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_LQR:
|
||||
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:
|
||||
if (p)
|
||||
chap_Input(p, bp);
|
||||
else {
|
||||
log_Printf(LogERROR, "DecodePacket: CHAP: Not a physical link !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
case PROTO_VJUNCOMP:
|
||||
case PROTO_VJCOMP:
|
||||
bp = vj_Input(&bundle->ncp.ipcp, bp, proto);
|
||||
if (bp == NULL)
|
||||
break;
|
||||
/* fall down */
|
||||
case PROTO_IP:
|
||||
ip_Input(bundle, bp);
|
||||
break;
|
||||
case PROTO_IPCP:
|
||||
ipcp_Input(&bundle->ncp.ipcp, bundle, bp);
|
||||
break;
|
||||
case PROTO_CCP:
|
||||
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(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Fall through */
|
||||
default:
|
||||
switch (proto) {
|
||||
case PROTO_MP:
|
||||
case PROTO_COMPD:
|
||||
case PROTO_ICOMPD:
|
||||
type = "Unexpected";
|
||||
break;
|
||||
default:
|
||||
type = "Unknown";
|
||||
break;
|
||||
}
|
||||
log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n", type, proto,
|
||||
hdlc_Protocol2Nam(proto));
|
||||
bp->offset -= 2;
|
||||
bp->cnt += 2;
|
||||
cp = MBUF_CTOP(bp);
|
||||
lcp_SendProtoRej(&l->lcp, cp, bp->cnt);
|
||||
if (p) {
|
||||
p->hdlc.lqm.SaveInDiscards++;
|
||||
p->hdlc.stats.unknownproto++;
|
||||
}
|
||||
mbuf_Free(bp);
|
||||
break;
|
||||
if (!p) {
|
||||
log_Printf(LogERROR, "Can't Pull a hdlc packet from a logical link\n");
|
||||
return bp;
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
hdlc_GetProto(const u_char *cp, u_short *proto)
|
||||
{
|
||||
*proto = *cp;
|
||||
if (!(*proto & 1)) {
|
||||
*proto = (*proto << 8) | cp[1];
|
||||
return 2;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
hdlc_Input(struct bundle *bundle, struct mbuf * bp, struct physical *physical)
|
||||
{
|
||||
u_short fcs, proto;
|
||||
u_char *cp, addr, ctrl;
|
||||
int n;
|
||||
|
||||
log_DumpBp(LogHDLC, "hdlc_Input:", bp);
|
||||
if (physical_IsSync(physical))
|
||||
fcs = GOODFCS;
|
||||
else
|
||||
fcs = hdlc_Fcs(INITFCS, MBUF_CTOP(bp), bp->cnt);
|
||||
physical->hdlc.lqm.SaveInOctets += bp->cnt + 1;
|
||||
|
||||
fcs = hdlc_Fcs(MBUF_CTOP(bp), bp->cnt);
|
||||
|
||||
log_Printf(LogDEBUG, "%s: hdlc_Input: fcs = %04x (%s)\n",
|
||||
physical->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
|
||||
p->link.name, fcs, (fcs == GOODFCS) ? "good" : "BAD!");
|
||||
|
||||
if (fcs != GOODFCS) {
|
||||
physical->hdlc.lqm.SaveInErrors++;
|
||||
physical->hdlc.stats.badfcs++;
|
||||
p->hdlc.lqm.SaveInErrors++;
|
||||
p->hdlc.stats.badfcs++;
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
if (!physical_IsSync(physical))
|
||||
bp->cnt -= 2; /* discard FCS part */
|
||||
|
||||
if (bp->cnt < 2) { /* XXX: raise this bar ? */
|
||||
p->hdlc.lqm.SaveInOctets += bp->cnt + 1;
|
||||
p->hdlc.lqm.SaveInPackets++;
|
||||
|
||||
len = mbuf_Length(bp);
|
||||
if (len < 4) { /* rfc1662 section 4.3 */
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
cp = MBUF_CTOP(bp);
|
||||
|
||||
if (!physical->link.lcp.want_acfcomp) {
|
||||
/* We expect the packet not to be compressed */
|
||||
addr = *cp++;
|
||||
if (addr != HDLC_ADDR) {
|
||||
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) {
|
||||
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 packets, but the peer still sends
|
||||
* uncompressed packets !
|
||||
*/
|
||||
cp += 2;
|
||||
bp->offset += 2;
|
||||
bp->cnt -= 2;
|
||||
bp = NULL;
|
||||
}
|
||||
|
||||
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);
|
||||
bp = mbuf_Truncate(bp, len - 2); /* discard the FCS */
|
||||
|
||||
link_ProtocolRecord(&physical->link, proto, PROTO_IN);
|
||||
physical->hdlc.lqm.SaveInPackets++;
|
||||
|
||||
hdlc_DecodePacket(bundle, proto, bp, &physical->link);
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -650,3 +441,5 @@ hdlc_StopTimer(struct hdlc *hdlc)
|
|||
{
|
||||
timer_Stop(&hdlc->ReportTimer);
|
||||
}
|
||||
|
||||
struct layer hdlclayer = { LAYER_HDLC, "hdlc", hdlc_LayerPush, hdlc_LayerPull };
|
||||
|
|
|
@ -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.15 1998/05/21 21:45:30 brian Exp $
|
||||
* $Id: hdlc.h,v 1.16 1999/04/03 11:54:00 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -109,7 +109,8 @@ 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_short hdlc_Fcs(u_char *, size_t);
|
||||
extern int hdlc_Detect(u_char const **, int, int);
|
||||
extern int hdlc_WrapperOctets(struct lcp *, u_short);
|
||||
|
||||
extern struct layer hdlclayer;
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: iface.c,v 1.3 1999/01/28 01:56:32 brian Exp $
|
||||
* $Id: iface.c,v 1.4 1999/04/26 08:54:24 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -46,6 +46,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ip.c,v 1.57 1999/04/26 08:54:34 brian Exp $
|
||||
* $Id: ip.c,v 1.58 1999/05/01 11:31:29 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o Return ICMP message for filterd packet
|
||||
|
@ -40,15 +40,11 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#ifndef NOALIAS
|
||||
#ifdef __FreeBSD__
|
||||
#include <alias.h>
|
||||
#else
|
||||
#include "alias.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "proto.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
@ -99,7 +95,7 @@ PortMatch(int op, u_short pport, u_short rport)
|
|||
}
|
||||
|
||||
/*
|
||||
* Check a packet against with defined filters
|
||||
* Check a packet against a defined filter
|
||||
*/
|
||||
static int
|
||||
FilterCheck(struct ip *pip, struct filter *filter)
|
||||
|
@ -384,124 +380,42 @@ PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ip_Input(struct bundle *bundle, struct mbuf * bp)
|
||||
struct mbuf *
|
||||
ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
u_char *cp;
|
||||
struct mbuf *wp;
|
||||
int nb, nw;
|
||||
struct tun_data tun;
|
||||
struct ip *pip = (struct ip *)tun.data;
|
||||
#ifndef NOALIAS
|
||||
struct ip *piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
|
||||
#endif
|
||||
struct ip *pip;
|
||||
|
||||
if (bundle->ncp.ipcp.fsm.state != ST_OPENED) {
|
||||
log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
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) {
|
||||
log_Printf(LogWARN, "ip_Input: Packet too large (%d) - dropped\n",
|
||||
mbuf_Length(bp));
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
memcpy(cp, MBUF_CTOP(wp), wp->cnt);
|
||||
cp += wp->cnt;
|
||||
nb += wp->cnt;
|
||||
nb = mbuf_Length(bp);
|
||||
mbuf_Read(bp, tun.data, nb);
|
||||
|
||||
if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0)
|
||||
return NULL;
|
||||
|
||||
pip = (struct ip *)tun.data;
|
||||
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(bundle->dev.fd, &tun, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
|
||||
#ifndef NOALIAS
|
||||
if (bundle->AliasEnabled && pip->ip_p != IPPROTO_IGMP &&
|
||||
(pip->ip_p != IPPROTO_IPIP || !IN_CLASSD(ntohl(piip->ip_dst.s_addr)))) {
|
||||
struct tun_data *frag;
|
||||
int iresult;
|
||||
char *fptr;
|
||||
|
||||
iresult = PacketAliasIn(tun.data, sizeof tun.data);
|
||||
nb = ntohs(((struct ip *) tun.data)->ip_len);
|
||||
|
||||
if (nb > MAX_MRU) {
|
||||
log_Printf(LogWARN, "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(bundle, tun.data, nb, &bundle->filter.in) < 0) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
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(bundle->dev.fd, &tun, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
|
||||
strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
|
||||
if (iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
|
||||
while ((fptr = PacketAliasGetFragment(tun.data)) != NULL) {
|
||||
PacketAliasFragmentIn(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(bundle->dev.fd, frag, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
|
||||
strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
free(frag);
|
||||
}
|
||||
}
|
||||
} else if (iresult == PKT_ALIAS_UNRESOLVED_FRAGMENT) {
|
||||
nb = ntohs(((struct ip *) tun.data)->ip_len);
|
||||
nb += sizeof tun - sizeof tun.data;
|
||||
frag = (struct tun_data *)malloc(nb);
|
||||
if (frag == NULL)
|
||||
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);
|
||||
PacketAliasSaveFragment(frag->data);
|
||||
}
|
||||
}
|
||||
} else
|
||||
#endif /* #ifndef NOALIAS */
|
||||
{ /* no aliasing */
|
||||
if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
|
||||
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(bundle->dev.fd, &tun, nb);
|
||||
if (nw != nb) {
|
||||
if (nw == -1)
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
|
||||
else
|
||||
log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
|
||||
}
|
||||
}
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -512,7 +426,15 @@ ip_Enqueue(struct ipcp *ipcp, int pri, char *ptr, int count)
|
|||
if (pri < 0 || pri > sizeof ipcp->Queue / sizeof ipcp->Queue[0])
|
||||
log_Printf(LogERROR, "Can't store in ip queue %d\n", pri);
|
||||
else {
|
||||
bp = mbuf_Alloc(count, MB_IPQ);
|
||||
/*
|
||||
* We allocate an extra 6 bytes, four at the front and two at the end.
|
||||
* This is an optimisation so that we need to do less work in
|
||||
* mbuf_Prepend() in acf_LayerPush() and proto_LayerPush() and
|
||||
* appending in hdlc_LayerPush().
|
||||
*/
|
||||
bp = mbuf_Alloc(count + 6, MB_IPQ);
|
||||
bp->offset += 4;
|
||||
bp->cnt -= 6;
|
||||
memcpy(MBUF_CTOP(bp), ptr, count);
|
||||
mbuf_Enqueue(&ipcp->Queue[pri], bp);
|
||||
}
|
||||
|
@ -541,11 +463,12 @@ ip_QueueLen(struct ipcp *ipcp)
|
|||
}
|
||||
|
||||
int
|
||||
ip_FlushPacket(struct link *l, struct bundle *bundle)
|
||||
ip_PushPacket(struct link *l, struct bundle *bundle)
|
||||
{
|
||||
struct ipcp *ipcp = &bundle->ncp.ipcp;
|
||||
struct mqueue *queue;
|
||||
struct mbuf *bp;
|
||||
struct ip *pip;
|
||||
int cnt;
|
||||
|
||||
if (ipcp->fsm.state != ST_OPENED)
|
||||
|
@ -554,16 +477,13 @@ ip_FlushPacket(struct link *l, struct bundle *bundle)
|
|||
for (queue = &ipcp->Queue[PRI_FAST]; queue >= ipcp->Queue; queue--)
|
||||
if (queue->top) {
|
||||
bp = mbuf_Contiguous(mbuf_Dequeue(queue));
|
||||
if (bp) {
|
||||
struct ip *pip = (struct ip *)MBUF_CTOP(bp);
|
||||
|
||||
cnt = mbuf_Length(bp);
|
||||
if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
|
||||
bundle_StartIdleTimer(bundle);
|
||||
vj_SendFrame(l, bp, bundle);
|
||||
ipcp_AddOutOctets(ipcp, cnt);
|
||||
return 1;
|
||||
}
|
||||
cnt = mbuf_Length(bp);
|
||||
pip = (struct ip *)MBUF_CTOP(bp);
|
||||
if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
|
||||
bundle_StartIdleTimer(bundle);
|
||||
link_PushPacket(l, bp, bundle, PRI_NORMAL, PROTO_IP);
|
||||
ipcp_AddOutOctets(ipcp, cnt);
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ip.h,v 1.10 1998/08/25 17:48:42 brian Exp $
|
||||
* $Id: ip.h,v 1.11 1998/08/26 17:39:37 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -26,9 +26,9 @@ struct filter;
|
|||
struct link;
|
||||
struct bundle;
|
||||
|
||||
extern int ip_FlushPacket(struct link *, struct bundle *);
|
||||
extern int ip_PushPacket(struct link *, struct bundle *);
|
||||
extern int PacketCheck(struct bundle *, char *, int, struct filter *);
|
||||
extern void ip_Enqueue(struct ipcp *, int, char *, int);
|
||||
extern void ip_Input(struct bundle *, struct mbuf *);
|
||||
extern struct mbuf *ip_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
extern void ip_DeleteQueue(struct ipcp *);
|
||||
extern int ip_QueueLen(struct ipcp *);
|
||||
|
|
|
@ -17,10 +17,11 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: ipcp.c,v 1.74 1999/04/26 08:54:24 brian Exp $
|
||||
* $Id: ipcp.c,v 1.75 1999/04/26 08:54:34 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* o More RFC1772 backward compatibility
|
||||
* o Support IPADDRS properly
|
||||
* o Validate the length in IpcpDecodeConfig
|
||||
*/
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in_systm.h>
|
||||
|
@ -47,6 +48,7 @@
|
|||
#include "alias.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "ua.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
|
@ -54,7 +56,7 @@
|
|||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "iplist.h"
|
||||
#include "throughput.h"
|
||||
|
@ -1007,22 +1009,12 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
|||
|
||||
switch (mode_type) {
|
||||
case MODE_REQ:
|
||||
ipcp->peer_ip = ipaddr;
|
||||
ipcp->my_ip = dstipaddr;
|
||||
memcpy(dec->ackend, cp, length);
|
||||
dec->ackend += length;
|
||||
memcpy(dec->rejend, cp, length);
|
||||
dec->rejend += length;
|
||||
break;
|
||||
|
||||
case MODE_NAK:
|
||||
snprintf(tbuff2, sizeof tbuff2, "%s changing address: %s", tbuff,
|
||||
inet_ntoa(ipcp->my_ip));
|
||||
log_Printf(LogIPCP, "%s --> %s\n", tbuff2, inet_ntoa(ipaddr));
|
||||
ipcp->my_ip = ipaddr;
|
||||
ipcp->peer_ip = dstipaddr;
|
||||
break;
|
||||
|
||||
case MODE_REJ:
|
||||
ipcp->peer_reject |= (1 << type);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
@ -1147,18 +1139,19 @@ IpcpDecodeConfig(struct fsm *fp, u_char * cp, int plen, int mode_type,
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
ipcp_Input(struct ipcp *ipcp, struct bundle *bundle, struct mbuf *bp)
|
||||
extern struct mbuf *
|
||||
ipcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
/* Got PROTO_IPCP from link */
|
||||
if (bundle_Phase(bundle) == PHASE_NETWORK)
|
||||
fsm_Input(&ipcp->fsm, bp);
|
||||
fsm_Input(&bundle->ncp.ipcp.fsm, bp);
|
||||
else {
|
||||
if (bundle_Phase(bundle) < PHASE_NETWORK)
|
||||
log_Printf(LogIPCP, "%s: Error: Unexpected IPCP in phase %s (ignored)\n",
|
||||
ipcp->fsm.link->name, bundle_PhaseName(bundle));
|
||||
l->name, bundle_PhaseName(bundle));
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int
|
||||
|
|
|
@ -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.24 1999/02/26 21:28:12 brian Exp $
|
||||
* $Id: ipcp.h,v 1.25 1999/03/03 23:00:40 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -108,7 +108,7 @@ extern void ipcp_Setup(struct ipcp *, u_int32_t);
|
|||
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 struct mbuf *ipcp_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
extern void ipcp_AddInOctets(struct ipcp *, int);
|
||||
extern void ipcp_AddOutOctets(struct ipcp *, int);
|
||||
extern int ipcp_UseHisIPaddr(struct bundle *, struct in_addr);
|
||||
|
|
|
@ -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.6 1998/06/15 19:06:47 brian Exp $
|
||||
* $Id: iplist.c,v 1.7 1998/06/27 23:48:47 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -32,6 +32,7 @@
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
|
|
@ -0,0 +1,52 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
#define LAYER_ASYNC 2
|
||||
#define LAYER_SYNC 3
|
||||
#define LAYER_HDLC 4
|
||||
#define LAYER_ACF 5
|
||||
#define LAYER_PROTO 6
|
||||
#define LAYER_LQR 7
|
||||
#define LAYER_CCP 8
|
||||
#define LAYER_VJ 9
|
||||
#define LAYER_ALIAS 10
|
||||
|
||||
#define LAYER_MAX 10 /* How many layers we can handle on a link */
|
||||
|
||||
struct mbuf;
|
||||
struct link;
|
||||
struct bundle;
|
||||
|
||||
struct layer {
|
||||
int type;
|
||||
const char *name;
|
||||
struct mbuf *(*push)(struct bundle *, struct link *, struct mbuf *,
|
||||
int pri, u_short *proto);
|
||||
struct mbuf *(*pull)(struct bundle *, struct link *, struct mbuf *,
|
||||
u_short *);
|
||||
};
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.c,v 1.69 1999/02/26 21:28:12 brian Exp $
|
||||
* $Id: lcp.c,v 1.72 1999/04/11 08:51:04 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "ua.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
|
@ -44,7 +45,7 @@
|
|||
#include "iplist.h"
|
||||
#include "lcp.h"
|
||||
#include "throughput.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "descriptor.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
|
@ -1147,9 +1148,10 @@ reqreject:
|
|||
}
|
||||
}
|
||||
|
||||
void
|
||||
lcp_Input(struct lcp *lcp, struct mbuf *bp)
|
||||
extern struct mbuf *
|
||||
lcp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
/* Got PROTO_LCP from link */
|
||||
fsm_Input(&lcp->fsm, bp);
|
||||
fsm_Input(&l->lcp.fsm, bp);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcp.h,v 1.20 1999/02/18 00:52:15 brian Exp $
|
||||
* $Id: lcp.h,v 1.21 1999/02/26 21:28:12 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -136,5 +136,5 @@ 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 struct mbuf *lcp_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
extern void lcp_SetupCallbacks(struct lcp *);
|
||||
|
|
|
@ -23,30 +23,49 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: link.c,v 1.7 1999/02/06 02:54:46 brian Exp $
|
||||
* $Id: link.c,v 1.8 1999/03/31 14:21:45 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netdb.h>
|
||||
#include <sys/un.h>
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/ip.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "fsm.h"
|
||||
#include "descriptor.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "prompt.h"
|
||||
#include "async.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "ip.h"
|
||||
#include "auth.h"
|
||||
#include "pap.h"
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
|
||||
static void Despatch(struct bundle *, struct link *, struct mbuf *, u_short);
|
||||
|
||||
void
|
||||
link_AddInOctets(struct link *l, int n)
|
||||
|
@ -125,39 +144,6 @@ link_Dequeue(struct link *l)
|
|||
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;
|
||||
|
@ -208,3 +194,147 @@ link_ReportProtocolStatus(struct link *l, struct prompt *prompt)
|
|||
if (!(i % 2))
|
||||
prompt_Printf(prompt, "\n");
|
||||
}
|
||||
|
||||
void
|
||||
link_PushPacket(struct link *l, struct mbuf *bp, struct bundle *b, int pri,
|
||||
u_short proto)
|
||||
{
|
||||
int layer;
|
||||
|
||||
/*
|
||||
* When we ``push'' a packet into the link, it gets processed by the
|
||||
* ``push'' function in each layer starting at the top.
|
||||
* We never expect the result of a ``push'' to be more than one
|
||||
* packet (as we do with ``pull''s).
|
||||
*/
|
||||
|
||||
if(pri < 0 || pri >= LINK_QUEUES)
|
||||
pri = 0;
|
||||
|
||||
for (layer = l->nlayers; layer && bp; layer--)
|
||||
if (l->layer[layer - 1]->push != NULL)
|
||||
bp = (*l->layer[layer - 1]->push)(b, l, bp, pri, &proto);
|
||||
|
||||
if (bp) {
|
||||
log_Printf(LogDEBUG, "link_PushPacket: proto = 0x%04x\n", proto);
|
||||
link_AddOutOctets(l, mbuf_Length(bp));
|
||||
mbuf_Enqueue(l->Queue + pri, mbuf_Contiguous(bp));
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
link_PullPacket(struct link *l, char *buf, size_t len, struct bundle *b)
|
||||
{
|
||||
struct mbuf *bp, *lbp[LAYER_MAX], *next;
|
||||
u_short lproto[LAYER_MAX], proto;
|
||||
int layer;
|
||||
|
||||
/*
|
||||
* When we ``pull'' a packet from the link, it gets processed by the
|
||||
* ``pull'' function in each layer starting at the bottom.
|
||||
* Each ``pull'' may produce multiple packets, chained together using
|
||||
* bp->pnext.
|
||||
* Each packet that results from each pull has to be pulled through
|
||||
* all of the higher layers before the next resulting packet is pulled
|
||||
* through anything; this ensures that packets that depend on the
|
||||
* fsm state resulting from the receipt of the previous packet aren't
|
||||
* surprised.
|
||||
*/
|
||||
|
||||
link_AddInOctets(l, len);
|
||||
|
||||
memset(lbp, '\0', sizeof lbp);
|
||||
lbp[0] = mbuf_Alloc(len, MB_ASYNC);
|
||||
memcpy(MBUF_CTOP(lbp[0]), buf, len);
|
||||
lproto[0] = 0;
|
||||
layer = 0;
|
||||
|
||||
while (layer || lbp[layer]) {
|
||||
if (lbp[layer] == NULL) {
|
||||
layer--;
|
||||
continue;
|
||||
}
|
||||
bp = lbp[layer];
|
||||
lbp[layer] = bp->pnext;
|
||||
bp->pnext = NULL;
|
||||
proto = lproto[layer];
|
||||
|
||||
if (l->layer[layer]->pull != NULL)
|
||||
bp = (*l->layer[layer]->pull)(b, l, bp, &proto);
|
||||
|
||||
if (layer == l->nlayers - 1) {
|
||||
/* We've just done the top layer, despatch the packet(s) */
|
||||
while (bp) {
|
||||
next = bp->pnext;
|
||||
bp->pnext = NULL;
|
||||
Despatch(b, l, bp, proto);
|
||||
bp = next;
|
||||
}
|
||||
} else {
|
||||
lbp[++layer] = bp;
|
||||
lproto[layer] = proto;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
link_Stack(struct link *l, struct layer *layer)
|
||||
{
|
||||
if (l->nlayers == sizeof l->layer / sizeof l->layer[0]) {
|
||||
log_Printf(LogERROR, "%s: Oops, cannot stack a %s layer...\n",
|
||||
l->name, layer->name);
|
||||
return 0;
|
||||
}
|
||||
l->layer[l->nlayers++] = layer;
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
link_EmptyStack(struct link *l)
|
||||
{
|
||||
l->nlayers = 0;
|
||||
}
|
||||
|
||||
static const struct {
|
||||
u_short proto;
|
||||
struct mbuf *(*fn)(struct bundle *, struct link *, struct mbuf *);
|
||||
} despatcher[] = {
|
||||
{ PROTO_IP, ip_Input },
|
||||
{ PROTO_MP, mp_Input },
|
||||
{ PROTO_LCP, lcp_Input },
|
||||
{ PROTO_IPCP, ipcp_Input },
|
||||
{ PROTO_PAP, pap_Input },
|
||||
{ PROTO_CHAP, chap_Input },
|
||||
{ PROTO_CCP, ccp_Input },
|
||||
{ PROTO_LQR, lqr_Input },
|
||||
{ PROTO_CBCP, cbcp_Input }
|
||||
};
|
||||
|
||||
#define DSIZE (sizeof despatcher / sizeof despatcher[0])
|
||||
|
||||
static void
|
||||
Despatch(struct bundle *bundle, struct link *l, struct mbuf *bp, u_short proto)
|
||||
{
|
||||
int f;
|
||||
|
||||
for (f = 0; f < DSIZE; f++)
|
||||
if (despatcher[f].proto == proto) {
|
||||
bp = (*despatcher[f].fn)(bundle, l, bp);
|
||||
break;
|
||||
}
|
||||
|
||||
if (bp) {
|
||||
struct physical *p = link2physical(l);
|
||||
|
||||
log_Printf(LogPHASE, "%s protocol 0x%04x (%s)\n",
|
||||
f == DSIZE ? "Unknown" : "Unexpected", proto,
|
||||
hdlc_Protocol2Nam(proto));
|
||||
bp = mbuf_Contiguous(proto_Prepend(bp, proto, 0, 0));
|
||||
lcp_SendProtoRej(&l->lcp, MBUF_CTOP(bp), bp->cnt);
|
||||
if (p) {
|
||||
p->hdlc.lqm.SaveInDiscards++;
|
||||
p->hdlc.stats.unknownproto++;
|
||||
}
|
||||
mbuf_Free(bp);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -23,13 +23,13 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: link.h,v 1.3 1998/05/23 17:05:27 brian Exp $
|
||||
* $Id: link.h,v 1.4 1998/08/25 17:48:42 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#define PHYSICAL_LINK 1
|
||||
#define MP_LINK 2
|
||||
#define PHYSICAL_LINK 1
|
||||
#define LOGICAL_LINK 2
|
||||
|
||||
#define LINK_QUEUES (PRI_MAX + 1)
|
||||
#define NPROTOSTAT 13
|
||||
|
@ -49,6 +49,9 @@ struct link {
|
|||
|
||||
struct lcp lcp; /* Our line control FSM */
|
||||
struct ccp ccp; /* Our compression FSM */
|
||||
|
||||
struct layer const *layer[LAYER_MAX]; /* i/o layers */
|
||||
int nlayers;
|
||||
};
|
||||
|
||||
extern void link_AddInOctets(struct link *, int);
|
||||
|
@ -59,9 +62,12 @@ extern void link_DeleteQueue(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 *);
|
||||
|
||||
extern void link_PushPacket(struct link *, struct mbuf *, struct bundle *,
|
||||
int, u_short);
|
||||
extern void link_PullPacket(struct link *, char *, size_t, struct bundle *);
|
||||
extern int link_Stack(struct link *, struct layer *);
|
||||
extern void link_EmptyStack(struct link *);
|
||||
|
||||
#define PROTO_IN 1 /* third arg to link_ProtocolRecord */
|
||||
#define PROTO_OUT 2
|
||||
|
|
|
@ -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.31 1999/01/28 01:56:33 brian Exp $
|
||||
* $Id: lqr.c,v 1.32 1999/03/29 08:21:28 brian Exp $
|
||||
*
|
||||
* o LQR based on RFC1333
|
||||
*
|
||||
|
@ -32,12 +32,14 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "acf.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
|
@ -108,8 +110,8 @@ lqr_ChangeOrder(struct lqrdata * src, struct lqrdata * dst)
|
|||
|
||||
sp = (u_int32_t *) src;
|
||||
dp = (u_int32_t *) dst;
|
||||
for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_int32_t); n++)
|
||||
*dp++ = ntohl(*sp++);
|
||||
for (n = 0; n < sizeof(struct lqrdata) / sizeof(u_int32_t); n++, sp++, dp++)
|
||||
*dp = ntohl(*sp);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -118,7 +120,7 @@ SendLqrData(struct lcp *lcp)
|
|||
struct mbuf *bp;
|
||||
|
||||
bp = mbuf_Alloc(sizeof(struct lqrdata), MB_LQR);
|
||||
hdlc_Output(lcp->fsm.link, PRI_LINK, PROTO_LQR, bp);
|
||||
link_PushPacket(lcp->fsm.link, bp, lcp->fsm.bundle, PRI_LINK, PROTO_LQR);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -160,59 +162,65 @@ SendLqrReport(void *v)
|
|||
timer_Start(&p->hdlc.lqm.timer);
|
||||
}
|
||||
|
||||
void
|
||||
lqr_Input(struct physical *physical, struct mbuf *bp)
|
||||
struct mbuf *
|
||||
lqr_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct lcp *lcp = p->hdlc.lqm.owner;
|
||||
int len;
|
||||
|
||||
if (p == NULL) {
|
||||
log_Printf(LogERROR, "lqr_Input: Not a physical link - dropped\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p->hdlc.lqm.lqr.SaveInLQRs++;
|
||||
|
||||
len = mbuf_Length(bp);
|
||||
if (len != sizeof(struct lqrdata))
|
||||
log_Printf(LogWARN, "lqr_Input: Got packet size %d, expecting %ld !\n",
|
||||
len, (long)sizeof(struct lqrdata));
|
||||
else if (!IsAccepted(physical->link.lcp.cfg.lqr) &&
|
||||
!(physical->hdlc.lqm.method & LQM_LQR)) {
|
||||
bp->offset -= 2; /* XXX: We have a bit too much knowledge here ! */
|
||||
bp->cnt += 2;
|
||||
lcp_SendProtoRej(physical->hdlc.lqm.owner, MBUF_CTOP(bp), bp->cnt);
|
||||
else if (!IsAccepted(l->lcp.cfg.lqr) && !(p->hdlc.lqm.method & LQM_LQR)) {
|
||||
bp = mbuf_Contiguous(proto_Prepend(bp, PROTO_LQR, 0, 0));
|
||||
lcp_SendProtoRej(lcp, MBUF_CTOP(bp), bp->cnt);
|
||||
} else {
|
||||
struct lqrdata *lqr;
|
||||
struct lcp *lcp;
|
||||
u_int32_t lastLQR;
|
||||
|
||||
bp = mbuf_Contiguous(bp);
|
||||
lqr = (struct lqrdata *)MBUF_CTOP(bp);
|
||||
lcp = physical->hdlc.lqm.owner;
|
||||
if (ntohl(lqr->MagicNumber) != physical->hdlc.lqm.owner->his_magic)
|
||||
if (ntohl(lqr->MagicNumber) != lcp->his_magic)
|
||||
log_Printf(LogWARN, "lqr_Input: magic 0x%08lx is wrong,"
|
||||
" expecting 0x%08lx\n",
|
||||
(u_long)ntohl(lqr->MagicNumber),
|
||||
(u_long)physical->hdlc.lqm.owner->his_magic);
|
||||
(u_long)ntohl(lqr->MagicNumber), (u_long)lcp->his_magic);
|
||||
else {
|
||||
/*
|
||||
* Remember our PeerInLQRs, then convert byte order and save
|
||||
*/
|
||||
lastLQR = physical->hdlc.lqm.lqr.peer.PeerInLQRs;
|
||||
lastLQR = p->hdlc.lqm.lqr.peer.PeerInLQRs;
|
||||
|
||||
lqr_ChangeOrder(lqr, &physical->hdlc.lqm.lqr.peer);
|
||||
lqr_Dump(physical->link.name, "Input", &physical->hdlc.lqm.lqr.peer);
|
||||
lqr_ChangeOrder(lqr, &p->hdlc.lqm.lqr.peer);
|
||||
lqr_Dump(l->name, "Input", &p->hdlc.lqm.lqr.peer);
|
||||
/* we have received an LQR from peer */
|
||||
physical->hdlc.lqm.lqr.resent = 0;
|
||||
p->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);
|
||||
if (p->hdlc.lqm.timer.load == 0 ||
|
||||
!(p->hdlc.lqm.method & LQM_LQR) ||
|
||||
(lastLQR && lastLQR == p->hdlc.lqm.lqr.peer.PeerInLQRs) ||
|
||||
(p->hdlc.lqm.lqr.peer_timeout &&
|
||||
p->hdlc.lqm.timer.rest * 100 / SECTICKS >
|
||||
p->hdlc.lqm.lqr.peer_timeout))
|
||||
SendLqrData(lcp);
|
||||
}
|
||||
}
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -319,3 +327,82 @@ lqr_Dump(const char *link, const char *message, const struct lqrdata *lqr)
|
|||
lqr->PeerOutPackets, lqr->PeerOutOctets);
|
||||
}
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
lqr_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
int len;
|
||||
|
||||
if (!p) {
|
||||
/* Oops - can't happen :-] */
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* From rfc1989:
|
||||
*
|
||||
* All octets which are included in the FCS calculation MUST be counted,
|
||||
* including the packet header, the information field, and any padding.
|
||||
* The FCS octets MUST also be counted, and one flag octet per frame
|
||||
* MUST be counted. All other octets (such as additional flag
|
||||
* sequences, and escape bits or octets) MUST NOT be counted.
|
||||
*
|
||||
* As we're stacked before the HDLC layer (otherwise HDLC wouldn't be
|
||||
* able to calculate the FCS), we must not forget about these additional
|
||||
* bytes when we're asynchronous.
|
||||
*
|
||||
* We're also expecting to be stacked *before* the proto and acf layers.
|
||||
* If we were after these, it makes alignment more of a pain, and we
|
||||
* don't do LQR without these layers.
|
||||
*/
|
||||
|
||||
bp = mbuf_Contiguous(bp);
|
||||
len = mbuf_Length(bp);
|
||||
|
||||
if (!physical_IsSync(p))
|
||||
p->hdlc.lqm.OutOctets += hdlc_WrapperOctets(&l->lcp, *proto);
|
||||
p->hdlc.lqm.OutOctets += acf_WrapperOctets(&l->lcp, *proto) +
|
||||
proto_WrapperOctets(&l->lcp, *proto) + len + 1;
|
||||
p->hdlc.lqm.OutPackets++;
|
||||
|
||||
if (*proto == PROTO_LQR) {
|
||||
/* 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 = ++p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output", &lqr);
|
||||
} else {
|
||||
lqr.PeerOutLQRs = p->hdlc.lqm.lqr.OutLQRs;
|
||||
lqr_Dump(l->name, "Output (again)", &lqr);
|
||||
}
|
||||
lqr_ChangeOrder(&lqr, (struct lqrdata *)MBUF_CTOP(bp));
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
* Statistics for pulled packets are recorded either in hdlc_PullPacket()
|
||||
* or sync_PullPacket()
|
||||
*/
|
||||
|
||||
struct layer lqrlayer = { LAYER_LQR, "lqr", lqr_LayerPush, NULL };
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lqr.h,v 1.12.2.6 1998/05/08 01:15:09 brian Exp $
|
||||
* $Id: lqr.h,v 1.13 1998/05/21 21:46:36 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -48,6 +48,8 @@ struct mbuf;
|
|||
struct physical;
|
||||
struct lcp;
|
||||
struct fsm;
|
||||
struct link;
|
||||
struct bundle;
|
||||
|
||||
extern void lqr_Dump(const char *, const char *, const struct lqrdata *);
|
||||
extern void lqr_ChangeOrder(struct lqrdata *, struct lqrdata *);
|
||||
|
@ -56,4 +58,6 @@ 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 *);
|
||||
extern struct mbuf *lqr_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
|
||||
extern struct layer lqrlayer;
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: main.c,v 1.152 1999/03/30 00:44:57 brian Exp $
|
||||
* $Id: main.c,v 1.153 1999/04/26 08:54:34 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -45,6 +45,7 @@
|
|||
#include "alias.h"
|
||||
#endif
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "probe.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
|
@ -571,7 +572,6 @@ DoLoop(struct bundle *bundle)
|
|||
t.tv_usec = 100000;
|
||||
select(0, NULL, NULL, NULL, &t);
|
||||
}
|
||||
|
||||
} while (bundle_CleanDatalinks(bundle), !bundle_IsDead(bundle));
|
||||
|
||||
log_Printf(LogDEBUG, "DoLoop done.\n");
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: mbuf.c,v 1.23 1999/02/06 02:54:47 brian Exp $
|
||||
* $Id: mbuf.c,v 1.24 1999/03/29 08:21:28 brian Exp $
|
||||
*
|
||||
*/
|
||||
#include <sys/types.h>
|
||||
|
@ -42,6 +42,7 @@ static struct memmap {
|
|||
} MemMap[MB_MAX + 2];
|
||||
|
||||
static int totalalloced;
|
||||
static unsigned long long mbuf_Mallocs, mbuf_Frees;
|
||||
|
||||
int
|
||||
mbuf_Length(struct mbuf * bp)
|
||||
|
@ -66,6 +67,7 @@ mbuf_Alloc(int cnt, int type)
|
|||
(long)sizeof(struct mbuf));
|
||||
AbortProgram(EX_OSERR);
|
||||
}
|
||||
mbuf_Mallocs++;
|
||||
memset(bp, '\0', sizeof(struct mbuf));
|
||||
MemMap[type].fragments++;
|
||||
MemMap[type].octets += cnt;
|
||||
|
@ -76,7 +78,7 @@ mbuf_Alloc(int cnt, int type)
|
|||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_FreeSeg(struct mbuf * bp)
|
||||
mbuf_FreeSeg(struct mbuf *bp)
|
||||
{
|
||||
struct mbuf *nbp;
|
||||
|
||||
|
@ -86,6 +88,7 @@ mbuf_FreeSeg(struct mbuf * bp)
|
|||
MemMap[bp->type].octets -= bp->size;
|
||||
totalalloced -= bp->size;
|
||||
free(bp);
|
||||
mbuf_Frees++;
|
||||
bp = nbp;
|
||||
}
|
||||
|
||||
|
@ -93,35 +96,108 @@ mbuf_FreeSeg(struct mbuf * bp)
|
|||
}
|
||||
|
||||
void
|
||||
mbuf_Free(struct mbuf * bp)
|
||||
mbuf_Free(struct mbuf *bp)
|
||||
{
|
||||
while (bp)
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_Read(struct mbuf * bp, u_char * ptr, int len)
|
||||
mbuf_Read(struct mbuf *bp, void *v, size_t len)
|
||||
{
|
||||
int nb;
|
||||
u_char *ptr = v;
|
||||
|
||||
while (bp && len > 0) {
|
||||
if (len > bp->cnt)
|
||||
nb = bp->cnt;
|
||||
else
|
||||
nb = len;
|
||||
memcpy(ptr, MBUF_CTOP(bp), nb);
|
||||
ptr += nb;
|
||||
bp->cnt -= nb;
|
||||
len -= nb;
|
||||
bp->offset += nb;
|
||||
if (nb) {
|
||||
memcpy(ptr, MBUF_CTOP(bp), nb);
|
||||
ptr += nb;
|
||||
bp->cnt -= nb;
|
||||
len -= nb;
|
||||
bp->offset += nb;
|
||||
}
|
||||
if (bp->cnt == 0)
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
}
|
||||
return (bp);
|
||||
|
||||
while (bp && bp->cnt == 0)
|
||||
bp = mbuf_FreeSeg(bp);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
size_t
|
||||
mbuf_View(struct mbuf *bp, void *v, size_t len)
|
||||
{
|
||||
size_t nb, l = len;
|
||||
u_char *ptr = v;
|
||||
|
||||
while (bp && l > 0) {
|
||||
if (l > bp->cnt)
|
||||
nb = bp->cnt;
|
||||
else
|
||||
nb = l;
|
||||
memcpy(ptr, MBUF_CTOP(bp), nb);
|
||||
ptr += nb;
|
||||
l -= nb;
|
||||
bp = bp->next;
|
||||
}
|
||||
|
||||
return len - l;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_Prepend(struct mbuf *bp, const void *ptr, size_t len, size_t extra)
|
||||
{
|
||||
struct mbuf *head;
|
||||
|
||||
if (bp->offset) {
|
||||
if (bp->offset >= len) {
|
||||
bp->offset -= len;
|
||||
bp->cnt += len;
|
||||
memcpy(MBUF_CTOP(bp), ptr, len);
|
||||
return bp;
|
||||
}
|
||||
len -= bp->offset;
|
||||
memcpy(bp + sizeof *bp, (const char *)ptr + len, bp->offset);
|
||||
bp->cnt += bp->offset;
|
||||
bp->offset = 0;
|
||||
}
|
||||
|
||||
head = mbuf_Alloc(len + extra, bp->type);
|
||||
head->offset = extra;
|
||||
head->cnt -= extra;
|
||||
memcpy(MBUF_CTOP(head), ptr, len);
|
||||
head->next = bp;
|
||||
|
||||
return head;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mbuf_Truncate(struct mbuf *bp, size_t n)
|
||||
{
|
||||
if (n == 0) {
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (; bp; bp = bp->next, n -= bp->cnt)
|
||||
if (n < bp->cnt) {
|
||||
bp->cnt = n;
|
||||
mbuf_Free(bp->next);
|
||||
bp->next = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
void
|
||||
mbuf_Write(struct mbuf * bp, u_char * ptr, int cnt)
|
||||
mbuf_Write(struct mbuf *bp, const void *ptr, size_t cnt)
|
||||
{
|
||||
int plen;
|
||||
int nb;
|
||||
|
@ -143,8 +219,8 @@ mbuf_Show(struct cmdargs const *arg)
|
|||
{
|
||||
int i;
|
||||
static const char *mbuftype[] = {
|
||||
"async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "link",
|
||||
"vjcomp", "ipq", "mp" };
|
||||
"async", "fsm", "cbcp", "hdlcout", "ipin", "echo", "lqr", "vjcomp",
|
||||
"ipq", "mp" };
|
||||
|
||||
prompt_Printf(arg->prompt, "Fragments (octets) in use:\n");
|
||||
for (i = 1; i < MB_MAX; i += 2)
|
||||
|
@ -156,6 +232,9 @@ mbuf_Show(struct cmdargs const *arg)
|
|||
prompt_Printf(arg->prompt, "%10.10s: %04d (%06d)\n",
|
||||
mbuftype[i-1], MemMap[i].fragments, MemMap[i].octets);
|
||||
|
||||
prompt_Printf(arg->prompt, "Mallocs: %qu, Frees: %qu\n",
|
||||
mbuf_Mallocs, mbuf_Frees);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -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.14 1998/08/21 18:10:15 brian Exp $
|
||||
* $Id: mbuf.h,v 1.15 1999/03/29 08:21:28 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -46,10 +46,9 @@ struct mqueue {
|
|||
#define MB_IPIN 5
|
||||
#define MB_ECHO 6
|
||||
#define MB_LQR 7
|
||||
#define MB_LINK 8
|
||||
#define MB_VJCOMP 9
|
||||
#define MB_IPQ 10
|
||||
#define MB_MP 11
|
||||
#define MB_VJCOMP 8
|
||||
#define MB_IPQ 9
|
||||
#define MB_MP 10
|
||||
#define MB_MAX MB_MP
|
||||
|
||||
struct cmdargs;
|
||||
|
@ -58,8 +57,11 @@ 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_Write(struct mbuf *, const void *, size_t);
|
||||
extern struct mbuf *mbuf_Read(struct mbuf *, void *, size_t);
|
||||
extern size_t mbuf_View(struct mbuf *, void *, size_t);
|
||||
extern struct mbuf *mbuf_Prepend(struct mbuf *, const void *, size_t, size_t);
|
||||
extern struct mbuf *mbuf_Truncate(struct mbuf *, size_t);
|
||||
extern void mbuf_Log(void);
|
||||
extern int mbuf_Show(struct cmdargs const *);
|
||||
extern void mbuf_Enqueue(struct mqueue *, struct mbuf *);
|
||||
|
|
1155
usr.sbin/ppp/modem.c
1155
usr.sbin/ppp/modem.c
File diff suppressed because it is too large
Load Diff
|
@ -1,43 +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: modem.h,v 1.17 1998/05/21 21:47:02 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
||||
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 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, pid_t);
|
||||
extern void modem_ChangedPid(struct physical *, pid_t);
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp.c,v 1.17 1998/10/24 01:08:45 brian Exp $
|
||||
* $Id: mp.c,v 1.18 1999/01/28 01:56:33 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -44,6 +44,11 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#ifndef NOALIAS
|
||||
#include "alias_cmd.h"
|
||||
#endif
|
||||
#include "vjcomp.h"
|
||||
#include "ua.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
|
@ -65,7 +70,7 @@
|
|||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "chat.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "filter.h"
|
||||
#include "mp.h"
|
||||
#include "chap.h"
|
||||
|
@ -193,7 +198,7 @@ mp_Init(struct mp *mp, struct bundle *bundle)
|
|||
mp->inbufs = NULL;
|
||||
mp->bundle = bundle;
|
||||
|
||||
mp->link.type = MP_LINK;
|
||||
mp->link.type = LOGICAL_LINK;
|
||||
mp->link.name = "mp";
|
||||
mp->link.len = sizeof *mp;
|
||||
|
||||
|
@ -218,6 +223,14 @@ mp_Init(struct mp *mp, struct bundle *bundle)
|
|||
|
||||
lcp_Init(&mp->link.lcp, mp->bundle, &mp->link, NULL);
|
||||
ccp_Init(&mp->link.ccp, mp->bundle, &mp->link, &mp->fsmp);
|
||||
|
||||
link_EmptyStack(&mp->link);
|
||||
link_Stack(&mp->link, &protolayer);
|
||||
link_Stack(&mp->link, &ccplayer);
|
||||
link_Stack(&mp->link, &vjlayer);
|
||||
#ifndef NOALIAS
|
||||
link_Stack(&mp->link, &aliaslayer);
|
||||
#endif
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -323,8 +336,8 @@ mp_linkInit(struct mp_link *mplink)
|
|||
mplink->weight = 1500;
|
||||
}
|
||||
|
||||
void
|
||||
mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
|
||||
static void
|
||||
mp_Assemble(struct mp *mp, struct mbuf *m, struct physical *p)
|
||||
{
|
||||
struct mp_header mh, h;
|
||||
struct mbuf *q, *last;
|
||||
|
@ -490,7 +503,8 @@ mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
|
|||
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);
|
||||
q = mbuf_Contiguous(q);
|
||||
link_PullPacket(&mp->link, MBUF_CTOP(q), q->cnt, mp->bundle);
|
||||
}
|
||||
|
||||
mp->seq.next_in = seq = inc_seq(mp->local_is12bit, h.seq);
|
||||
|
@ -521,9 +535,27 @@ mp_Input(struct mp *mp, struct mbuf *m, struct physical *p)
|
|||
}
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
mp_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
|
||||
if (!bundle->ncp.mp.active)
|
||||
/* Let someone else deal with it ! */
|
||||
return bp;
|
||||
|
||||
if (p == NULL) {
|
||||
log_Printf(LogWARN, "DecodePacket: Can't do MP inside MP !\n");
|
||||
mbuf_Free(bp);
|
||||
} else
|
||||
mp_Assemble(&bundle->ncp.mp, bp, p);
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void
|
||||
mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin,
|
||||
u_int32_t end)
|
||||
mp_Output(struct mp *mp, struct bundle *bundle, struct link *l,
|
||||
struct mbuf *m, u_int32_t begin, u_int32_t end)
|
||||
{
|
||||
struct mbuf *mo;
|
||||
|
||||
|
@ -548,8 +580,7 @@ mp_Output(struct mp *mp, struct link *l, struct mbuf *m, u_int32_t begin,
|
|||
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);
|
||||
link_PushPacket(l, mo, bundle, PRI_NORMAL, PROTO_MP);
|
||||
}
|
||||
|
||||
int
|
||||
|
@ -600,7 +631,7 @@ mp_FillQueues(struct bundle *bundle)
|
|||
/* this link has got stuff already queued. Let it continue */
|
||||
continue;
|
||||
|
||||
if (!link_QueueLen(&mp->link) && !ip_FlushPacket(&mp->link, bundle))
|
||||
if (!link_QueueLen(&mp->link) && !ip_PushPacket(&mp->link, bundle))
|
||||
/* Nothing else to send */
|
||||
break;
|
||||
|
||||
|
@ -624,7 +655,7 @@ mp_FillQueues(struct bundle *bundle)
|
|||
len -= mo->cnt;
|
||||
m = mbuf_Read(m, MBUF_CTOP(mo), mo->cnt);
|
||||
}
|
||||
mp_Output(mp, &dl->physical->link, mo, begin, end);
|
||||
mp_Output(mp, bundle, &dl->physical->link, mo, begin, end);
|
||||
begin = 0;
|
||||
}
|
||||
|
||||
|
@ -1028,7 +1059,7 @@ mp_LinkLost(struct mp *mp, struct datalink *dl)
|
|||
{
|
||||
if (mp->seq.min_in == dl->mp.seq)
|
||||
/* We've lost the link that's holding everything up ! */
|
||||
mp_Input(mp, NULL, NULL);
|
||||
mp_Assemble(mp, NULL, NULL);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: mp.h,v 1.3 1998/05/23 17:05:28 brian Exp $
|
||||
* $Id: mp.h,v 1.4 1998/08/25 17:48:43 brian Exp $
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
|
@ -126,7 +126,7 @@ 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 struct mbuf *mp_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
extern int mp_FillQueues(struct bundle *);
|
||||
extern int mp_SetDatalinkWeight(struct cmdargs const *);
|
||||
extern int mp_ShowStatus(struct cmdargs const *);
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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.22 1999/03/25 23:36:23 brian Exp $
|
||||
* $Id: alias_cmd.c,v 1.23 1999/04/26 08:54:32 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -24,6 +24,8 @@
|
|||
#else
|
||||
#include "alias.h"
|
||||
#endif
|
||||
#include "layer.h"
|
||||
#include "proto.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "log.h"
|
||||
|
@ -304,3 +306,96 @@ alias_Pptp(struct cmdargs const *arg)
|
|||
PacketAliasPptp(addr);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_PadMbuf(struct mbuf *bp, int type)
|
||||
{
|
||||
struct mbuf **last;
|
||||
int len;
|
||||
|
||||
for (last = &bp, len = 0; *last != NULL; last = &(*last)->next)
|
||||
len += (*last)->cnt;
|
||||
|
||||
len = MAX_MRU - len;
|
||||
*last = mbuf_Alloc(len, type);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
if (!bundle->AliasEnabled || *proto != PROTO_IP)
|
||||
return bp;
|
||||
|
||||
bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPQ));
|
||||
PacketAliasOut(MBUF_CTOP(bp), bp->cnt);
|
||||
bp->cnt = ntohs(((struct ip *)MBUF_CTOP(bp))->ip_len);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
alias_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
struct ip *pip, *piip;
|
||||
int ret;
|
||||
struct mbuf **last;
|
||||
char *fptr;
|
||||
|
||||
if (!bundle->AliasEnabled || *proto != PROTO_IP)
|
||||
return bp;
|
||||
|
||||
bp = mbuf_Contiguous(alias_PadMbuf(bp, MB_IPIN));
|
||||
pip = (struct ip *)MBUF_CTOP(bp);
|
||||
piip = (struct ip *)((char *)pip + (pip->ip_hl << 2));
|
||||
|
||||
if (pip->ip_p == IPPROTO_IGMP ||
|
||||
(pip->ip_p == IPPROTO_IPIP && IN_CLASSD(ntohl(piip->ip_dst.s_addr))))
|
||||
return bp;
|
||||
|
||||
ret = PacketAliasIn(MBUF_CTOP(bp), bp->cnt);
|
||||
|
||||
bp->cnt = ntohs(pip->ip_len);
|
||||
if (bp->cnt > MAX_MRU) {
|
||||
log_Printf(LogWARN, "alias_LayerPull: Problem with IP header length\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch (ret) {
|
||||
case PKT_ALIAS_OK:
|
||||
break;
|
||||
|
||||
case PKT_ALIAS_UNRESOLVED_FRAGMENT:
|
||||
/* Save the data for later */
|
||||
fptr = malloc(bp->cnt);
|
||||
mbuf_Read(bp, fptr, bp->cnt);
|
||||
PacketAliasSaveFragment(fptr);
|
||||
break;
|
||||
|
||||
case PKT_ALIAS_FOUND_HEADER_FRAGMENT:
|
||||
/* Fetch all the saved fragments and chain them on the end of `bp' */
|
||||
last = &bp->pnext;
|
||||
while ((fptr = PacketAliasGetFragment(MBUF_CTOP(bp))) != NULL) {
|
||||
PacketAliasFragmentIn(MBUF_CTOP(bp), fptr);
|
||||
*last = mbuf_Alloc(ntohs(((struct ip *)fptr)->ip_len), MB_IPIN);
|
||||
memcpy(MBUF_CTOP(*last), fptr, (*last)->cnt);
|
||||
free(fptr);
|
||||
last = &(*last)->pnext;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
break;
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct layer aliaslayer =
|
||||
{ LAYER_ALIAS, "alias", alias_LayerPush, alias_LayerPull };
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
* 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.9 1999/03/07 15:02:37 brian Exp $
|
||||
* $Id: alias_cmd.h,v 1.10 1999/03/07 18:13:44 brian Exp $
|
||||
*/
|
||||
|
||||
struct cmdargs;
|
||||
|
@ -11,3 +11,5 @@ extern int alias_RedirectPort(struct cmdargs const *);
|
|||
extern int alias_RedirectAddr(struct cmdargs const *);
|
||||
extern int alias_ProxyRule(struct cmdargs const *);
|
||||
extern int alias_Pptp(struct cmdargs const *);
|
||||
|
||||
extern struct layer aliaslayer;
|
||||
|
|
|
@ -18,7 +18,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: pap.c,v 1.33 1999/03/31 14:21:45 brian Exp $
|
||||
* $Id: pap.c,v 1.34 1999/04/01 11:05:23 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -32,6 +32,7 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "defs.h"
|
||||
|
@ -42,7 +43,7 @@
|
|||
#include "pap.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "async.h"
|
||||
#include "throughput.h"
|
||||
#include "ccp.h"
|
||||
|
@ -93,8 +94,7 @@ pap_Req(struct authinfo *authp)
|
|||
cp += namelen;
|
||||
*cp++ = keylen;
|
||||
memcpy(cp, bundle->cfg.auth.key, keylen);
|
||||
|
||||
hdlc_Output(&authp->physical->link, PRI_LINK, PROTO_PAP, bp);
|
||||
link_PushPacket(&authp->physical->link, bp, bundle, PRI_LINK, PROTO_PAP);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -117,7 +117,8 @@ SendPapCode(struct authinfo *authp, int code, const char *message)
|
|||
memcpy(cp, message, mlen);
|
||||
log_Printf(LogPHASE, "Pap Output: %s\n", papcodes[code]);
|
||||
|
||||
hdlc_Output(&authp->physical->link, PRI_LINK, PROTO_PAP, bp);
|
||||
link_PushPacket(&authp->physical->link, bp, authp->physical->dl->bundle,
|
||||
PRI_LINK, PROTO_PAP);
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -150,38 +151,45 @@ pap_Init(struct authinfo *pap, struct physical *p)
|
|||
auth_Init(pap, p, pap_Req, pap_Success, pap_Failure);
|
||||
}
|
||||
|
||||
void
|
||||
pap_Input(struct physical *p, struct mbuf *bp)
|
||||
struct mbuf *
|
||||
pap_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
struct authinfo *authp = &p->dl->pap;
|
||||
u_char nlen, klen, *key;
|
||||
|
||||
if (bundle_Phase(p->dl->bundle) != PHASE_NETWORK &&
|
||||
bundle_Phase(p->dl->bundle) != PHASE_AUTHENTICATE) {
|
||||
if (p == NULL) {
|
||||
log_Printf(LogERROR, "pap_Input: Not a physical link - dropped\n");
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (bundle_Phase(bundle) != PHASE_NETWORK &&
|
||||
bundle_Phase(bundle) != PHASE_AUTHENTICATE) {
|
||||
log_Printf(LogPHASE, "Unexpected pap input - dropped !\n");
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((bp = auth_ReadHeader(authp, bp)) == NULL &&
|
||||
ntohs(authp->in.hdr.length) == 0) {
|
||||
log_Printf(LogWARN, "Pap Input: Truncated header !\n");
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (authp->in.hdr.code == 0 || authp->in.hdr.code > MAXPAPCODE) {
|
||||
log_Printf(LogPHASE, "Pap Input: %d: Bad PAP code !\n", authp->in.hdr.code);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (authp->in.hdr.code != PAP_REQUEST && authp->id != authp->in.hdr.id &&
|
||||
Enabled(p->dl->bundle, OPT_IDCHECK)) {
|
||||
Enabled(bundle, OPT_IDCHECK)) {
|
||||
/* Wrong conversation dude ! */
|
||||
log_Printf(LogPHASE, "Pap Input: %s dropped (got id %d, not %d)\n",
|
||||
papcodes[authp->in.hdr.code], authp->in.hdr.id, authp->id);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
return NULL;
|
||||
}
|
||||
authp->id = authp->in.hdr.id; /* We respond with this id */
|
||||
|
||||
|
@ -212,12 +220,12 @@ pap_Input(struct physical *p, struct mbuf *bp)
|
|||
key[klen] = '\0';
|
||||
|
||||
#ifndef NORADIUS
|
||||
if (*p->dl->bundle->radius.cfg.file)
|
||||
radius_Authenticate(&p->dl->bundle->radius, authp, authp->in.name,
|
||||
if (*bundle->radius.cfg.file)
|
||||
radius_Authenticate(&bundle->radius, authp, authp->in.name,
|
||||
key, NULL);
|
||||
else
|
||||
#endif
|
||||
if (auth_Validate(p->dl->bundle, authp->in.name, key, p))
|
||||
if (auth_Validate(bundle, authp->in.name, key, p))
|
||||
pap_Success(authp);
|
||||
else
|
||||
pap_Failure(authp);
|
||||
|
@ -246,4 +254,5 @@ pap_Input(struct physical *p, struct mbuf *bp)
|
|||
}
|
||||
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -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.8 1999/02/02 09:35:17 brian Exp $
|
||||
* $Id: pap.h,v 1.9 1999/02/06 02:54:47 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -29,4 +29,4 @@ struct physical;
|
|||
struct authinfo;
|
||||
|
||||
extern void pap_Init(struct authinfo *, struct physical *);
|
||||
extern void pap_Input(struct physical *, struct mbuf *);
|
||||
extern struct mbuf *pap_Input(struct bundle *, struct link *, struct mbuf *);
|
||||
|
|
|
@ -16,51 +16,593 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: physical.c,v 1.7 1999/01/10 01:26:29 brian Exp $
|
||||
* $Id: physical.c,v 1.8 1999/04/27 00:23:56 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.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 <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/tty.h> /* TIOCOUTQ */
|
||||
#include <sys/uio.h>
|
||||
#include <sys/wait.h>
|
||||
#include <time.h>
|
||||
#include <unistd.h>
|
||||
#include <utmp.h>
|
||||
#include <sys/tty.h>
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#include <sys/ioctl.h>
|
||||
#include <util.h>
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include "layer.h"
|
||||
#ifndef NOALIAS
|
||||
#include "alias_cmd.h"
|
||||
#endif
|
||||
#include "proto.h"
|
||||
#include "acf.h"
|
||||
#include "vjcomp.h"
|
||||
#include "defs.h"
|
||||
#include "command.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);
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "lcp.h"
|
||||
#include "throughput.h"
|
||||
#include "sync.h"
|
||||
#include "async.h"
|
||||
#include "iplist.h"
|
||||
#include "slcompress.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#ifndef NORADIUS
|
||||
#include "radius.h"
|
||||
#endif
|
||||
#include "bundle.h"
|
||||
#include "prompt.h"
|
||||
#include "chat.h"
|
||||
#include "auth.h"
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "tcp.h"
|
||||
#include "exec.h"
|
||||
#include "tty.h"
|
||||
|
||||
|
||||
int
|
||||
physical_GetFD(struct physical *phys) {
|
||||
return phys->fd;
|
||||
}
|
||||
static int physical_DescriptorWrite(struct descriptor *, struct bundle *,
|
||||
const fd_set *);
|
||||
static void physical_DescriptorRead(struct descriptor *, struct bundle *,
|
||||
const fd_set *);
|
||||
|
||||
int
|
||||
physical_IsSync(struct physical *phys) {
|
||||
return phys->cfg.speed == 0;
|
||||
}
|
||||
static const struct device *handlers[] = {
|
||||
&ttydevice, &tcpdevice, &execdevice
|
||||
};
|
||||
|
||||
const char *physical_GetDevice(struct physical *phys)
|
||||
#define NHANDLERS (sizeof handlers / sizeof handlers[0])
|
||||
|
||||
static int
|
||||
physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
||||
int *n)
|
||||
{
|
||||
return phys->name.full;
|
||||
return physical_doUpdateSet(d, r, w, e, n, 0);
|
||||
}
|
||||
|
||||
struct physical *
|
||||
physical_Create(struct datalink *dl, int type)
|
||||
{
|
||||
struct physical *p;
|
||||
|
||||
p = (struct physical *)malloc(sizeof(struct physical));
|
||||
if (!p)
|
||||
return NULL;
|
||||
|
||||
p->link.type = PHYSICAL_LINK;
|
||||
p->link.name = dl->name;
|
||||
p->link.len = sizeof *p;
|
||||
throughput_init(&p->link.throughput);
|
||||
|
||||
memset(p->link.Queue, '\0', sizeof p->link.Queue);
|
||||
memset(p->link.proto_in, '\0', sizeof p->link.proto_in);
|
||||
memset(p->link.proto_out, '\0', sizeof p->link.proto_out);
|
||||
link_EmptyStack(&p->link);
|
||||
|
||||
memset(&p->Timer, '\0', sizeof p->Timer);
|
||||
p->handler = NULL;
|
||||
p->desc.type = PHYSICAL_DESCRIPTOR;
|
||||
p->desc.UpdateSet = physical_UpdateSet;
|
||||
p->desc.IsSet = physical_IsSet;
|
||||
p->desc.Read = physical_DescriptorRead;
|
||||
p->desc.Write = physical_DescriptorWrite;
|
||||
p->type = type;
|
||||
|
||||
hdlc_Init(&p->hdlc, &p->link.lcp);
|
||||
async_Init(&p->async);
|
||||
|
||||
p->fd = -1;
|
||||
p->out = NULL;
|
||||
p->connect_count = 0;
|
||||
p->dl = dl;
|
||||
p->input.sz = 0;
|
||||
*p->name.full = '\0';
|
||||
p->name.base = p->name.full;
|
||||
|
||||
p->Utmp = 0;
|
||||
p->session_owner = (pid_t)-1;
|
||||
|
||||
p->cfg.rts_cts = MODEM_CTSRTS;
|
||||
p->cfg.speed = MODEM_SPEED;
|
||||
p->cfg.parity = CS8;
|
||||
memcpy(p->cfg.devlist, MODEM_LIST, sizeof MODEM_LIST);
|
||||
p->cfg.ndev = NMODEMS;
|
||||
p->cfg.cd.required = 0;
|
||||
p->cfg.cd.delay = DEF_CDDELAY;
|
||||
|
||||
lcp_Init(&p->link.lcp, dl->bundle, &p->link, &dl->fsmp);
|
||||
ccp_Init(&p->link.ccp, dl->bundle, &p->link, &dl->fsmp);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
static const struct parity {
|
||||
const char *name;
|
||||
const char *name1;
|
||||
int set;
|
||||
} validparity[] = {
|
||||
{ "even", "P_EVEN", CS7 | PARENB },
|
||||
{ "odd", "P_ODD", CS7 | PARENB | PARODD },
|
||||
{ "none", "P_ZERO", CS8 },
|
||||
{ NULL, 0 },
|
||||
};
|
||||
|
||||
static int
|
||||
GetParityValue(const char *str)
|
||||
{
|
||||
const struct parity *pp;
|
||||
|
||||
for (pp = validparity; pp->name; pp++) {
|
||||
if (strcasecmp(pp->name, str) == 0 ||
|
||||
strcasecmp(pp->name1, str) == 0) {
|
||||
return pp->set;
|
||||
}
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
physical_SetParity(struct physical *p, const char *str)
|
||||
{
|
||||
struct termios rstio;
|
||||
int val;
|
||||
|
||||
val = GetParityValue(str);
|
||||
if (val > 0) {
|
||||
p->cfg.parity = val;
|
||||
if (p->fd >= 0) {
|
||||
tcgetattr(p->fd, &rstio);
|
||||
rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
|
||||
rstio.c_cflag |= val;
|
||||
tcsetattr(p->fd, TCSADRAIN, &rstio);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
log_Printf(LogWARN, "%s: %s: Invalid parity\n", p->link.name, str);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int
|
||||
physical_GetSpeed(struct physical *p)
|
||||
{
|
||||
if (p->handler && p->handler->speed)
|
||||
return (*p->handler->speed)(p);
|
||||
|
||||
return 115200;
|
||||
}
|
||||
|
||||
int
|
||||
physical_SetSpeed(struct physical *p, int speed)
|
||||
{
|
||||
if (IntToSpeed(speed) != B0) {
|
||||
p->cfg.speed = speed;
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
physical_Raw(struct physical *p)
|
||||
{
|
||||
if (p->handler && p->handler->raw)
|
||||
return (*p->handler->raw)(p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
void
|
||||
physical_Offline(struct physical *p)
|
||||
{
|
||||
if (p->handler && p->handler->offline)
|
||||
(*p->handler->offline)(p);
|
||||
log_Printf(LogPHASE, "%s: Disconnected!\n", p->link.name);
|
||||
}
|
||||
|
||||
static void
|
||||
physical_ReallyClose(struct physical *p)
|
||||
{
|
||||
int newsid;
|
||||
|
||||
log_Printf(LogDEBUG, "%s: Really close %d\n", p->link.name, p->fd);
|
||||
if (p->fd >= 0) {
|
||||
timer_Stop(&p->Timer);
|
||||
if (p->Utmp) {
|
||||
ID0logout(p->name.base);
|
||||
p->Utmp = 0;
|
||||
}
|
||||
newsid = tcgetpgrp(p->fd) == getpgrp();
|
||||
close(p->fd);
|
||||
p->fd = -1;
|
||||
log_SetTtyCommandMode(p->dl);
|
||||
throughput_stop(&p->link.throughput);
|
||||
throughput_log(&p->link.throughput, LogPHASE, p->link.name);
|
||||
if (p->session_owner != (pid_t)-1) {
|
||||
ID0kill(p->session_owner, SIGHUP);
|
||||
p->session_owner = (pid_t)-1;
|
||||
}
|
||||
if (newsid)
|
||||
bundle_setsid(p->dl->bundle, 0);
|
||||
if (p->handler && p->handler->postclose)
|
||||
(*p->handler->postclose)(p);
|
||||
p->handler = NULL;
|
||||
}
|
||||
*p->name.full = '\0';
|
||||
p->name.base = p->name.full;
|
||||
}
|
||||
|
||||
void
|
||||
physical_Close(struct physical *p)
|
||||
{
|
||||
if (p->fd < 0)
|
||||
return;
|
||||
|
||||
log_Printf(LogDEBUG, "%s: Close\n", p->link.name);
|
||||
|
||||
if (p->handler && p->handler->cooked)
|
||||
(*p->handler->cooked)(p);
|
||||
|
||||
physical_ReallyClose(p);
|
||||
}
|
||||
|
||||
void
|
||||
physical_Destroy(struct physical *p)
|
||||
{
|
||||
physical_Close(p);
|
||||
free(p);
|
||||
}
|
||||
|
||||
static int
|
||||
physical_DescriptorWrite(struct descriptor *d, struct bundle *bundle,
|
||||
const fd_set *fdset)
|
||||
{
|
||||
struct physical *p = descriptor2physical(d);
|
||||
int nw, result = 0;
|
||||
|
||||
if (p->out == NULL)
|
||||
p->out = link_Dequeue(&p->link);
|
||||
|
||||
if (p->out) {
|
||||
nw = physical_Write(p, MBUF_CTOP(p->out), p->out->cnt);
|
||||
log_Printf(LogDEBUG, "%s: DescriptorWrite: wrote %d(%d) to %d\n",
|
||||
p->link.name, nw, p->out->cnt, p->fd);
|
||||
if (nw > 0) {
|
||||
p->out->cnt -= nw;
|
||||
p->out->offset += nw;
|
||||
if (p->out->cnt == 0)
|
||||
p->out = mbuf_FreeSeg(p->out);
|
||||
result = 1;
|
||||
} else if (nw < 0) {
|
||||
if (errno != EAGAIN) {
|
||||
log_Printf(LogPHASE, "%s: write (%d): %s\n", p->link.name,
|
||||
p->fd, strerror(errno));
|
||||
datalink_Down(p->dl, CLOSE_NORMAL);
|
||||
}
|
||||
result = 1;
|
||||
}
|
||||
/* else we shouldn't really have been called ! select() is broken ! */
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
int
|
||||
physical_ShowStatus(struct cmdargs const *arg)
|
||||
{
|
||||
struct physical *p = arg->cx->physical;
|
||||
const char *dev;
|
||||
int n;
|
||||
|
||||
prompt_Printf(arg->prompt, "Name: %s\n", p->link.name);
|
||||
prompt_Printf(arg->prompt, " State: ");
|
||||
if (p->fd < 0)
|
||||
prompt_Printf(arg->prompt, "closed\n");
|
||||
else if (p->handler && p->handler->openinfo)
|
||||
prompt_Printf(arg->prompt, "open (%s)\n", (*p->handler->openinfo)(p));
|
||||
else
|
||||
prompt_Printf(arg->prompt, "open\n");
|
||||
|
||||
prompt_Printf(arg->prompt, " Device: %s",
|
||||
*p->name.full ? p->name.full :
|
||||
p->type == PHYS_DIRECT ? "unknown" : "N/A");
|
||||
if (p->session_owner != (pid_t)-1)
|
||||
prompt_Printf(arg->prompt, " (session owner: %d)", (int)p->session_owner);
|
||||
|
||||
prompt_Printf(arg->prompt, "\n Link Type: %s\n", mode2Nam(p->type));
|
||||
prompt_Printf(arg->prompt, " Connect Count: %d\n", p->connect_count);
|
||||
#ifdef TIOCOUTQ
|
||||
if (p->fd >= 0 && ioctl(p->fd, TIOCOUTQ, &n) >= 0)
|
||||
prompt_Printf(arg->prompt, " Physical outq: %d\n", n);
|
||||
#endif
|
||||
|
||||
prompt_Printf(arg->prompt, " Queued Packets: %d\n",
|
||||
link_QueueLen(&p->link));
|
||||
prompt_Printf(arg->prompt, " Phone Number: %s\n", arg->cx->phone.chosen);
|
||||
|
||||
prompt_Printf(arg->prompt, "\nDefaults:\n");
|
||||
|
||||
prompt_Printf(arg->prompt, " Device List: ");
|
||||
dev = p->cfg.devlist;
|
||||
for (n = 0; n < p->cfg.ndev; n++) {
|
||||
if (n)
|
||||
prompt_Printf(arg->prompt, ", ");
|
||||
prompt_Printf(arg->prompt, "\"%s\"", dev);
|
||||
dev += strlen(dev) + 1;
|
||||
}
|
||||
|
||||
prompt_Printf(arg->prompt, "\n Characteristics: ");
|
||||
if (physical_IsSync(arg->cx->physical))
|
||||
prompt_Printf(arg->prompt, "sync");
|
||||
else
|
||||
prompt_Printf(arg->prompt, "%dbps", p->cfg.speed);
|
||||
|
||||
switch (p->cfg.parity & CSIZE) {
|
||||
case CS7:
|
||||
prompt_Printf(arg->prompt, ", cs7");
|
||||
break;
|
||||
case CS8:
|
||||
prompt_Printf(arg->prompt, ", cs8");
|
||||
break;
|
||||
}
|
||||
if (p->cfg.parity & PARENB) {
|
||||
if (p->cfg.parity & PARODD)
|
||||
prompt_Printf(arg->prompt, ", odd parity");
|
||||
else
|
||||
prompt_Printf(arg->prompt, ", even parity");
|
||||
} else
|
||||
prompt_Printf(arg->prompt, ", no parity");
|
||||
|
||||
prompt_Printf(arg->prompt, ", CTS/RTS %s\n", (p->cfg.rts_cts ? "on" : "off"));
|
||||
|
||||
prompt_Printf(arg->prompt, " CD check delay: %d second%s",
|
||||
p->cfg.cd.delay, p->cfg.cd.delay == 1 ? "" : "s");
|
||||
if (p->cfg.cd.required)
|
||||
prompt_Printf(arg->prompt, " (required!)\n\n");
|
||||
else
|
||||
prompt_Printf(arg->prompt, "\n\n");
|
||||
|
||||
throughput_disp(&p->link.throughput, arg->prompt);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
physical_DescriptorRead(struct descriptor *d, struct bundle *bundle,
|
||||
const fd_set *fdset)
|
||||
{
|
||||
struct physical *p = descriptor2physical(d);
|
||||
u_char *rbuff;
|
||||
int n, found;
|
||||
|
||||
rbuff = p->input.buf + p->input.sz;
|
||||
|
||||
/* something to read */
|
||||
n = physical_Read(p, rbuff, sizeof p->input.buf - p->input.sz);
|
||||
log_Printf(LogDEBUG, "%s: DescriptorRead: read %d/%d from %d\n",
|
||||
p->link.name, n, (int)(sizeof p->input.buf - p->input.sz), p->fd);
|
||||
if (n <= 0) {
|
||||
if (n < 0)
|
||||
log_Printf(LogPHASE, "%s: read (%d): %s\n", p->link.name, p->fd,
|
||||
strerror(errno));
|
||||
else
|
||||
log_Printf(LogPHASE, "%s: read (%d): Got zero bytes\n",
|
||||
p->link.name, p->fd);
|
||||
datalink_Down(p->dl, CLOSE_NORMAL);
|
||||
return;
|
||||
}
|
||||
|
||||
log_DumpBuff(LogASYNC, "ReadFromModem", rbuff, n);
|
||||
rbuff -= p->input.sz;
|
||||
n += p->input.sz;
|
||||
|
||||
if (p->link.lcp.fsm.state <= ST_CLOSED) {
|
||||
if (p->type != PHYS_DEDICATED) {
|
||||
found = hdlc_Detect((u_char const **)&rbuff, n, physical_IsSync(p));
|
||||
if (rbuff != p->input.buf)
|
||||
log_WritePrompts(p->dl, "%.*s", (int)(rbuff - p->input.buf),
|
||||
p->input.buf);
|
||||
p->input.sz = n - (rbuff - p->input.buf);
|
||||
|
||||
if (found) {
|
||||
/* LCP packet is detected. Turn ourselves into packet mode */
|
||||
log_Printf(LogPHASE, "%s: PPP packet detected, coming up\n",
|
||||
p->link.name);
|
||||
log_SetTtyCommandMode(p->dl);
|
||||
datalink_Up(p->dl, 0, 1);
|
||||
link_PullPacket(&p->link, rbuff, p->input.sz, bundle);
|
||||
p->input.sz = 0;
|
||||
} else
|
||||
bcopy(rbuff, p->input.buf, p->input.sz);
|
||||
} else
|
||||
/* In -dedicated mode, we just discard input until LCP is started */
|
||||
p->input.sz = 0;
|
||||
} else if (n > 0)
|
||||
link_PullPacket(&p->link, rbuff, n, bundle);
|
||||
}
|
||||
|
||||
struct physical *
|
||||
iov2physical(struct datalink *dl, struct iovec *iov, int *niov, int maxiov,
|
||||
int fd)
|
||||
{
|
||||
struct physical *p;
|
||||
int len, h;
|
||||
|
||||
p = (struct physical *)iov[(*niov)++].iov_base;
|
||||
p->link.name = dl->name;
|
||||
throughput_init(&p->link.throughput);
|
||||
memset(&p->Timer, '\0', sizeof p->Timer);
|
||||
memset(p->link.Queue, '\0', sizeof p->link.Queue);
|
||||
|
||||
p->desc.UpdateSet = physical_UpdateSet;
|
||||
p->desc.IsSet = physical_IsSet;
|
||||
p->desc.Read = physical_DescriptorRead;
|
||||
p->desc.Write = physical_DescriptorWrite;
|
||||
p->type = PHYS_DIRECT;
|
||||
p->dl = dl;
|
||||
len = strlen(_PATH_DEV);
|
||||
p->name.base = strncmp(p->name.full, _PATH_DEV, len) ?
|
||||
p->name.full : p->name.full + len;
|
||||
p->out = NULL;
|
||||
p->connect_count = 1;
|
||||
|
||||
if (p->handler) {
|
||||
for (h = 0; h < NHANDLERS; h++)
|
||||
if (p->handler == (const struct device *)(long)handlers[h]->type) {
|
||||
p->handler = handlers[h];
|
||||
break;
|
||||
}
|
||||
if (h == NHANDLERS) {
|
||||
log_Printf(LogERROR, "iov2physical: Can't find device hander !\n");
|
||||
p->handler = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
p->link.lcp.fsm.bundle = dl->bundle;
|
||||
p->link.lcp.fsm.link = &p->link;
|
||||
memset(&p->link.lcp.fsm.FsmTimer, '\0', sizeof p->link.lcp.fsm.FsmTimer);
|
||||
memset(&p->link.lcp.fsm.OpenTimer, '\0', sizeof p->link.lcp.fsm.OpenTimer);
|
||||
memset(&p->link.lcp.fsm.StoppedTimer, '\0',
|
||||
sizeof p->link.lcp.fsm.StoppedTimer);
|
||||
p->link.lcp.fsm.parent = &dl->fsmp;
|
||||
lcp_SetupCallbacks(&p->link.lcp);
|
||||
|
||||
p->link.ccp.fsm.bundle = dl->bundle;
|
||||
p->link.ccp.fsm.link = &p->link;
|
||||
/* Our in.state & out.state are NULL (no link-level ccp yet) */
|
||||
memset(&p->link.ccp.fsm.FsmTimer, '\0', sizeof p->link.ccp.fsm.FsmTimer);
|
||||
memset(&p->link.ccp.fsm.OpenTimer, '\0', sizeof p->link.ccp.fsm.OpenTimer);
|
||||
memset(&p->link.ccp.fsm.StoppedTimer, '\0',
|
||||
sizeof p->link.ccp.fsm.StoppedTimer);
|
||||
p->link.ccp.fsm.parent = &dl->fsmp;
|
||||
ccp_SetupCallbacks(&p->link.ccp);
|
||||
|
||||
p->hdlc.lqm.owner = &p->link.lcp;
|
||||
p->hdlc.ReportTimer.state = TIMER_STOPPED;
|
||||
p->hdlc.lqm.timer.state = TIMER_STOPPED;
|
||||
|
||||
p->fd = fd;
|
||||
|
||||
if (p->hdlc.lqm.method && p->hdlc.lqm.timer.load)
|
||||
lqr_reStart(&p->link.lcp);
|
||||
hdlc_StartTimer(&p->hdlc);
|
||||
|
||||
throughput_start(&p->link.throughput, "physical throughput",
|
||||
Enabled(dl->bundle, OPT_THROUGHPUT));
|
||||
if (p->handler && p->handler->restored)
|
||||
(*p->handler->restored)(p);
|
||||
|
||||
return p;
|
||||
}
|
||||
|
||||
int
|
||||
physical2iov(struct physical *p, struct iovec *iov, int *niov, int maxiov,
|
||||
pid_t newpid)
|
||||
{
|
||||
if (p) {
|
||||
hdlc_StopTimer(&p->hdlc);
|
||||
lqr_StopTimer(p);
|
||||
timer_Stop(&p->link.lcp.fsm.FsmTimer);
|
||||
timer_Stop(&p->link.ccp.fsm.FsmTimer);
|
||||
timer_Stop(&p->link.lcp.fsm.OpenTimer);
|
||||
timer_Stop(&p->link.ccp.fsm.OpenTimer);
|
||||
timer_Stop(&p->link.lcp.fsm.StoppedTimer);
|
||||
timer_Stop(&p->link.ccp.fsm.StoppedTimer);
|
||||
if (p->handler)
|
||||
p->handler = (const struct device *)(long)p->handler->type;
|
||||
if (p->Timer.state != TIMER_STOPPED) {
|
||||
timer_Stop(&p->Timer);
|
||||
p->Timer.state = TIMER_RUNNING; /* Special - see iov2physical() */
|
||||
}
|
||||
if (tcgetpgrp(p->fd) == getpgrp())
|
||||
p->session_owner = getpid(); /* So I'll eventually get HUP'd */
|
||||
timer_Stop(&p->link.throughput.Timer);
|
||||
physical_ChangedPid(p, newpid);
|
||||
}
|
||||
|
||||
if (*niov >= maxiov) {
|
||||
log_Printf(LogERROR, "physical2iov: No room for physical !\n");
|
||||
if (p)
|
||||
free(p);
|
||||
return -1;
|
||||
}
|
||||
|
||||
iov[*niov].iov_base = p ? p : malloc(sizeof *p);
|
||||
iov[*niov].iov_len = sizeof *p;
|
||||
(*niov)++;
|
||||
|
||||
return p ? p->fd : 0;
|
||||
}
|
||||
|
||||
void
|
||||
physical_ChangedPid(struct physical *p, pid_t newpid)
|
||||
{
|
||||
if (p->fd >= 0 && p->type != PHYS_DIRECT) {
|
||||
int res;
|
||||
|
||||
if ((res = ID0uu_lock_txfr(p->name.base, newpid)) != UU_LOCK_OK)
|
||||
log_Printf(LogPHASE, "uu_lock_txfr: %s\n", uu_lockerr(res));
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
physical_IsSync(struct physical *p)
|
||||
{
|
||||
return p->cfg.speed == 0;
|
||||
}
|
||||
|
||||
const char *physical_GetDevice(struct physical *p)
|
||||
{
|
||||
return p->name.full;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -78,44 +620,36 @@ physical_SetDeviceList(struct physical *p, int argc, const char *const *argv)
|
|||
p->cfg.ndev = f;
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
physical_SetSync(struct physical *p)
|
||||
{
|
||||
p->cfg.speed = 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
physical_SetRtsCts(struct physical *phys, int enable) {
|
||||
phys->cfg.rts_cts = enable ? 1 : 0;
|
||||
physical_SetRtsCts(struct physical *p, int enable)
|
||||
{
|
||||
p->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);
|
||||
physical_Read(struct physical *p, void *buf, size_t nbytes)
|
||||
{
|
||||
return read(p->fd, buf, nbytes);
|
||||
}
|
||||
|
||||
ssize_t
|
||||
physical_Write(struct physical *phys, const void *buf, size_t nbytes) {
|
||||
return write(phys->fd, buf, nbytes);
|
||||
physical_Write(struct physical *p, const void *buf, size_t nbytes)
|
||||
{
|
||||
return write(p->fd, buf, nbytes);
|
||||
}
|
||||
|
||||
int
|
||||
physical_UpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
||||
int *n, int force)
|
||||
physical_doUpdateSet(struct descriptor *d, fd_set *r, fd_set *w, fd_set *e,
|
||||
int *n, int force)
|
||||
{
|
||||
struct physical *p = descriptor2physical(d);
|
||||
int sets;
|
||||
|
@ -179,34 +713,21 @@ physical_IsSet(struct descriptor *d, const fd_set *fdset)
|
|||
}
|
||||
|
||||
void
|
||||
physical_Login(struct physical *phys, const char *name)
|
||||
physical_Login(struct physical *p, const char *name)
|
||||
{
|
||||
if (phys->type == PHYS_DIRECT && phys->isatty) {
|
||||
if (phys->Utmp)
|
||||
log_Printf(LogERROR, "Oops, already logged in on %s\n", phys->name.base);
|
||||
else {
|
||||
struct utmp ut;
|
||||
const char *connstr;
|
||||
if (p->type == PHYS_DIRECT && !p->Utmp) {
|
||||
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;
|
||||
memset(&ut, 0, sizeof ut);
|
||||
time(&ut.ut_time);
|
||||
strncpy(ut.ut_name, name, sizeof ut.ut_name);
|
||||
strncpy(ut.ut_line, p->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);
|
||||
p->Utmp = 1;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -233,3 +754,94 @@ physical_DeleteQueue(struct physical *p)
|
|||
}
|
||||
link_DeleteQueue(&p->link);
|
||||
}
|
||||
|
||||
void
|
||||
physical_SetDevice(struct physical *p, const char *name)
|
||||
{
|
||||
int len = strlen(_PATH_DEV);
|
||||
|
||||
strncpy(p->name.full, name, sizeof p->name.full - 1);
|
||||
p->name.full[sizeof p->name.full - 1] = '\0';
|
||||
p->name.base = *p->name.full == '!' ? p->name.full + 1 :
|
||||
strncmp(p->name.full, _PATH_DEV, len) ?
|
||||
p->name.full : p->name.full + len;
|
||||
}
|
||||
|
||||
static void
|
||||
physical_Found(struct physical *p)
|
||||
{
|
||||
throughput_start(&p->link.throughput, "physical throughput",
|
||||
Enabled(p->dl->bundle, OPT_THROUGHPUT));
|
||||
p->connect_count++;
|
||||
p->input.sz = 0;
|
||||
|
||||
log_Printf(LogPHASE, "%s: Connected!\n", p->link.name);
|
||||
}
|
||||
|
||||
int
|
||||
physical_Open(struct physical *p, struct bundle *bundle)
|
||||
{
|
||||
int devno, h;
|
||||
char *dev;
|
||||
|
||||
if (p->fd >= 0)
|
||||
log_Printf(LogDEBUG, "%s: Open: Modem is already open!\n", p->link.name);
|
||||
/* We're going back into "term" mode */
|
||||
else if (p->type == PHYS_DIRECT) {
|
||||
if (tty_OpenStdin(p)) {
|
||||
physical_Found(p);
|
||||
p->handler = &ttydevice;
|
||||
} else {
|
||||
log_Printf(LogDEBUG, "%s: physical_Open: stdin is not a tty\n",
|
||||
p->link.name);
|
||||
physical_SetDevice(p, "");
|
||||
physical_SetupStack(p, 0);
|
||||
physical_Found(p);
|
||||
return p->fd = STDIN_FILENO;
|
||||
}
|
||||
} else {
|
||||
dev = p->cfg.devlist;
|
||||
devno = 0;
|
||||
while (devno < p->cfg.ndev && p->fd < 0) {
|
||||
physical_SetDevice(p, dev);
|
||||
|
||||
for (h = 0; h < NHANDLERS; h++)
|
||||
if (handlers[h]->open && (*handlers[h]->open)(p)) {
|
||||
p->handler = handlers[h];
|
||||
physical_Found(p);
|
||||
}
|
||||
|
||||
if (p->fd < 0)
|
||||
log_Printf(LogWARN, "%s: Device (%s) must begin with a '/',"
|
||||
" a '!' or be a host:port pair\n", p->link.name,
|
||||
p->name.full);
|
||||
dev += strlen(dev) + 1;
|
||||
devno++;
|
||||
}
|
||||
}
|
||||
|
||||
return p->fd;
|
||||
}
|
||||
|
||||
void
|
||||
physical_SetupStack(struct physical *p, int forceasync)
|
||||
{
|
||||
link_EmptyStack(&p->link);
|
||||
if (!forceasync && physical_IsSync(p))
|
||||
link_Stack(&p->link, &synclayer);
|
||||
else {
|
||||
link_Stack(&p->link, &asynclayer);
|
||||
link_Stack(&p->link, &hdlclayer);
|
||||
}
|
||||
link_Stack(&p->link, &acflayer);
|
||||
link_Stack(&p->link, &protolayer);
|
||||
link_Stack(&p->link, &lqrlayer);
|
||||
link_Stack(&p->link, &ccplayer);
|
||||
link_Stack(&p->link, &vjlayer);
|
||||
#ifndef NOALIAS
|
||||
link_Stack(&p->link, &aliaslayer);
|
||||
#endif
|
||||
if (forceasync && physical_IsSync(p))
|
||||
log_Printf(LogWARN, "Sync device setting ignored for ``%s'' device\n",
|
||||
p->handler ? p->handler->name : "unknown");
|
||||
}
|
||||
|
|
|
@ -16,11 +16,34 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: physical.h,v 1.7 1999/04/03 11:54:00 brian Exp $
|
||||
* $Id: physical.h,v 1.8 1999/04/27 00:23:57 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
struct datalink;
|
||||
struct bundle;
|
||||
struct iovec;
|
||||
struct physical;
|
||||
struct bundle;
|
||||
struct ccp;
|
||||
struct cmdargs;
|
||||
|
||||
#define TTY_DEVICE 1
|
||||
#define TCP_DEVICE 2
|
||||
#define EXEC_DEVICE 3
|
||||
|
||||
struct device {
|
||||
int type;
|
||||
const char *name;
|
||||
int (*open)(struct physical *);
|
||||
int (*raw)(struct physical *);
|
||||
void (*offline)(struct physical *);
|
||||
void (*cooked)(struct physical *);
|
||||
void (*postclose)(struct physical *);
|
||||
void (*restored)(struct physical *);
|
||||
int (*speed)(struct physical *);
|
||||
const char *(*openinfo)(struct physical *);
|
||||
};
|
||||
|
||||
struct physical {
|
||||
struct link link;
|
||||
|
@ -30,7 +53,6 @@ struct physical {
|
|||
struct hdlc hdlc; /* Our hdlc state */
|
||||
int fd; /* File descriptor for this device */
|
||||
int mbits; /* Current DCD status */
|
||||
unsigned isatty : 1;
|
||||
struct mbuf *out; /* mbuf that suffered a short write */
|
||||
int connect_count;
|
||||
struct datalink *dl; /* my owner */
|
||||
|
@ -41,20 +63,18 @@ struct physical {
|
|||
} input;
|
||||
|
||||
struct {
|
||||
char full[40];
|
||||
char full[40]; /* Our current device name */
|
||||
char *base;
|
||||
} name;
|
||||
|
||||
unsigned Utmp : 1; /* Are we in utmp ? */
|
||||
pid_t session_owner; /* HUP this when closing the link */
|
||||
|
||||
/* 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 */
|
||||
unsigned rts_cts : 1; /* Is rts/cts enabled ? */
|
||||
unsigned parity; /* What parity is enabled? (tty flags) */
|
||||
unsigned speed; /* tty speed */
|
||||
|
||||
char devlist[LINE_LEN]; /* NUL separated list of devices */
|
||||
int ndev; /* number of devices in list */
|
||||
struct {
|
||||
|
@ -66,6 +86,8 @@ struct physical {
|
|||
struct termios ios; /* To be able to reset from raw mode */
|
||||
|
||||
struct pppTimer Timer; /* CD checks */
|
||||
|
||||
const struct device *handler; /* device specific handlers */
|
||||
};
|
||||
|
||||
#define field2phys(fp, name) \
|
||||
|
@ -77,32 +99,36 @@ struct physical {
|
|||
#define descriptor2physical(d) \
|
||||
((d)->type == PHYSICAL_DESCRIPTOR ? field2phys(d, desc) : NULL)
|
||||
|
||||
extern int physical_GetFD(struct physical *);
|
||||
extern struct physical *physical_Create(struct datalink *, int);
|
||||
extern int physical_Open(struct physical *, struct bundle *);
|
||||
extern int physical_Raw(struct physical *);
|
||||
extern int physical_GetSpeed(struct physical *);
|
||||
extern int physical_SetSpeed(struct physical *, int);
|
||||
extern int physical_SetParity(struct physical *, const char *);
|
||||
extern int physical_SetRtsCts(struct physical *, int);
|
||||
extern void physical_SetSync(struct physical *);
|
||||
extern int physical_ShowStatus(struct cmdargs const *);
|
||||
extern void physical_Offline(struct physical *);
|
||||
extern void physical_Close(struct physical *);
|
||||
extern void physical_Destroy(struct physical *);
|
||||
extern struct physical *iov2physical(struct datalink *, struct iovec *, int *,
|
||||
int, int);
|
||||
extern int physical2iov(struct physical *, struct iovec *, int *, int, pid_t);
|
||||
extern void physical_ChangedPid(struct physical *, pid_t);
|
||||
|
||||
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 void physical_SetDevice(struct physical *, const char *);
|
||||
|
||||
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_doUpdateSet(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);
|
||||
extern void physical_DeleteQueue(struct physical *);
|
||||
extern void physical_SetupStack(struct physical *, int);
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: ppp.8,v 1.165 1999/04/23 13:45:50 brian Exp $
|
||||
.\" $Id: ppp.8,v 1.166 1999/05/02 08:52:50 brian Exp $
|
||||
.Dd 20 September 1995
|
||||
.nr XX \w'\fC00'
|
||||
.Os FreeBSD
|
||||
|
@ -40,8 +40,8 @@ also be optionally password protected for security.
|
|||
.It Supports both manual and automatic dialing.
|
||||
Interactive mode has a
|
||||
.Dq term
|
||||
command which enables you to talk to your modem directly. When your
|
||||
modem is connected to the remote peer and it starts to talk
|
||||
command which enables you to talk to the device directly. When you
|
||||
are connected to the remote peer and it starts to talk
|
||||
.Em PPP ,
|
||||
.Nm
|
||||
detects it and switches to packet mode automatically. Once you have
|
||||
|
@ -490,9 +490,9 @@ on even parity when logging in:
|
|||
ppp ON awfulhak> set parity even
|
||||
.Ed
|
||||
.Pp
|
||||
You can now see what your current modem settings look like:
|
||||
You can now see what your current device settings look like:
|
||||
.Bd -literal -offset indent
|
||||
ppp ON awfulhak> show modem
|
||||
ppp ON awfulhak> show physical
|
||||
Name: deflink
|
||||
State: closed
|
||||
Device: N/A
|
||||
|
@ -511,7 +511,7 @@ Overall 0 bytes/sec
|
|||
ppp ON awfulhak>
|
||||
.Ed
|
||||
.Pp
|
||||
The term command can now be used to talk directly to your modem:
|
||||
The term command can now be used to talk directly to the device:
|
||||
.Bd -literal -offset indent
|
||||
ppp ON awfulhak> term
|
||||
at
|
||||
|
@ -590,7 +590,7 @@ to help you.
|
|||
When the link is established, the show command can be used to see how
|
||||
things are going:
|
||||
.Bd -literal -offset indent
|
||||
PPP ON awfulhak> show modem
|
||||
PPP ON awfulhak> show physical
|
||||
* Modem related information is shown here *
|
||||
PPP ON awfulhak> show ccp
|
||||
* CCP (compression) related information is shown here *
|
||||
|
@ -2527,7 +2527,7 @@ layer shuts down, and is also available using the
|
|||
command. Throughput statistics are available at the
|
||||
.Dq IPCP
|
||||
and
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
levels.
|
||||
.It utmp
|
||||
Default: Enabled. Normally, when a user is authenticated using PAP or
|
||||
|
@ -2863,13 +2863,13 @@ If you wish to pause
|
|||
while the command executes, use the
|
||||
.Dq shell
|
||||
command instead.
|
||||
.It clear modem|ipcp Op current|overall|peak...
|
||||
.It clear physical|ipcp Op current|overall|peak...
|
||||
Clear the specified throughput values at either the
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
or
|
||||
.Dq ipcp
|
||||
level. If
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
is specified, context must be given (see the
|
||||
.Dq link
|
||||
command below). If no second argument is given, all values are
|
||||
|
@ -2956,7 +2956,7 @@ are terminated). If
|
|||
.Sq lcp
|
||||
is specified, the
|
||||
.Em LCP
|
||||
layer is terminated but the modem is not brought offline and the link
|
||||
layer is terminated but the device is not brought offline and the link
|
||||
is not closed. If
|
||||
.Sq ccp
|
||||
is specified, only the relevant compression layer(s) are terminated.
|
||||
|
@ -3587,7 +3587,7 @@ To do this, the first character of the expect or send string is an
|
|||
exclamation mark
|
||||
.Pq Dq \&! .
|
||||
When the command is executed, standard input and standard output are
|
||||
directed to the modem device (see the
|
||||
directed to the open device (see the
|
||||
.Dq set device
|
||||
command), and standard error is read by
|
||||
.Nm
|
||||
|
@ -3750,7 +3750,7 @@ section on
|
|||
.Sx PACKET FILTERING
|
||||
above for further details.
|
||||
.It set hangup Ar chat-script
|
||||
This specifies the chat script that will be used to reset the modem
|
||||
This specifies the chat script that will be used to reset the device
|
||||
before it is closed. It should not normally be necessary, but can
|
||||
be used for devices that fail to reset themselves properly on close.
|
||||
.It set help|? Op Ar command
|
||||
|
@ -4351,7 +4351,7 @@ Show a list of available logical links.
|
|||
Show the current log values.
|
||||
.It show mem
|
||||
Show current memory statistics.
|
||||
.It show modem
|
||||
.It show physical
|
||||
Show low level link information.
|
||||
.It show mp
|
||||
Show Multi-link information.
|
||||
|
@ -4370,10 +4370,10 @@ Show the current version number of
|
|||
.Pp
|
||||
.It term
|
||||
Go into terminal mode. Characters typed at the keyboard are sent to
|
||||
the modem. Characters read from the modem are displayed on the
|
||||
screen. When a
|
||||
.Nm
|
||||
peer is detected on the other side of the modem,
|
||||
the device. Characters read from the device are displayed on the
|
||||
screen. When a remote
|
||||
.Em PPP
|
||||
peer is detected,
|
||||
.Nm
|
||||
automatically enables Packet Mode and goes back into command mode.
|
||||
.El
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
.\" $Id: ppp.8,v 1.165 1999/04/23 13:45:50 brian Exp $
|
||||
.\" $Id: ppp.8,v 1.166 1999/05/02 08:52:50 brian Exp $
|
||||
.Dd 20 September 1995
|
||||
.nr XX \w'\fC00'
|
||||
.Os FreeBSD
|
||||
|
@ -40,8 +40,8 @@ also be optionally password protected for security.
|
|||
.It Supports both manual and automatic dialing.
|
||||
Interactive mode has a
|
||||
.Dq term
|
||||
command which enables you to talk to your modem directly. When your
|
||||
modem is connected to the remote peer and it starts to talk
|
||||
command which enables you to talk to the device directly. When you
|
||||
are connected to the remote peer and it starts to talk
|
||||
.Em PPP ,
|
||||
.Nm
|
||||
detects it and switches to packet mode automatically. Once you have
|
||||
|
@ -490,9 +490,9 @@ on even parity when logging in:
|
|||
ppp ON awfulhak> set parity even
|
||||
.Ed
|
||||
.Pp
|
||||
You can now see what your current modem settings look like:
|
||||
You can now see what your current device settings look like:
|
||||
.Bd -literal -offset indent
|
||||
ppp ON awfulhak> show modem
|
||||
ppp ON awfulhak> show physical
|
||||
Name: deflink
|
||||
State: closed
|
||||
Device: N/A
|
||||
|
@ -511,7 +511,7 @@ Overall 0 bytes/sec
|
|||
ppp ON awfulhak>
|
||||
.Ed
|
||||
.Pp
|
||||
The term command can now be used to talk directly to your modem:
|
||||
The term command can now be used to talk directly to the device:
|
||||
.Bd -literal -offset indent
|
||||
ppp ON awfulhak> term
|
||||
at
|
||||
|
@ -590,7 +590,7 @@ to help you.
|
|||
When the link is established, the show command can be used to see how
|
||||
things are going:
|
||||
.Bd -literal -offset indent
|
||||
PPP ON awfulhak> show modem
|
||||
PPP ON awfulhak> show physical
|
||||
* Modem related information is shown here *
|
||||
PPP ON awfulhak> show ccp
|
||||
* CCP (compression) related information is shown here *
|
||||
|
@ -2527,7 +2527,7 @@ layer shuts down, and is also available using the
|
|||
command. Throughput statistics are available at the
|
||||
.Dq IPCP
|
||||
and
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
levels.
|
||||
.It utmp
|
||||
Default: Enabled. Normally, when a user is authenticated using PAP or
|
||||
|
@ -2863,13 +2863,13 @@ If you wish to pause
|
|||
while the command executes, use the
|
||||
.Dq shell
|
||||
command instead.
|
||||
.It clear modem|ipcp Op current|overall|peak...
|
||||
.It clear physical|ipcp Op current|overall|peak...
|
||||
Clear the specified throughput values at either the
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
or
|
||||
.Dq ipcp
|
||||
level. If
|
||||
.Dq modem
|
||||
.Dq physical
|
||||
is specified, context must be given (see the
|
||||
.Dq link
|
||||
command below). If no second argument is given, all values are
|
||||
|
@ -2956,7 +2956,7 @@ are terminated). If
|
|||
.Sq lcp
|
||||
is specified, the
|
||||
.Em LCP
|
||||
layer is terminated but the modem is not brought offline and the link
|
||||
layer is terminated but the device is not brought offline and the link
|
||||
is not closed. If
|
||||
.Sq ccp
|
||||
is specified, only the relevant compression layer(s) are terminated.
|
||||
|
@ -3587,7 +3587,7 @@ To do this, the first character of the expect or send string is an
|
|||
exclamation mark
|
||||
.Pq Dq \&! .
|
||||
When the command is executed, standard input and standard output are
|
||||
directed to the modem device (see the
|
||||
directed to the open device (see the
|
||||
.Dq set device
|
||||
command), and standard error is read by
|
||||
.Nm
|
||||
|
@ -3750,7 +3750,7 @@ section on
|
|||
.Sx PACKET FILTERING
|
||||
above for further details.
|
||||
.It set hangup Ar chat-script
|
||||
This specifies the chat script that will be used to reset the modem
|
||||
This specifies the chat script that will be used to reset the device
|
||||
before it is closed. It should not normally be necessary, but can
|
||||
be used for devices that fail to reset themselves properly on close.
|
||||
.It set help|? Op Ar command
|
||||
|
@ -4351,7 +4351,7 @@ Show a list of available logical links.
|
|||
Show the current log values.
|
||||
.It show mem
|
||||
Show current memory statistics.
|
||||
.It show modem
|
||||
.It show physical
|
||||
Show low level link information.
|
||||
.It show mp
|
||||
Show Multi-link information.
|
||||
|
@ -4370,10 +4370,10 @@ Show the current version number of
|
|||
.Pp
|
||||
.It term
|
||||
Go into terminal mode. Characters typed at the keyboard are sent to
|
||||
the modem. Characters read from the modem are displayed on the
|
||||
screen. When a
|
||||
.Nm
|
||||
peer is detected on the other side of the modem,
|
||||
the device. Characters read from the device are displayed on the
|
||||
screen. When a remote
|
||||
.Em PPP
|
||||
peer is detected,
|
||||
.Nm
|
||||
automatically enables Packet Mode and goes back into command mode.
|
||||
.El
|
||||
|
|
|
@ -26,15 +26,17 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: pred.c,v 1.23 1999/03/11 01:49:15 brian Exp $
|
||||
* $Id: pred.c,v 1.24 1999/03/16 01:24:23 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "defs.h"
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
|
@ -166,8 +168,8 @@ Pred1InitOutput(struct lcp_opt *o)
|
|||
return state;
|
||||
}
|
||||
|
||||
static int
|
||||
Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
||||
static struct mbuf *
|
||||
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;
|
||||
|
@ -183,10 +185,10 @@ Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
cp = bufp;
|
||||
*wp++ = *cp++ = orglen >> 8;
|
||||
*wp++ = *cp++ = orglen & 0377;
|
||||
*cp++ = proto >> 8;
|
||||
*cp++ = proto & 0377;
|
||||
*cp++ = *proto >> 8;
|
||||
*cp++ = *proto & 0377;
|
||||
mbuf_Read(bp, cp, orglen - 2);
|
||||
fcs = hdlc_Fcs(INITFCS, bufp, 2 + orglen);
|
||||
fcs = hdlc_Fcs(bufp, 2 + orglen);
|
||||
fcs = ~fcs;
|
||||
|
||||
len = compress(state, bufp + 2, wp, orglen);
|
||||
|
@ -205,8 +207,8 @@ Pred1Output(void *v, struct ccp *ccp, struct link *l, int pri, u_short proto,
|
|||
*wp++ = fcs & 0377;
|
||||
*wp++ = fcs >> 8;
|
||||
mwp->cnt = wp - MBUF_CTOP(mwp);
|
||||
hdlc_Output(l, PRI_NORMAL, ccp_Proto(ccp), mwp);
|
||||
return 1;
|
||||
*proto = ccp_Proto(ccp);
|
||||
return mwp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
|
@ -255,7 +257,7 @@ Pred1Input(void *v, struct ccp *ccp, u_short *proto, struct mbuf *bp)
|
|||
}
|
||||
*pp++ = *cp++; /* CRC */
|
||||
*pp++ = *cp++;
|
||||
fcs = hdlc_Fcs(INITFCS, bufp, wp->cnt = pp - bufp);
|
||||
fcs = hdlc_Fcs(bufp, wp->cnt = pp - bufp);
|
||||
if (fcs == GOODFCS) {
|
||||
wp->offset += 2; /* skip length */
|
||||
wp->cnt -= 4; /* skip length & CRC */
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: prompt.c,v 1.13 1999/01/28 01:56:34 brian Exp $
|
||||
* $Id: prompt.c,v 1.14 1999/04/03 11:54:00 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -41,6 +41,7 @@
|
|||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "command.h"
|
||||
|
|
|
@ -0,0 +1,110 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "acf.h"
|
||||
#include "defs.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "mbuf.h"
|
||||
#include "proto.h"
|
||||
#include "lcp.h"
|
||||
#include "throughput.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
|
||||
int
|
||||
proto_WrapperOctets(struct lcp *lcp, u_short proto)
|
||||
{
|
||||
return (lcp->his_protocomp && !(proto & 0xff00)) ? 1 : 2;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
proto_Prepend(struct mbuf *bp, u_short proto, unsigned comp, int extra)
|
||||
{
|
||||
u_char cp[2];
|
||||
|
||||
cp[0] = proto >> 8;
|
||||
cp[1] = proto & 0xff;
|
||||
|
||||
if (comp && cp[0] == 0)
|
||||
bp = mbuf_Prepend(bp, cp + 1, 1, extra);
|
||||
else
|
||||
bp = mbuf_Prepend(bp, cp, 2, extra);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
proto_LayerPush(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
int pri, u_short *proto)
|
||||
{
|
||||
bp = proto_Prepend(bp, *proto, l->lcp.his_protocomp,
|
||||
acf_WrapperOctets(&l->lcp, *proto));
|
||||
link_ProtocolRecord(l, *proto, PROTO_OUT);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
proto_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
u_char cp[2];
|
||||
size_t got;
|
||||
|
||||
if ((got = mbuf_View(bp, cp, 2)) == 0) {
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
*proto = cp[0];
|
||||
if (!(*proto & 1)) {
|
||||
if (got == 1) {
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
bp = mbuf_Read(bp, cp, 2);
|
||||
*proto = (*proto << 8) | cp[1];
|
||||
} else
|
||||
bp = mbuf_Read(bp, cp, 1);
|
||||
|
||||
link_ProtocolRecord(l, *proto, PROTO_IN);
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct layer protolayer =
|
||||
{ LAYER_PROTO, "proto", proto_LayerPush, proto_LayerPull };
|
|
@ -15,9 +15,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: lcpproto.h,v 1.11 1998/05/21 21:46:05 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
* $Id:$
|
||||
*/
|
||||
|
||||
/*
|
||||
|
@ -41,3 +39,10 @@
|
|||
#define PROTO_CBCP 0xc029
|
||||
#define PROTO_LQR 0xc025
|
||||
#define PROTO_CHAP 0xc223
|
||||
|
||||
struct lcp;
|
||||
|
||||
extern int proto_WrapperOctets(struct lcp *, u_short);
|
||||
struct mbuf *proto_Prepend(struct mbuf *, u_short, unsigned, int);
|
||||
|
||||
extern struct layer protolayer;
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: radius.c,v 1.4 1999/03/03 23:00:41 brian Exp $
|
||||
* $Id: radius.c,v 1.5 1999/04/21 08:13:09 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -42,6 +42,7 @@
|
|||
#include <sys/time.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "log.h"
|
||||
#include "descriptor.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: route.c,v 1.54 1998/10/22 02:32:50 brian Exp $
|
||||
* $Id: route.c,v 1.55 1999/01/28 01:56:34 brian Exp $
|
||||
*
|
||||
*/
|
||||
|
||||
|
@ -40,6 +40,7 @@
|
|||
#include <sys/sysctl.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: slcompress.c,v 1.23 1999/03/31 13:33:43 brian Exp $
|
||||
* $Id: slcompress.c,v 1.24 1999/03/31 13:44:07 brian Exp $
|
||||
*
|
||||
* Van Jacobson (van@helios.ee.lbl.gov), Dec 31, 1989:
|
||||
* - Initial distribution.
|
||||
|
@ -34,6 +34,7 @@
|
|||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "command.h"
|
||||
#include "mbuf.h"
|
||||
|
@ -459,9 +460,8 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp,
|
|||
* 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_state || comp->last_recv == 255) {
|
||||
if (*cp > max_state || comp->last_recv == 255)
|
||||
goto bad;
|
||||
}
|
||||
|
||||
comp->flags &= ~SLF_TOSS;
|
||||
comp->last_recv = *cp++;
|
||||
|
@ -478,8 +478,6 @@ sl_uncompress_tcp(u_char ** bufp, int len, u_int type, struct slcompress *comp,
|
|||
}
|
||||
cs = &comp->rstate[comp->last_recv];
|
||||
hlen = cs->cs_ip.ip_hl << 2;
|
||||
if (hlen == 0)
|
||||
goto bad; /* We've been pointed at a not-yet-used slot ! */
|
||||
th = (struct tcphdr *) & ((u_char *) & cs->cs_ip)[hlen];
|
||||
th->th_sum = htons((*cp << 8) | cp[1]);
|
||||
cp += 2;
|
||||
|
|
|
@ -0,0 +1,68 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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/types.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "sync.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "async.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
|
||||
static struct mbuf *
|
||||
sync_LayerPull(struct bundle *b, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
struct physical *p = link2physical(l);
|
||||
|
||||
if (!p)
|
||||
log_Printf(LogERROR, "Can't Pull a sync packet from a logical link\n");
|
||||
else {
|
||||
/* Normally done by the HDLC layer */
|
||||
p->hdlc.lqm.SaveInOctets += mbuf_Length(bp) + 1;
|
||||
p->hdlc.lqm.SaveInPackets++;
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
struct layer synclayer = { LAYER_SYNC, "sync", NULL, sync_LayerPull };
|
|
@ -0,0 +1,29 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
extern struct layer synclayer;
|
|
@ -17,7 +17,7 @@
|
|||
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
|
||||
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
|
||||
*
|
||||
* $Id: systems.c,v 1.41 1999/02/02 09:35:30 brian Exp $
|
||||
* $Id: systems.c,v 1.42 1999/03/09 20:39:03 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -28,6 +28,7 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "defs.h"
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "sync.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "async.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "tcp.h"
|
||||
|
||||
static int
|
||||
OpenConnection(const char *name, char *host, char *port)
|
||||
{
|
||||
struct sockaddr_in dest;
|
||||
int sock;
|
||||
struct servent *sp;
|
||||
|
||||
dest.sin_family = AF_INET;
|
||||
dest.sin_addr.s_addr = inet_addr(host);
|
||||
dest.sin_addr = GetIpAddr(host);
|
||||
if (dest.sin_addr.s_addr == INADDR_NONE) {
|
||||
log_Printf(LogWARN, "%s: %s: unknown host\n", name, host);
|
||||
return (-1);
|
||||
}
|
||||
dest.sin_port = htons(atoi(port));
|
||||
if (dest.sin_port == 0) {
|
||||
sp = getservbyname(port, "tcp");
|
||||
if (sp) {
|
||||
dest.sin_port = sp->s_port;
|
||||
} else {
|
||||
log_Printf(LogWARN, "%s: %s: unknown service\n", name, port);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
log_Printf(LogPHASE, "%s: Connecting to %s:%s\n", name, host, port);
|
||||
|
||||
sock = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (sock < 0) {
|
||||
return (sock);
|
||||
}
|
||||
if (connect(sock, (struct sockaddr *)&dest, sizeof dest) < 0) {
|
||||
log_Printf(LogWARN, "%s: connect: %s\n", name, strerror(errno));
|
||||
close(sock);
|
||||
return (-1);
|
||||
}
|
||||
return (sock);
|
||||
}
|
||||
|
||||
static int
|
||||
tcp_Open(struct physical *p)
|
||||
{
|
||||
char *cp, *host, *port;
|
||||
|
||||
if ((cp = strchr(p->name.full, ':')) != NULL) {
|
||||
*cp = '\0';
|
||||
host = p->name.full;
|
||||
port = cp + 1;
|
||||
if (*host && *port) {
|
||||
p->fd = OpenConnection(p->link.name, host, port);
|
||||
*cp = ':'; /* Don't destroy name.full */
|
||||
if (p->fd >= 0) {
|
||||
log_Printf(LogDEBUG, "%s: Opened socket %s\n", p->link.name,
|
||||
p->name.full);
|
||||
physical_SetupStack(p, 1);
|
||||
return 1;
|
||||
}
|
||||
} else
|
||||
*cp = ':'; /* Don't destroy name.full */
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
const struct device tcpdevice = {
|
||||
TTY_DEVICE,
|
||||
"tcp",
|
||||
tcp_Open,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL,
|
||||
NULL
|
||||
};
|
|
@ -0,0 +1,29 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
extern const struct device tcpdevice;
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: throughput.c,v 1.7 1998/06/12 17:45:41 brian Exp $
|
||||
* $Id: throughput.c,v 1.8 1998/06/12 20:12:26 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
|
@ -65,16 +65,16 @@ throughput_disp(struct pppThroughput *t, struct prompt *prompt)
|
|||
prompt_Printf(prompt, "Connect time: %d secs\n", secs_up);
|
||||
if (secs_up == 0)
|
||||
secs_up = 1;
|
||||
prompt_Printf(prompt, "%ld octets in, %ld octets out\n",
|
||||
prompt_Printf(prompt, "%qu octets in, %qu octets out\n",
|
||||
t->OctetsIn, t->OctetsOut);
|
||||
if (t->rolling) {
|
||||
prompt_Printf(prompt, " overall %5ld bytes/sec\n",
|
||||
prompt_Printf(prompt, " overall %6qu 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 on %s",
|
||||
prompt_Printf(prompt, " currently %6qu bytes/sec\n", t->OctetsPerSecond);
|
||||
prompt_Printf(prompt, " peak %6qu bytes/sec on %s",
|
||||
t->BestOctetsPerSecond, ctime(&t->BestOctetsPerSecondTime));
|
||||
} else
|
||||
prompt_Printf(prompt, "Overall %ld bytes/sec\n",
|
||||
prompt_Printf(prompt, "Overall %qu bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
}
|
||||
|
||||
|
@ -87,19 +87,19 @@ throughput_log(struct pppThroughput *t, int level, const char *title)
|
|||
|
||||
secs_up = t->uptime ? time(NULL) - t->uptime : 0;
|
||||
if (title)
|
||||
log_Printf(level, "%s: Connect time: %d secs: %ld octets in, %ld octets"
|
||||
log_Printf(level, "%s: Connect time: %d secs: %qu octets in, %qu octets"
|
||||
" out\n", title, secs_up, t->OctetsIn, t->OctetsOut);
|
||||
else
|
||||
log_Printf(level, "Connect time: %d secs: %ld octets in, %ld octets out\n",
|
||||
log_Printf(level, "Connect time: %d secs: %qu octets in, %qu octets out\n",
|
||||
secs_up, t->OctetsIn, t->OctetsOut);
|
||||
if (secs_up == 0)
|
||||
secs_up = 1;
|
||||
if (t->rolling)
|
||||
log_Printf(level, " total %ld bytes/sec, peak %d bytes/sec on %s",
|
||||
log_Printf(level, " total %qu bytes/sec, peak %qu bytes/sec on %s",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up, t->BestOctetsPerSecond,
|
||||
ctime(&t->BestOctetsPerSecondTime));
|
||||
else
|
||||
log_Printf(level, " total %ld bytes/sec\n",
|
||||
log_Printf(level, " total %qu bytes/sec\n",
|
||||
(t->OctetsIn+t->OctetsOut)/secs_up);
|
||||
}
|
||||
}
|
||||
|
@ -108,7 +108,7 @@ static void
|
|||
throughput_sampler(void *v)
|
||||
{
|
||||
struct pppThroughput *t = (struct pppThroughput *)v;
|
||||
u_long old;
|
||||
unsigned long long old;
|
||||
|
||||
timer_Stop(&t->Timer);
|
||||
|
||||
|
@ -148,13 +148,13 @@ throughput_stop(struct pppThroughput *t)
|
|||
}
|
||||
|
||||
void
|
||||
throughput_addin(struct pppThroughput *t, int n)
|
||||
throughput_addin(struct pppThroughput *t, long long n)
|
||||
{
|
||||
t->OctetsIn += n;
|
||||
}
|
||||
|
||||
void
|
||||
throughput_addout(struct pppThroughput *t, int n)
|
||||
throughput_addout(struct pppThroughput *t, long long n)
|
||||
{
|
||||
t->OctetsOut += n;
|
||||
}
|
||||
|
@ -174,14 +174,14 @@ throughput_clear(struct pppThroughput *t, int clear_type, struct prompt *prompt)
|
|||
int secs_up;
|
||||
|
||||
secs_up = t->uptime ? time(NULL) - t->uptime : 1;
|
||||
prompt_Printf(prompt, "overall cleared (was %5ld bytes/sec)\n",
|
||||
prompt_Printf(prompt, "overall cleared (was %6qu bytes/sec)\n",
|
||||
(t->OctetsIn + t->OctetsOut)/secs_up);
|
||||
t->OctetsIn = t->OctetsOut = 0;
|
||||
t->uptime = time(NULL);
|
||||
}
|
||||
|
||||
if (clear_type & THROUGHPUT_CURRENT) {
|
||||
prompt_Printf(prompt, "current cleared (was %5d bytes/sec)\n",
|
||||
prompt_Printf(prompt, "current cleared (was %6qu bytes/sec)\n",
|
||||
t->OctetsPerSecond);
|
||||
t->OctetsPerSecond = 0;
|
||||
}
|
||||
|
@ -193,7 +193,7 @@ throughput_clear(struct pppThroughput *t, int clear_type, struct prompt *prompt)
|
|||
last = time_buf + strlen(time_buf);
|
||||
if (last > time_buf && *--last == '\n')
|
||||
*last = '\0';
|
||||
prompt_Printf(prompt, "peak cleared (was %5d bytes/sec on %s)\n",
|
||||
prompt_Printf(prompt, "peak cleared (was %6qu bytes/sec on %s)\n",
|
||||
t->BestOctetsPerSecond, time_buf);
|
||||
t->BestOctetsPerSecond = 0;
|
||||
t->BestOctetsPerSecondTime = time(NULL);
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: throughput.h,v 1.4 1998/06/09 18:49:10 brian Exp $
|
||||
* $Id: throughput.h,v 1.5 1998/06/12 20:12:26 brian Exp $
|
||||
*/
|
||||
|
||||
#define SAMPLE_PERIOD 5
|
||||
|
@ -36,11 +36,11 @@
|
|||
|
||||
struct pppThroughput {
|
||||
time_t uptime;
|
||||
u_long OctetsIn;
|
||||
u_long OctetsOut;
|
||||
u_long SampleOctets[SAMPLE_PERIOD];
|
||||
int OctetsPerSecond;
|
||||
int BestOctetsPerSecond;
|
||||
unsigned long long OctetsIn;
|
||||
unsigned long long OctetsOut;
|
||||
unsigned long long SampleOctets[SAMPLE_PERIOD];
|
||||
unsigned long long OctetsPerSecond;
|
||||
unsigned long long BestOctetsPerSecond;
|
||||
time_t BestOctetsPerSecondTime;
|
||||
int nSample;
|
||||
unsigned rolling : 1;
|
||||
|
@ -52,6 +52,6 @@ extern void throughput_disp(struct pppThroughput *, struct prompt *);
|
|||
extern void throughput_log(struct pppThroughput *, int, const char *);
|
||||
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);
|
||||
extern void throughput_addin(struct pppThroughput *, long long);
|
||||
extern void throughput_addout(struct pppThroughput *, long long);
|
||||
extern void throughput_clear(struct pppThroughput *, int, struct prompt *);
|
||||
|
|
|
@ -0,0 +1,446 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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 <sys/socket.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>
|
||||
#if defined(__OpenBSD__) || defined(__NetBSD__)
|
||||
#include <sys/ioctl.h>
|
||||
#include <util.h>
|
||||
#else
|
||||
#include <libutil.h>
|
||||
#endif
|
||||
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <paths.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <sys/wait.h>
|
||||
#include <termios.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "defs.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "id.h"
|
||||
#include "sync.h"
|
||||
#include "timer.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
#include "throughput.h"
|
||||
#include "fsm.h"
|
||||
#include "lcp.h"
|
||||
#include "ccp.h"
|
||||
#include "link.h"
|
||||
#include "async.h"
|
||||
#include "slcompress.h"
|
||||
#include "iplist.h"
|
||||
#include "ipcp.h"
|
||||
#include "filter.h"
|
||||
#include "descriptor.h"
|
||||
#include "physical.h"
|
||||
#include "mp.h"
|
||||
#ifndef NORADIUS
|
||||
#include "radius.h"
|
||||
#endif
|
||||
#include "chat.h"
|
||||
#include "command.h"
|
||||
#include "bundle.h"
|
||||
#include "prompt.h"
|
||||
#include "auth.h"
|
||||
#include "chap.h"
|
||||
#include "cbcp.h"
|
||||
#include "datalink.h"
|
||||
#include "tty.h"
|
||||
|
||||
#define Online(p) ((p)->mbits & TIOCM_CD)
|
||||
|
||||
static int
|
||||
tty_Lock(struct physical *p, int tunno)
|
||||
{
|
||||
int res;
|
||||
FILE *lockfile;
|
||||
char fn[MAXPATHLEN];
|
||||
|
||||
if (*p->name.full != '/')
|
||||
return 0;
|
||||
|
||||
if (p->type != PHYS_DIRECT &&
|
||||
(res = ID0uu_lock(p->name.base)) != UU_LOCK_OK) {
|
||||
if (res == UU_LOCK_INUSE)
|
||||
log_Printf(LogPHASE, "%s: %s is in use\n", p->link.name, p->name.full);
|
||||
else
|
||||
log_Printf(LogPHASE, "%s: %s is in use: uu_lock: %s\n",
|
||||
p->link.name, p->name.full, uu_lockerr(res));
|
||||
return (-1);
|
||||
}
|
||||
|
||||
snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base);
|
||||
lockfile = ID0fopen(fn, "w");
|
||||
if (lockfile != NULL) {
|
||||
fprintf(lockfile, "%s%d\n", TUN_NAME, tunno);
|
||||
fclose(lockfile);
|
||||
}
|
||||
#ifndef RELEASE_CRUNCH
|
||||
else
|
||||
log_Printf(LogALERT, "%s: Can't create %s: %s\n",
|
||||
p->link.name, fn, strerror(errno));
|
||||
#endif
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_Unlock(struct physical *p)
|
||||
{
|
||||
char fn[MAXPATHLEN];
|
||||
|
||||
if (*p->name.full != '/')
|
||||
return;
|
||||
|
||||
snprintf(fn, sizeof fn, "%s%s.if", _PATH_VARRUN, p->name.base);
|
||||
#ifndef RELEASE_CRUNCH
|
||||
if (ID0unlink(fn) == -1)
|
||||
log_Printf(LogALERT, "%s: Can't remove %s: %s\n",
|
||||
p->link.name, fn, strerror(errno));
|
||||
#else
|
||||
ID0unlink(fn);
|
||||
#endif
|
||||
|
||||
if (p->type != PHYS_DIRECT && ID0uu_unlock(p->name.base) == -1)
|
||||
log_Printf(LogALERT, "%s: Can't uu_unlock %s\n", p->link.name, fn);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_SetupDevice(struct physical *p)
|
||||
{
|
||||
struct termios rstio;
|
||||
int oldflag;
|
||||
|
||||
tcgetattr(p->fd, &rstio);
|
||||
p->ios = rstio;
|
||||
|
||||
log_Printf(LogDEBUG, "%s: tty_SetupDevice: physical (get): fd = %d,"
|
||||
" iflag = %lx, oflag = %lx, cflag = %lx\n", p->link.name, p->fd,
|
||||
(u_long)rstio.c_iflag, (u_long)rstio.c_oflag,
|
||||
(u_long)rstio.c_cflag);
|
||||
|
||||
cfmakeraw(&rstio);
|
||||
if (p->cfg.rts_cts)
|
||||
rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
|
||||
else {
|
||||
rstio.c_cflag |= CLOCAL;
|
||||
rstio.c_iflag |= IXOFF;
|
||||
}
|
||||
rstio.c_iflag |= IXON;
|
||||
if (p->type != PHYS_DEDICATED)
|
||||
rstio.c_cflag |= HUPCL;
|
||||
|
||||
if (p->type != PHYS_DIRECT) {
|
||||
/* Change tty speed when we're not in -direct mode */
|
||||
rstio.c_cflag &= ~(CSIZE | PARODD | PARENB);
|
||||
rstio.c_cflag |= p->cfg.parity;
|
||||
if (cfsetspeed(&rstio, IntToSpeed(p->cfg.speed)) == -1)
|
||||
log_Printf(LogWARN, "%s: %s: Unable to set speed to %d\n",
|
||||
p->link.name, p->name.full, p->cfg.speed);
|
||||
}
|
||||
tcsetattr(p->fd, TCSADRAIN, &rstio);
|
||||
log_Printf(LogDEBUG, "%s: physical (put): iflag = %lx, oflag = %lx, "
|
||||
"cflag = %lx\n", p->link.name, (u_long)rstio.c_iflag,
|
||||
(u_long)rstio.c_oflag, (u_long)rstio.c_cflag);
|
||||
|
||||
if (ioctl(p->fd, TIOCMGET, &p->mbits) == -1) {
|
||||
if (p->type != PHYS_DIRECT) {
|
||||
log_Printf(LogWARN, "%s: Open: Cannot get physical status: %s\n",
|
||||
p->link.name, strerror(errno));
|
||||
physical_Close(p);
|
||||
return;
|
||||
} else
|
||||
p->mbits = TIOCM_CD;
|
||||
}
|
||||
log_Printf(LogDEBUG, "%s: Open: physical control = %o\n",
|
||||
p->link.name, p->mbits);
|
||||
|
||||
oldflag = fcntl(p->fd, F_GETFL, 0);
|
||||
if (oldflag < 0) {
|
||||
log_Printf(LogWARN, "%s: Open: Cannot get physical flags: %s\n",
|
||||
p->link.name, strerror(errno));
|
||||
physical_Close(p);
|
||||
return;
|
||||
} else
|
||||
fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
|
||||
|
||||
physical_SetupStack(p, 0);
|
||||
}
|
||||
|
||||
static int
|
||||
tty_Open(struct physical *p)
|
||||
{
|
||||
if (*p->name.full == '/') {
|
||||
p->mbits = 0;
|
||||
if (tty_Lock(p, p->dl->bundle->unit) != -1) {
|
||||
p->fd = ID0open(p->name.full, O_RDWR | O_NONBLOCK);
|
||||
if (p->fd < 0) {
|
||||
log_Printf(LogPHASE, "%s: Open(\"%s\"): %s\n",
|
||||
p->link.name, p->name.full, strerror(errno));
|
||||
tty_Unlock(p);
|
||||
} else if (!isatty(p->fd)) {
|
||||
log_Printf(LogPHASE, "%s: Open(\"%s\"): Not a tty\n",
|
||||
p->link.name, p->name.full);
|
||||
close(p->fd);
|
||||
p->fd = -1;
|
||||
tty_Unlock(p);
|
||||
} else {
|
||||
log_Printf(LogDEBUG, "%s: Opened %s\n", p->link.name, p->name.full);
|
||||
tty_SetupDevice(p);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return p->fd >= 0;
|
||||
}
|
||||
|
||||
int
|
||||
tty_OpenStdin(struct physical *p)
|
||||
{
|
||||
if (isatty(STDIN_FILENO)) {
|
||||
p->mbits = 0;
|
||||
log_Printf(LogDEBUG, "%s: tty_Open: stdin is a tty\n", p->link.name);
|
||||
physical_SetDevice(p, ttyname(STDIN_FILENO));
|
||||
if (tty_Lock(p, p->dl->bundle->unit) == -1)
|
||||
close(STDIN_FILENO);
|
||||
else {
|
||||
p->fd = STDIN_FILENO;
|
||||
tty_SetupDevice(p);
|
||||
}
|
||||
}
|
||||
|
||||
return p->fd >= 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* tty_Timeout() watches the DCD signal and mentions it if it's status
|
||||
* changes.
|
||||
*/
|
||||
static void
|
||||
tty_Timeout(void *data)
|
||||
{
|
||||
struct physical *p = data;
|
||||
int ombits, change;
|
||||
|
||||
timer_Stop(&p->Timer);
|
||||
p->Timer.load = SECTICKS; /* Once a second please */
|
||||
timer_Start(&p->Timer);
|
||||
ombits = p->mbits;
|
||||
|
||||
if (p->fd >= 0) {
|
||||
if (ioctl(p->fd, TIOCMGET, &p->mbits) < 0) {
|
||||
log_Printf(LogPHASE, "%s: ioctl error (%s)!\n", p->link.name,
|
||||
strerror(errno));
|
||||
datalink_Down(p->dl, CLOSE_NORMAL);
|
||||
timer_Stop(&p->Timer);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
p->mbits = 0;
|
||||
|
||||
if (ombits == -1) {
|
||||
/* First time looking for carrier */
|
||||
if (Online(p))
|
||||
log_Printf(LogDEBUG, "%s: %s: CD detected\n", p->link.name, p->name.full);
|
||||
else if (p->cfg.cd.required) {
|
||||
log_Printf(LogPHASE, "%s: %s: Required CD not detected\n",
|
||||
p->link.name, p->name.full);
|
||||
datalink_Down(p->dl, CLOSE_NORMAL);
|
||||
} else {
|
||||
log_Printf(LogPHASE, "%s: %s doesn't support CD\n",
|
||||
p->link.name, p->name.full);
|
||||
timer_Stop(&p->Timer);
|
||||
p->mbits = TIOCM_CD;
|
||||
}
|
||||
} else {
|
||||
change = ombits ^ p->mbits;
|
||||
if (change & TIOCM_CD) {
|
||||
if (p->mbits & TIOCM_CD)
|
||||
log_Printf(LogDEBUG, "%s: offline -> online\n", p->link.name);
|
||||
else {
|
||||
log_Printf(LogDEBUG, "%s: online -> offline\n", p->link.name);
|
||||
log_Printf(LogPHASE, "%s: Carrier lost\n", p->link.name);
|
||||
datalink_Down(p->dl, CLOSE_NORMAL);
|
||||
timer_Stop(&p->Timer);
|
||||
}
|
||||
} else
|
||||
log_Printf(LogDEBUG, "%s: Still %sline\n", p->link.name,
|
||||
Online(p) ? "on" : "off");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tty_StartTimer(struct physical *p)
|
||||
{
|
||||
timer_Stop(&p->Timer);
|
||||
p->Timer.load = SECTICKS * p->cfg.cd.delay;
|
||||
p->Timer.func = tty_Timeout;
|
||||
p->Timer.name = "tty CD";
|
||||
p->Timer.arg = p;
|
||||
log_Printf(LogDEBUG, "%s: Using tty_Timeout [%p]\n",
|
||||
p->link.name, tty_Timeout);
|
||||
p->mbits = -1; /* So we know it's the first time */
|
||||
timer_Start(&p->Timer);
|
||||
}
|
||||
|
||||
static int
|
||||
tty_Raw(struct physical *p)
|
||||
{
|
||||
struct termios rstio;
|
||||
int oldflag;
|
||||
|
||||
if (physical_IsSync(p))
|
||||
return 1;
|
||||
|
||||
log_Printf(LogDEBUG, "%s: Entering physical_Raw\n", p->link.name);
|
||||
|
||||
if (p->type != PHYS_DIRECT && p->fd >= 0 && !Online(p))
|
||||
log_Printf(LogDEBUG, "%s: Raw: descriptor = %d, mbits = %x\n",
|
||||
p->link.name, p->fd, p->mbits);
|
||||
|
||||
tcgetattr(p->fd, &rstio);
|
||||
cfmakeraw(&rstio);
|
||||
if (p->cfg.rts_cts)
|
||||
rstio.c_cflag |= CLOCAL | CCTS_OFLOW | CRTS_IFLOW;
|
||||
else
|
||||
rstio.c_cflag |= CLOCAL;
|
||||
|
||||
if (p->type != PHYS_DEDICATED)
|
||||
rstio.c_cflag |= HUPCL;
|
||||
|
||||
tcsetattr(p->fd, TCSANOW, &rstio);
|
||||
|
||||
oldflag = fcntl(p->fd, F_GETFL, 0);
|
||||
if (oldflag < 0)
|
||||
return 0;
|
||||
fcntl(p->fd, F_SETFL, oldflag | O_NONBLOCK);
|
||||
|
||||
if (ioctl(p->fd, TIOCMGET, &p->mbits) == 0)
|
||||
tty_StartTimer(p);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void
|
||||
tty_Offline(struct physical *p)
|
||||
{
|
||||
if (p->fd >= 0) {
|
||||
timer_Stop(&p->Timer);
|
||||
p->mbits &= ~TIOCM_DTR;
|
||||
if (Online(p)) {
|
||||
struct termios tio;
|
||||
|
||||
tcgetattr(p->fd, &tio);
|
||||
if (cfsetspeed(&tio, B0) == -1)
|
||||
log_Printf(LogWARN, "%s: Unable to set physical to speed 0\n",
|
||||
p->link.name);
|
||||
else
|
||||
tcsetattr(p->fd, TCSANOW, &tio);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tty_Cooked(struct physical *p)
|
||||
{
|
||||
int oldflag;
|
||||
|
||||
tcflush(p->fd, TCIOFLUSH);
|
||||
if (!physical_IsSync(p)) {
|
||||
tcsetattr(p->fd, TCSAFLUSH, &p->ios);
|
||||
oldflag = fcntl(p->fd, F_GETFL, 0);
|
||||
if (oldflag == 0)
|
||||
fcntl(p->fd, F_SETFL, oldflag & ~O_NONBLOCK);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
tty_Close(struct physical *p)
|
||||
{
|
||||
tty_Unlock(p);
|
||||
}
|
||||
|
||||
static void
|
||||
tty_Restored(struct physical *p)
|
||||
{
|
||||
if (p->Timer.state != TIMER_STOPPED) {
|
||||
p->Timer.state = TIMER_STOPPED; /* Special - see physical2iov() */
|
||||
tty_StartTimer(p);
|
||||
}
|
||||
}
|
||||
|
||||
static int
|
||||
tty_Speed(struct physical *p)
|
||||
{
|
||||
struct termios rstio;
|
||||
|
||||
if (tcgetattr(p->fd, &rstio) == -1)
|
||||
return 0;
|
||||
|
||||
return SpeedToInt(cfgetispeed(&rstio));
|
||||
}
|
||||
|
||||
static const char *
|
||||
tty_OpenInfo(struct physical *p)
|
||||
{
|
||||
static char buf[13];
|
||||
|
||||
if (Online(p))
|
||||
strcpy(buf, "with");
|
||||
else
|
||||
strcpy(buf, "no");
|
||||
strcat(buf, " carrier");
|
||||
return buf;
|
||||
}
|
||||
|
||||
const struct device ttydevice = {
|
||||
TTY_DEVICE,
|
||||
"tty",
|
||||
tty_Open,
|
||||
tty_Raw,
|
||||
tty_Offline,
|
||||
tty_Cooked,
|
||||
tty_Close,
|
||||
tty_Restored,
|
||||
tty_Speed,
|
||||
tty_OpenInfo
|
||||
};
|
|
@ -0,0 +1,33 @@
|
|||
/*-
|
||||
* Copyright (c) 1999 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:$
|
||||
*/
|
||||
|
||||
struct physical;
|
||||
|
||||
extern int tty_OpenStdin(struct physical *);
|
||||
|
||||
extern const struct device ttydevice;
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: tun.c,v 1.12 1999/04/26 08:54:25 brian Exp $
|
||||
* $Id: tun.c,v 1.13 1999/04/26 08:54:34 brian Exp $
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
|
@ -39,11 +39,13 @@
|
|||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <termios.h>
|
||||
#ifdef __NetBSD__
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
|
|
|
@ -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.26 1999/03/29 08:21:28 brian Exp $
|
||||
* $Id: vjcomp.c,v 1.27 1999/03/31 14:21:46 brian Exp $
|
||||
*
|
||||
* TODO:
|
||||
*/
|
||||
|
@ -29,12 +29,14 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <termios.h>
|
||||
|
||||
#include "layer.h"
|
||||
#include "mbuf.h"
|
||||
#include "log.h"
|
||||
#include "timer.h"
|
||||
#include "fsm.h"
|
||||
#include "lcpproto.h"
|
||||
#include "proto.h"
|
||||
#include "slcompress.h"
|
||||
#include "lqr.h"
|
||||
#include "hdlc.h"
|
||||
|
@ -56,43 +58,44 @@
|
|||
|
||||
#define MAX_VJHEADER 16 /* Maximum size of compressed header */
|
||||
|
||||
void
|
||||
vj_SendFrame(struct link *l, struct mbuf * bp, struct bundle *bundle)
|
||||
static struct mbuf *
|
||||
vj_LayerPush(struct bundle *bundle, struct link *l, struct mbuf *bp, int pri,
|
||||
u_short *proto)
|
||||
{
|
||||
int type;
|
||||
u_short proto;
|
||||
struct ip *pip;
|
||||
u_short cproto = bundle->ncp.ipcp.peer_compproto >> 16;
|
||||
|
||||
log_Printf(LogDEBUG, "vj_SendFrame: COMPPROTO = %x\n",
|
||||
log_Printf(LogDEBUG, "vj_LayerWrite: COMPPROTO = %x\n",
|
||||
bundle->ncp.ipcp.peer_compproto);
|
||||
bp = mbuf_Contiguous(bp);
|
||||
pip = (struct ip *)MBUF_CTOP(bp);
|
||||
if (pip->ip_p == IPPROTO_TCP && cproto == PROTO_VJCOMP) {
|
||||
if (*proto == PROTO_IP && pip->ip_p == IPPROTO_TCP &&
|
||||
cproto == PROTO_VJCOMP) {
|
||||
type = sl_compress_tcp(bp, pip, &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);
|
||||
log_Printf(LogDEBUG, "vj_LayerWrite: type = %x\n", type);
|
||||
switch (type) {
|
||||
case TYPE_IP:
|
||||
proto = PROTO_IP;
|
||||
break;
|
||||
case TYPE_UNCOMPRESSED_TCP:
|
||||
proto = PROTO_VJUNCOMP;
|
||||
break;
|
||||
case TYPE_COMPRESSED_TCP:
|
||||
proto = PROTO_VJCOMP;
|
||||
break;
|
||||
default:
|
||||
log_Printf(LogALERT, "Unknown frame type %x\n", type);
|
||||
mbuf_Free(bp);
|
||||
return;
|
||||
}
|
||||
} else
|
||||
proto = PROTO_IP;
|
||||
|
||||
if (!ccp_Compress(&l->ccp, l, PRI_NORMAL, proto, bp))
|
||||
hdlc_Output(l, PRI_NORMAL, proto, bp);
|
||||
case TYPE_UNCOMPRESSED_TCP:
|
||||
*proto = PROTO_VJUNCOMP;
|
||||
break;
|
||||
|
||||
case TYPE_COMPRESSED_TCP:
|
||||
*proto = PROTO_VJCOMP;
|
||||
break;
|
||||
|
||||
default:
|
||||
log_Printf(LogERROR, "Unknown frame type %x\n", type);
|
||||
mbuf_Free(bp);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
return bp;
|
||||
}
|
||||
|
||||
static struct mbuf *
|
||||
|
@ -106,7 +109,6 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
|
|||
bp = mbuf_Contiguous(bp);
|
||||
olen = len = mbuf_Length(bp);
|
||||
if (type == TYPE_UNCOMPRESSED_TCP) {
|
||||
|
||||
/*
|
||||
* Uncompressed packet does NOT change its size, so that we can use mbuf
|
||||
* space for uncompression job.
|
||||
|
@ -118,7 +120,7 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
|
|||
mbuf_Free(bp);
|
||||
bp = NULL;
|
||||
}
|
||||
return (bp);
|
||||
return bp;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -142,18 +144,19 @@ VjUncompressTcp(struct ipcp *ipcp, struct mbuf * bp, u_char type)
|
|||
nbp = mbuf_Alloc(len, MB_VJCOMP);
|
||||
memcpy(MBUF_CTOP(nbp), bufp, len);
|
||||
nbp->next = bp;
|
||||
return (nbp);
|
||||
return nbp;
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
vj_Input(struct ipcp *ipcp, struct mbuf *bp, int proto)
|
||||
static struct mbuf *
|
||||
vj_LayerPull(struct bundle *bundle, struct link *l, struct mbuf *bp,
|
||||
u_short *proto)
|
||||
{
|
||||
u_char type;
|
||||
|
||||
log_Printf(LogDEBUG, "vj_Input: proto %02x\n", proto);
|
||||
log_Printf(LogDEBUG, "vj_LayerPull: proto %02x\n", *proto);
|
||||
log_DumpBp(LogDEBUG, "Raw packet info:", bp);
|
||||
|
||||
switch (proto) {
|
||||
switch (*proto) {
|
||||
case PROTO_VJCOMP:
|
||||
type = TYPE_COMPRESSED_TCP;
|
||||
break;
|
||||
|
@ -161,11 +164,11 @@ vj_Input(struct ipcp *ipcp, struct mbuf *bp, int proto)
|
|||
type = TYPE_UNCOMPRESSED_TCP;
|
||||
break;
|
||||
default:
|
||||
log_Printf(LogWARN, "vj_Input...???\n");
|
||||
return (bp);
|
||||
return bp;
|
||||
}
|
||||
bp = VjUncompressTcp(ipcp, bp, type);
|
||||
return (bp);
|
||||
|
||||
*proto = PROTO_IP;
|
||||
return VjUncompressTcp(&bundle->ncp.ipcp, bp, type);
|
||||
}
|
||||
|
||||
const char *
|
||||
|
@ -174,9 +177,11 @@ vj2asc(u_int32_t val)
|
|||
static char asc[50]; /* The return value is used immediately */
|
||||
|
||||
if (val)
|
||||
snprintf(asc, sizeof asc, "%d VJ slots %s slot compression",
|
||||
(int)((val>>8)&15)+1, val & 1 ? "with" : "without");
|
||||
snprintf(asc, sizeof asc, "%d VJ slots with%s slot compression",
|
||||
(int)((val>>8)&15)+1, val & 1 ? "" : "out");
|
||||
else
|
||||
strcpy(asc, "VJ disabled");
|
||||
return asc;
|
||||
}
|
||||
|
||||
struct layer vjlayer = { LAYER_VJ, "vj", vj_LayerPush, vj_LayerPull };
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id: vjcomp.h,v 1.5.4.6 1998/05/01 19:26:12 brian Exp $
|
||||
* $Id: vjcomp.h,v 1.6 1998/05/21 21:49:08 brian Exp $
|
||||
*/
|
||||
|
||||
struct mbuf;
|
||||
|
@ -31,6 +31,6 @@ 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);
|
||||
|
||||
extern struct layer vjlayer;
|
||||
|
|
Loading…
Reference in New Issue