ip.c revision 78411
1143247Sphantom/*- 2143247Sphantom * Copyright (c) 1996 - 2001 Brian Somers <brian@Awfulhak.org> 3143247Sphantom * based on work by Toshiharu OHNO <tony-o@iij.ad.jp> 4143247Sphantom * Internet Initiative Japan, Inc (IIJ) 5143247Sphantom * All rights reserved. 6143247Sphantom * 7143247Sphantom * Redistribution and use in source and binary forms, with or without 8143247Sphantom * modification, are permitted provided that the following conditions 9143247Sphantom * are met: 10143247Sphantom * 1. Redistributions of source code must retain the above copyright 11143247Sphantom * notice, this list of conditions and the following disclaimer. 12143247Sphantom * 2. Redistributions in binary form must reproduce the above copyright 13143247Sphantom * notice, this list of conditions and the following disclaimer in the 14143247Sphantom * documentation and/or other materials provided with the distribution. 15143247Sphantom * 16143247Sphantom * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 17143247Sphantom * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 18143247Sphantom * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 19143247Sphantom * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 20143247Sphantom * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 21143247Sphantom * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 22143247Sphantom * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 23143247Sphantom * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 24143247Sphantom * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 25143247Sphantom * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 26143247Sphantom * SUCH DAMAGE. 27143247Sphantom * 28143247Sphantom * $FreeBSD: head/usr.sbin/ppp/ip.c 78411 2001-06-18 15:00:22Z brian $ 29143247Sphantom */ 30143247Sphantom 31143247Sphantom#include <sys/param.h> 32143247Sphantom#include <sys/socket.h> 33143247Sphantom#include <netinet/in.h> 34143247Sphantom#include <netinet/in_systm.h> 35143247Sphantom#include <netinet/ip.h> 36143247Sphantom#include <netinet/ip_icmp.h> 37143247Sphantom#include <netinet/udp.h> 38143247Sphantom#include <netinet/tcp.h> 39143247Sphantom#include <arpa/inet.h> 40143247Sphantom#include <sys/un.h> 41143247Sphantom 42143247Sphantom#include <errno.h> 43143247Sphantom#include <stdio.h> 44143247Sphantom#include <string.h> 45143247Sphantom#include <termios.h> 46143247Sphantom#include <unistd.h> 47143247Sphantom 48143247Sphantom#include "layer.h" 49143247Sphantom#include "proto.h" 50143247Sphantom#include "mbuf.h" 51143247Sphantom#include "log.h" 52143247Sphantom#include "defs.h" 53143247Sphantom#include "timer.h" 54143247Sphantom#include "fsm.h" 55143247Sphantom#include "lqr.h" 56143247Sphantom#include "hdlc.h" 57143247Sphantom#include "throughput.h" 58143247Sphantom#include "iplist.h" 59143247Sphantom#include "slcompress.h" 60143247Sphantom#include "ipcp.h" 61143247Sphantom#include "filter.h" 62143247Sphantom#include "descriptor.h" 63143247Sphantom#include "lcp.h" 64143247Sphantom#include "ccp.h" 65143247Sphantom#include "link.h" 66143247Sphantom#include "mp.h" 67143247Sphantom#ifndef NORADIUS 68143247Sphantom#include "radius.h" 69143247Sphantom#endif 70143247Sphantom#include "bundle.h" 71143247Sphantom#include "tun.h" 72143247Sphantom#include "ip.h" 73143247Sphantom 74143247Sphantom 75143247Sphantom#define OPCODE_QUERY 0 76143247Sphantom#define OPCODE_IQUERY 1 77143247Sphantom#define OPCODE_STATUS 2 78143247Sphantom 79143247Sphantomstruct dns_header { 80143247Sphantom u_short id; 81143247Sphantom unsigned qr : 1; 82143247Sphantom unsigned opcode : 4; 83143247Sphantom unsigned aa : 1; 84143247Sphantom unsigned tc : 1; 85143247Sphantom unsigned rd : 1; 86143247Sphantom unsigned ra : 1; 87143247Sphantom unsigned z : 3; 88143247Sphantom unsigned rcode : 4; 89143247Sphantom u_short qdcount; 90143247Sphantom u_short ancount; 91143247Sphantom u_short nscount; 92143247Sphantom u_short arcount; 93143247Sphantom}; 94143247Sphantom 95143247Sphantomstatic const char * 96143247Sphantomdns_Qclass2Txt(u_short qclass) 97143247Sphantom{ 98143247Sphantom static char failure[6]; 99143247Sphantom struct { 100143247Sphantom u_short id; 101143247Sphantom const char *txt; 102143247Sphantom } qtxt[] = { 103143247Sphantom /* rfc1035 */ 104143247Sphantom { 1, "IN" }, { 2, "CS" }, { 3, "CH" }, { 4, "HS" }, { 255, "*" } 105143247Sphantom }; 106143247Sphantom int f; 107143247Sphantom 108143247Sphantom for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++) 109143247Sphantom if (qtxt[f].id == qclass) 110143247Sphantom return qtxt[f].txt; 111143247Sphantom 112143247Sphantom return HexStr(qclass, failure, sizeof failure); 113143247Sphantom} 114143247Sphantom 115143247Sphantomstatic const char * 116143247Sphantomdns_Qtype2Txt(u_short qtype) 117143247Sphantom{ 118143247Sphantom static char failure[6]; 119143247Sphantom struct { 120143247Sphantom u_short id; 121143247Sphantom const char *txt; 122143247Sphantom } qtxt[] = { 123143247Sphantom /* rfc1035/rfc1700 */ 124143247Sphantom { 1, "A" }, { 2, "NS" }, { 3, "MD" }, { 4, "MF" }, { 5, "CNAME" }, 125143247Sphantom { 6, "SOA" }, { 7, "MB" }, { 8, "MG" }, { 9, "MR" }, { 10, "NULL" }, 126143247Sphantom { 11, "WKS" }, { 12, "PTR" }, { 13, "HINFO" }, { 14, "MINFO" }, 127143247Sphantom { 15, "MX" }, { 16, "TXT" }, { 17, "RP" }, { 18, "AFSDB" }, 128143247Sphantom { 19, "X25" }, { 20, "ISDN" }, { 21, "RT" }, { 22, "NSAP" }, 129143247Sphantom { 23, "NSAP-PTR" }, { 24, "SIG" }, { 25, "KEY" }, { 26, "PX" }, 130143247Sphantom { 27, "GPOS" }, { 28, "AAAA" }, { 252, "AXFR" }, { 253, "MAILB" }, 131143247Sphantom { 254, "MAILA" }, { 255, "*" } 132143247Sphantom }; 133143247Sphantom int f; 134143247Sphantom 135143247Sphantom for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++) 136143247Sphantom if (qtxt[f].id == qtype) 137143247Sphantom return qtxt[f].txt; 138143247Sphantom 139143247Sphantom return HexStr(qtype, failure, sizeof failure); 140143247Sphantom} 141143247Sphantom 142143247Sphantomstatic __inline int 143143247SphantomPortMatch(int op, u_short pport, u_short rport) 144143247Sphantom{ 145143247Sphantom switch (op) { 146143247Sphantom case OP_EQ: 147143247Sphantom return pport == rport; 148143247Sphantom case OP_GT: 149143247Sphantom return pport > rport; 150143247Sphantom case OP_LT: 151143247Sphantom return pport < rport; 152143247Sphantom default: 153143247Sphantom return 0; 154143247Sphantom } 155143247Sphantom} 156143247Sphantom 157143247Sphantom/* 158143247Sphantom * Check a packet against a defined filter 159143247Sphantom * Returns 0 to accept the packet, non-zero to drop the packet 160143247Sphantom * 161143247Sphantom * If filtering is enabled, the initial fragment of a datagram must 162143247Sphantom * contain the complete protocol header, and subsequent fragments 163143247Sphantom * must not attempt to over-write it. 164143247Sphantom */ 165143247Sphantomstatic int 166143247SphantomFilterCheck(const struct ip *pip, const struct filter *filter, unsigned *psecs) 167143247Sphantom{ 168143247Sphantom int gotinfo; /* true if IP payload decoded */ 169143247Sphantom int cproto; /* P_* protocol type if (gotinfo) */ 170143247Sphantom int estab, syn, finrst; /* TCP state flags if (gotinfo) */ 171143247Sphantom u_short sport, dport; /* src, dest port from packet if (gotinfo) */ 172143247Sphantom int n; /* filter rule to process */ 173143247Sphantom int len; /* bytes used in dbuff */ 174143247Sphantom int didname; /* true if filter header printed */ 175143247Sphantom int match; /* true if condition matched */ 176143247Sphantom const struct filterent *fp = filter->rule; 177143247Sphantom char dbuff[100], dstip[16]; 178143247Sphantom 179143247Sphantom if (fp->f_action == A_NONE) 180143247Sphantom return 0; /* No rule is given. Permit this packet */ 181143247Sphantom 182143247Sphantom /* 183143247Sphantom * Deny any packet fragment that tries to over-write the header. 184199329Sjkim * Since we no longer have the real header available, punt on the 185199329Sjkim * largest normal header - 20 bytes for TCP without options, rounded 186199329Sjkim * up to the next possible fragment boundary. Since the smallest 187199329Sjkim * `legal' MTU is 576, and the smallest recommended MTU is 296, any 188199329Sjkim * fragmentation within this range is dubious at best 189199329Sjkim */ 190199329Sjkim len = ntohs(pip->ip_off) & IP_OFFMASK; /* fragment offset */ 191199329Sjkim if (len > 0) { /* Not first fragment within datagram */ 192199329Sjkim if (len < (24 >> 3)) { /* don't allow fragment to over-write header */ 193199329Sjkim log_Printf(LogFILTER, " error: illegal header\n"); 194143247Sphantom return 1; 195143247Sphantom } 196143247Sphantom /* permit fragments on in and out filter */ 197143247Sphantom if (!filter->fragok) { 198143247Sphantom log_Printf(LogFILTER, " error: illegal fragmentation\n"); 199143247Sphantom return 1; 200143247Sphantom } else 201143247Sphantom return 0; 202143247Sphantom } 203143247Sphantom 204143247Sphantom cproto = gotinfo = estab = syn = finrst = didname = 0; 205143247Sphantom sport = dport = 0; 206143247Sphantom for (n = 0; n < MAXFILTERS; ) { 207148073Sjkim if (fp->f_action == A_NONE) { 208143247Sphantom n++; 209148073Sjkim fp++; 210143247Sphantom continue; 211148073Sjkim } 212143247Sphantom 213143247Sphantom if (!didname) { 214143247Sphantom log_Printf(LogDEBUG, "%s filter:\n", filter->name); 215143247Sphantom didname = 1; 216143247Sphantom } 217143247Sphantom 218143247Sphantom match = 0; 219143247Sphantom if (!((pip->ip_src.s_addr ^ fp->f_src.ipaddr.s_addr) & 220143247Sphantom fp->f_src.mask.s_addr) && 221143247Sphantom !((pip->ip_dst.s_addr ^ fp->f_dst.ipaddr.s_addr) & 222143247Sphantom fp->f_dst.mask.s_addr)) { 223143247Sphantom if (fp->f_proto != P_NONE) { 224143247Sphantom if (!gotinfo) { 225143247Sphantom const char *ptop = (const char *) pip + (pip->ip_hl << 2); 226143247Sphantom const struct tcphdr *th; 227143247Sphantom const struct udphdr *uh; 228143247Sphantom const struct icmp *ih; 229143247Sphantom int datalen; /* IP datagram length */ 230143247Sphantom 231143247Sphantom datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2); 232143247Sphantom switch (pip->ip_p) { 233143247Sphantom case IPPROTO_ICMP: 234143247Sphantom cproto = P_ICMP; 235143247Sphantom if (datalen < 8) { /* ICMP must be at least 8 octets */ 236143247Sphantom log_Printf(LogFILTER, " error: ICMP must be at least 8 octets\n"); 237143247Sphantom return 1; 238143247Sphantom } 239143247Sphantom 240143247Sphantom ih = (const struct icmp *) ptop; 241143247Sphantom sport = ih->icmp_type; 242143247Sphantom estab = syn = finrst = -1; 243199329Sjkim if (log_IsKept(LogDEBUG)) 244143247Sphantom snprintf(dbuff, sizeof dbuff, "sport = %d", sport); 245143247Sphantom break; 246143247Sphantom case IPPROTO_IGMP: 247143247Sphantom cproto = P_IGMP; 248143247Sphantom if (datalen < 8) { /* IGMP uses 8-octet messages */ 249143247Sphantom log_Printf(LogFILTER, " error: IGMP must be at least 8 octets\n"); 250143247Sphantom return 1; 251143247Sphantom } 252143247Sphantom estab = syn = finrst = -1; 253143247Sphantom sport = ntohs(0); 254143247Sphantom break; 255143247Sphantom#ifdef IPPROTO_GRE 256143247Sphantom case IPPROTO_GRE: 257143247Sphantom cproto = P_GRE; 258143247Sphantom if (datalen < 2) { /* GRE uses 2-octet+ messages */ 259143247Sphantom log_Printf(LogFILTER, " error: GRE must be at least 2 octets\n"); 260199329Sjkim return 1; 261199329Sjkim } 262199329Sjkim estab = syn = finrst = -1; 263199329Sjkim sport = ntohs(0); 264199329Sjkim break; 265199329Sjkim#endif 266199329Sjkim#ifdef IPPROTO_OSPFIGP 267199329Sjkim case IPPROTO_OSPFIGP: 268199329Sjkim cproto = P_OSPF; 269199329Sjkim if (datalen < 8) { /* IGMP uses 8-octet messages */ 270199329Sjkim log_Printf(LogFILTER, " error: IGMP must be at least 8 octets\n"); 271199329Sjkim return 1; 272199329Sjkim } 273199329Sjkim estab = syn = finrst = -1; 274199329Sjkim sport = ntohs(0); 275199329Sjkim break; 276199329Sjkim#endif 277199329Sjkim case IPPROTO_ESP: 278199329Sjkim cproto = P_ESP; 279199329Sjkim estab = syn = finrst = -1; 280199329Sjkim sport = ntohs(0); 281199329Sjkim break; 282199329Sjkim case IPPROTO_AH: 283199329Sjkim cproto = P_AH; 284199329Sjkim estab = syn = finrst = -1; 285199329Sjkim sport = ntohs(0); 286199329Sjkim break; 287199329Sjkim case IPPROTO_IPIP: 288199329Sjkim cproto = P_IPIP; 289199329Sjkim sport = dport = 0; 290199329Sjkim estab = syn = finrst = -1; 291199329Sjkim break; 292199329Sjkim case IPPROTO_UDP: 293199329Sjkim cproto = P_UDP; 294199329Sjkim if (datalen < 8) { /* UDP header is 8 octets */ 295199329Sjkim 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 /* 910 * If ccp is not open but is required, do nothing. 911 */ 912 if (l->ccp.fsm.state != ST_OPENED && ccp_Required(&l->ccp)) { 913 log_Printf(LogPHASE, "%s: Not transmitting... waiting for CCP\n", l->name); 914 return 0; 915 } 916 917 queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1; 918 do { 919 if (queue->top) { 920 bp = m_dequeue(queue); 921 bp = mbuf_Read(bp, &secs, sizeof secs); 922 bp = m_pullup(bp); 923 m_len = m_length(bp); 924 pip = (struct ip *)MBUF_CTOP(bp); 925 if (!FilterCheck(pip, &bundle->filter.alive, &alivesecs)) { 926 if (secs == 0) 927 secs = alivesecs; 928 bundle_StartIdleTimer(bundle, secs); 929 } 930 link_PushPacket(l, bp, bundle, 0, PROTO_IP); 931 ipcp_AddOutOctets(ipcp, m_len); 932 return 1; 933 } 934 } while (queue-- != ipcp->Queue); 935 936 return 0; 937} 938