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