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