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