]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/aurp_open.c
xnu-792.6.56.tar.gz
[apple/xnu.git] / bsd / netat / aurp_open.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
ff6e181a
A
6 * This file contains Original Code and/or Modifications of Original Code
7 * as defined in and that are subject to the Apple Public Source License
8 * Version 2.0 (the 'License'). You may not use this file except in
9 * compliance with the License. Please obtain a copy of the License at
10 * http://www.opensource.apple.com/apsl/ and read it before using this
11 * file.
1c79356b 12 *
ff6e181a
A
13 * The Original Code and all software distributed under the License are
14 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
15 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
16 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
ff6e181a
A
17 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
18 * Please see the License for the specific language governing rights and
19 * limitations under the License.
1c79356b
A
20 *
21 * @APPLE_LICENSE_HEADER_END@
22 */
23/*
24 * Copyright (c) 1996 Apple Computer, Inc.
25 *
26 * Created April 8, 1996 by Tuyen Nguyen
27 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
28 *
29 * File: open.c
30 */
31#include <sys/errno.h>
32#include <sys/types.h>
33#include <sys/param.h>
34#include <machine/spl.h>
35#include <sys/systm.h>
36#include <sys/kernel.h>
37#include <sys/proc.h>
38#include <sys/filedesc.h>
39#include <sys/fcntl.h>
40#include <sys/mbuf.h>
41#include <sys/socket.h>
42#include <sys/socketvar.h>
43#include <net/if.h>
44
45#include <netat/sysglue.h>
46#include <netat/appletalk.h>
47#include <netat/at_var.h>
48#include <netat/routing_tables.h>
49#include <netat/at_pcb.h>
50#include <netat/aurp.h>
51#include <netat/debug.h>
52
53
91447636
A
54/* locked version of AURPsndOpenReq */
55void AURPsndOpenReq_locked(state)
1c79356b
A
56 aurp_state_t *state;
57{
91447636 58 atalk_lock();
1c79356b 59 AURPsndOpenReq(state);
91447636 60 atalk_unlock();
1c79356b
A
61}
62
63/* */
64void AURPsndOpenReq(state)
65 aurp_state_t *state;
66{
67 int msize;
68 gbuf_t *m;
69 aurp_hdr_t *hdrp;
70
71 if (aurp_gref == 0) {
72 return;
73 }
74 if (state->rcv_retry && (state->rcv_state != AURPSTATE_WaitingForOpenRsp)) {
75 return;
76 }
77
78 /* stop trying if the retry count exceeds the maximum value */
79 if (++state->rcv_retry > AURP_MaxRetry) {
80 dPrintf(D_M_AURP, D_L_WARNING,
81 ("AURPsndOpenReq: no response, node %u\n",
82 state->rem_node));
83 state->rcv_state = AURPSTATE_Unconnected;
84 state->rcv_tmo = 0;
85 state->rcv_retry = 0;
86 return;
87 }
88
89 msize = sizeof(aurp_hdr_t) + 3;
90 if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
91 gbuf_wset(m,msize);
92
93 /* construct the open request packet */
94 hdrp = (aurp_hdr_t *)gbuf_rptr(m);
95 if (state->rcv_retry > 1)
96 hdrp->connection_id = state->rcv_connection_id;
97 else {
98 if (++rcv_connection_id == 0)
99 rcv_connection_id = 1;
100 hdrp->connection_id = rcv_connection_id;
101 }
102 hdrp->sequence_number = 0;
103 hdrp->command_code = AURPCMD_OpenReq;
104 hdrp->flags = (AURPFLG_NA | AURPFLG_ND | AURPFLG_NDC | AURPFLG_ZC);
105 *(short *)(hdrp+1) = AURP_Version;
106 ((char *)(hdrp+1))[2] = 0; /* option count */
107
108 /* update state info */
109 state->rcv_connection_id = hdrp->connection_id;
110 state->rcv_state = AURPSTATE_WaitingForOpenRsp;
111
112 /* send the packet */
113 dPrintf(D_M_AURP, D_L_TRACE,
114 ("AURPsndOpenReq: sending AURPCMD_OpenReq, node %u\n",
115 state->rem_node));
116 AURPsend(m, AUD_AURP, state->rem_node);
117 }
118
119 /* start the retry timer */
91447636 120 timeout(AURPsndOpenReq_locked, state, AURP_RetryInterval*HZ);
1c79356b
A
121 state->rcv_tmo = 1;
122}
123
124/* */
125void AURPrcvOpenReq(state, m)
126 aurp_state_t *state;
127 gbuf_t *m;
128{
129 short rc, version;
130 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
131 unsigned short sui = hdrp->flags;
132
133 /* make sure we're in a valid state to accept it */
134 if ((update_tmo == 0) || ((state->snd_state != AURPSTATE_Unconnected) &&
135 (state->snd_state != AURPSTATE_Connected))) {
136 dPrintf(D_M_AURP, D_L_WARNING,
137 ("AURPrcvOpenReq: unexpected request, update_tmo=0x%x, snd_state=%u\n", (unsigned int) update_tmo, state->snd_state));
138 gbuf_freem(m);
139 return;
140 }
141
142 /* check for the correct version number */
143 version = *(short *)(hdrp+1);
144 if (version != AURP_Version) {
145 dPrintf(D_M_AURP, D_L_WARNING,
146 ("AURPrcvOpenReq: invalid version number %d, expected %d\n", version, AURP_Version));
147 rc = AURPERR_InvalidVersionNumber;
148 } else
149 rc = (short)AURP_UpdateRate;
150
151 /* construct the open response packet */
152 gbuf_wset(m,sizeof(aurp_hdr_t)+sizeof(short));
153 hdrp->command_code = AURPCMD_OpenRsp;
154 hdrp->flags = 0;
155 *(short *)(hdrp+1) = rc;
156 ((char *)(hdrp+1))[2] = 0; /* option count */
157
158 /*
159 * reset if we're in the Connected state and this is
160 * a completely new open request
161 */
162 if ((state->snd_state == AURPSTATE_Connected) &&
163 ((state->snd_connection_id != hdrp->connection_id) ||
164 (state->snd_sequence_number != AURP_FirstSeqNum))) {
165 extern void AURPsndTickle();
166 if (state->rcv_state == AURPSTATE_Connected) {
167 state->rcv_state = AURPSTATE_Unconnected;
168 untimeout(AURPsndTickle, state);
169 }
170 state->snd_state = AURPSTATE_Unconnected;
171 AURPcleanup(state);
172 AURPpurgeri(state->rem_node);
173 }
174
175 /* update state info */
176 if (state->snd_state == AURPSTATE_Unconnected) {
177 state->snd_state = AURPSTATE_Connected;
178 state->snd_sui = sui;
179 state->snd_connection_id = hdrp->connection_id;
180 state->snd_sequence_number = AURP_FirstSeqNum;
181 }
182
183 /* send the packet */
184 AURPsend(m, AUD_AURP, state->rem_node);
185
186 /* open connection for the data receiver side if not yet connected */
187 if (state->rcv_state == AURPSTATE_Unconnected) {
188 state->rcv_retry = 0;
189 state->tickle_retry = 0;
190 state->rcv_sequence_number = 0;
191 AURPsndOpenReq(state);
192 }
193}
194
195/* */
196void AURPrcvOpenRsp(state, m)
197 aurp_state_t *state;
198 gbuf_t *m;
199{
200 extern void AURPsndTickle();
201 short rc;
202 aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
203
204 /* make sure we're in a valid state to accept it */
205 if (state->rcv_state != AURPSTATE_WaitingForOpenRsp) {
206 dPrintf(D_M_AURP, D_L_WARNING,
207 ("AURPrcvOpenRsp: unexpected response\n"));
208 gbuf_freem(m);
209 return;
210 }
211
212 /* check for the correct connection id */
213 if (hdrp->connection_id != state->rcv_connection_id) {
214 dPrintf(D_M_AURP, D_L_WARNING,
215 ("AURPrcvOpenRsp: invalid connection id, r=%d, m=%d\n",
216 hdrp->connection_id, state->rcv_connection_id));
217 gbuf_freem(m);
218 return;
219 }
220
221 /* cancel the retry timer */
91447636 222 untimeout(AURPsndOpenReq_locked, state);
1c79356b
A
223 state->rcv_tmo = 0;
224 state->rcv_retry = 0;
225
226 /* update state info */
227 state->rcv_sequence_number = AURP_FirstSeqNum;
228 state->rcv_env = hdrp->flags;
229
230 /* check for error */
231 rc = *(short *)(hdrp+1);
232 gbuf_freem(m);
233 if (rc < 0) {
234 dPrintf(D_M_AURP, D_L_WARNING,
235 ("AURPrcvOpenRsp: error=%d\n", rc));
236 return;
237 }
238
239 /* update state info */
240 state->rcv_update_rate = (unsigned short)rc;
241 state->rcv_state = AURPSTATE_Connected;
242 dPrintf(D_M_AURP, D_L_TRACE, ("AURPrcvOpenRsp: moved rcv_state to AURPSTATE_Connected\n"));
243
244 /* start tickle */
245 timeout(AURPsndTickle, state, AURP_TickleRetryInterval*HZ);
246
247 /* get routing info */
248 AURPsndRIReq(state);
249}