]>
git.saurik.com Git - apple/xnu.git/blob - bsd/netat/at_pcb.c
2 * Copyright (c) 2000-2004 Apple Computer, Inc. All rights reserved.
4 * @APPLE_LICENSE_HEADER_START@
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
20 * @APPLE_LICENSE_HEADER_END@
24 * Copyright (c) 1997-1999 Apple Computer, Inc.
25 * All Rights Reserved.
27 /* Copyright (c) 1995 NeXT Computer, Inc. All Rights Reserved */
29 * Copyright (c) 1982, 1986, 1991, 1993
30 * The Regents of the University of California. All rights reserved.
32 * Redistribution and use in source and binary forms, with or without
33 * modification, are permitted provided that the following conditions
35 * 1. Redistributions of source code must retain the above copyright
36 * notice, this list of conditions and the following disclaimer.
37 * 2. Redistributions in binary form must reproduce the above copyright
38 * notice, this list of conditions and the following disclaimer in the
39 * documentation and/or other materials provided with the distribution.
40 * 3. All advertising materials mentioning features or use of this software
41 * must display the following acknowledgement:
42 * This product includes software developed by the University of
43 * California, Berkeley and its contributors.
44 * 4. Neither the name of the University nor the names of its contributors
45 * may be used to endorse or promote products derived from this software
46 * without specific prior written permission.
48 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
49 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
50 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
51 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
52 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
53 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
54 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
55 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
56 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
57 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60 * @(#)at_pcb.c 8.2 (Berkeley) 1/4/94
63 #include <sys/param.h>
64 #include <sys/systm.h>
65 #include <sys/malloc.h>
67 #include <sys/protosw.h>
68 #include <sys/socket.h>
69 #include <sys/socketvar.h>
70 #include <sys/ioctl.h>
71 #include <sys/errno.h>
74 #include <kern/kern_types.h>
75 #include <kern/zalloc.h>
76 #include <kern/queue.h>
80 #include <netat/sysglue.h>
81 #include <netat/appletalk.h>
82 #include <netat/ddp.h>
83 #include <netat/at_pcb.h>
84 #include <netat/debug.h>
85 #include <netat/at_var.h>
86 #include <netat/adsp.h>
87 #include <netat/adsp_internal.h>
89 extern struct atpcb ddp_head
;
90 extern struct atpcb
*atp_inputQ
[];
91 extern CCB
*adsp_inputQ
[];
92 extern at_ifaddr_t
*ifID_home
;
97 int DDP_chksum_on
= FALSE
;
98 int DDP_slfsnd_on
= FALSE
;
102 void at_memzone_init()
106 str_size
= (vm_size_t
)sizeof(struct atpcb
);
107 atpcb_zone
= (zone_t
)zinit(str_size
, 1000*str_size
, 8192, "atpcb zone");
110 int at_pcballoc(so
, head
)
114 register struct atpcb
*pcb
;
116 pcb
= (struct atpcb
*)zalloc(atpcb_zone
);
119 bzero((caddr_t
)pcb
, sizeof(*pcb
));
121 /* set the flags to the system defaults */
123 pcb
->ddp_flags
|= DDPFLG_CHKSUM
;
125 pcb
->ddp_flags
&= ~DDPFLG_CHKSUM
;
127 pcb
->ddp_flags
|= DDPFLG_SLFSND
;
129 pcb
->ddp_flags
&= ~DDPFLG_SLFSND
;
131 pcb
->atpcb_head
= head
;
132 pcb
->atpcb_socket
= so
;
133 atalk_lock(); /* makes sure the list is locked while inserting atpcb */
135 insque((queue_t
)pcb
, (queue_t
)head
);
136 so
->so_pcb
= (caddr_t
)pcb
;
142 int at_pcbdetach(pcb
)
145 struct socket
*so
= pcb
->atpcb_socket
;
147 /* Notify NBP that we are closing this DDP socket */
149 ddp_notify_nbp(pcb
->lport
, pcb
->pid
, pcb
->ddptype
);
154 so
->so_flags
|= SOF_PCBCLEARING
;
155 if ((pcb
->atpcb_next
) && (pcb
->atpcb_prev
))
156 remque((queue_t
)pcb
);
157 zfree(atpcb_zone
, pcb
);
162 int ddp_socket_inuse(ddpsock
, proto
)
163 u_char ddpsock
, proto
;
167 if ((!proto
|| (proto
== DDP_ATP
)) && atp_inputQ
[ddpsock
])
169 if ((!proto
|| (proto
== DDP_ADSP
)) && adsp_inputQ
[ddpsock
])
171 if (ddp_handler
[ddpsock
].func
)
173 for (pcb
= ddp_head
.atpcb_next
; pcb
!= &ddp_head
;
174 pcb
= pcb
->atpcb_next
) {
175 if (pcb
->lport
== ddpsock
&&
176 (!pcb
->ddptype
|| !proto
|| (pcb
->ddptype
== proto
)))
182 int at_pcbbind(pcb
, nam
)
183 register struct atpcb
*pcb
;
184 struct sockaddr
*nam
;
186 register struct socket
*so
= pcb
->atpcb_socket
;
187 register struct sockaddr_at
*local
= (struct sockaddr_at
*) nam
;
188 u_char ddpsock
= local
->sat_port
;
190 if ((!ifID_home
) || (local
->sat_family
!= AF_APPLETALK
))
191 return(EADDRNOTAVAIL
);
193 if (pcb
->lport
!= ATADDR_ANYPORT
||
194 pcb
->laddr
.s_node
!= ATADDR_ANYNODE
||
195 pcb
->laddr
.s_net
!= ATADDR_ANYNET
)
198 /* Request for dynamic socket? */
200 /* Search table for free one */
201 /* *** borrow IP algorithm, instead? *** */
202 for (ddpsock
= DDP_SOCKET_LAST
;
203 ddpsock
>= (DDP_SOCKET_1st_DYNAMIC
+ 1);
206 if (! ddp_socket_inuse(ddpsock
, pcb
->ddptype
))
209 if (ddpsock
< (DDP_SOCKET_1st_DYNAMIC
+ 1))
210 return(EADDRNOTAVAIL
); /* Error if no free sockets */
212 /* Asking to open a socket by its number.
213 Check if its legal & free. */
214 if (ddpsock
> DDP_SOCKET_LAST
)
216 if (ddp_socket_inuse(ddpsock
, pcb
->ddptype
))
217 return(EADDRNOTAVAIL
);
220 pcb
->lport
= ddpsock
;
221 /* if address is specified, make sure address matches one of the
222 interfaces configured for AppleTalk */
223 if (local
->sat_addr
.s_net
|| local
->sat_addr
.s_node
) {
224 if (MULTIHOME_MODE
) {
226 TAILQ_FOREACH(ifID
, &at_ifQueueHd
, aa_link
) {
227 if (ifID
->ifThisNode
.s_net
== local
->sat_addr
.s_net
&&
228 ifID
->ifThisNode
.s_node
== local
->sat_addr
.s_node
) {
229 pcb
->laddr
= local
->sat_addr
;
235 /* for single-port and router modes if the local address is
236 specified, it must match the default interface, which is
237 what will be put into packets' source address anyway */
238 if (ifID_home
->ifThisNode
.s_net
== local
->sat_addr
.s_net
&&
239 ifID_home
->ifThisNode
.s_node
== local
->sat_addr
.s_node
) {
240 pcb
->laddr
= local
->sat_addr
;