]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netinet6/natpt_usrreq.c
1 /* $KAME: natpt_usrreq.c,v 1.9 2000/03/25 07:23:57 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/types.h>
33 #include <sys/param.h>
34 #include <sys/malloc.h>
36 #include <sys/domain.h>
37 /* FreeBSD330 compiler complain that do not #include ioctl.h in the kernel, */
38 /* Include xxxio.h instead */
39 /* #include <sys/ioctl.h> */
40 #include <sys/ioccom.h>
41 #if defined(__FreeBSD__) && __FreeBSD__ >= 3 || defined (__APPLE__)
44 #include <sys/protosw.h>
45 #include <sys/socket.h>
46 #include <sys/socketvar.h>
47 #include <sys/syslog.h>
48 #include <sys/systm.h>
51 #include <net/raw_cb.h>
53 #include <netinet/in.h>
54 #include <netinet/in_systm.h>
56 #include <netinet6/natpt_defs.h>
57 #include <netinet6/natpt_log.h>
58 #include <netinet6/natpt_soctl.h>
59 #include <netinet6/natpt_var.h>
66 #define NATPTSNDQ (8192)
67 #define NATPTRCVQ (8192)
69 u_long natpt_sendspace
= NATPTSNDQ
;
70 u_long natpt_recvspace
= NATPTRCVQ
;
72 #if defined(__bsdi__) || defined(__FreeBSD__) && __FreeBSD__ <= 2
73 static struct rawcb ptrcb
;
75 LIST_HEAD(, rawcb
) ptrcb
;
78 static struct sockaddr natpt_dst
= {2, PF_INET
};
80 static struct sockaddr natpt_src
= {2, PF_INET
};
84 int natpt_sosetopt
__P((struct socket
*, int, struct mbuf
*));
85 int natpt_sogetopt
__P((struct socket
*, int, struct mbuf
*));
88 static int _natptSetIf
__P((caddr_t
));
89 static int _natptGetIf
__P((caddr_t
));
90 static int _natptSetValue
__P((caddr_t
));
91 static int _natptTestLog
__P((caddr_t
));
93 void natpt_init
__P((void));
96 int natpt_usrreq
__P((struct socket
*, int,
97 struct mbuf
*, struct mbuf
*, struct mbuf
*));
98 #elif defined(__NetBSD__)
99 int natpt_usrreq
__P((struct socket
*, int,
100 struct mbuf
*, struct mbuf
*, struct mbuf
*, struct proc
*));
101 #endif /* defined(__bsdi__) || defined(__NetBSD__) */
104 #if defined(__FreeBSD__) && __FreeBSD__ >= 3 || defined (__APPLE__)
105 int natpt_uabort
__P((struct socket
*));
106 int natpt_uattach
__P((struct socket
*, int, struct proc
*));
107 int natpt_ubind
__P((struct socket
*, struct sockaddr
*, struct proc
*));
108 int natpt_uconnect
__P((struct socket
*, struct sockaddr
*, struct proc
*));
109 int natpt_udetach
__P((struct socket
*));
110 int natpt_ucontrol
__P((struct socket
*, u_long
, caddr_t
, struct ifnet
*, struct proc
*));
111 #endif /* defined(__FreeBSD__) && __FreeBSD__ >= 3 */
113 int natpt_attach
__P((struct socket
*, int));
114 int natpt_control
__P((struct socket
*, int, caddr_t
, struct ifnet
*));
115 int natpt_detach
__P((struct socket
*));
116 int natpt_disconnect
__P((struct socket
*));
121 struct pr_usrreqs natpt_usrreqs
=
123 natpt_uabort
, NULL
, natpt_uattach
, natpt_ubind
,
124 natpt_uconnect
, NULL
, natpt_ucontrol
, natpt_udetach
,
125 natpt_disconnect
, NULL
, NULL
, NULL
,
126 NULL
, NULL
, NULL
, NULL
,
127 NULL
, sosend
, soreceive
, sopoll
130 struct pr_usrreqs natpt_usrreqs
=
132 NULL
, NULL
, natpt_attach
, NULL
,
133 NULL
, NULL
, natpt_control
, natpt_detach
,
134 natpt_disconnect
, NULL
, NULL
, NULL
,
135 NULL
, NULL
, NULL
, NULL
,
138 #endif /* __FreeBSD__ >= 3 */
139 #endif /* __FreeBSD__ */
149 natpt_initialized
= 0;
154 #if defined(__bsdi__) || defined(__FreeBSD__) && __FreeBSD__ <= 2
155 ptrcb
.rcb_next
= ptrcb
.rcb_prev
= &ptrcb
;
160 printf("NATPT: initialized.\n");
165 natpt_input(struct mbuf
*m0
, struct sockproto
*proto
,
166 struct sockaddr
*src
, struct sockaddr
*dst
)
174 #if defined(__bsdi__) || defined(__FreeBSD__) && __FreeBSD__ <= 2
175 for (rp
= ptrcb
.rcb_next
; rp
!= &ptrcb
; rp
= rp
->rcb_next
)
177 for (rp
= ptrcb
.lh_first
; rp
!= 0; rp
= rp
->rcb_list
.le_next
)
180 if (rp
->rcb_proto
.sp_family
!= proto
->sp_family
)
182 if (rp
->rcb_proto
.sp_protocol
183 && (rp
->rcb_proto
.sp_protocol
!= proto
->sp_protocol
))
186 #define equal(a1, a2) (bcmp((caddr_t)(a1), (caddr_t)(a2), a1->sa_len) == 0)
188 if (rp
->rcb_laddr
&& !equal(rp
->rcb_laddr
, dst
))
190 if (rp
->rcb_faddr
&& !equal(rp
->rcb_faddr
, src
))
197 if ((n
= m_copy(m
, 0, (int)M_COPYALL
)) != NULL
)
199 if (sbappendaddr(&last
->so_rcv
, src
, n
, (struct mbuf
*)NULL
) == 0)
200 m_freem(n
); /* should notify about lost packet */
208 last
= rp
->rcb_socket
;
213 if (sbappendaddr(&last
->so_rcv
, src
, m
, (struct mbuf
*)NULL
) == 0)
226 #if defined(__bsdi__) || defined(__NetBSD__)
228 natpt_usrreq(struct socket
*so
, int req
,
229 struct mbuf
*m
, struct mbuf
*nam
, struct mbuf
*control
235 struct rawcb
*rp
= sotorawcb(so
);
238 if ((rp
== NULL
) && (req
!= PRU_ATTACH
))
247 error
= natpt_attach(so
, (int)nam
);
251 error
= natpt_detach(so
);
255 if (rp
->rcb_faddr
== NULL
)
260 rp
->rcb_faddr
= NULL
;
262 soisdisconnected(so
);
277 error
= natpt_control(so
, (int)m
, (caddr_t
)nam
, (struct ifnet
*)NULL
);
303 #endif /* defined(__bsdi__) || defined(__NetBSD__) */
306 #if defined(__FreeBSD__) && __FreeBSD__ >= 3 || defined (__APPLE__)
308 natpt_uabort(struct socket
*so
)
310 struct rawcb
*rp
= sotorawcb(so
);
317 soisdisconnected(so
);
324 natpt_uattach(struct socket
*so
, int proto
, struct proc
*p
)
329 if (p
&& (error
= suser(p
->p_ucred
, &p
->p_acflag
)) != 0)
332 if ((so
->so_state
& SS_PRIV
) != 0)
336 return (natpt_attach(so
, proto
));
341 natpt_ubind(struct socket
*so
, struct sockaddr
*nam
, struct proc
*p
)
348 natpt_uconnect(struct socket
*so
, struct sockaddr
*nam
, struct proc
*p
)
355 natpt_ucontrol(struct socket
*so
, u_long cmd
, caddr_t data
, struct ifnet
*ifp
,
358 return (natpt_control(so
, cmd
, data
, ifp
));
363 natpt_udetach(struct socket
*so
)
365 struct rawcb
*rp
= sotorawcb(so
);
370 return (natpt_detach(so
));
373 #endif /* defined(__FreeBSD__) && __FreeBSD__ >= 3 */
377 natpt_attach(struct socket
*so
, int proto
)
382 if (so
->so_pcb
== NULL
)
384 MALLOC(rp
, struct rawcb
*, sizeof(*rp
), M_PCB
, M_WAITOK
);
385 so
->so_pcb
= (caddr_t
)rp
;
386 bzero(rp
, sizeof(*rp
));
389 if ((rp
= sotorawcb(so
)) == NULL
)
391 if ((error
= soreserve(so
, natpt_sendspace
, natpt_recvspace
)))
395 rp
->rcb_proto
.sp_family
= so
->so_proto
->pr_domain
->dom_family
;
396 rp
->rcb_proto
.sp_protocol
= proto
;
397 #if defined(__bsdi__) || defined(__FreeBSD__) && __FreeBSD__ <= 2
400 LIST_INSERT_HEAD(&ptrcb
, rp
, rcb_list
);
403 /* The socket is always "connected" because
404 we always know "where" to send the packet */
405 rp
->rcb_faddr
= &natpt_dst
;
413 natpt_detach(struct socket
*so
)
415 struct rawcb
*rp
= sotorawcb(so
);
423 #if defined(__bsdi__) || defined(__FreeBSD__) && __FreeBSD__ <= 2
426 LIST_REMOVE(rp
, rcb_list
);
429 m_freem(dtom(rp
->rcb_laddr
));
431 m_freem(dtom(rp
->rcb_faddr
));
439 natpt_disconnect(struct socket
*so
)
441 struct rawcb
*rp
= sotorawcb(so
);
446 if (rp
->rcb_faddr
== NULL
)
449 rp
->rcb_faddr
= NULL
;
451 soisdisconnected(so
);
458 natpt_control(struct socket
*so
, int cmd
, caddr_t data
, struct ifnet
*ifp
)
460 if (natpt_initialized
== 0)
465 case SIOCSETIF
: return (_natptSetIf(data
));
466 case SIOCGETIF
: return (_natptGetIf(data
));
467 case SIOCENBTRANS
: return (_natptEnableTrans(data
));
468 case SIOCDSBTRANS
: return (_natptDisableTrans(data
));
469 case SIOCSETRULE
: return (_natptSetRule(data
));
470 case SIOCFLUSHRULE
: return (_natptFlushRule(data
));
471 case SIOCSETPREFIX
: return (_natptSetPrefix(data
));
472 case SIOCSETVALUE
: return (_natptSetValue(data
));
474 case SIOCTESTLOG
: return (_natptTestLog(data
));
476 case SIOCBREAK
: return (_natptBreak());
488 _natptSetIf(caddr_t addr
)
490 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
493 if (((ifb
= natpt_asIfBox(mbx
->m_ifName
)) == NULL
)
494 && ((ifb
= natpt_setIfBox(mbx
->m_ifName
)) == NULL
))
497 if (ifb
->side
!= noSide
)
501 sprintf(WoW
, "[natpt]: interface `%s\' already configured.", mbx
->m_ifName
);
502 natpt_logMsg(LOG_WARNING
, WoW
, strlen(WoW
));
510 natpt_ip6src
= ifb
->ifnet
;
511 if (mbx
->flags
== IF_EXTERNAL
)
512 ifb
->side
= outSide
, s
= "outside";
514 ifb
->side
= inSide
, s
= "inside";
516 sprintf(WoW
, "[natpt]: interface `%s\' set as %s.", mbx
->m_ifName
, s
);
517 natpt_logMsg(LOG_INFO
, WoW
, strlen(WoW
));
525 _natptGetIf(caddr_t addr
)
527 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
530 if (((ifb
= natpt_asIfBox(mbx
->m_ifName
)) == NULL
)
531 && ((ifb
= natpt_setIfBox(mbx
->m_ifName
)) == NULL
))
537 case outSide
: mbx
->flags
|= IF_EXTERNAL
; break;
538 case inSide
: mbx
->flags
|= IF_INTERNAL
; break;
539 default: mbx
->flags
= -1; break;
548 _natptSetValue(caddr_t addr
)
550 struct natpt_msgBox
*mbx
= (struct natpt_msgBox
*)addr
;
555 natpt_debug
= *((u_int
*)mbx
->m_aux
);
559 natpt_dump
= *((u_int
*)mbx
->m_aux
);
568 _natptTestLog(caddr_t addr
)
571 struct natpt_msgBox
*mbox
= (struct natpt_msgBox
*)addr
;
573 MALLOC(fragile
, char *, mbox
->size
, M_TEMP
, M_WAITOK
);
574 copyin(mbox
->freight
, fragile
, mbox
->size
);
576 natpt_logMsg(LOG_DEBUG
, fragile
, mbox
->size
);
578 FREE(fragile
, M_TEMP
);