1 /* 2 * PPP IP Protocol Interface 3 * 4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp) 5 * 6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd. 7 * 8 * Redistribution and use in source and binary forms are permitted 9 * provided that the above copyright notice and this paragraph are 10 * duplicated in all such forms and that any documentation, 11 * advertising materials, and other materials related to such 12 * distribution and use acknowledge that the software was developed 13 * by the Internet Initiative Japan. The name of the 14 * IIJ may not be used to endorse or promote products derived 15 * from this software without specific prior written permission. 16 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR 17 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 18 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 19 * 20 * $FreeBSD$ 21 * 22 * TODO: 23 * o Return ICMP message for filterd packet 24 * and optionaly record it into log. 25 */ 26 #include <sys/param.h> 27 #if defined(__OpenBSD__) || defined(__NetBSD__) 28 #include <sys/socket.h> 29 #endif 30 #include <netinet/in.h> 31 #include <netinet/in_systm.h> 32 #include <netinet/ip.h> 33 #include <netinet/ip_icmp.h> 34 #include <netinet/udp.h> 35 #include <netinet/tcp.h> 36 #include <arpa/inet.h> 37 #include <sys/un.h> 38 39 #include <errno.h> 40 #include <stdio.h> 41 #include <string.h> 42 #include <termios.h> 43 #include <unistd.h> 44 45 #include "layer.h" 46 #include "proto.h" 47 #include "mbuf.h" 48 #include "log.h" 49 #include "defs.h" 50 #include "timer.h" 51 #include "fsm.h" 52 #include "lqr.h" 53 #include "hdlc.h" 54 #include "throughput.h" 55 #include "iplist.h" 56 #include "slcompress.h" 57 #include "ipcp.h" 58 #include "filter.h" 59 #include "descriptor.h" 60 #include "lcp.h" 61 #include "ccp.h" 62 #include "link.h" 63 #include "mp.h" 64 #ifndef NORADIUS 65 #include "radius.h" 66 #endif 67 #include "bundle.h" 68 #include "tun.h" 69 #include "ip.h" 70 71 static const char *TcpFlags[] = { "FIN", "SYN", "RST", "PSH", "ACK", "URG" }; 72 73 static __inline int 74 PortMatch(int op, u_short pport, u_short rport) 75 { 76 switch (op) { 77 case OP_EQ: 78 return (pport == rport); 79 case OP_GT: 80 return (pport > rport); 81 case OP_LT: 82 return (pport < rport); 83 default: 84 return (0); 85 } 86 } 87 88 /* 89 * Check a packet against a defined filter 90 * Returns 0 to accept the packet, non-zero to drop the packet 91 * 92 * If filtering is enabled, the initial fragment of a datagram must 93 * contain the complete protocol header, and subsequent fragments 94 * must not attempt to over-write it. 95 */ 96 static int 97 FilterCheck(const struct ip *pip, const struct filter *filter) 98 { 99 int gotinfo; /* true if IP payload decoded */ 100 int cproto; /* P_* protocol type if (gotinfo) */ 101 int estab, syn, finrst; /* TCP state flags if (gotinfo) */ 102 u_short sport, dport; /* src, dest port from packet if (gotinfo) */ 103 int n; /* filter rule to process */ 104 int len; /* bytes used in dbuff */ 105 int didname; /* true if filter header printed */ 106 int match; /* true if condition matched */ 107 const struct filterent *fp = filter->rule; 108 char dbuff[100]; 109 110 if (fp->f_action == A_NONE) 111 return (0); /* No rule is given. Permit this packet */ 112 113 /* Deny any packet fragment that tries to over-write the header. 114 * Since we no longer have the real header available, punt on the 115 * largest normal header - 20 bytes for TCP without options, rounded 116 * up to the next possible fragment boundary. Since the smallest 117 * `legal' MTU is 576, and the smallest recommended MTU is 296, any 118 * fragmentation within this range is dubious at best */ 119 len = ntohs(pip->ip_off) & IP_OFFMASK; /* fragment offset */ 120 if (len > 0) { /* Not first fragment within datagram */ 121 if (len < (24 >> 3)) /* don't allow fragment to over-write header */ 122 return (1); 123 /* permit fragments on in and out filter */ 124 return (!filter->fragok); 125 } 126 127 cproto = gotinfo = estab = syn = finrst = didname = 0; 128 sport = dport = 0; 129 for (n = 0; n < MAXFILTERS; ) { 130 if (fp->f_action == A_NONE) { 131 n++; 132 fp++; 133 continue; 134 } 135 136 if (!didname) { 137 log_Printf(LogDEBUG, "%s filter:\n", filter->name); 138 didname = 1; 139 } 140 141 match = 0; 142 if (!((pip->ip_src.s_addr ^ fp->f_src.ipaddr.s_addr) & 143 fp->f_src.mask.s_addr) && 144 !((pip->ip_dst.s_addr ^ fp->f_dst.ipaddr.s_addr) & 145 fp->f_dst.mask.s_addr)) { 146 if (fp->f_proto != P_NONE) { 147 if (!gotinfo) { 148 const char *ptop = (const char *) pip + (pip->ip_hl << 2); 149 const struct tcphdr *th; 150 const struct udphdr *uh; 151 const struct icmp *ih; 152 int datalen; /* IP datagram length */ 153 154 datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2); 155 switch (pip->ip_p) { 156 case IPPROTO_ICMP: 157 cproto = P_ICMP; 158 if (datalen < 8) /* ICMP must be at least 8 octets */ 159 return (1); 160 ih = (const struct icmp *) ptop; 161 sport = ih->icmp_type; 162 estab = syn = finrst = -1; 163 if (log_IsKept(LogDEBUG)) 164 snprintf(dbuff, sizeof dbuff, "sport = %d", sport); 165 break; 166 case IPPROTO_IGMP: 167 cproto = P_IGMP; 168 if (datalen < 8) /* IGMP uses 8-octet messages */ 169 return (1); 170 estab = syn = finrst = -1; 171 sport = ntohs(0); 172 break; 173 #ifdef IPPROTO_GRE 174 case IPPROTO_GRE: 175 cproto = P_GRE; 176 if (datalen < 2) /* GRE uses 2-octet+ messages */ 177 return (1); 178 estab = syn = finrst = -1; 179 sport = ntohs(0); 180 break; 181 #endif 182 #ifdef IPPROTO_OSPFIGP 183 case IPPROTO_OSPFIGP: 184 cproto = P_OSPF; 185 if (datalen < 8) /* IGMP uses 8-octet messages */ 186 return (1); 187 estab = syn = finrst = -1; 188 sport = ntohs(0); 189 break; 190 #endif 191 case IPPROTO_UDP: 192 case IPPROTO_IPIP: 193 cproto = P_UDP; 194 if (datalen < 8) /* UDP header is 8 octets */ 195 return (1); 196 uh = (const struct udphdr *) ptop; 197 sport = ntohs(uh->uh_sport); 198 dport = ntohs(uh->uh_dport); 199 estab = syn = finrst = -1; 200 if (log_IsKept(LogDEBUG)) 201 snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d", 202 sport, dport); 203 break; 204 case IPPROTO_TCP: 205 cproto = P_TCP; 206 th = (const struct tcphdr *) ptop; 207 /* TCP headers are variable length. The following code 208 * ensures that the TCP header length isn't de-referenced if 209 * the datagram is too short 210 */ 211 if (datalen < 20 || datalen < (th->th_off << 2)) 212 return (1); 213 sport = ntohs(th->th_sport); 214 dport = ntohs(th->th_dport); 215 estab = (th->th_flags & TH_ACK); 216 syn = (th->th_flags & TH_SYN); 217 finrst = (th->th_flags & (TH_FIN|TH_RST)); 218 if (log_IsKept(LogDEBUG)) { 219 if (!estab) 220 snprintf(dbuff, sizeof dbuff, 221 "flags = %02x, sport = %d, dport = %d", 222 th->th_flags, sport, dport); 223 else 224 *dbuff = '\0'; 225 } 226 break; 227 default: 228 return (1); /* We'll block unknown type of packet */ 229 } 230 231 if (log_IsKept(LogDEBUG)) { 232 if (estab != -1) { 233 len = strlen(dbuff); 234 snprintf(dbuff + len, sizeof dbuff - len, 235 ", estab = %d, syn = %d, finrst = %d", 236 estab, syn, finrst); 237 } 238 log_Printf(LogDEBUG, " Filter: proto = %s, %s\n", 239 filter_Proto2Nam(cproto), dbuff); 240 } 241 gotinfo = 1; 242 } 243 if (log_IsKept(LogDEBUG)) { 244 if (fp->f_srcop != OP_NONE) { 245 snprintf(dbuff, sizeof dbuff, ", src %s %d", 246 filter_Op2Nam(fp->f_srcop), fp->f_srcport); 247 len = strlen(dbuff); 248 } else 249 len = 0; 250 if (fp->f_dstop != OP_NONE) { 251 snprintf(dbuff + len, sizeof dbuff - len, 252 ", dst %s %d", filter_Op2Nam(fp->f_dstop), 253 fp->f_dstport); 254 } else if (!len) 255 *dbuff = '\0'; 256 257 log_Printf(LogDEBUG, " rule = %d: Address match, " 258 "check against proto %s%s, action = %s\n", 259 n, filter_Proto2Nam(fp->f_proto), 260 dbuff, filter_Action2Nam(fp->f_action)); 261 } 262 263 if (cproto == fp->f_proto) { 264 if ((fp->f_srcop == OP_NONE || 265 PortMatch(fp->f_srcop, sport, fp->f_srcport)) && 266 (fp->f_dstop == OP_NONE || 267 PortMatch(fp->f_dstop, dport, fp->f_dstport)) && 268 (fp->f_estab == 0 || estab) && 269 (fp->f_syn == 0 || syn) && 270 (fp->f_finrst == 0 || finrst)) { 271 match = 1; 272 } 273 } 274 } else { 275 /* Address is matched and no protocol specified. Make a decision. */ 276 log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n, 277 filter_Action2Nam(fp->f_action)); 278 match = 1; 279 } 280 } else 281 log_Printf(LogDEBUG, " rule = %d: Address mismatch\n", n); 282 283 if (match != fp->f_invert) { 284 /* Take specified action */ 285 if (fp->f_action < A_NONE) 286 fp = &filter->rule[n = fp->f_action]; 287 else 288 return (fp->f_action != A_PERMIT); 289 } else { 290 n++; 291 fp++; 292 } 293 } 294 return (1); /* No rule is mached. Deny this packet */ 295 } 296 297 #ifdef notdef 298 static void 299 IcmpError(struct ip *pip, int code) 300 { 301 struct mbuf *bp; 302 303 if (pip->ip_p != IPPROTO_ICMP) { 304 bp = m_get(m_len, MB_IPIN); 305 memcpy(MBUF_CTOP(bp), ptr, m_len); 306 vj_SendFrame(bp); 307 ipcp_AddOutOctets(m_len); 308 } 309 } 310 #endif 311 312 /* 313 * For debugging aid. 314 */ 315 int 316 PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter) 317 { 318 struct ip *pip; 319 struct tcphdr *th; 320 struct udphdr *uh; 321 struct icmp *icmph; 322 char *ptop; 323 int mask, len, n; 324 int pri = 0; 325 int logit, loglen; 326 char logbuf[200]; 327 328 logit = log_IsKept(LogTCPIP) && filter->logok; 329 loglen = 0; 330 331 pip = (struct ip *) cp; 332 333 if (logit && loglen < sizeof logbuf) { 334 snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name); 335 loglen += strlen(logbuf + loglen); 336 } 337 ptop = (cp + (pip->ip_hl << 2)); 338 339 switch (pip->ip_p) { 340 case IPPROTO_ICMP: 341 if (logit && loglen < sizeof logbuf) { 342 icmph = (struct icmp *) ptop; 343 snprintf(logbuf + loglen, sizeof logbuf - loglen, 344 "ICMP: %s:%d ---> ", inet_ntoa(pip->ip_src), icmph->icmp_type); 345 loglen += strlen(logbuf + loglen); 346 snprintf(logbuf + loglen, sizeof logbuf - loglen, 347 "%s:%d", inet_ntoa(pip->ip_dst), icmph->icmp_type); 348 loglen += strlen(logbuf + loglen); 349 } 350 break; 351 352 case IPPROTO_UDP: 353 uh = (struct udphdr *) ptop; 354 if (pip->ip_tos == IPTOS_LOWDELAY) 355 pri++; 356 357 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 && 358 ipcp_IsUrgentUdpPort(&bundle->ncp.ipcp, ntohs(uh->uh_sport), 359 ntohs(uh->uh_dport))) 360 pri++; 361 362 if (logit && loglen < sizeof logbuf) { 363 snprintf(logbuf + loglen, sizeof logbuf - loglen, 364 "UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); 365 loglen += strlen(logbuf + loglen); 366 snprintf(logbuf + loglen, sizeof logbuf - loglen, 367 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); 368 loglen += strlen(logbuf + loglen); 369 } 370 break; 371 372 #ifdef IPPROTO_GRE 373 case IPPROTO_GRE: 374 if (logit && loglen < sizeof logbuf) { 375 snprintf(logbuf + loglen, sizeof logbuf - loglen, 376 "GRE: %s ---> ", inet_ntoa(pip->ip_src)); 377 loglen += strlen(logbuf + loglen); 378 snprintf(logbuf + loglen, sizeof logbuf - loglen, 379 "%s", inet_ntoa(pip->ip_dst)); 380 loglen += strlen(logbuf + loglen); 381 } 382 break; 383 #endif 384 385 #ifdef IPPROTO_OSPFIGP 386 case IPPROTO_OSPFIGP: 387 if (logit && loglen < sizeof logbuf) { 388 snprintf(logbuf + loglen, sizeof logbuf - loglen, 389 "OSPF: %s ---> ", inet_ntoa(pip->ip_src)); 390 loglen += strlen(logbuf + loglen); 391 snprintf(logbuf + loglen, sizeof logbuf - loglen, 392 "%s", inet_ntoa(pip->ip_dst)); 393 loglen += strlen(logbuf + loglen); 394 } 395 break; 396 #endif 397 398 case IPPROTO_IPIP: 399 if (logit && loglen < sizeof logbuf) { 400 uh = (struct udphdr *) ptop; 401 snprintf(logbuf + loglen, sizeof logbuf - loglen, 402 "IPIP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); 403 loglen += strlen(logbuf + loglen); 404 snprintf(logbuf + loglen, sizeof logbuf - loglen, 405 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); 406 loglen += strlen(logbuf + loglen); 407 } 408 break; 409 410 case IPPROTO_IGMP: 411 if (logit && loglen < sizeof logbuf) { 412 uh = (struct udphdr *) ptop; 413 snprintf(logbuf + loglen, sizeof logbuf - loglen, 414 "IGMP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport)); 415 loglen += strlen(logbuf + loglen); 416 snprintf(logbuf + loglen, sizeof logbuf - loglen, 417 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport)); 418 loglen += strlen(logbuf + loglen); 419 } 420 break; 421 422 case IPPROTO_TCP: 423 th = (struct tcphdr *) ptop; 424 if (pip->ip_tos == IPTOS_LOWDELAY) 425 pri++; 426 427 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 && 428 ipcp_IsUrgentTcpPort(&bundle->ncp.ipcp, ntohs(th->th_sport), 429 ntohs(th->th_dport))) 430 pri++; 431 432 if (logit && loglen < sizeof logbuf) { 433 len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - (th->th_off << 2); 434 snprintf(logbuf + loglen, sizeof logbuf - loglen, 435 "TCP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(th->th_sport)); 436 loglen += strlen(logbuf + loglen); 437 snprintf(logbuf + loglen, sizeof logbuf - loglen, 438 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(th->th_dport)); 439 loglen += strlen(logbuf + loglen); 440 n = 0; 441 for (mask = TH_FIN; mask != 0x40; mask <<= 1) { 442 if (th->th_flags & mask) { 443 snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]); 444 loglen += strlen(logbuf + loglen); 445 } 446 n++; 447 } 448 snprintf(logbuf + loglen, sizeof logbuf - loglen, 449 " seq:%lx ack:%lx (%d/%d)", 450 (u_long)ntohl(th->th_seq), (u_long)ntohl(th->th_ack), len, nb); 451 loglen += strlen(logbuf + loglen); 452 if ((th->th_flags & TH_SYN) && nb > 40) { 453 u_short *sp; 454 455 ptop += 20; 456 sp = (u_short *) ptop; 457 if (ntohs(sp[0]) == 0x0204) { 458 snprintf(logbuf + loglen, sizeof logbuf - loglen, 459 " MSS = %d", ntohs(sp[1])); 460 loglen += strlen(logbuf + loglen); 461 } 462 } 463 } 464 break; 465 } 466 467 if (FilterCheck(pip, filter)) { 468 if (logit) 469 log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf); 470 #ifdef notdef 471 if (direction == 0) 472 IcmpError(pip, pri); 473 #endif 474 return (-1); 475 } else { 476 /* Check Keep Alive filter */ 477 if (logit) { 478 if (FilterCheck(pip, &bundle->filter.alive)) 479 log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf); 480 else 481 log_Printf(LogTCPIP, "%s\n", logbuf); 482 } 483 return (pri); 484 } 485 } 486 487 struct mbuf * 488 ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp) 489 { 490 int nb, nw; 491 struct tun_data tun; 492 struct ip *pip; 493 494 if (bundle->ncp.ipcp.fsm.state != ST_OPENED) { 495 log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n"); 496 m_freem(bp); 497 return NULL; 498 } 499 500 m_settype(bp, MB_IPIN); 501 tun_fill_header(tun, AF_INET); 502 nb = m_length(bp); 503 if (nb > sizeof tun.data) { 504 log_Printf(LogWARN, "ip_Input: %s: Packet too large (got %d, max %d)\n", 505 l->name, nb, (int)(sizeof tun.data)); 506 m_freem(bp); 507 return NULL; 508 } 509 mbuf_Read(bp, tun.data, nb); 510 511 if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0) 512 return NULL; 513 514 pip = (struct ip *)tun.data; 515 if (!FilterCheck(pip, &bundle->filter.alive)) 516 bundle_StartIdleTimer(bundle); 517 518 ipcp_AddInOctets(&bundle->ncp.ipcp, nb); 519 520 nb += sizeof tun - sizeof tun.data; 521 nw = write(bundle->dev.fd, &tun, nb); 522 if (nw != nb) { 523 if (nw == -1) 524 log_Printf(LogERROR, "ip_Input: %s: wrote %d, got %s\n", 525 l->name, nb, strerror(errno)); 526 else 527 log_Printf(LogERROR, "ip_Input: %s: wrote %d, got %d\n", l->name, nb, nw); 528 } 529 530 return NULL; 531 } 532 533 void 534 ip_Enqueue(struct ipcp *ipcp, int pri, char *ptr, int count) 535 { 536 struct mbuf *bp; 537 538 if (pri < 0 || pri >= IPCP_QUEUES(ipcp)) 539 log_Printf(LogERROR, "Can't store in ip queue %d\n", pri); 540 else { 541 /* 542 * We allocate an extra 6 bytes, four at the front and two at the end. 543 * This is an optimisation so that we need to do less work in 544 * m_prepend() in acf_LayerPush() and proto_LayerPush() and 545 * appending in hdlc_LayerPush(). 546 */ 547 bp = m_get(count + 6, MB_IPOUT); 548 bp->m_offset += 4; 549 bp->m_len -= 6; 550 memcpy(MBUF_CTOP(bp), ptr, count); 551 m_enqueue(ipcp->Queue + pri, bp); 552 } 553 } 554 555 void 556 ip_DeleteQueue(struct ipcp *ipcp) 557 { 558 struct mqueue *queue; 559 560 for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++) 561 while (queue->top) 562 m_freem(m_dequeue(queue)); 563 } 564 565 size_t 566 ip_QueueLen(struct ipcp *ipcp) 567 { 568 struct mqueue *queue; 569 size_t result; 570 571 result = 0; 572 for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++) 573 result += queue->len; 574 575 return result; 576 } 577 578 int 579 ip_PushPacket(struct link *l, struct bundle *bundle) 580 { 581 struct ipcp *ipcp = &bundle->ncp.ipcp; 582 struct mqueue *queue; 583 struct mbuf *bp; 584 struct ip *pip; 585 int m_len; 586 587 if (ipcp->fsm.state != ST_OPENED) 588 return 0; 589 590 queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1; 591 do { 592 if (queue->top) { 593 bp = m_pullup(m_dequeue(queue)); 594 m_len = m_length(bp); 595 pip = (struct ip *)MBUF_CTOP(bp); 596 if (!FilterCheck(pip, &bundle->filter.alive)) 597 bundle_StartIdleTimer(bundle); 598 link_PushPacket(l, bp, bundle, 0, PROTO_IP); 599 ipcp_AddOutOctets(ipcp, m_len); 600 return 1; 601 } 602 } while (queue-- != ipcp->Queue); 603 604 return 0; 605 } 606