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