Projet

Général

Profil

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

univnautes-tools / patches / stable / 10 / reply-to.RELENG_10.diff @ 4ab3b90b

1
diff --git a/sys/netpfil/pf/pf.c b/sys/netpfil/pf/pf.c
2
index 118184c..a07c5f3 100644
3
--- a/sys/netpfil/pf/pf.c
4
+++ b/sys/netpfil/pf/pf.c
5
@@ -5417,6 +5417,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
@@ -5464,7 +5470,60 @@ 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 || r->rt == PF_ROUTETO) {
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
+	}
70
+	if (r->rt == PF_ROUTETO && r->direction == dir && in_localip(ip->ip_dst))
71
+		return;
72
+
73
 	if (oifp != ifp) {
74
+		if (in_broadcast(ip->ip_dst, oifp)) /* XXX: LOCKING of address list?! */
75
+			return;
76
 		if (pf_test(PF_OUT, ifp, &m0, NULL) != PF_PASS)
77
 			goto bad;
78
 		else if (m0 == NULL)
79
@@ -5597,6 +5656,12 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
80
 
81
 	ip6 = mtod(m0, struct ip6_hdr *);
82
 
83
+	if (IN6_IS_ADDR_MULTICAST(&ip6->ip6_src)) {
84
+		if (s)
85
+			PF_STATE_UNLOCK(s);
86
+		return;
87
+	}
88
+
89
 	bzero(&dst, sizeof(dst));
90
 	dst.sin6_family = AF_INET6;
91
 	dst.sin6_len = sizeof(dst);
92
@@ -5635,6 +5700,56 @@ pf_route6(struct mbuf **m, struct pf_rule *r, int dir, struct ifnet *oifp,
93
 
94
 	if (ifp == NULL)
95
 		goto bad;
96
+       else if (r->rt == PF_REPLYTO) {
97
+               /* XXX: Copied from ifaof_ifpforaddr() since it mostly will not return NULL! */
98
+               struct sockaddr_in6 inaddr6;
99
+               struct sockaddr *addr;
100
+               struct ifaddr *ifa;
101
+               char *cp, *cp2, *cp3;
102
+               char *cplim;
103
+
104
+               inaddr6.sin6_addr = ip6->ip6_dst;
105
+               inaddr6.sin6_family = AF_INET6;
106
+               inaddr6.sin6_len = sizeof(inaddr6);
107
+               inaddr6.sin6_port = 0;
108
+               inaddr6.sin6_flowinfo = 0;
109
+               addr = (struct sockaddr *)&inaddr6;
110
+
111
+               IF_ADDR_RLOCK(ifp);
112
+               TAILQ_FOREACH(ifa, &ifp->if_addrhead, ifa_link) {
113
+                       if (ifa->ifa_addr->sa_family != AF_INET6)
114
+                               continue;
115
+                       if (ifa->ifa_netmask == 0) {
116
+                               if ((bcmp(addr, ifa->ifa_addr, addr->sa_len) == 0) ||
117
+                                   (ifa->ifa_dstaddr &&
118
+                                   (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0))) {
119
+                                       IF_ADDR_RUNLOCK(ifp);
120
+                                       return;
121
+                               }
122
+                               continue;
123
+                       }
124
+                       if (ifp->if_flags & IFF_POINTOPOINT) {
125
+                               if (bcmp(addr, ifa->ifa_dstaddr, addr->sa_len) == 0) {
126
+                                       IF_ADDR_RUNLOCK(ifp);
127
+                                       return;
128
+                               }
129
+                       } else {
130
+                               cp = addr->sa_data;
131
+                               cp2 = ifa->ifa_addr->sa_data;
132
+                               cp3 = ifa->ifa_netmask->sa_data;
133
+                               cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
134
+                               for (; cp3 < cplim; cp3++)
135
+                                       if ((*cp++ ^ *cp2++) & *cp3)
136
+                                               break;
137
+                               if (cp3 == cplim) {
138
+                                       IF_ADDR_RUNLOCK(ifp);
139
+                                       return;
140
+                               }
141
+                       }
142
+               }
143
+               IF_ADDR_RUNLOCK(ifp);
144
+       } else if (r->rt == PF_ROUTETO && r->direction == dir && in6_localaddr(&ip6->ip6_dst))
145
+	       return;
146
 
147
 	if (oifp != ifp) {
148
 		if (pf_test6(PF_OUT, ifp, &m0, NULL) != PF_PASS)
(56-56/67)