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