1 /* $KAME: natpt_rule.c,v 1.9 2000/03/25 07:23:56 sumikawa Exp $ */
4 * Copyright (C) 1995, 1996, 1997, and 1998 WIDE Project.
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 * 3. Neither the name of the project nor the names of its contributors
16 * may be used to endorse or promote products derived from this software
17 * without specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
21 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
22 * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
23 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
24 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
25 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
26 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
27 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
28 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
32 #include <sys/errno.h>
33 #include <sys/param.h>
34 #include <sys/malloc.h>
36 #include <sys/socket.h>
37 #include <sys/syslog.h>
38 #include <sys/systm.h>
42 #include <netinet/in.h>
43 #include <netinet/in_systm.h>
44 #include <netinet/ip.h>
45 #include <netinet/tcp.h>
47 #include <netinet/ip6.h>
48 #if (defined(__FreeBSD__) && __FreeBSD__ < 3) || defined(__bsdi__)
49 #include <netinet6/tcp6.h>
52 #include <netinet6/natpt_defs.h>
53 #include <netinet6/natpt_list.h>
54 #include <netinet6/natpt_log.h>
55 #include <netinet6/natpt_soctl.h>
56 #include <netinet6/natpt_var.h>
63 Cell
*natptStatic
; /* list of struct _cSlot */
64 Cell
*natptDynamic
; /* list of struct _cSlot */
65 Cell
*natptFaith
; /* list of struct _cSlot */
67 int matchIn4addr
__P((struct _cv
*, struct pAddr
*));
68 int matchIn6addr
__P((struct _cv
*, struct pAddr
*));
69 static void _flushPtrRules
__P((struct _cell
**));
72 extern struct in6_addr faith_prefix
;
73 extern struct in6_addr faith_prefixmask
;
74 extern struct in6_addr natpt_prefix
;
75 extern struct in6_addr natpt_prefixmask
;
77 extern void in4_len2mask
__P((struct in_addr
*, int));
78 extern void in6_len2mask
__P((struct in6_addr
*, int));
86 lookingForIncomingV4Rule(struct _cv
*cv
)
91 for (p
= natptStatic
; p
; p
= CDR(p
))
93 acs
= (struct _cSlot
*)CAR(p
);
94 if ((acs
->dir
== NATPT_INBOUND
)
96 || (acs
->proto
== cv
->ip_payload
))
97 && (matchIn4addr(cv
, &acs
->remote
) != 0))
101 for (p
= natptDynamic
; p
; p
= CDR(p
))
103 acs
= (struct _cSlot
*)CAR(p
);
104 if ((acs
->dir
== NATPT_INBOUND
)
105 && ((acs
->proto
== 0)
106 || (acs
->proto
== cv
->ip_payload
))
107 && (matchIn4addr(cv
, &acs
->remote
) != 0))
116 lookingForOutgoingV4Rule(struct _cv
*cv
)
121 for (p
= natptStatic
; p
; p
= CDR(p
))
123 acs
= (struct _cSlot
*)CAR(p
);
125 if ((acs
->dir
== NATPT_OUTBOUND
)
126 && (matchIn4addr(cv
, &acs
->local
) != 0))
130 for (p
= natptDynamic
; p
; p
= CDR(p
))
132 acs
= (struct _cSlot
*)CAR(p
);
133 if ((acs
->dir
== NATPT_OUTBOUND
)
134 && (matchIn4addr(cv
, &acs
->local
) != 0))
143 lookingForIncomingV6Rule(struct _cv
*cv
)
148 for (p
= natptStatic
; p
; p
= CDR(p
))
150 acs
= (struct _cSlot
*)CAR(p
);
151 if ((acs
->dir
== NATPT_INBOUND
)
152 && (matchIn6addr(cv
, &acs
->remote
)) != 0)
156 for (p
= natptDynamic
; p
; p
= CDR(p
))
158 acs
= (struct _cSlot
*)CAR(p
);
159 if ((acs
->dir
== NATPT_INBOUND
)
160 && (matchIn6addr(cv
, &acs
->remote
)) != 0)
169 lookingForOutgoingV6Rule(struct _cv
*cv
)
174 for (p
= natptStatic
; p
; p
= CDR(p
))
176 acs
= (struct _cSlot
*)CAR(p
);
177 if ((acs
->dir
== NATPT_OUTBOUND
)
178 && ((acs
->proto
== 0)
179 || (acs
->proto
== cv
->ip_payload
))
180 && (matchIn6addr(cv
, &acs
->local
)) != 0)
184 for (p
= natptDynamic
; p
; p
= CDR(p
))
186 acs
= (struct _cSlot
*)CAR(p
);
187 if ((acs
->dir
== NATPT_OUTBOUND
)
188 && ((acs
->proto
== 0)
189 || (acs
->proto
== cv
->ip_payload
))
190 && (matchIn6addr(cv
, &acs
->local
)) != 0)
194 for (p
= natptFaith
; p
; p
= CDR(p
))
196 acs
= (struct _cSlot
*)CAR(p
);
197 if ((acs
->dir
== NATPT_OUTBOUND
)
198 && ((acs
->proto
== 0)
199 || (acs
->proto
== cv
->ip_payload
))
200 && (matchIn6addr(cv
, &acs
->local
)) != 0)
209 matchIn4addr(struct _cv
*cv4
, struct pAddr
*from
)
211 struct in_addr in4from
= cv4
->_ip
._ip4
->ip_src
;
212 struct in_addr in4masked
;
214 if (from
->sa_family
!= AF_INET
)
217 switch (from
->ad
.type
)
219 case ADDR_ANY
: goto port
;
222 if (in4from
.s_addr
== from
->in4Addr
.s_addr
) goto port
;
226 in4masked
.s_addr
= in4from
.s_addr
& from
->in4Mask
.s_addr
;
227 if (in4masked
.s_addr
== from
->in4Addr
.s_addr
) goto port
;
231 if ((in4from
.s_addr
>= from
->in4RangeStart
.s_addr
)
232 && (in4from
.s_addr
<= from
->in4RangeEnd
.s_addr
)) goto port
;
240 if ((cv4
->ip_payload
!= IPPROTO_UDP
)
241 && (cv4
->ip_payload
!= IPPROTO_TCP
)) return (1);
243 if (from
->_port0
== 0) return (1);
245 if (from
->_port1
== 0)
247 if ((cv4
->_payload
._tcp4
->th_dport
== from
->_port0
)) return (1);
251 u_short dport
= ntohs(cv4
->_payload
._tcp4
->th_dport
);
252 u_short port0
= ntohs(from
->_port0
);
253 u_short port1
= ntohs(from
->_port1
);
256 && (dport
<= port1
)) return (1);
264 matchIn6addr(struct _cv
*cv6
, struct pAddr
*from
)
266 struct in6_addr
*in6from
= &cv6
->_ip
._ip6
->ip6_src
;
267 struct in6_addr in6masked
;
269 if (from
->sa_family
!= AF_INET6
)
272 switch (from
->ad
.type
)
274 case ADDR_ANY
: goto port
;
277 if (IN6_ARE_ADDR_EQUAL(in6from
, &from
->in6Addr
)) goto port
;
281 in6masked
.s6_addr32
[0] = in6from
->s6_addr32
[0] & from
->in6Mask
.s6_addr32
[0];
282 in6masked
.s6_addr32
[1] = in6from
->s6_addr32
[1] & from
->in6Mask
.s6_addr32
[1];
283 in6masked
.s6_addr32
[2] = in6from
->s6_addr32
[2] & from
->in6Mask
.s6_addr32
[2];
284 in6masked
.s6_addr32
[3] = in6from
->s6_addr32
[3] & from
->in6Mask
.s6_addr32
[3];
286 if (IN6_ARE_ADDR_EQUAL(&in6masked
, &from
->in6Addr
)) goto port
;
294 if ((cv6
->ip_payload
!= IPPROTO_UDP
)
295 && (cv6
->ip_payload
!= IPPROTO_TCP
)) return (1);
297 if (from
->_port0
== 0) return (1);
299 if (from
->_port1
== 0)
301 if (cv6
->_payload
._tcp6
->th_dport
== from
->_port0
) return (1);
305 u_short dport
= ntohs(cv6
->_payload
._tcp6
->th_dport
);
306 #ifdef UnusedVariable
307 u_short port0
= ntohs(from
->_port0
);
308 u_short port1
= ntohs(from
->_port1
);
311 if ((dport
>= from
->_port0
)
312 && (dport
<= from
->_port1
)) return (1);
323 _natptEnableTrans(caddr_t addr
)
327 sprintf(Wow
, "map enable");
328 natpt_logMsg(LOG_INFO
, Wow
, strlen(Wow
));
336 _natptDisableTrans(caddr_t addr
)
340 sprintf(Wow
, "map disable");
341 natpt_logMsg(LOG_INFO
, Wow
, strlen(Wow
));
349 _natptSetRule(caddr_t addr
)
351 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
356 if (((ifb
= natpt_asIfBox(mbx
->m_ifName
)) == NULL
)
357 && ((ifb
= natpt_setIfBox(mbx
->m_ifName
)) == NULL
))
361 if (mbx
->flags
== NATPT_FAITH
)
362 return (_natptSetFaithRule(addr
));
364 MALLOC(cst
, struct _cSlot
*, sizeof(struct _cSlot
), M_TEMP
, M_WAITOK
);
365 copyin(mbx
->freight
, cst
, sizeof(struct _cSlot
));
371 if (cst
->dir
== NATPT_INBOUND
)
374 if (from
->sa_family
== AF_INET
)
376 in4_len2mask(&from
->in4Mask
, cst
->prefix
);
377 from
->in4Addr
.s_addr
&= from
->in4Mask
.s_addr
;
381 in6_len2mask(&from
->in6Mask
, cst
->prefix
);
382 from
->in6Addr
.s6_addr32
[0]
383 = from
->in6Addr
.s6_addr32
[0] & from
->in6Mask
.s6_addr32
[0];
384 from
->in6Addr
.s6_addr32
[1]
385 = from
->in6Addr
.s6_addr32
[1] & from
->in6Mask
.s6_addr32
[1];
386 from
->in6Addr
.s6_addr32
[2]
387 = from
->in6Addr
.s6_addr32
[2] & from
->in6Mask
.s6_addr32
[2];
388 from
->in6Addr
.s6_addr32
[3]
389 = from
->in6Addr
.s6_addr32
[3] & from
->in6Mask
.s6_addr32
[3];
393 natpt_log(LOG_CSLOT
, LOG_DEBUG
, (void *)cst
, sizeof(struct _cSlot
));
395 anchor
= &natptStatic
;
396 if (cst
->flags
== NATPT_DYNAMIC
)
397 anchor
= &natptDynamic
;
399 LST_hookup_list(anchor
, cst
);
406 _natptSetFaithRule(caddr_t addr
)
408 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
411 MALLOC(cst
, struct _cSlot
*, sizeof(struct _cSlot
), M_TEMP
, M_WAITOK
);
412 copyin(mbx
->freight
, cst
, sizeof(struct _cSlot
));
414 LST_hookup_list(&natptFaith
, cst
);
421 _natptFlushRule(caddr_t addr
)
423 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
425 if (mbx
->flags
& FLUSH_STATIC
)
426 _flushPtrRules(&natptStatic
);
428 if (mbx
->flags
& FLUSH_DYNAMIC
)
429 _flushPtrRules(&natptDynamic
);
436 _natptSetPrefix(caddr_t addr
)
438 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
441 MALLOC(load
, struct pAddr
*, sizeof(struct pAddr
), M_TEMP
, M_WAITOK
);
442 copyin(mbx
->freight
, load
, SZSIN6
* 2);
444 if (mbx
->flags
& PREFIX_FAITH
)
446 faith_prefix
= load
->addr
[0].in6
;
447 faith_prefixmask
= load
->addr
[1].in6
;
449 natpt_logIN6addr(LOG_INFO
, "FAITH prefix: ", &faith_prefix
);
450 natpt_logIN6addr(LOG_INFO
, "FAITH prefixmask: ", &faith_prefixmask
);
452 else if (mbx
->flags
& PREFIX_NATPT
)
454 natpt_prefix
= load
->addr
[0].in6
;
455 natpt_prefixmask
= load
->addr
[1].in6
;
457 natpt_logIN6addr(LOG_INFO
, "NATPT prefix: ", &natpt_prefix
);
458 natpt_logIN6addr(LOG_INFO
, "NATPT prefixmask: ", &natpt_prefixmask
);
480 _flushPtrRules(struct _cell
**anchor
)
482 struct _cell
*p0
, *p1
;
491 cslt
= (struct _cSlot
*)CAR(p1
);