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