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:
Brian Somers 1999-05-08 11:07:56 +00:00
parent 46be34b902
commit 5d9e610366
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=46686
77 changed files with 3392 additions and 2298 deletions

View File

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

View File

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

111
usr.sbin/ppp/acf.c Normal file
View File

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

33
usr.sbin/ppp/acf.h Normal file
View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: arp.c,v 1.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"

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ccp.h,v 1.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;

View File

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

View File

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

View File

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

View File

@ -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 ! */

View File

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

View File

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

View File

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

View File

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

View File

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

160
usr.sbin/ppp/exec.c Normal file
View File

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

29
usr.sbin/ppp/exec.h Normal file
View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: hdlc.h,v 1.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;

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: ipcp.h,v 1.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);

View File

@ -23,7 +23,7 @@
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* $Id: iplist.c,v 1.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"

52
usr.sbin/ppp/layer.h Normal file
View File

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

View File

@ -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 @@ LcpDecodeConfig(struct fsm *fp, u_char *cp, int plen, int mode_type,
}
}
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;
}

View File

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

View File

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

View File

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

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: lqr.c,v 1.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 };

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: mbuf.h,v 1.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 *);

File diff suppressed because it is too large Load Diff

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -15,7 +15,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: pap.h,v 1.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 *);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

110
usr.sbin/ppp/proto.c Normal file
View File

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

View File

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

View File

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

View File

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

View File

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

68
usr.sbin/ppp/sync.c Normal file
View File

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

29
usr.sbin/ppp/sync.h Normal file
View File

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

View File

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

134
usr.sbin/ppp/tcp.c Normal file
View File

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

29
usr.sbin/ppp/tcp.h Normal file
View File

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

View File

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

View File

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

446
usr.sbin/ppp/tty.c Normal file
View File

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

33
usr.sbin/ppp/tty.h Normal file
View File

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

View File

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

View File

@ -17,7 +17,7 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
* $Id: vjcomp.c,v 1.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 };

View File

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