2 * PPP IP Protocol Interface
4 * Written by Toshiharu OHNO (tony-o@iij.ad.jp)
6 * Copyright (C) 1993, Internet Initiative Japan, Inc. All rights reserverd.
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.
23 * o Return ICMP message for filterd packet
24 * and optionaly record it into log.
26 #include <sys/param.h>
27 #include <sys/socket.h>
28 #include <netinet/in.h>
29 #include <netinet/in_systm.h>
30 #include <netinet/ip.h>
31 #include <netinet/ip_icmp.h>
32 #include <netinet/udp.h>
33 #include <netinet/tcp.h>
34 #include <arpa/inet.h>
52 #include "throughput.h"
54 #include "slcompress.h"
57 #include "descriptor.h"
70 #define OPCODE_QUERY 0
71 #define OPCODE_IQUERY 1
72 #define OPCODE_STATUS 2
91 dns_Qclass2Txt(u_short qclass)
93 static char failure[6];
99 { 1, "IN" }, { 2, "CS" }, { 3, "CH" }, { 4, "HS" }, { 255, "*" }
103 for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++)
104 if (qtxt[f].id == qclass)
107 return HexStr(qclass, failure, sizeof failure);
111 dns_Qtype2Txt(u_short qtype)
113 static char failure[6];
118 /* rfc1035/rfc1700 */
119 { 1, "A" }, { 2, "NS" }, { 3, "MD" }, { 4, "MF" }, { 5, "CNAME" },
120 { 6, "SOA" }, { 7, "MB" }, { 8, "MG" }, { 9, "MR" }, { 10, "NULL" },
121 { 11, "WKS" }, { 12, "PTR" }, { 13, "HINFO" }, { 14, "MINFO" },
122 { 15, "MX" }, { 16, "TXT" }, { 17, "RP" }, { 18, "AFSDB" },
123 { 19, "X25" }, { 20, "ISDN" }, { 21, "RT" }, { 22, "NSAP" },
124 { 23, "NSAP-PTR" }, { 24, "SIG" }, { 25, "KEY" }, { 26, "PX" },
125 { 27, "GPOS" }, { 28, "AAAA" }, { 252, "AXFR" }, { 253, "MAILB" },
126 { 254, "MAILA" }, { 255, "*" }
130 for (f = 0; f < sizeof qtxt / sizeof *qtxt; f++)
131 if (qtxt[f].id == qtype)
134 return HexStr(qtype, failure, sizeof failure);
138 PortMatch(int op, u_short pport, u_short rport)
142 return (pport == rport);
144 return (pport > rport);
146 return (pport < rport);
153 * Check a packet against a defined filter
154 * Returns 0 to accept the packet, non-zero to drop the packet
156 * If filtering is enabled, the initial fragment of a datagram must
157 * contain the complete protocol header, and subsequent fragments
158 * must not attempt to over-write it.
161 FilterCheck(const struct ip *pip, const struct filter *filter)
163 int gotinfo; /* true if IP payload decoded */
164 int cproto; /* P_* protocol type if (gotinfo) */
165 int estab, syn, finrst; /* TCP state flags if (gotinfo) */
166 u_short sport, dport; /* src, dest port from packet if (gotinfo) */
167 int n; /* filter rule to process */
168 int len; /* bytes used in dbuff */
169 int didname; /* true if filter header printed */
170 int match; /* true if condition matched */
171 const struct filterent *fp = filter->rule;
174 if (fp->f_action == A_NONE)
175 return (0); /* No rule is given. Permit this packet */
177 /* Deny any packet fragment that tries to over-write the header.
178 * Since we no longer have the real header available, punt on the
179 * largest normal header - 20 bytes for TCP without options, rounded
180 * up to the next possible fragment boundary. Since the smallest
181 * `legal' MTU is 576, and the smallest recommended MTU is 296, any
182 * fragmentation within this range is dubious at best */
183 len = ntohs(pip->ip_off) & IP_OFFMASK; /* fragment offset */
184 if (len > 0) { /* Not first fragment within datagram */
185 if (len < (24 >> 3)) /* don't allow fragment to over-write header */
187 /* permit fragments on in and out filter */
188 return (!filter->fragok);
191 cproto = gotinfo = estab = syn = finrst = didname = 0;
193 for (n = 0; n < MAXFILTERS; ) {
194 if (fp->f_action == A_NONE) {
201 log_Printf(LogDEBUG, "%s filter:\n", filter->name);
206 if (!((pip->ip_src.s_addr ^ fp->f_src.ipaddr.s_addr) &
207 fp->f_src.mask.s_addr) &&
208 !((pip->ip_dst.s_addr ^ fp->f_dst.ipaddr.s_addr) &
209 fp->f_dst.mask.s_addr)) {
210 if (fp->f_proto != P_NONE) {
212 const char *ptop = (const char *) pip + (pip->ip_hl << 2);
213 const struct tcphdr *th;
214 const struct udphdr *uh;
215 const struct icmp *ih;
216 int datalen; /* IP datagram length */
218 datalen = ntohs(pip->ip_len) - (pip->ip_hl << 2);
222 if (datalen < 8) /* ICMP must be at least 8 octets */
224 ih = (const struct icmp *) ptop;
225 sport = ih->icmp_type;
226 estab = syn = finrst = -1;
227 if (log_IsKept(LogDEBUG))
228 snprintf(dbuff, sizeof dbuff, "sport = %d", sport);
232 if (datalen < 8) /* IGMP uses 8-octet messages */
234 estab = syn = finrst = -1;
240 if (datalen < 2) /* GRE uses 2-octet+ messages */
242 estab = syn = finrst = -1;
246 #ifdef IPPROTO_OSPFIGP
247 case IPPROTO_OSPFIGP:
249 if (datalen < 8) /* IGMP uses 8-octet messages */
251 estab = syn = finrst = -1;
258 if (datalen < 8) /* UDP header is 8 octets */
260 uh = (const struct udphdr *) ptop;
261 sport = ntohs(uh->uh_sport);
262 dport = ntohs(uh->uh_dport);
263 estab = syn = finrst = -1;
264 if (log_IsKept(LogDEBUG))
265 snprintf(dbuff, sizeof dbuff, "sport = %d, dport = %d",
270 th = (const struct tcphdr *) ptop;
271 /* TCP headers are variable length. The following code
272 * ensures that the TCP header length isn't de-referenced if
273 * the datagram is too short
275 if (datalen < 20 || datalen < (th->th_off << 2))
277 sport = ntohs(th->th_sport);
278 dport = ntohs(th->th_dport);
279 estab = (th->th_flags & TH_ACK);
280 syn = (th->th_flags & TH_SYN);
281 finrst = (th->th_flags & (TH_FIN|TH_RST));
282 if (log_IsKept(LogDEBUG)) {
284 snprintf(dbuff, sizeof dbuff,
285 "flags = %02x, sport = %d, dport = %d",
286 th->th_flags, sport, dport);
292 return (1); /* We'll block unknown type of packet */
295 if (log_IsKept(LogDEBUG)) {
298 snprintf(dbuff + len, sizeof dbuff - len,
299 ", estab = %d, syn = %d, finrst = %d",
302 log_Printf(LogDEBUG, " Filter: proto = %s, %s\n",
303 filter_Proto2Nam(cproto), dbuff);
307 if (log_IsKept(LogDEBUG)) {
308 if (fp->f_srcop != OP_NONE) {
309 snprintf(dbuff, sizeof dbuff, ", src %s %d",
310 filter_Op2Nam(fp->f_srcop), fp->f_srcport);
314 if (fp->f_dstop != OP_NONE) {
315 snprintf(dbuff + len, sizeof dbuff - len,
316 ", dst %s %d", filter_Op2Nam(fp->f_dstop),
321 log_Printf(LogDEBUG, " rule = %d: Address match, "
322 "check against proto %s%s, action = %s\n",
323 n, filter_Proto2Nam(fp->f_proto),
324 dbuff, filter_Action2Nam(fp->f_action));
327 if (cproto == fp->f_proto) {
328 if ((fp->f_srcop == OP_NONE ||
329 PortMatch(fp->f_srcop, sport, fp->f_srcport)) &&
330 (fp->f_dstop == OP_NONE ||
331 PortMatch(fp->f_dstop, dport, fp->f_dstport)) &&
332 (fp->f_estab == 0 || estab) &&
333 (fp->f_syn == 0 || syn) &&
334 (fp->f_finrst == 0 || finrst)) {
339 /* Address is matched and no protocol specified. Make a decision. */
340 log_Printf(LogDEBUG, " rule = %d: Address match, action = %s\n", n,
341 filter_Action2Nam(fp->f_action));
345 log_Printf(LogDEBUG, " rule = %d: Address mismatch\n", n);
347 if (match != fp->f_invert) {
348 /* Take specified action */
349 if (fp->f_action < A_NONE)
350 fp = &filter->rule[n = fp->f_action];
352 return (fp->f_action != A_PERMIT);
358 return (1); /* No rule is mached. Deny this packet */
363 IcmpError(struct ip *pip, int code)
367 if (pip->ip_p != IPPROTO_ICMP) {
368 bp = m_get(m_len, MB_IPIN);
369 memcpy(MBUF_CTOP(bp), ptr, m_len);
371 ipcp_AddOutOctets(m_len);
377 ip_LogDNS(const struct udphdr *uh, const char *direction)
379 struct dns_header header;
380 const u_short *pktptr;
385 ptr = (const char *)uh + sizeof *uh;
386 len = ntohs(uh->uh_ulen) - sizeof *uh;
387 if (len < sizeof header + 5) /* rfc1024 */
390 pktptr = (const u_short *)ptr;
391 hptr = (u_short *)&header;
392 ptr += sizeof header;
393 len -= sizeof header;
395 while (pktptr < (const u_short *)ptr) {
396 *hptr++ = ntohs(*pktptr); /* Careful of macro side-effects ! */
400 if (header.opcode == OPCODE_QUERY && header.qr == 0) {
402 char name[MAXHOSTNAMELEN + 1], *n;
403 const char *qtype, *qclass;
408 if (end - ptr > MAXHOSTNAMELEN)
409 end = ptr + MAXHOSTNAMELEN;
421 qtype = dns_Qtype2Txt(ntohs(*(const u_short *)end));
422 qclass = dns_Qclass2Txt(ntohs(*(const u_short *)(end + 2)));
424 log_Printf(LogDNS, "%sbound query %s %s %s\n",
425 direction, qclass, qtype, name);
433 PacketCheck(struct bundle *bundle, char *cp, int nb, struct filter *filter)
435 static const char *const TcpFlags[] = {
436 "FIN", "SYN", "RST", "PSH", "ACK", "URG"
443 int mask, len, n, pri, logit, loglen, result;
446 logit = (log_IsKept(LogTCPIP) || log_IsKept(LogDNS)) &&
447 (!filter || filter->logok);
451 pip = (struct ip *)cp;
454 if (logit && loglen < sizeof logbuf) {
456 snprintf(logbuf + loglen, sizeof logbuf - loglen, "%s ", filter->name);
458 snprintf(logbuf + loglen, sizeof logbuf - loglen, " ");
459 loglen += strlen(logbuf + loglen);
461 ptop = (cp + (pip->ip_hl << 2));
465 if (logit && loglen < sizeof logbuf) {
466 icmph = (struct icmp *) ptop;
467 snprintf(logbuf + loglen, sizeof logbuf - loglen,
468 "ICMP: %s:%d ---> ", inet_ntoa(pip->ip_src), icmph->icmp_type);
469 loglen += strlen(logbuf + loglen);
470 snprintf(logbuf + loglen, sizeof logbuf - loglen,
471 "%s:%d", inet_ntoa(pip->ip_dst), icmph->icmp_type);
472 loglen += strlen(logbuf + loglen);
477 uh = (struct udphdr *) ptop;
478 if (pip->ip_tos == IPTOS_LOWDELAY)
481 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
482 ipcp_IsUrgentUdpPort(&bundle->ncp.ipcp, ntohs(uh->uh_sport),
483 ntohs(uh->uh_dport)))
486 if (logit && loglen < sizeof logbuf) {
487 snprintf(logbuf + loglen, sizeof logbuf - loglen,
488 "UDP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport));
489 loglen += strlen(logbuf + loglen);
490 snprintf(logbuf + loglen, sizeof logbuf - loglen,
491 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport));
492 loglen += strlen(logbuf + loglen);
498 if (logit && loglen < sizeof logbuf) {
499 snprintf(logbuf + loglen, sizeof logbuf - loglen,
500 "GRE: %s ---> ", inet_ntoa(pip->ip_src));
501 loglen += strlen(logbuf + loglen);
502 snprintf(logbuf + loglen, sizeof logbuf - loglen,
503 "%s", inet_ntoa(pip->ip_dst));
504 loglen += strlen(logbuf + loglen);
509 #ifdef IPPROTO_OSPFIGP
510 case IPPROTO_OSPFIGP:
511 if (logit && loglen < sizeof logbuf) {
512 snprintf(logbuf + loglen, sizeof logbuf - loglen,
513 "OSPF: %s ---> ", inet_ntoa(pip->ip_src));
514 loglen += strlen(logbuf + loglen);
515 snprintf(logbuf + loglen, sizeof logbuf - loglen,
516 "%s", inet_ntoa(pip->ip_dst));
517 loglen += strlen(logbuf + loglen);
523 if (logit && loglen < sizeof logbuf) {
524 uh = (struct udphdr *) ptop;
525 snprintf(logbuf + loglen, sizeof logbuf - loglen,
526 "IPIP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport));
527 loglen += strlen(logbuf + loglen);
528 snprintf(logbuf + loglen, sizeof logbuf - loglen,
529 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport));
530 loglen += strlen(logbuf + loglen);
535 if (logit && loglen < sizeof logbuf) {
536 uh = (struct udphdr *) ptop;
537 snprintf(logbuf + loglen, sizeof logbuf - loglen,
538 "IGMP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(uh->uh_sport));
539 loglen += strlen(logbuf + loglen);
540 snprintf(logbuf + loglen, sizeof logbuf - loglen,
541 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(uh->uh_dport));
542 loglen += strlen(logbuf + loglen);
547 th = (struct tcphdr *) ptop;
548 if (pip->ip_tos == IPTOS_LOWDELAY)
551 if ((ntohs(pip->ip_off) & IP_OFFMASK) == 0 &&
552 ipcp_IsUrgentTcpPort(&bundle->ncp.ipcp, ntohs(th->th_sport),
553 ntohs(th->th_dport)))
556 if (logit && loglen < sizeof logbuf) {
557 len = ntohs(pip->ip_len) - (pip->ip_hl << 2) - (th->th_off << 2);
558 snprintf(logbuf + loglen, sizeof logbuf - loglen,
559 "TCP: %s:%d ---> ", inet_ntoa(pip->ip_src), ntohs(th->th_sport));
560 loglen += strlen(logbuf + loglen);
561 snprintf(logbuf + loglen, sizeof logbuf - loglen,
562 "%s:%d", inet_ntoa(pip->ip_dst), ntohs(th->th_dport));
563 loglen += strlen(logbuf + loglen);
565 for (mask = TH_FIN; mask != 0x40; mask <<= 1) {
566 if (th->th_flags & mask) {
567 snprintf(logbuf + loglen, sizeof logbuf - loglen, " %s", TcpFlags[n]);
568 loglen += strlen(logbuf + loglen);
572 snprintf(logbuf + loglen, sizeof logbuf - loglen,
573 " seq:%lx ack:%lx (%d/%d)",
574 (u_long)ntohl(th->th_seq), (u_long)ntohl(th->th_ack), len, nb);
575 loglen += strlen(logbuf + loglen);
576 if ((th->th_flags & TH_SYN) && nb > 40) {
580 sp = (u_short *) ptop;
581 if (ntohs(sp[0]) == 0x0204) {
582 snprintf(logbuf + loglen, sizeof logbuf - loglen,
583 " MSS = %d", ntohs(sp[1]));
584 loglen += strlen(logbuf + loglen);
591 if (filter && FilterCheck(pip, filter)) {
593 log_Printf(LogTCPIP, "%s - BLOCKED\n", logbuf);
600 /* Check Keep Alive filter */
601 if (logit && log_IsKept(LogTCPIP)) {
602 if (filter && FilterCheck(pip, &bundle->filter.alive))
603 log_Printf(LogTCPIP, "%s - NO KEEPALIVE\n", logbuf);
605 log_Printf(LogTCPIP, "%s\n", logbuf);
610 if (filter && uh && ntohs(uh->uh_dport) == 53 && log_IsKept(LogDNS))
611 ip_LogDNS(uh, filter->name);
617 ip_Input(struct bundle *bundle, struct link *l, struct mbuf *bp)
624 if (bundle->ncp.ipcp.fsm.state != ST_OPENED) {
625 log_Printf(LogWARN, "ip_Input: IPCP not open - packet dropped\n");
630 m_settype(bp, MB_IPIN);
632 if (nb > sizeof tun.data) {
633 log_Printf(LogWARN, "ip_Input: %s: Packet too large (got %d, max %d)\n",
634 l->name, nb, (int)(sizeof tun.data));
638 mbuf_Read(bp, tun.data, nb);
640 if (PacketCheck(bundle, tun.data, nb, &bundle->filter.in) < 0)
643 pip = (struct ip *)tun.data;
644 if (!FilterCheck(pip, &bundle->filter.alive))
645 bundle_StartIdleTimer(bundle);
647 ipcp_AddInOctets(&bundle->ncp.ipcp, nb);
649 if (bundle->dev.header) {
650 tun.family = htonl(AF_INET);
651 nb += sizeof tun - sizeof tun.data;
656 nw = write(bundle->dev.fd, data, nb);
659 log_Printf(LogERROR, "ip_Input: %s: wrote %d, got %s\n",
660 l->name, nb, strerror(errno));
662 log_Printf(LogERROR, "ip_Input: %s: wrote %d, got %d\n", l->name, nb, nw);
669 ip_Enqueue(struct ipcp *ipcp, int pri, char *ptr, int count)
673 if (pri < 0 || pri >= IPCP_QUEUES(ipcp))
674 log_Printf(LogERROR, "Can't store in ip queue %d\n", pri);
677 * We allocate an extra 6 bytes, four at the front and two at the end.
678 * This is an optimisation so that we need to do less work in
679 * m_prepend() in acf_LayerPush() and proto_LayerPush() and
680 * appending in hdlc_LayerPush().
682 bp = m_get(count + 6, MB_IPOUT);
685 memcpy(MBUF_CTOP(bp), ptr, count);
686 m_enqueue(ipcp->Queue + pri, bp);
691 ip_DeleteQueue(struct ipcp *ipcp)
693 struct mqueue *queue;
695 for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++)
697 m_freem(m_dequeue(queue));
701 ip_QueueLen(struct ipcp *ipcp)
703 struct mqueue *queue;
707 for (queue = ipcp->Queue; queue < ipcp->Queue + IPCP_QUEUES(ipcp); queue++)
708 result += queue->len;
714 ip_PushPacket(struct link *l, struct bundle *bundle)
716 struct ipcp *ipcp = &bundle->ncp.ipcp;
717 struct mqueue *queue;
722 if (ipcp->fsm.state != ST_OPENED)
725 queue = ipcp->Queue + IPCP_QUEUES(ipcp) - 1;
728 bp = m_pullup(m_dequeue(queue));
729 m_len = m_length(bp);
730 pip = (struct ip *)MBUF_CTOP(bp);
731 if (!FilterCheck(pip, &bundle->filter.alive))
732 bundle_StartIdleTimer(bundle);
733 link_PushPacket(l, bp, bundle, 0, PROTO_IP);
734 ipcp_AddOutOctets(ipcp, m_len);
737 } while (queue-- != ipcp->Queue);