Projet

Général

Profil

Télécharger (5,09 ko) Statistiques
| Branche: | Révision:

univnautes-tools / patches / stable / 10 / reply-to.RELENG_10.diff @ 2e75006f

1
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
2
index 1249613..686b68b 100644
3
--- a/sys/netpfil/pf/pf.c
4
+++ b/sys/netpfil/pf/pf.c
5
@@ -5401,6 +5401,12 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
6
 
7
 	ip = mtod(m0, struct ip *);
8
 
9
+	if (IN_MULTICAST(ntohl(ip->ip_dst.s_addr))) {
10
+		if (s)
11
+			PF_STATE_UNLOCK(s);
12
+		return;
13
+	}
14
+
15
 	bzero(&dst, sizeof(dst));
16
 	dst.sin_family = AF_INET;
17
 	dst.sin_len = sizeof(dst);
18
@@ -5448,7 +5454,59 @@ pf_route(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
19
 	if (ifp == NULL)
20
 		goto bad;
21
 
22
+	else if (r->rt == PF_REPLYTO) {
23
+		/* XXX: Copied from ifaof_ifpforaddr() since it mostly will not return NULL! */
24
+		struct sockaddr_in inaddr;
25
+		struct sockaddr *addr;
26
+		struct ifaddr *ifa;
27
+		char *cp, *cp2, *cp3;
28
+		char *cplim;
29
+
30
+		inaddr.sin_addr = ip->ip_dst;
31
+		inaddr.sin_family = AF_INET;
32
+		inaddr.sin_len = sizeof(inaddr);
33
+		inaddr.sin_port = 0;
34
+		addr = (struct sockaddr *)&inaddr;
35
+
36
+		IF_ADDR_RLOCK(ifp);
37
+		TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
38
+			if (ifa->ifa_addr->sa_family != AF_INET)
39
+				continue;
40
+			if (ifa->ifa_netmask == 0) {
41
+				if ((bcmp(addr, ifa->ifa_addr, addr->sa_len) == 0) ||
42
+				    (ifa->ifa_dstaddr &&
43
+				    (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0))) {
44
+					IF_ADDR_RUNLOCK(ifp);
45
+					return;
46
+				}
47
+				continue;
48
+			}
49
+			if (ifp->if_flags & IFF_POINTOPOINT) {
50
+				if (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0) {
51
+					IF_ADDR_RUNLOCK(ifp);
52
+					return;
53
+				}
54
+			} else {
55
+				cp = addr->sa_data;
56
+				cp2 = ifa->ifa_addr->sa_data;
57
+				cp3 = ifa->ifa_netmask->sa_data;
58
+				cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
59
+				for (; cp3 < cplim; cp3++)
60
+					if ((*cp++ ^ *cp2++) & *cp3)
61
+						break;
62
+				if (cp3 == cplim) {
63
+					IF_ADDR_RUNLOCK(ifp);
64
+					return;
65
+				}
66
+			}
67
+		}
68
+		IF_ADDR_RUNLOCK(ifp);
69
+	} else if (r->rt == PF_ROUTETO && r->direction == dir && in_localip(ip->ip_dst))
70
+		return;
71
+
72
 	if (oifp != ifp) {
73
+		if (in_broadcast(ip->ip_dst, oifp)) /* XXX: LOCKING of address list?! */
74
+			return;
75
 		if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
76
 			goto bad;
77
 		else if (m0 == NULL)
78
@@ -5581,6 +5639,12 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
79
 
80
 	ip6 = mtod(m0, struct ip6_hdr *);
81
 
82
+	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
83
+		if (s)
84
+			PF_STATE_UNLOCK(s);
85
+		return;
86
+	}
87
+
88
 	bzero(&dst, sizeof(dst));
89
 	dst.sin6_family = AF_INET6;
90
 	dst.sin6_len = sizeof(dst);
91
@@ -5619,6 +5683,56 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
92
 
93
 	if (ifp == NULL)
94
 		goto bad;
95
+       else if (r->rt == PF_REPLYTO) {
96
+               /* XXX: Copied from ifaof_ifpforaddr() since it mostly will not return NULL! */
97
+               struct sockaddr_in6 inaddr6;
98
+               struct sockaddr *addr;
99
+               struct ifaddr *ifa;
100
+               char *cp, *cp2, *cp3;
101
+               char *cplim;
102
+
103
+               inaddr6.sin6_addr = ip6->ip6_dst;
104
+               inaddr6.sin6_family = AF_INET6;
105
+               inaddr6.sin6_len = sizeof(inaddr6);
106
+               inaddr6.sin6_port = 0;
107
+               inaddr6.sin6_flowinfo = 0;
108
+               addr = (struct sockaddr *)&inaddr6;
109
+
110
+               IF_ADDR_RLOCK(ifp);
111
+               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
112
+                       if (ifa->ifa_addr->sa_family != AF_INET6)
113
+                               continue;
114
+                       if (ifa->ifa_netmask == 0) {
115
+                               if ((bcmp(addr, ifa->ifa_addr, addr->sa_len) == 0) ||
116
+                                   (ifa->ifa_dstaddr &&
117
+                                   (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0))) {
118
+                                       IF_ADDR_RUNLOCK(ifp);
119
+                                       return;
120
+                               }
121
+                               continue;
122
+                       }
123
+                       if (ifp->if_flags & IFF_POINTOPOINT) {
124
+                               if (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0) {
125
+                                       IF_ADDR_RUNLOCK(ifp);
126
+                                       return;
127
+                               }
128
+                       } else {
129
+                               cp = addr->sa_data;
130
+                               cp2 = ifa->ifa_addr->sa_data;
131
+                               cp3 = ifa->ifa_netmask->sa_data;
132
+                               cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
133
+                               for (; cp3 < cplim; cp3++)
134
+                                       if ((*cp++ ^ *cp2++) & *cp3)
135
+                                               break;
136
+                               if (cp3 == cplim) {
137
+                                       IF_ADDR_RUNLOCK(ifp);
138
+                                       return;
139
+                               }
140
+                       }
141
+               }
142
+               IF_ADDR_RUNLOCK(ifp);
143
+       } else if (r->rt == PF_ROUTETO && r->direction == dir && in6_localaddr(&ip6->ip6_dst))
144
+	       return;
145
 
146
 	if (oifp != ifp) {
147
 		if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
(53-53/64)