diff options
author | 2001-11-26 16:50:25 +0000 | |
---|---|---|
committer | 2001-11-26 16:50:25 +0000 | |
commit | cb3a4e31184d5885c222e519a0133b7c98a69210 (patch) | |
tree | 7ebb0baf4c339d23bef8eb33370f7707244d0ba1 | |
parent | Trident 4DWAVE-DX/NX, SiS 7018, ALi M5451 Sound Driver; from SOMEYA Yoshihiko and KUROSAWA Takahiro; tested by Matt Behrens <matt@zigg.com> (diff) | |
download | wireguard-openbsd-cb3a4e31184d5885c222e519a0133b7c98a69210.tar.xz wireguard-openbsd-cb3a4e31184d5885c222e519a0133b7c98a69210.zip |
add fastroute options similar to what is found in ipf
ok dhartmei@, frantzen@
-rw-r--r-- | sbin/pfctl/parse.y | 131 | ||||
-rw-r--r-- | sbin/pfctl/pfctl_parser.c | 17 | ||||
-rw-r--r-- | sys/net/if_bridge.c | 4 | ||||
-rw-r--r-- | sys/net/pf.c | 290 | ||||
-rw-r--r-- | sys/net/pfvar.h | 7 | ||||
-rw-r--r-- | sys/netinet/ip_input.c | 4 | ||||
-rw-r--r-- | sys/netinet/ip_output.c | 9 | ||||
-rw-r--r-- | sys/netinet6/ip6_forward.c | 7 | ||||
-rw-r--r-- | sys/netinet6/ip6_input.c | 8 | ||||
-rw-r--r-- | sys/netinet6/ip6_output.c | 12 |
10 files changed, 450 insertions, 39 deletions
diff --git a/sbin/pfctl/parse.y b/sbin/pfctl/parse.y index 2de09e5f771..6be61af4e0e 100644 --- a/sbin/pfctl/parse.y +++ b/sbin/pfctl/parse.y @@ -1,4 +1,4 @@ -/* $OpenBSD: parse.y,v 1.43 2001/11/05 09:28:00 deraadt Exp $ */ +/* $OpenBSD: parse.y,v 1.44 2001/11/26 16:50:25 jasoni Exp $ */ /* * Copyright (c) 2001 Markus Friedl. All rights reserved. @@ -151,6 +151,12 @@ typedef struct { struct { struct peer src, dst; } fromto; + struct { + char *string; + struct pf_addr *addr; + u_int8_t rt; + u_int8_t af; + } route; } v; int lineno; } YYSTYPE; @@ -160,7 +166,7 @@ typedef struct { %token PASS BLOCK SCRUB RETURN IN OUT LOG LOGALL QUICK ON FROM TO FLAGS %token RETURNRST RETURNICMP RETURNICMP6 PROTO INET INET6 ALL ANY ICMPTYPE %token ICMP6TYPE CODE KEEP MODULATE STATE PORT RDR NAT BINAT ARROW NODF -%token MINTTL IPV6ADDR ERROR ALLOWOPTS +%token MINTTL IPV6ADDR ERROR ALLOWOPTS FASTROUTE ROUTETO DUPTO %token <v.string> STRING %token <v.number> NUMBER %token <v.i> PORTUNARY PORTBINARY @@ -175,6 +181,7 @@ typedef struct { %type <v.peer> ipportspec %type <v.host> ipspec xhost host address host_list IPV6ADDR %type <v.port> portspec port_list port_item +%type <v.route> route %% ruleset : /* empty */ @@ -198,7 +205,7 @@ varset : STRING PORTUNARY STRING } ; -pfrule : action dir log quick interface af proto fromto flags icmpspec keep nodf minttl allowopts +pfrule : action dir log quick interface route af proto fromto flags icmpspec keep nodf minttl allowopts { struct pf_rule r; @@ -217,20 +224,42 @@ pfrule : action dir log quick interface af proto fromto flags icmpspec keep nod r.log = $3; r.quick = $4; - r.af = $6; - r.flags = $9.b1; - r.flagset = $9.b2; - r.keep_state = $11; + r.af = $7; + r.flags = $10.b1; + r.flagset = $10.b2; + + r.keep_state = $12; - if ($12) - r.rule_flag |= PFRULE_NODF; if ($13) - r.min_ttl = $13; - r.allow_opts = $14; + r.rule_flag |= PFRULE_NODF; + if ($14) + r.min_ttl = $14; + r.allow_opts = $15; + + if ($6.rt) { + r.rt = $6.rt; + if ($6.string) { + memcpy(r.rt_ifname, $6.string, + sizeof(r.rt_ifname)); + free($6.string); + } + if ($6.addr) { + if (!r.af) + r.af = $6.af; + else if (r.af != $6.af) { + yyerror("address family" + " mismatch"); + YYERROR; + } + memcpy(&r.rt_addr, $6.addr, + sizeof(r.rt_addr)); + free($6.addr); + } + } - expand_rule(&r, $5, $7, $8.src.host, $8.src.port, - $8.dst.host, $8.dst.port, $10); + expand_rule(&r, $5, $8, $9.src.host, $9.src.port, + $9.dst.host, $9.dst.port, $11); } ; @@ -932,6 +961,41 @@ rport : PORT port { $$.t = PF_RPORT_RANGE; } ; + +route : /* empty */ { + $$.string = NULL; + $$.rt = 0; + $$.addr = NULL; + $$.af = 0; + } + | FASTROUTE { + $$.string = NULL; + $$.rt = PF_FASTROUTE; + $$.addr = NULL; + } + | ROUTETO STRING ':' address { + $$.string = strdup($2); + $$.rt = PF_ROUTETO; + $$.addr = &$4->addr; + $$.af = $4->af; + } + | ROUTETO STRING { + $$.string = strdup($2); + $$.rt = PF_ROUTETO; + $$.addr = NULL; + } + | DUPTO STRING ':' address { + $$.string = strdup($2); + $$.rt = PF_DUPTO; + $$.addr = &$4->addr; + $$.af = $4->af; + } + | DUPTO STRING { + $$.string = strdup($2); + $$.rt = PF_DUPTO; + $$.addr = NULL; + } + ; %% int @@ -1081,19 +1145,37 @@ void expand_rule_hosts(struct pf_rule *r, r->dst.port_op = dst_port->op; r->type = icmp_type->type; r->code = icmp_type->code; - - if (src_host->af && - dst_host->af && - (src_host->af != - dst_host->af)) { + + if ((src_host->af && dst_host->af && + r->af) && (src_host->af != + dst_host->af || + src_host->af != r->af || + dst_host->af != r->af)) { + yyerror("address family" + " mismatch"); + nomatch++; + } else if ((src_host->af && + dst_host->af) && + (src_host->af != dst_host->af)) { + yyerror("address family" + " mismatch"); + nomatch++; + } else if ((src_host->af && r->af) && + (src_host->af != r->af)) { + yyerror("address family" + " mismatch"); + nomatch++; + } else if ((dst_host->af && r->af) && + (dst_host->af != r->af)) { yyerror("address family" " mismatch"); nomatch++; - } else if (src_host->af) + } else if (src_host->af && !r->af) { r->af = src_host->af; - else if (dst_host->af) - r->af = dst_host->af; - + } else if (dst_host->af && !r->af) { + r->af= dst_host->af; + } + if (icmp_type->proto && r->proto != icmp_type->proto) { yyerror("icmp-type mismatch"); @@ -1187,7 +1269,9 @@ lookup(char *s) { "binat", BINAT}, { "block", BLOCK}, { "code", CODE}, + { "dup-to", DUPTO}, { "flags", FLAGS}, + { "fastroute", FASTROUTE}, { "from", FROM}, { "icmp-type", ICMPTYPE}, { "ipv6-icmp-type", ICMP6TYPE}, @@ -1212,6 +1296,7 @@ lookup(char *s) { "return-icmp",RETURNICMP}, { "return-icmp6",RETURNICMP6}, { "return-rst", RETURNRST}, + { "route-to", ROUTETO}, { "scrub", SCRUB}, { "state", STATE}, { "to", TO}, @@ -1495,7 +1580,7 @@ top: #define allowed_in_string(x) \ (isalnum(x) || (ispunct(x) && x != '(' && x != ')' && \ x != '{' && x != '}' && x != '<' && x != '>' && \ - x != '!' && x != '=' && x != '/' && x != '#' && x != ',')) + x != '!' && x != '=' && x != '/' && x != '#' && x != ',' && x != ':')) if (isalnum(c)) { do { diff --git a/sbin/pfctl/pfctl_parser.c b/sbin/pfctl/pfctl_parser.c index ae47423cb03..78940146700 100644 --- a/sbin/pfctl/pfctl_parser.c +++ b/sbin/pfctl/pfctl_parser.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pfctl_parser.c,v 1.53 2001/10/24 09:09:32 dhartmei Exp $ */ +/* $OpenBSD: pfctl_parser.c,v 1.54 2001/11/26 16:50:26 jasoni Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -652,6 +652,21 @@ print_rule(struct pf_rule *r) printf("quick "); if (r->ifname[0]) printf("on %s ", r->ifname); + if (r->rt) { + if (r->rt == PF_ROUTETO) + printf("route-to "); + else if (r->rt == PF_DUPTO) + printf("dup-to "); + else if (r->rt == PF_FASTROUTE) + printf("fastroute"); + if (r->rt_ifname[0]) + printf("%s", r->rt_ifname); + if (r->af && !PF_AZERO(&r->rt_addr, r->af)) { + printf(":"); + print_addr(&r->rt_addr, NULL, r->af); + } + printf(" "); + } if (r->af) { if (r->af == AF_INET) printf("inet "); diff --git a/sys/net/if_bridge.c b/sys/net/if_bridge.c index 2a4479d60a5..7f1ec92aff8 100644 --- a/sys/net/if_bridge.c +++ b/sys/net/if_bridge.c @@ -1,4 +1,4 @@ -/* $OpenBSD: if_bridge.c,v 1.76 2001/08/21 15:18:20 jason Exp $ */ +/* $OpenBSD: if_bridge.c,v 1.77 2001/11/26 16:50:26 jasoni Exp $ */ /* * Copyright (c) 1999, 2000 Jason L. Wright (jason@thought.net) @@ -2002,6 +2002,8 @@ bridge_filter(sc, dir, ifp, eh, m) m->m_pkthdr.rcvif = ifp; if (pf_test(dir, ifp, &m) != PF_PASS) goto dropit; + if (m == NULL) + goto dropit; /* Rebuild the IP header */ if (m->m_len < hlen && ((m = m_pullup(m, hlen)) == NULL)) diff --git a/sys/net/pf.c b/sys/net/pf.c index 2b6cb4d6696..70b4533cd86 100644 --- a/sys/net/pf.c +++ b/sys/net/pf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: pf.c,v 1.170 2001/11/21 19:00:24 dhartmei Exp $ */ +/* $OpenBSD: pf.c,v 1.171 2001/11/26 16:50:26 jasoni Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -57,6 +57,10 @@ #include <netinet/tcp_seq.h> #include <netinet/udp.h> #include <netinet/ip_icmp.h> +#include <netinet/in_pcb.h> +#include <netinet/tcp_timer.h> +#include <netinet/tcp_var.h> +#include <netinet/udp_var.h> #include <dev/rndvar.h> #include <net/pfvar.h> @@ -248,6 +252,8 @@ int pf_add_sport(struct pf_port_list *, u_int16_t); int pf_chk_sport(struct pf_port_list *, u_int16_t); int pf_normalize_tcp(int, struct ifnet *, struct mbuf *, int, int, void *, struct pf_pdesc *); +void pf_route(struct mbuf *, struct pf_rule *); +void pf_route6(struct mbuf *, struct pf_rule *); #if NPFLOG > 0 @@ -1113,6 +1119,15 @@ pfioctl(dev_t dev, u_long cmd, caddr_t addr, int flags, struct proc *p) } } else rule->ifp = NULL; + if (rule->rt_ifname[0]) { + rule->rt_ifp = ifunit(rule->rt_ifname); + if (rule->rt_ifname == NULL) { + pool_put(&pf_rule_pl, rule); + error = EINVAL; + break; + } + } else + rule->rt_ifp = NULL; rule->evaluations = rule->packets = rule->bytes = 0; TAILQ_INSERT_TAIL(pf_rules_inactive, rule, entries); break; @@ -4311,6 +4326,265 @@ pf_pull_hdr(struct mbuf *m, int off, void *p, int len, } #ifdef INET +void +pf_route(struct mbuf *m, struct pf_rule *r) +{ + struct mbuf *m0, *m1; + struct route iproute; + struct route *ro; + struct sockaddr_in *dst; + struct ip *ip, *mhip; + struct ifnet *ifp = r->rt_ifp; + int hlen; + int len, off, error = 0; + + if (m == NULL) + return; + + m0 = m_copym2(m, 0, M_COPYALL, M_NOWAIT); + if (m0 == NULL) + return; + + ip = mtod(m0, struct ip *); + hlen = ip->ip_hl << 2; + + ro = &iproute; + bzero((caddr_t)ro, sizeof(*ro)); + dst = satosin(&ro->ro_dst); + dst->sin_family = AF_INET; + dst->sin_len = sizeof(*dst); + dst->sin_addr = ip->ip_dst; + + if (r->rt == PF_FASTROUTE) { + rtalloc(ro); + if (ro->ro_rt == 0) { + ipstat.ips_noroute++; + goto bad; + } + + ifp = ro->ro_rt->rt_ifp; + ro->ro_rt->rt_use++; + + if (ro->ro_rt->rt_flags & RTF_GATEWAY) + dst = satosin(ro->ro_rt->rt_gateway); + } else { + if (!PF_AZERO(&r->rt_addr, AF_INET)) + dst->sin_addr.s_addr = r->rt_addr.v4.s_addr; + } + + if (ifp == NULL) + goto bad; + + /* Copied from ip_output. */ + if ((u_int16_t)ip->ip_len <= ifp->if_mtu) { + ip->ip_len = htons((u_int16_t)ip->ip_len); + ip->ip_off = htons((u_int16_t)ip->ip_off); + if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && + ifp->if_bridge == NULL) { + m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; + ipstat.ips_outhwcsum++; + } else { + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m0, hlen); + } + /* Update relevant hardware checksum stats for TCP/UDP */ + if (m0->m_pkthdr.csum & M_TCPV4_CSUM_OUT) + tcpstat.tcps_outhwcsum++; + else if (m0->m_pkthdr.csum & M_UDPV4_CSUM_OUT) + udpstat.udps_outhwcsum++; + error = (*ifp->if_output)(ifp, m0, sintosa(dst), NULL); + + goto done; + } + + /* + * Too large for interface; fragment if possible. + * Must be able to put at least 8 bytes per fragment. + */ + if (ip->ip_off & IP_DF) { + error = EMSGSIZE; + ipstat.ips_cantfrag++; + goto bad; + } + len = (ifp->if_mtu - hlen) &~ 7; + if (len < 8) { + error = EMSGSIZE; + goto bad; + } + /* + * If we are doing fragmentation, we can't defer TCP/UDP + * checksumming; compute the checksum and clear the flag. + */ + if (m0->m_pkthdr.csum & (M_TCPV4_CSUM_OUT | M_UDPV4_CSUM_OUT)) { + in_delayed_cksum(m0); + m0->m_pkthdr.csum &= ~(M_UDPV4_CSUM_OUT | M_TCPV4_CSUM_OUT); + } + + { + int mhlen, firstlen = len; + struct mbuf **mnext = &m0->m_nextpkt; + + /* + * Loop through length of segment after first fragment, + * make new header and copy data of each part and link onto chain. + */ + m1 = m0; + mhlen = sizeof (struct ip); + for (off = hlen + len; off < (u_int16_t)ip->ip_len; off += len) { + MGETHDR(m0, M_DONTWAIT, MT_HEADER); + if (m0 == 0) { + error = ENOBUFS; + ipstat.ips_odropped++; + goto sendorfree; + } + *mnext = m0; + mnext = &m0->m_nextpkt; + m0->m_data += max_linkhdr; + mhip = mtod(m0, struct ip *); + *mhip = *ip; + /* we must inherit MCAST and BCAST flags */ + m0->m_flags |= m1->m_flags & (M_MCAST|M_BCAST); + if (hlen > sizeof (struct ip)) { + mhlen = ip_optcopy(ip, mhip) + sizeof (struct ip); + mhip->ip_hl = mhlen >> 2; + } + m0->m_len = mhlen; + mhip->ip_off = ((off - hlen) >> 3) + (ip->ip_off & ~IP_MF); + if (ip->ip_off & IP_MF) + mhip->ip_off |= IP_MF; + if (off + len >= (u_int16_t)ip->ip_len) + len = (u_int16_t)ip->ip_len - off; + else + mhip->ip_off |= IP_MF; + mhip->ip_len = htons((u_int16_t)(len + mhlen)); + m0->m_next = m_copy(m1, off, len); + if (m0->m_next == 0) { + error = ENOBUFS;/* ??? */ + ipstat.ips_odropped++; + goto sendorfree; + } + m0->m_pkthdr.len = mhlen + len; + m0->m_pkthdr.rcvif = (struct ifnet *)0; + mhip->ip_off = htons((u_int16_t)mhip->ip_off); + if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && + ifp->if_bridge == NULL) { + m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; + ipstat.ips_outhwcsum++; + } else { + mhip->ip_sum = 0; + mhip->ip_sum = in_cksum(m0, mhlen); + } + ipstat.ips_ofragments++; + } + /* + * Update first fragment by trimming what's been copied out + * and updating header, then send each fragment (in order). + */ + m0 = m1; + m_adj(m0, hlen + firstlen - (u_int16_t)ip->ip_len); + m0->m_pkthdr.len = hlen + firstlen; + ip->ip_len = htons((u_int16_t)m0->m_pkthdr.len); + ip->ip_off = htons((u_int16_t)(ip->ip_off | IP_MF)); + if ((ifp->if_capabilities & IFCAP_CSUM_IPv4) && + ifp->if_bridge == NULL) { + m0->m_pkthdr.csum |= M_IPV4_CSUM_OUT; + ipstat.ips_outhwcsum++; + } else { + ip->ip_sum = 0; + ip->ip_sum = in_cksum(m0, hlen); + } +sendorfree: + for (m0 = m1; m0; m0 = m1) { + m1 = m0->m_nextpkt; + m->m_nextpkt = 0; + if (error == 0) + error = (*ifp->if_output)(ifp, m0, sintosa(dst), + NULL); + else + m_freem(m0); + } + + if (error == 0) + ipstat.ips_fragmented++; + } + +done: + if (ro == &iproute && ro->ro_rt) + RTFREE(ro->ro_rt); + return; + +bad: + m_freem(m0); + goto done; +} +#endif /* INET */ + +#ifdef INET6 +void +pf_route6(struct mbuf *m, struct pf_rule *r) +{ + struct mbuf *m0; + struct m_tag *mtag; + struct route_in6 ip6route; + struct route_in6 *ro; + struct sockaddr_in6 *dst; + struct ip6_hdr *ip6; + struct ifnet *ifp = r->rt_ifp; + int error = 0; + + if (m == NULL) + return; + + m0 = m_copym2(m, 0, M_COPYALL, M_NOWAIT); + if (m0 == NULL) + return; + + ip6 = mtod(m0, struct ip6_hdr *); + + ro = &ip6route; + bzero((caddr_t)ro, sizeof(*ro)); + dst = (struct sockaddr_in6 *)&ro->ro_dst; + dst->sin6_family = AF_INET6; + dst->sin6_len = sizeof(*dst); + dst->sin6_addr = ip6->ip6_dst; + + if (!PF_AZERO(&r->rt_addr, AF_INET6)) + dst->sin6_addr = r->rt_addr.v6; + + /* Cheat. */ + if (r->rt == PF_FASTROUTE) { + mtag = m_tag_get(PACKET_TAG_PF_GENERATED, 0, M_NOWAIT); + if (mtag == NULL) + goto bad; + m_tag_prepend(m0, mtag); + ip6_output(m0, NULL, NULL, NULL, NULL, NULL); + return; + } + + if (ifp == NULL) + goto bad; + + /* + * Do not fragment packets (yet). Not much is done here for dealing + * with errors. Actions on errors depend on whether the packet + * was generated locally or being forwarded. + */ + if (m0->m_pkthdr.len <= ifp->if_mtu) { + error = (*ifp->if_output)(ifp, m0, (struct sockaddr *)dst, + NULL); + } else + m_freem(m0); + +done: + return; + +bad: + m_freem(m0); + goto done; +} +#endif /* INET6 */ + +#ifdef INET int pf_test(int dir, struct ifnet *ifp, struct mbuf **m0) { @@ -4464,6 +4738,13 @@ done: } PFLOG_PACKET(ifp, h, m, AF_INET, dir, reason, r); } + if (r && r->rt) { + pf_route(m, r); + if (r->rt != PF_DUPTO) { + m_freem(*m0); + *m0 = NULL; + } + } return (action); } #endif /* INET */ @@ -4637,6 +4918,13 @@ done: } PFLOG_PACKET(ifp, h, m, AF_INET6, dir, reason, r); } + if (r && r->rt) { + pf_route6(m, r); + if (r->rt != PF_DUPTO) { + m_freem(*m0); + *m0 = NULL; + } + } return (action); } #endif /* INET6 */ diff --git a/sys/net/pfvar.h b/sys/net/pfvar.h index a5d82e0bd48..ce65e0d3637 100644 --- a/sys/net/pfvar.h +++ b/sys/net/pfvar.h @@ -1,4 +1,4 @@ -/* $OpenBSD: pfvar.h,v 1.55 2001/11/06 11:48:29 dhartmei Exp $ */ +/* $OpenBSD: pfvar.h,v 1.56 2001/11/26 16:50:26 jasoni Exp $ */ /* * Copyright (c) 2001 Daniel Hartmeier @@ -49,6 +49,7 @@ enum { PFTM_TCP_FIRST_PACKET=0, PFTM_TCP_OPENING=1, PFTM_TCP_ESTABLISHED=2, PFTM_UDP_FIRST_PACKET=6, PFTM_UDP_SINGLE=7, PFTM_UDP_MULTIPLE=8, PFTM_ICMP_FIRST_PACKET=9, PFTM_ICMP_ERROR_REPLY=10, PFTM_FRAG=11, PFTM_INTERVAL=12, PFTM_MAX=13 }; +enum { PF_FASTROUTE=1, PF_ROUTETO=2, PF_DUPTO=3 }; struct pf_addr { union { @@ -188,9 +189,12 @@ struct pf_rule_addr { struct pf_rule { char ifname[IFNAMSIZ]; + char rt_ifname[IFNAMSIZ]; struct ifnet *ifp; + struct ifnet *rt_ifp; struct pf_rule_addr src; struct pf_rule_addr dst; + struct pf_addr rt_addr; #define PF_SKIP_IFP 0 #define PF_SKIP_AF 1 @@ -229,6 +233,7 @@ struct pf_rule { u_int8_t rule_flag; u_int8_t min_ttl; /* minimum ttl for packet normalize */ u_int8_t allow_opts; + u_int8_t rt; }; #define PFRULE_RETURNRST 0x01 diff --git a/sys/netinet/ip_input.c b/sys/netinet/ip_input.c index e40d819c80f..a7e35ed31d2 100644 --- a/sys/netinet/ip_input.c +++ b/sys/netinet/ip_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_input.c,v 1.93 2001/09/18 15:24:32 aaron Exp $ */ +/* $OpenBSD: ip_input.c,v 1.94 2001/11/26 16:50:26 jasoni Exp $ */ /* $NetBSD: ip_input.c,v 1.30 1996/03/16 23:53:58 christos Exp $ */ /* @@ -395,6 +395,8 @@ ipv4_input(m) */ if (pf_test(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS) goto bad; + if (m == NULL) + goto bad; ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; diff --git a/sys/netinet/ip_output.c b/sys/netinet/ip_output.c index 6a659520fc7..9514a052e50 100644 --- a/sys/netinet/ip_output.c +++ b/sys/netinet/ip_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip_output.c,v 1.139 2001/11/24 19:29:06 deraadt Exp $ */ +/* $OpenBSD: ip_output.c,v 1.140 2001/11/26 16:50:26 jasoni Exp $ */ /* $NetBSD: ip_output.c,v 1.28 1996/02/13 23:43:07 christos Exp $ */ /* @@ -554,6 +554,10 @@ sendit: m_freem(m); goto done; } + if (m == NULL) { + splx(s); + goto done; + } ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; #endif @@ -654,6 +658,9 @@ sendit: m_freem(m); goto done; } + if (m == NULL) + goto done; + ip = mtod(m, struct ip *); hlen = ip->ip_hl << 2; #endif diff --git a/sys/netinet6/ip6_forward.c b/sys/netinet6/ip6_forward.c index dab86d9c8ae..8f98801e00c 100644 --- a/sys/netinet6/ip6_forward.c +++ b/sys/netinet6/ip6_forward.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_forward.c,v 1.17 2001/09/29 08:02:07 jasoni Exp $ */ +/* $OpenBSD: ip6_forward.c,v 1.18 2001/11/26 16:50:26 jasoni Exp $ */ /* $KAME: ip6_forward.c,v 1.75 2001/06/29 12:42:13 jinmei Exp $ */ /* @@ -487,10 +487,13 @@ ip6_forward(m, srcrt) ip6->ip6_dst.s6_addr16[1] = 0; #if NPF > 0 - if (pf_test6(PF_OUT, rt->rt_ifp, &m) != PF_PASS) { + if (pf_test6(PF_OUT, rt->rt_ifp, &m) != PF_PASS) { m_freem(m); goto senderr; } + if (m == NULL) + goto senderr; + ip6 = mtod(m, struct ip6_hdr *); #endif diff --git a/sys/netinet6/ip6_input.c b/sys/netinet6/ip6_input.c index e2a54b387f7..f368bf86560 100644 --- a/sys/netinet6/ip6_input.c +++ b/sys/netinet6/ip6_input.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_input.c,v 1.35 2001/11/06 19:53:21 miod Exp $ */ +/* $OpenBSD: ip6_input.c,v 1.36 2001/11/26 16:50:26 jasoni Exp $ */ /* $KAME: ip6_input.c,v 1.188 2001/03/29 05:34:31 itojun Exp $ */ /* @@ -265,8 +265,10 @@ ip6_input(m) /* * Packet filter */ - if (pf_test6(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS) - goto bad; + if (pf_test6(PF_IN, m->m_pkthdr.rcvif, &m) != PF_PASS) + goto bad; + if (m == NULL) + goto bad; #endif if (m->m_len < sizeof(struct ip6_hdr)) { diff --git a/sys/netinet6/ip6_output.c b/sys/netinet6/ip6_output.c index c4289cc5257..0ce39864fdb 100644 --- a/sys/netinet6/ip6_output.c +++ b/sys/netinet6/ip6_output.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ip6_output.c,v 1.52 2001/10/01 16:03:09 jasoni Exp $ */ +/* $OpenBSD: ip6_output.c,v 1.53 2001/11/26 16:50:26 jasoni Exp $ */ /* $KAME: ip6_output.c,v 1.172 2001/03/25 09:55:56 itojun Exp $ */ /* @@ -881,11 +881,13 @@ skip_ipsec2:; } #if NPF > 0 - if (pf_test6(PF_OUT, ifp, &m) != PF_PASS) { - error = EHOSTUNREACH; + if (pf_test6(PF_OUT, ifp, &m) != PF_PASS) { + error = EHOSTUNREACH; m_freem(m); - goto done; - } + goto done; + } + if (m == NULL) + goto done; ip6 = mtod(m, struct ip6_hdr *); #endif |