summaryrefslogtreecommitdiffstats
path: root/usr.sbin/ppp/ip.c
diff options
context:
space:
mode:
authorbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
committerbrian <brian@FreeBSD.org>1998-05-21 21:49:08 +0000
commit56df88b778aee0e60678672b107a48a8ea05cb48 (patch)
tree13b88ca17b38e787c84b0cd242677b3c3c0b93c3 /usr.sbin/ppp/ip.c
parente077fa331b8a428923ded3a95d0b8d47084cf670 (diff)
downloadFreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.zip
FreeBSD-src-56df88b778aee0e60678672b107a48a8ea05cb48.tar.gz
MFMP: Make ppp multilink capable.
See the file README.changes, and re-read the man page.
Diffstat (limited to 'usr.sbin/ppp/ip.c')
-rw-r--r--usr.sbin/ppp/ip.c344
1 files changed, 161 insertions, 183 deletions
diff --git a/usr.sbin/ppp/ip.c b/usr.sbin/ppp/ip.c
index e9546e0..7a889e0 100644
--- a/usr.sbin/ppp/ip.c
+++ b/usr.sbin/ppp/ip.c
@@ -17,17 +17,14 @@
* IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
* WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
*
- * $Id: ip.c,v 1.39 1998/03/13 01:36:09 brian Exp $
+ * $Id: ip.c,v 1.38.2.26 1998/05/06 23:50:11 brian Exp $
*
* TODO:
* o Return ICMP message for filterd packet
* and optionaly record it into log.
*/
-#include <sys/param.h>
-#include <sys/time.h>
+#include <sys/types.h>
#include <sys/socket.h>
-#include <net/if.h>
-#include <net/if_tun.h>
#include <netinet/in.h>
#include <netinet/in_systm.h>
#include <netinet/ip.h>
@@ -35,6 +32,8 @@
#include <netinet/udp.h>
#include <netinet/tcp.h>
#include <arpa/inet.h>
+#include <net/if_tun.h>
+#include <sys/un.h>
#ifndef NOALIAS
#include <alias.h>
@@ -43,91 +42,31 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
-#include <termios.h>
#include <unistd.h>
-#include "command.h"
#include "mbuf.h"
#include "log.h"
#include "defs.h"
#include "timer.h"
#include "fsm.h"
+#include "lqr.h"
#include "hdlc.h"
#include "loadalias.h"
-#include "vars.h"
-#include "filter.h"
-#include "os.h"
+#include "throughput.h"
+#include "iplist.h"
+#include "slcompress.h"
#include "ipcp.h"
-#include "vjcomp.h"
+#include "filter.h"
+#include "descriptor.h"
#include "lcp.h"
-#include "modem.h"
+#include "ccp.h"
+#include "link.h"
+#include "mp.h"
+#include "bundle.h"
+#include "vjcomp.h"
#include "tun.h"
#include "ip.h"
-static struct pppTimer IdleTimer;
-
-static void
-IdleTimeout(void *v)
-{
- LogPrintf(LogPHASE, "Idle timer expired.\n");
- reconnect(RECON_FALSE);
- LcpClose();
-}
-
-/*
- * Start Idle timer. If timeout is reached, we call LcpClose() to
- * close LCP and link.
- */
-void
-StartIdleTimer()
-{
- static time_t IdleStarted;
-
- if (!(mode & (MODE_DEDICATED | MODE_DDIAL))) {
- StopTimer(&IdleTimer);
- IdleTimer.func = IdleTimeout;
- IdleTimer.load = VarIdleTimeout * SECTICKS;
- IdleTimer.state = TIMER_STOPPED;
- time(&IdleStarted);
- IdleTimer.arg = (void *)&IdleStarted;
- StartTimer(&IdleTimer);
- }
-}
-
-void
-UpdateIdleTimer()
-{
- if (OsLinkIsUp())
- StartIdleTimer();
-}
-
-void
-StopIdleTimer()
-{
- StopTimer(&IdleTimer);
-}
-
-int
-RemainingIdleTime()
-{
- if (VarIdleTimeout == 0 || IdleTimer.state != TIMER_RUNNING ||
- IdleTimer.arg == NULL)
- return -1;
- return VarIdleTimeout - (time(NULL) - *(time_t *)IdleTimer.arg);
-}
-
-/*
- * If any IP layer traffic is detected, refresh IdleTimer.
- */
-static void
-RestartIdleTimer(void)
-{
- if (!(mode & (MODE_DEDICATED | MODE_DDIAL)) && ipKeepAlive) {
- time((time_t *)IdleTimer.arg);
- StartTimer(&IdleTimer);
- }
-}
-
static const u_short interactive_ports[32] = {
544, 513, 514, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 21, 22, 23, 0, 0, 0, 0, 0, 0, 0, 543,
@@ -137,9 +76,6 @@ static const u_short interactive_ports[32] = {
static const char *TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" };
-static const char *Direction[] = {"INP", "OUT", "OUT", "IN/OUT"};
-static struct filterent *Filters[] = {ifilters, ofilters, dfilters, afilters};
-
static int
PortMatch(int op, u_short pport, u_short rport)
{
@@ -159,27 +95,30 @@ PortMatch(int op, u_short pport, u_short rport)
* Check a packet against with defined filters
*/
static int
-FilterCheck(struct ip * pip, int direction)
+FilterCheck(struct ip *pip, struct filter *filter)
{
- struct filterent *fp = Filters[direction];
- int gotinfo, cproto, estab, n;
+ int gotinfo, cproto, estab, syn, finrst, n, len, didname;
struct tcphdr *th;
struct udphdr *uh;
struct icmp *ih;
char *ptop;
u_short sport, dport;
+ struct filterent *fp = filter->rule;
+ char dbuff[100];
if (fp->action) {
- cproto = gotinfo = estab = 0;
+ cproto = gotinfo = estab = syn = finrst = didname = 0;
sport = dport = 0;
for (n = 0; n < MAXFILTERS; n++) {
if (fp->action) {
/* permit fragments on in and out filter */
- if ((direction == FL_IN || direction == FL_OUT) &&
- (ntohs(pip->ip_off) & IP_OFFMASK) != 0) {
+ if (filter->fragok && (ntohs(pip->ip_off) & IP_OFFMASK) != 0)
return (A_PERMIT);
- }
- LogPrintf(LogDEBUG, "rule = %d\n", n);
+
+ if (!didname)
+ log_Printf(LogDEBUG, "%s filter:\n", filter->name);
+ didname = 1;
+
if ((pip->ip_src.s_addr & fp->smask.s_addr) ==
(fp->saddr.s_addr & fp->smask.s_addr) &&
(pip->ip_dst.s_addr & fp->dmask.s_addr) ==
@@ -193,14 +132,19 @@ FilterCheck(struct ip * pip, int direction)
cproto = P_ICMP;
ih = (struct icmp *) ptop;
sport = ih->icmp_type;
- estab = 1;
+ estab = syn = finrst = -1;
+ if (log_IsKept(LogDEBUG))
+ snprintf(dbuff, sizeof dbuff, "sport = %d", sport);
break;
case IPPROTO_UDP:
cproto = P_UDP;
uh = (struct udphdr *) ptop;
sport = ntohs(uh->uh_sport);
dport = ntohs(uh->uh_dport);
- estab = 1;
+ estab = syn = finrst = -1;
+ if (log_IsKept(LogDEBUG))
+ snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d",
+ sport, dport);
break;
case IPPROTO_TCP:
cproto = P_TCP;
@@ -208,39 +152,67 @@ FilterCheck(struct ip * pip, int direction)
sport = ntohs(th->th_sport);
dport = ntohs(th->th_dport);
estab = (th->th_flags & TH_ACK);
- if (estab == 0)
- LogPrintf(LogDEBUG, "flag = %02x, sport = %d, dport = %d\n",
- th->th_flags, sport, dport);
+ syn = (th->th_flags & TH_SYN);
+ finrst = (th->th_flags & (TH_FIN|TH_RST));
+ if (log_IsKept(LogDEBUG) && !estab)
+ snprintf(dbuff, sizeof dbuff,
+ "flags = %02x, sport = %d, dport = %d",
+ th->th_flags, sport, dport);
break;
default:
- return (A_DENY);/* We'll block unknown type of packet */
+ return (A_DENY); /* We'll block unknown type of packet */
}
+ if (log_IsKept(LogDEBUG)) {
+ if (estab != -1) {
+ len = strlen(dbuff);
+ snprintf(dbuff + len, sizeof dbuff - len,
+ ", estab = %d, syn = %d, finrst = %d",
+ estab, syn, finrst);
+ }
+ log_Printf(LogDEBUG, " Filter: proto = %s, %s\n",
+ filter_Proto2Nam(cproto), dbuff);
+ }
gotinfo = 1;
- LogPrintf(LogDEBUG, "dir = %d, proto = %d, srcop = %d,"
- " dstop = %d, estab = %d\n", direction, cproto,
- fp->opt.srcop, fp->opt.dstop, estab);
}
- LogPrintf(LogDEBUG, "check0: rule = %d, proto = %d, sport = %d,"
- " dport = %d\n", n, cproto, sport, dport);
- LogPrintf(LogDEBUG, "check0: action = %d\n", fp->action);
+ if (log_IsKept(LogDEBUG)) {
+ if (fp->opt.srcop != OP_NONE) {
+ snprintf(dbuff, sizeof dbuff, ", src %s %d",
+ filter_Op2Nam(fp->opt.srcop), fp->opt.srcport);
+ len = strlen(dbuff);
+ } else
+ len = 0;
+ if (fp->opt.dstop != OP_NONE) {
+ snprintf(dbuff + len, sizeof dbuff - len,
+ ", dst %s %d", filter_Op2Nam(fp->opt.dstop),
+ fp->opt.dstport);
+ } else if (!len)
+ *dbuff = '\0';
+
+ log_Printf(LogDEBUG, " rule = %d: Address match, "
+ "check against proto %s%s, action = %s\n",
+ n, filter_Proto2Nam(fp->proto),
+ dbuff, filter_Action2Nam(fp->action));
+ }
if (cproto == fp->proto) {
if ((fp->opt.srcop == OP_NONE ||
- PortMatch(fp->opt.srcop, sport, fp->opt.srcport))
- &&
+ PortMatch(fp->opt.srcop, sport, fp->opt.srcport)) &&
(fp->opt.dstop == OP_NONE ||
- PortMatch(fp->opt.dstop, dport, fp->opt.dstport))
- &&
- (fp->opt.estab == 0 || estab)) {
+ PortMatch(fp->opt.dstop, dport, fp->opt.dstport)) &&
+ (fp->opt.estab == 0 || estab) &&
+ (fp->opt.syn == 0 || syn) &&
+ (fp->opt.finrst == 0 || finrst)) {
return (fp->action);
}
}
} else {
/* Address is mached. Make a decision. */
- LogPrintf(LogDEBUG, "check1: action = %d\n", fp->action);
+ log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n,
+ filter_Action2Nam(fp->action));
return (fp->action);
}
- }
+ } else
+ log_Printf(LogDEBUG, " rule = %d: Address mismatch\n", n);
}
fp++;
}
@@ -249,27 +221,26 @@ FilterCheck(struct ip * pip, int direction)
return (A_PERMIT); /* No rule is given. Permit this packet */
}
+#ifdef notdef
static void
IcmpError(struct ip * pip, int code)
{
-#ifdef notdef
struct mbuf *bp;
if (pip->ip_p != IPPROTO_ICMP) {
- bp = mballoc(cnt, MB_IPIN);
+ bp = mbuf_Alloc(cnt, MB_IPIN);
memcpy(MBUF_CTOP(bp), ptr, cnt);
- SendPppFrame(bp);
- RestartIdleTimer();
- IpcpAddOutOctets(cnt);
+ vj_SendFrame(bp);
+ ipcp_AddOutOctets(cnt);
}
-#endif
}
+#endif
/*
* For debugging aid.
*/
int
-PacketCheck(char *cp, int nb, int direction)
+PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
{
struct ip *pip;
struct tcphdr *th;
@@ -281,14 +252,13 @@ PacketCheck(char *cp, int nb, int direction)
int logit, loglen;
static char logbuf[200];
- logit = LogIsKept(LogTCPIP) && direction != FL_DIAL;
+ logit = log_IsKept(LogTCPIP) && filter->logok;
loglen = 0;
pip = (struct ip *) cp;
if (logit && loglen < sizeof logbuf) {
- snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ",
- Direction[direction]);
+ snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name);
loglen += strlen(logbuf + loglen);
}
ptop = (cp + (pip->ip_hl << 2));
@@ -359,42 +329,43 @@ PacketCheck(char *cp, int nb, int direction)
break;
}
- if ((FilterCheck(pip, direction) & A_DENY)) {
+ if ((FilterCheck(pip, filter) & A_DENY)) {
if (logit)
- LogPrintf(LogTCPIP, "%s - BLOCKED\n", logbuf);
+ log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf);
+#ifdef notdef
if (direction == 0)
IcmpError(pip, pri);
+#endif
return (-1);
} else {
- if (FilterCheck(pip, FL_KEEP) & A_DENY) { /* Check Keep Alive filter */
- if (logit)
- LogPrintf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
- ipKeepAlive = 0;
- } else {
- if (logit)
- LogPrintf(LogTCPIP, "%s\n", logbuf);
- ipKeepAlive = 1;
+ /* Check Keep Alive filter */
+ if (logit) {
+ if (FilterCheck(pip, &bundle->filter.alive) & A_DENY)
+ log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
+ else
+ log_Printf(LogTCPIP, "%s\n", logbuf);
}
return (pri);
}
}
void
-IpInput(struct mbuf * bp)
-{ /* IN: Pointer to IP pakcet */
+ip_Input(struct bundle *bundle, struct mbuf * bp)
+{
u_char *cp;
struct mbuf *wp;
int nb, nw;
struct tun_data tun;
+ struct ip *pip = (struct ip *)tun.data;
tun_fill_header(tun, AF_INET);
cp = tun.data;
nb = 0;
for (wp = bp; wp; wp = wp->next) { /* Copy to contiguous region */
if (sizeof tun.data - (cp - tun.data) < wp->cnt) {
- LogPrintf(LogERROR, "IpInput: Packet too large (%d) - dropped\n",
- plength(bp));
- pfree(bp);
+ log_Printf(LogERROR, "ip_Input: Packet too large (%d) - dropped\n",
+ mbuf_Length(bp));
+ mbuf_Free(bp);
return;
}
memcpy(cp, MBUF_CTOP(wp), wp->cnt);
@@ -403,52 +374,56 @@ IpInput(struct mbuf * bp)
}
#ifndef NOALIAS
- if (mode & MODE_ALIAS) {
+ if (alias_IsEnabled()) {
struct tun_data *frag;
int iresult;
char *fptr;
- iresult = VarPacketAliasIn(tun.data, sizeof tun.data);
+ iresult = (*PacketAlias.In)(tun.data, sizeof tun.data);
nb = ntohs(((struct ip *) tun.data)->ip_len);
if (nb > MAX_MRU) {
- LogPrintf(LogERROR, "IpInput: Problem with IP header length\n");
- pfree(bp);
+ log_Printf(LogERROR, "ip_Input: Problem with IP header length\n");
+ mbuf_Free(bp);
return;
}
if (iresult == PKT_ALIAS_OK
|| iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
- if (PacketCheck(tun.data, nb, FL_IN) < 0) {
- pfree(bp);
+ if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
+ mbuf_Free(bp);
return;
}
- IpcpAddInOctets(nb);
+
+ if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
+ bundle_StartIdleTimer(bundle);
+
+ ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
nb = ntohs(((struct ip *) tun.data)->ip_len);
nb += sizeof tun - sizeof tun.data;
- nw = write(tun_out, &tun, nb);
+ nw = write(bundle->dev.fd, &tun, nb);
if (nw != nb) {
if (nw == -1)
- LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb,
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
strerror(errno));
else
- LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
}
if (iresult == PKT_ALIAS_FOUND_HEADER_FRAGMENT) {
- while ((fptr = VarPacketAliasGetFragment(tun.data)) != NULL) {
- VarPacketAliasFragmentIn(tun.data, fptr);
+ while ((fptr = (*PacketAlias.GetFragment)(tun.data)) != NULL) {
+ (*PacketAlias.FragmentIn)(tun.data, fptr);
nb = ntohs(((struct ip *) fptr)->ip_len);
frag = (struct tun_data *)
((char *)fptr - sizeof tun + sizeof tun.data);
nb += sizeof tun - sizeof tun.data;
- nw = write(tun_out, frag, nb);
+ nw = write(bundle->dev.fd, frag, nb);
if (nw != nb) {
if (nw == -1)
- LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb,
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb,
strerror(errno));
else
- LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
}
free(frag);
}
@@ -458,83 +433,86 @@ IpInput(struct mbuf * bp)
nb += sizeof tun - sizeof tun.data;
frag = (struct tun_data *)malloc(nb);
if (frag == NULL)
- LogPrintf(LogALERT, "IpInput: Cannot allocate memory for fragment\n");
+ log_Printf(LogALERT, "ip_Input: Cannot allocate memory for fragment\n");
else {
tun_fill_header(*frag, AF_INET);
memcpy(frag->data, tun.data, nb - sizeof tun + sizeof tun.data);
- VarPacketAliasSaveFragment(frag->data);
+ (*PacketAlias.SaveFragment)(frag->data);
}
}
} else
#endif /* #ifndef NOALIAS */
{ /* no aliasing */
- if (PacketCheck(tun.data, nb, FL_IN) < 0) {
- pfree(bp);
+ if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) {
+ mbuf_Free(bp);
return;
}
- IpcpAddInOctets(nb);
+
+ if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
+ bundle_StartIdleTimer(bundle);
+
+ ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
+
nb += sizeof tun - sizeof tun.data;
- nw = write(tun_out, &tun, nb);
+ nw = write(bundle->dev.fd, &tun, nb);
if (nw != nb) {
if (nw == -1)
- LogPrintf(LogERROR, "IpInput: wrote %d, got %s\n", nb, strerror(errno));
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %s\n", nb, strerror(errno));
else
- LogPrintf(LogERROR, "IpInput: wrote %d, got %d\n", nb, nw);
+ log_Printf(LogERROR, "ip_Input: wrote %d, got %d\n", nb, nw);
}
}
- pfree(bp);
-
- RestartIdleTimer();
+ mbuf_Free(bp);
}
static struct mqueue IpOutputQueues[PRI_FAST + 1];
void
-IpEnqueue(int pri, char *ptr, int count)
+ip_Enqueue(int pri, char *ptr, int count)
{
struct mbuf *bp;
- bp = mballoc(count, MB_IPQ);
+ bp = mbuf_Alloc(count, MB_IPQ);
memcpy(MBUF_CTOP(bp), ptr, count);
- Enqueue(&IpOutputQueues[pri], bp);
+ mbuf_Enqueue(&IpOutputQueues[pri], bp);
}
-#if 0
int
-IsIpEnqueued()
+ip_QueueLen()
{
struct mqueue *queue;
- int exist = 0;
+ int result = 0;
- for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--) {
- if (queue->qlen > 0) {
- exist = 1;
- break;
- }
- }
- return (exist);
+ for (queue = &IpOutputQueues[PRI_MAX]; queue >= IpOutputQueues; queue--)
+ result += queue->qlen;
+
+ return result;
}
-#endif
-void
-IpStartOutput()
+int
+ip_FlushPacket(struct link *l, struct bundle *bundle)
{
struct mqueue *queue;
struct mbuf *bp;
int cnt;
- if (IpcpFsm.state != ST_OPENED)
- return;
- for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--) {
+ if (bundle->ncp.ipcp.fsm.state != ST_OPENED)
+ return 0;
+
+ for (queue = &IpOutputQueues[PRI_FAST]; queue >= IpOutputQueues; queue--)
if (queue->top) {
- bp = Dequeue(queue);
+ bp = mbuf_Dequeue(queue);
if (bp) {
- cnt = plength(bp);
- SendPppFrame(bp);
- RestartIdleTimer();
- IpcpAddOutOctets(cnt);
- break;
+ struct ip *pip = (struct ip *)MBUF_CTOP(bp);
+
+ cnt = mbuf_Length(bp);
+ vj_SendFrame(l, bp, bundle);
+ if (!(FilterCheck(pip, &bundle->filter.alive) & A_DENY))
+ bundle_StartIdleTimer(bundle);
+ ipcp_AddOutOctets(&bundle->ncp.ipcp, cnt);
+ return 1;
}
}
- }
+
+ return 0;
}
OpenPOWER on IntegriCloud