ip.c revision 330449
150276Speter/*-
2166124Srafan * SPDX-License-Identifier: BSD-2-Clause-FreeBSD
350276Speter *
450276Speter * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org>
550276Speter *          based on work by Toshiharu OHNO <tony-o@iij.ad.jp>
650276Speter *                           Internet Initiative Japan, Inc (IIJ)
750276Speter * All rights reserved.
850276Speter *
950276Speter * Redistribution and use in source and binary forms, with or without
1050276Speter * modification, are permitted provided that the following conditions
1150276Speter * are met:
1250276Speter * 1. Redistributions of source code must retain the above copyright
1350276Speter *    notice, this list of conditions and the following disclaimer.
1450276Speter * 2. Redistributions in binary form must reproduce the above copyright
1550276Speter *    notice, this list of conditions and the following disclaimer in the
1650276Speter *    documentation and/or other materials provided with the distribution.
1750276Speter *
1850276Speter * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
1950276Speter * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
2050276Speter * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
2150276Speter * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
2250276Speter * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
2350276Speter * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
2450276Speter * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
2550276Speter * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
2650276Speter * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
2750276Speter * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
2850276Speter * SUCH DAMAGE.
29166124Srafan *
3050276Speter * $FreeBSD: stable/11/usr.sbin/ppp/ip.c 330449 2018-03-05 07:26:05Z eadler $
31166124Srafan */
32166124Srafan
3350276Speter#include <sys/param.h>
34166124Srafan#include <sys/socket.h>
35166124Srafan#include <netinet/in.h>
36166124Srafan#include <netinet/in_systm.h>
37166124Srafan#include <netinet/ip.h>
38166124Srafan#ifndef NOINET6
39166124Srafan#include <netinet/icmp6.h>
40166124Srafan#include <netinet/ip6.h>
41166124Srafan#endif
4250276Speter#include <netinet/ip_icmp.h>
4350276Speter#include <netinet/udp.h>
44166124Srafan#include <netinet/tcp.h>
4550276Speter#include <sys/un.h>
4650276Speter
4750276Speter#include <errno.h>
4850276Speter#include <netdb.h>
4950276Speter#include <stdio.h>
5050276Speter#include <string.h>
5150276Speter#include <termios.h>
5250276Speter#include <unistd.h>
5350276Speter
5450276Speter#include "layer.h"
5550276Speter#include "proto.h"
5650276Speter#include "mbuf.h"
57166124Srafan#include "log.h"
58166124Srafan#include "defs.h"
5950276Speter#include "timer.h"
6050276Speter#include "fsm.h"
6150276Speter#include "lqr.h"
62166124Srafan#include "hdlc.h"
63166124Srafan#include "throughput.h"
6450276Speter#include "iplist.h"
65166124Srafan#include "slcompress.h"
66166124Srafan#include "ncpaddr.h"
67166124Srafan#include "ip.h"
68166124Srafan#include "ipcp.h"
69166124Srafan#include "filter.h"
70166124Srafan#include "descriptor.h"
7150276Speter#include "lcp.h"
72166124Srafan#include "ccp.h"
73166124Srafan#include "link.h"
7450276Speter#include "mp.h"
7550276Speter#ifndef NORADIUS
76166124Srafan#include "radius.h"
7750276Speter#endif
7850276Speter#include "ipv6cp.h"
7950276Speter#include "ncp.h"
80166124Srafan#include "bundle.h"
81166124Srafan#include "tun.h"
8250276Speter
83166124Srafan
84166124Srafan#define OPCODE_QUERY	0
8550276Speter#define OPCODE_IQUERY	1
8650276Speter#define OPCODE_STATUS	2
87166124Srafan
8850276Speterstruct dns_header {
8950276Speter  u_short id;
90166124Srafan  unsigned qr : 1;
91166124Srafan  unsigned opcode : 4;
92166124Srafan  unsigned aa : 1;
93166124Srafan  unsigned tc : 1;
94166124Srafan  unsigned rd : 1;
95166124Srafan  unsigned ra : 1;
9650276Speter  unsigned z : 3;
97166124Srafan  unsigned rcode : 4;
98166124Srafan  u_short qdcount;
9950276Speter  u_short ancount;
100166124Srafan  u_short nscount;
101166124Srafan  u_short arcount;
102166124Srafan};
103166124Srafan
10450276Speterstatic const char *
10550276Speterdns_Qclass2Txt(u_short qclass)
106166124Srafan{
10750276Speter  static char failure[6];
10850276Speter  struct {
10950276Speter    u_short id;
110166124Srafan    const char *txt;
111166124Srafan  } qtxt[] = {
11250276Speter    /* rfc1035 */
11350276Speter    { 1, "IN" }, { 2, "CS" }, { 3, "CH" }, { 4, "HS" }, { 255, "*" }
114166124Srafan  };
115166124Srafan  unsigned f;
11650276Speter
117166124Srafan  for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++)
118166124Srafan    if (qtxt[f].id == qclass)
119166124Srafan      return qtxt[f].txt;
120166124Srafan
121166124Srafan  return HexStr(qclass, failure, sizeof failure);
12250276Speter}
12350276Speter
12450276Speterstatic const char *
12550276Speterdns_Qtype2Txt(u_short qtype)
126166124Srafan{
12750276Speter  static char failure[6];
128166124Srafan  struct {
129166124Srafan    u_short id;
130166124Srafan    const char *txt;
131166124Srafan  } qtxt[] = {
132166124Srafan    /* rfc1035/rfc1700 */
133166124Srafan    { 1, "A" }, { 2, "NS" }, { 3, "MD" }, { 4, "MF" }, { 5, "CNAME" },
134166124Srafan    { 6, "SOA" }, { 7, "MB" }, { 8, "MG" }, { 9, "MR" }, { 10, "NULL" },
135166124Srafan    { 11, "WKS" }, { 12, "PTR" }, { 13, "HINFO" }, { 14, "MINFO" },
136166124Srafan    { 15, "MX" }, { 16, "TXT" }, { 17, "RP" }, { 18, "AFSDB" },
137166124Srafan    { 19, "X25" }, { 20, "ISDN" }, { 21, "RT" }, { 22, "NSAP" },
138166124Srafan    { 23, "NSAP-PTR" }, { 24, "SIG" }, { 25, "KEY" }, { 26, "PX" },
139166124Srafan    { 27, "GPOS" }, { 28, "AAAA" }, { 252, "AXFR" }, { 253, "MAILB" },
140166124Srafan    { 254, "MAILA" }, { 255, "*" }
141166124Srafan  };
142166124Srafan  unsigned f;
143166124Srafan
144166124Srafan  for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++)
145166124Srafan    if (qtxt[f].id == qtype)
146166124Srafan      return qtxt[f].txt;
147166124Srafan
148166124Srafan  return HexStr(qtype, failure, sizeof failure);
149166124Srafan}
150166124Srafan
15150276Speterstatic __inline int
15250276SpeterPortMatch(int op, u_short pport, u_short rport)
15350276Speter{
15450276Speter  switch (op) {
15550276Speter  case OP_EQ:
15650276Speter    return pport == rport;
15750276Speter  case OP_GT:
15850276Speter    return pport > rport;
15950276Speter  case OP_LT:
16050276Speter    return pport < rport;
16150276Speter  default:
16250276Speter    return 0;
163  }
164}
165
166/*
167 * Return a text string representing the cproto protocol number.
168 *
169 * The purpose of this routine is calculate this result, for
170 * the many times it is needed in FilterCheck, only on demand
171 * (i.e. when the corresponding logging functions are invoked).
172 *
173 * This optimization saves, over the previous implementation, which
174 * calculated prototxt at the beginning of FilterCheck, an
175 * open/read/close system call sequence per packet, approximately
176 * halving the ppp system overhead and reducing the overall (u + s)
177 * time by 38%.
178 *
179 * The caching performed here is just a side effect.
180 */
181static const char *
182prototxt(int cproto)
183{
184  static int oproto = -1;
185  static char protobuff[16] = "-1";
186  struct protoent *pe;
187
188  if (cproto == oproto)
189	return protobuff;
190  if ((pe = getprotobynumber(cproto)) == NULL)
191    snprintf(protobuff, sizeof protobuff, "%d", cproto);
192  else
193    snprintf(protobuff, sizeof protobuff, "%s", pe->p_name);
194  oproto = cproto;
195  return (protobuff);
196}
197
198/*
199 * Check a packet against the given filter
200 * Returns 0 to accept the packet, non-zero to drop the packet.
201 * If psecs is not NULL, populate it with the timeout associated
202 * with the filter rule matched.
203 *
204 * If filtering is enabled, the initial fragment of a datagram must
205 * contain the complete protocol header, and subsequent fragments
206 * must not attempt to over-write it.
207 *
208 * One (and only one) of pip or pip6 must be set.
209 */
210int
211FilterCheck(const unsigned char *packet,
212#ifdef NOINET6
213	    u_int32_t family __unused,
214#else
215	    u_int32_t family,
216#endif
217            const struct filter *filter, unsigned *psecs)
218{
219  int gotinfo;			/* true if IP payload decoded */
220  int cproto;			/* IPPROTO_* protocol number if (gotinfo) */
221  int estab, syn, finrst;	/* TCP state flags if (gotinfo) */
222  u_short sport, dport;		/* src, dest port from packet if (gotinfo) */
223  int n;			/* filter rule to process */
224  int len;			/* bytes used in dbuff */
225  int didname;			/* true if filter header printed */
226  int match;			/* true if condition matched */
227  int mindata;			/* minimum data size or zero */
228  const struct filterent *fp = filter->rule;
229  char dbuff[100], dstip[16];
230  struct ncpaddr srcaddr, dstaddr;
231  const char *payload;		/* IP payload */
232  int datalen;			/* IP datagram length */
233
234  if (fp->f_action == A_NONE)
235    return 0;		/* No rule is given. Permit this packet */
236
237#ifndef NOINET6
238  if (family == AF_INET6) {
239    const struct ip6_hdr *pip6 = (const struct ip6_hdr *)packet;
240
241    ncpaddr_setip6(&srcaddr, &pip6->ip6_src);
242    ncpaddr_setip6(&dstaddr, &pip6->ip6_dst);
243    datalen = ntohs(pip6->ip6_plen);
244    payload = packet + sizeof *pip6;
245    cproto = pip6->ip6_nxt;
246  } else
247#endif
248  {
249    /*
250     * Deny any packet fragment that tries to over-write the header.
251     * Since we no longer have the real header available, punt on the
252     * largest normal header - 20 bytes for TCP without options, rounded
253     * up to the next possible fragment boundary.  Since the smallest
254     * `legal' MTU is 576, and the smallest recommended MTU is 296, any
255     * fragmentation within this range is dubious at best
256     */
257    const struct ip *pip = (const struct ip *)packet;
258
259    len = ntohs(pip->ip_off) & IP_OFFMASK;	/* fragment offset */
260    if (len > 0) {		/* Not first fragment within datagram */
261      if (len < (24 >> 3)) {	/* don't allow fragment to over-write header */
262        log_Printf(LogFILTER, " error: illegal header\n");
263        return 1;
264      }
265      /* permit fragments on in and out filter */
266      if (!filter->fragok) {
267        log_Printf(LogFILTER, " error: illegal fragmentation\n");
268        return 1;
269      } else
270        return 0;
271    }
272
273    ncpaddr_setip4(&srcaddr, pip->ip_src);
274    ncpaddr_setip4(&dstaddr, pip->ip_dst);
275    datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
276    payload = packet + (pip->ip_hl << 2);
277    cproto = pip->ip_p;
278  }
279
280
281  gotinfo = estab = syn = finrst = didname = 0;
282  sport = dport = 0;
283
284  for (n = 0; n < MAXFILTERS; ) {
285    if (fp->f_action == A_NONE) {
286      n++;
287      fp++;
288      continue;
289    }
290
291    if (!didname) {
292      log_Printf(LogDEBUG, "%s filter:\n", filter->name);
293      didname = 1;
294    }
295
296    match = 0;
297
298    if ((ncprange_family(&fp->f_src) == AF_UNSPEC ||
299         ncprange_contains(&fp->f_src, &srcaddr)) &&
300        (ncprange_family(&fp->f_dst) == AF_UNSPEC ||
301         ncprange_contains(&fp->f_dst, &dstaddr))) {
302      if (fp->f_proto != 0) {
303        if (!gotinfo) {
304          const struct tcphdr *th;
305          const struct udphdr *uh;
306          const struct icmp *ih;
307#ifndef NOINET6
308          const struct icmp6_hdr *ih6;
309#endif
310          mindata = 0;
311          sport = dport = 0;
312          estab = syn = finrst = -1;
313
314          switch (cproto) {
315          case IPPROTO_ICMP:
316            mindata = 8;	/* ICMP must be at least 8 octets */
317            ih = (const struct icmp *)payload;
318            sport = ih->icmp_type;
319            if (log_IsKept(LogDEBUG))
320              snprintf(dbuff, sizeof dbuff, "sport = %d", sport);
321            break;
322
323#ifndef NOINET6
324          case IPPROTO_ICMPV6:
325            mindata = 8;	/* ICMP must be at least 8 octets */
326            ih6 = (const struct icmp6_hdr *)payload;
327            sport = ih6->icmp6_type;
328            if (log_IsKept(LogDEBUG))
329              snprintf(dbuff, sizeof dbuff, "sport = %d", sport);
330            break;
331#endif
332
333          case IPPROTO_IGMP:
334            mindata = 8;	/* IGMP uses 8-octet messages */
335            break;
336
337#ifdef IPPROTO_GRE
338          case IPPROTO_GRE:
339            mindata = 2;	/* GRE uses 2-octet+ messages */
340            break;
341#endif
342#ifdef IPPROTO_OSPFIGP
343          case IPPROTO_OSPFIGP:
344            mindata = 8;	/* IGMP uses 8-octet messages */
345            break;
346#endif
347#ifndef NOINET6
348          case IPPROTO_IPV6:
349            mindata = 20;	/* RFC2893 Section 3.5: 5 * 32bit words */
350            break;
351#endif
352
353          case IPPROTO_UDP:
354            mindata = 8;	/* UDP header is 8 octets */
355            uh = (const struct udphdr *)payload;
356            sport = ntohs(uh->uh_sport);
357            dport = ntohs(uh->uh_dport);
358            if (log_IsKept(LogDEBUG))
359              snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d",
360                       sport, dport);
361            break;
362
363          case IPPROTO_TCP:
364            th = (const struct tcphdr *)payload;
365            /*
366             * TCP headers are variable length.  The following code
367             * ensures that the TCP header length isn't de-referenced if
368             * the datagram is too short
369             */
370            if (datalen < 20 || datalen < (th->th_off << 2)) {
371              log_Printf(LogFILTER, " error: TCP header incorrect\n");
372              return 1;
373            }
374            sport = ntohs(th->th_sport);
375            dport = ntohs(th->th_dport);
376            estab = (th->th_flags & TH_ACK);
377            syn = (th->th_flags & TH_SYN);
378            finrst = (th->th_flags & (TH_FIN|TH_RST));
379            if (log_IsKept(LogDEBUG)) {
380              if (!estab)
381                snprintf(dbuff, sizeof dbuff,
382                         "flags = %02x, sport = %d, dport = %d",
383                         th->th_flags, sport, dport);
384              else
385                *dbuff = '\0';
386            }
387            break;
388          default:
389            break;
390          }
391
392          if (datalen < mindata) {
393            log_Printf(LogFILTER, " error: proto %s must be at least"
394                       " %d octets\n", prototxt(cproto), mindata);
395            return 1;
396          }
397
398          if (log_IsKept(LogDEBUG)) {
399            if (estab != -1) {
400              len = strlen(dbuff);
401              snprintf(dbuff + len, sizeof dbuff - len,
402                       ", estab = %d, syn = %d, finrst = %d",
403                       estab, syn, finrst);
404            }
405            log_Printf(LogDEBUG, " Filter: proto = %s, %s\n",
406                       prototxt(cproto), dbuff);
407          }
408          gotinfo = 1;
409        }
410
411        if (log_IsKept(LogDEBUG)) {
412          if (fp->f_srcop != OP_NONE) {
413            snprintf(dbuff, sizeof dbuff, ", src %s %d",
414                     filter_Op2Nam(fp->f_srcop), fp->f_srcport);
415            len = strlen(dbuff);
416          } else
417            len = 0;
418          if (fp->f_dstop != OP_NONE) {
419            snprintf(dbuff + len, sizeof dbuff - len,
420                     ", dst %s %d", filter_Op2Nam(fp->f_dstop),
421                     fp->f_dstport);
422          } else if (!len)
423            *dbuff = '\0';
424
425          log_Printf(LogDEBUG, "  rule = %d: Address match, "
426                     "check against proto %d%s, action = %s\n",
427                     n, fp->f_proto, dbuff, filter_Action2Nam(fp->f_action));
428        }
429
430        if (cproto == fp->f_proto) {
431          if ((fp->f_srcop == OP_NONE ||
432               PortMatch(fp->f_srcop, sport, fp->f_srcport)) &&
433              (fp->f_dstop == OP_NONE ||
434               PortMatch(fp->f_dstop, dport, fp->f_dstport)) &&
435              (fp->f_estab == 0 || estab) &&
436              (fp->f_syn == 0 || syn) &&
437              (fp->f_finrst == 0 || finrst)) {
438            match = 1;
439          }
440        }
441      } else {
442        /* Address is matched and no protocol specified. Make a decision. */
443        log_Printf(LogDEBUG, "  rule = %d: Address match, action = %s\n", n,
444                   filter_Action2Nam(fp->f_action));
445        match = 1;
446      }
447    } else
448      log_Printf(LogDEBUG, "  rule = %d: Address mismatch\n", n);
449
450    if (match != fp->f_invert) {
451      /* Take specified action */
452      if (fp->f_action < A_NONE)
453        fp = &filter->rule[n = fp->f_action];
454      else {
455        if (fp->f_action == A_PERMIT) {
456          if (psecs != NULL)
457            *psecs = fp->timeout;
458          if (strcmp(filter->name, "DIAL") == 0) {
459            /* If dial filter then even print out accept packets */
460            if (log_IsKept(LogFILTER)) {
461              snprintf(dstip, sizeof dstip, "%s", ncpaddr_ntoa(&dstaddr));
462              log_Printf(LogFILTER, "%sbound rule = %d accept %s "
463                         "src = %s:%d dst = %s:%d\n", filter->name, n,
464                         prototxt(cproto), ncpaddr_ntoa(&srcaddr), sport,
465                         dstip, dport);
466            }
467          }
468          return 0;
469        } else {
470          if (log_IsKept(LogFILTER)) {
471            snprintf(dstip, sizeof dstip, "%s", ncpaddr_ntoa(&dstaddr));
472            log_Printf(LogFILTER,
473                       "%sbound rule = %d deny %s src = %s/%d dst = %s/%d\n",
474                       filter->name, n, prototxt(cproto),
475                       ncpaddr_ntoa(&srcaddr), sport, dstip, dport);
476          }
477          return 1;
478        }		/* Explicit match.  Deny this packet */
479      }
480    } else {
481      n++;
482      fp++;
483    }
484  }
485
486  if (log_IsKept(LogFILTER)) {
487    snprintf(dstip, sizeof dstip, "%s", ncpaddr_ntoa(&dstaddr));
488    log_Printf(LogFILTER,
489               "%sbound rule = implicit deny %s src = %s/%d dst = %s/%d\n",
490               filter->name, prototxt(cproto), ncpaddr_ntoa(&srcaddr),
491               sport, dstip, dport);
492  }
493
494  return 1;		/* No rule matched, deny this packet */
495}
496
497static void
498ip_LogDNS(const struct udphdr *uh, const char *direction)
499{
500  struct dns_header header;
501  const u_short *pktptr;
502  const u_char *ptr;
503  u_short *hptr, tmp;
504  unsigned len;
505
506  ptr = (const char *)uh + sizeof *uh;
507  len = ntohs(uh->uh_ulen) - sizeof *uh;
508  if (len < sizeof header + 5)		/* rfc1024 */
509    return;
510
511  pktptr = (const u_short *)ptr;
512  hptr = (u_short *)&header;
513  ptr += sizeof header;
514  len -= sizeof header;
515
516  while (pktptr < (const u_short *)ptr) {
517    *hptr++ = ntohs(*pktptr);		/* Careful of macro side-effects ! */
518    pktptr++;
519  }
520
521  if (header.opcode == OPCODE_QUERY && header.qr == 0) {
522    /* rfc1035 */
523    char namewithdot[MAXHOSTNAMELEN + 1], *n;
524    const char *qtype, *qclass;
525    const u_char *end;
526
527    n = namewithdot;
528    end = ptr + len - 4;
529    if (end - ptr >= (int)sizeof namewithdot)
530      end = ptr + sizeof namewithdot - 1;
531    while (ptr < end) {
532      len = *ptr++;
533      if ((int)len > end - ptr)
534        len = end - ptr;
535      if (n != namewithdot)
536        *n++ = '.';
537      memcpy(n, ptr, len);
538      ptr += len;
539      n += len;
540    }
541    *n = '\0';
542
543    if (log_IsKept(LogDNS)) {
544      memcpy(&tmp, end, sizeof tmp);
545      qtype = dns_Qtype2Txt(ntohs(tmp));
546      memcpy(&tmp, end + 2, sizeof tmp);
547      qclass = dns_Qclass2Txt(ntohs(tmp));
548
549      log_Printf(LogDNS, "%sbound query %s %s %s\n",
550                 direction, qclass, qtype, namewithdot);
551    }
552  }
553}
554
555/*
556 * Check if the given packet matches the given filter.
557 * One of pip or pip6 must be set.
558 */
559int
560PacketCheck(struct bundle *bundle, u_int32_t family,
561            const unsigned char *packet, int nb, struct filter *filter,
562            const char *prefix, unsigned *psecs)
563{
564  char logbuf[200];
565  static const char *const TcpFlags[] = {
566    "FIN", "SYN", "RST", "PSH", "ACK", "URG"
567  };
568  const struct tcphdr *th;
569  const struct udphdr *uh;
570  const struct icmp *icmph;
571#ifndef NOINET6
572  const struct icmp6_hdr *icmp6h;
573#endif
574  const unsigned char *payload;
575  struct ncpaddr srcaddr, dstaddr;
576  int cproto, mask, len, n, pri, logit, result, datalen, frag;
577  unsigned loglen;
578  u_char tos;
579
580  logit = (log_IsKept(LogTCPIP) || log_IsKept(LogDNS)) &&
581          (!filter || filter->logok);
582  loglen = 0;
583  pri = 0;
584
585#ifndef NOINET6
586  if (family == AF_INET6) {
587    const struct ip6_hdr *pip6 = (const struct ip6_hdr *)packet;
588
589    ncpaddr_setip6(&srcaddr, &pip6->ip6_src);
590    ncpaddr_setip6(&dstaddr, &pip6->ip6_dst);
591    datalen = ntohs(pip6->ip6_plen);
592    payload = packet + sizeof *pip6;
593    cproto = pip6->ip6_nxt;
594    tos = 0;					/* XXX: pip6->ip6_vfc >> 4 ? */
595    frag = 0;					/* XXX: ??? */
596  } else
597#endif
598  {
599    const struct ip *pip = (const struct ip *)packet;
600
601    ncpaddr_setip4(&srcaddr, pip->ip_src);
602    ncpaddr_setip4(&dstaddr, pip->ip_dst);
603    datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
604    payload = packet + (pip->ip_hl << 2);
605    cproto = pip->ip_p;
606    tos = pip->ip_tos;
607    frag = ntohs(pip->ip_off) & IP_OFFMASK;
608  }
609
610  uh = NULL;
611
612  if (logit && loglen < sizeof logbuf) {
613    if (prefix)
614      snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s", prefix);
615    else if (filter)
616      snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name);
617    else
618      snprintf(logbuf + loglen, sizeof logbuf - loglen, "  ");
619    loglen += strlen(logbuf + loglen);
620  }
621
622  switch (cproto) {
623  case IPPROTO_ICMP:
624    if (logit && loglen < sizeof logbuf) {
625      len = datalen - sizeof *icmph;
626      icmph = (const struct icmp *)payload;
627      snprintf(logbuf + loglen, sizeof logbuf - loglen,
628               "ICMP: %s:%d ---> ", ncpaddr_ntoa(&srcaddr), icmph->icmp_type);
629      loglen += strlen(logbuf + loglen);
630      snprintf(logbuf + loglen, sizeof logbuf - loglen,
631               "%s (%d/%d)", ncpaddr_ntoa(&dstaddr), len, nb);
632      loglen += strlen(logbuf + loglen);
633    }
634    break;
635
636#ifndef NOINET6
637  case IPPROTO_ICMPV6:
638    if (logit && loglen < sizeof logbuf) {
639      len = datalen - sizeof *icmp6h;
640      icmp6h = (const struct icmp6_hdr *)payload;
641      snprintf(logbuf + loglen, sizeof logbuf - loglen,
642               "ICMP: %s:%d ---> ", ncpaddr_ntoa(&srcaddr), icmp6h->icmp6_type);
643      loglen += strlen(logbuf + loglen);
644      snprintf(logbuf + loglen, sizeof logbuf - loglen,
645               "%s (%d/%d)", ncpaddr_ntoa(&dstaddr), len, nb);
646      loglen += strlen(logbuf + loglen);
647    }
648    break;
649#endif
650
651  case IPPROTO_UDP:
652    uh = (const struct udphdr *)payload;
653    if (tos == IPTOS_LOWDELAY && bundle->ncp.cfg.urgent.tos)
654      pri++;
655
656    if (!frag && ncp_IsUrgentUdpPort(&bundle->ncp, ntohs(uh->uh_sport),
657                                     ntohs(uh->uh_dport)))
658      pri++;
659
660    if (logit && loglen < sizeof logbuf) {
661      len = datalen - sizeof *uh;
662      snprintf(logbuf + loglen, sizeof logbuf - loglen,
663               "UDP: %s:%d ---> ", ncpaddr_ntoa(&srcaddr), ntohs(uh->uh_sport));
664      loglen += strlen(logbuf + loglen);
665      snprintf(logbuf + loglen, sizeof logbuf - loglen,
666               "%s:%d (%d/%d)", ncpaddr_ntoa(&dstaddr), ntohs(uh->uh_dport),
667               len, nb);
668      loglen += strlen(logbuf + loglen);
669    }
670
671    if (Enabled(bundle, OPT_FILTERDECAP) &&
672        payload[sizeof *uh] == HDLC_ADDR &&
673        payload[sizeof *uh + 1] == HDLC_UI) {
674      u_short proto;
675      const char *type;
676
677      memcpy(&proto, payload + sizeof *uh + 2, sizeof proto);
678      type = NULL;
679
680      switch (ntohs(proto)) {
681        case PROTO_IP:
682          snprintf(logbuf + loglen, sizeof logbuf - loglen, " contains ");
683          result = PacketCheck(bundle, AF_INET, payload + sizeof *uh + 4,
684                               nb - (payload - packet) - sizeof *uh - 4, filter,
685                               logbuf, psecs);
686          if (result != -2)
687              return result;
688          type = "IP";
689          break;
690
691        case PROTO_VJUNCOMP: type = "compressed VJ";   break;
692        case PROTO_VJCOMP:   type = "uncompressed VJ"; break;
693        case PROTO_MP:       type = "Multi-link"; break;
694        case PROTO_ICOMPD:   type = "Individual link CCP"; break;
695        case PROTO_COMPD:    type = "CCP"; break;
696        case PROTO_IPCP:     type = "IPCP"; break;
697        case PROTO_LCP:      type = "LCP"; break;
698        case PROTO_PAP:      type = "PAP"; break;
699        case PROTO_CBCP:     type = "CBCP"; break;
700        case PROTO_LQR:      type = "LQR"; break;
701        case PROTO_CHAP:     type = "CHAP"; break;
702      }
703      if (type) {
704        snprintf(logbuf + loglen, sizeof logbuf - loglen,
705                 " - %s data", type);
706        loglen += strlen(logbuf + loglen);
707      }
708    }
709
710    break;
711
712#ifdef IPPROTO_GRE
713  case IPPROTO_GRE:
714    if (logit && loglen < sizeof logbuf) {
715      snprintf(logbuf + loglen, sizeof logbuf - loglen,
716          "GRE: %s ---> ", ncpaddr_ntoa(&srcaddr));
717      loglen += strlen(logbuf + loglen);
718      snprintf(logbuf + loglen, sizeof logbuf - loglen,
719              "%s (%d/%d)", ncpaddr_ntoa(&dstaddr), datalen, nb);
720      loglen += strlen(logbuf + loglen);
721    }
722    break;
723#endif
724
725#ifdef IPPROTO_OSPFIGP
726  case IPPROTO_OSPFIGP:
727    if (logit && loglen < sizeof logbuf) {
728      snprintf(logbuf + loglen, sizeof logbuf - loglen,
729               "OSPF: %s ---> ", ncpaddr_ntoa(&srcaddr));
730      loglen += strlen(logbuf + loglen);
731      snprintf(logbuf + loglen, sizeof logbuf - loglen,
732               "%s (%d/%d)", ncpaddr_ntoa(&dstaddr), datalen, nb);
733      loglen += strlen(logbuf + loglen);
734    }
735    break;
736#endif
737
738#ifndef NOINET6
739  case IPPROTO_IPV6:
740    if (logit && loglen < sizeof logbuf) {
741      snprintf(logbuf + loglen, sizeof logbuf - loglen,
742               "IPv6: %s ---> ", ncpaddr_ntoa(&srcaddr));
743      loglen += strlen(logbuf + loglen);
744      snprintf(logbuf + loglen, sizeof logbuf - loglen,
745               "%s (%d/%d)", ncpaddr_ntoa(&dstaddr), datalen, nb);
746      loglen += strlen(logbuf + loglen);
747    }
748
749    if (Enabled(bundle, OPT_FILTERDECAP)) {
750      snprintf(logbuf + loglen, sizeof logbuf - loglen, " contains ");
751      result = PacketCheck(bundle, AF_INET6, payload, nb - (payload - packet),
752                           filter, logbuf, psecs);
753      if (result != -2)
754        return result;
755    }
756    break;
757#endif
758
759  case IPPROTO_IPIP:
760    if (logit && loglen < sizeof logbuf) {
761      snprintf(logbuf + loglen, sizeof logbuf - loglen,
762               "IPIP: %s ---> ", ncpaddr_ntoa(&srcaddr));
763      loglen += strlen(logbuf + loglen);
764      snprintf(logbuf + loglen, sizeof logbuf - loglen,
765               "%s", ncpaddr_ntoa(&dstaddr));
766      loglen += strlen(logbuf + loglen);
767    }
768
769    if (Enabled(bundle, OPT_FILTERDECAP) &&
770        ((const struct ip *)payload)->ip_v == 4) {
771      snprintf(logbuf + loglen, sizeof logbuf - loglen, " contains ");
772      result = PacketCheck(bundle, AF_INET, payload, nb - (payload - packet),
773                           filter, logbuf, psecs);
774      loglen += strlen(logbuf + loglen);
775      if (result != -2)
776        return result;
777    }
778    break;
779
780  case IPPROTO_ESP:
781    if (logit && loglen < sizeof logbuf) {
782      snprintf(logbuf + loglen, sizeof logbuf - loglen,
783               "ESP: %s ---> ", ncpaddr_ntoa(&srcaddr));
784      loglen += strlen(logbuf + loglen);
785      snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s, spi %p",
786               ncpaddr_ntoa(&dstaddr), payload);
787      loglen += strlen(logbuf + loglen);
788    }
789    break;
790
791  case IPPROTO_AH:
792    if (logit && loglen < sizeof logbuf) {
793      snprintf(logbuf + loglen, sizeof logbuf - loglen,
794               "AH: %s ---> ", ncpaddr_ntoa(&srcaddr));
795      loglen += strlen(logbuf + loglen);
796      snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s, spi %p",
797               ncpaddr_ntoa(&dstaddr), payload + sizeof(u_int32_t));
798      loglen += strlen(logbuf + loglen);
799    }
800    break;
801
802  case IPPROTO_IGMP:
803    if (logit && loglen < sizeof logbuf) {
804      uh = (const struct udphdr *)payload;
805      snprintf(logbuf + loglen, sizeof logbuf - loglen,
806               "IGMP: %s:%d ---> ", ncpaddr_ntoa(&srcaddr),
807               ntohs(uh->uh_sport));
808      loglen += strlen(logbuf + loglen);
809      snprintf(logbuf + loglen, sizeof logbuf - loglen,
810               "%s:%d", ncpaddr_ntoa(&dstaddr), ntohs(uh->uh_dport));
811      loglen += strlen(logbuf + loglen);
812    }
813    break;
814
815  case IPPROTO_TCP:
816    th = (const struct tcphdr *)payload;
817    if (tos == IPTOS_LOWDELAY && bundle->ncp.cfg.urgent.tos)
818      pri++;
819
820    if (!frag && ncp_IsUrgentTcpPort(&bundle->ncp, ntohs(th->th_sport),
821                                     ntohs(th->th_dport)))
822      pri++;
823
824    if (logit && loglen < sizeof logbuf) {
825      len = datalen - (th->th_off << 2);
826      snprintf(logbuf + loglen, sizeof logbuf - loglen,
827           "TCP: %s:%d ---> ", ncpaddr_ntoa(&srcaddr), ntohs(th->th_sport));
828      loglen += strlen(logbuf + loglen);
829      snprintf(logbuf + loglen, sizeof logbuf - loglen,
830               "%s:%d", ncpaddr_ntoa(&dstaddr), ntohs(th->th_dport));
831      loglen += strlen(logbuf + loglen);
832      n = 0;
833      for (mask = TH_FIN; mask != 0x40; mask <<= 1) {
834        if (th->th_flags & mask) {
835          snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]);
836          loglen += strlen(logbuf + loglen);
837        }
838        n++;
839      }
840      snprintf(logbuf + loglen, sizeof logbuf - loglen,
841               "  seq:%lx  ack:%lx (%d/%d)",
842               (u_long)ntohl(th->th_seq), (u_long)ntohl(th->th_ack), len, nb);
843      loglen += strlen(logbuf + loglen);
844      if ((th->th_flags & TH_SYN) && nb > 40) {
845        const u_short *sp;
846
847        sp = (const u_short *)(payload + 20);
848        if (ntohs(sp[0]) == 0x0204) {
849          snprintf(logbuf + loglen, sizeof logbuf - loglen,
850                   " MSS = %d", ntohs(sp[1]));
851          loglen += strlen(logbuf + loglen);
852        }
853      }
854    }
855    break;
856
857  default:
858    if (prefix)
859      return -2;
860
861    if (logit && loglen < sizeof logbuf) {
862      snprintf(logbuf + loglen, sizeof logbuf - loglen,
863               "<%d>: %s ---> ", cproto, ncpaddr_ntoa(&srcaddr));
864      loglen += strlen(logbuf + loglen);
865      snprintf(logbuf + loglen, sizeof logbuf - loglen,
866               "%s (%d)", ncpaddr_ntoa(&dstaddr), nb);
867      loglen += strlen(logbuf + loglen);
868    }
869    break;
870  }
871
872  if (filter && FilterCheck(packet, family, filter, psecs)) {
873    if (logit)
874      log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf);
875    result = -1;
876  } else {
877    /* Check Keep Alive filter */
878    if (logit && log_IsKept(LogTCPIP)) {
879      unsigned alivesecs;
880
881      alivesecs = 0;
882      if (filter &&
883          FilterCheck(packet, family, &bundle->filter.alive, &alivesecs))
884        log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
885      else if (psecs != NULL) {
886        if(*psecs == 0)
887          *psecs = alivesecs;
888        if (*psecs) {
889          if (*psecs != alivesecs)
890            log_Printf(LogTCPIP, "%s - (timeout = %d / ALIVE = %d secs)\n",
891                       logbuf, *psecs, alivesecs);
892          else
893            log_Printf(LogTCPIP, "%s - (timeout = %d secs)\n", logbuf, *psecs);
894        } else
895          log_Printf(LogTCPIP, "%s\n", logbuf);
896      }
897    }
898    result = pri;
899  }
900
901  if (filter && uh && ntohs(uh->uh_dport) == 53 && log_IsKept(LogDNS))
902    ip_LogDNS(uh, filter->name);
903
904  return result;
905}
906
907static size_t
908ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp, u_int32_t af)
909{
910  ssize_t nw;
911  size_t nb;
912  struct tun_data tun;
913  char *data;
914  unsigned secs, alivesecs;
915
916  nb = m_length(bp);
917  if (nb > sizeof tun.data) {
918    log_Printf(LogWARN, "ip_Input: %s: Packet too large (got %zd, max %d)\n",
919               l->name, nb, (int)(sizeof tun.data));
920    m_freem(bp);
921    return 0;
922  }
923  mbuf_Read(bp, tun.data, nb);
924
925  secs = 0;
926  if (PacketCheck(bundle, af, tun.data, nb, &bundle->filter.in,
927                  NULL, &secs) < 0)
928    return 0;
929
930  alivesecs = 0;
931  if (!FilterCheck(tun.data, af, &bundle->filter.alive, &alivesecs)) {
932    if (secs == 0)
933      secs = alivesecs;
934    bundle_StartIdleTimer(bundle, secs);
935  }
936
937  if (bundle->dev.header) {
938    tun.header.family = htonl(af);
939    nb += sizeof tun - sizeof tun.data;
940    data = (char *)&tun;
941  } else
942    data = tun.data;
943
944  nw = write(bundle->dev.fd, data, nb);
945  if (nw != (ssize_t)nb) {
946    if (nw == -1)
947      log_Printf(LogERROR, "ip_Input: %s: wrote %zd, got %s\n",
948                 l->name, nb, strerror(errno));
949    else
950      log_Printf(LogERROR, "ip_Input: %s: wrote %zd, got %zd\n", l->name, nb,
951	  nw);
952  }
953
954  return nb;
955}
956
957struct mbuf *
958ipv4_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
959{
960  int nb;
961
962  if (bundle->ncp.ipcp.fsm.state != ST_OPENED) {
963    log_Printf(LogWARN, "ipv4_Input: IPCP not open - packet dropped\n");
964    m_freem(bp);
965    return NULL;
966  }
967
968  m_settype(bp, MB_IPIN);
969
970  nb = ip_Input(bundle, l, bp, AF_INET);
971  ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
972
973  return NULL;
974}
975
976#ifndef NOINET6
977struct mbuf *
978ipv6_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
979{
980  int nb;
981
982  if (bundle->ncp.ipv6cp.fsm.state != ST_OPENED) {
983    log_Printf(LogWARN, "ipv6_Input: IPV6CP not open - packet dropped\n");
984    m_freem(bp);
985    return NULL;
986  }
987
988  m_settype(bp, MB_IPV6IN);
989
990  nb = ip_Input(bundle, l, bp, AF_INET6);
991  ipv6cp_AddInOctets(&bundle->ncp.ipv6cp, nb);
992
993  return NULL;
994}
995#endif
996