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