1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
5 *
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. The rights granted to you under the License
10 * may not be used to create, or enable the creation or redistribution of,
11 * unlawful or unlicensed copies of an Apple operating system, or to
12 * circumvent, violate, or enable the circumvention or violation of, any
13 * terms of an Apple operating system software license agreement.
14 *
15 * Please obtain a copy of the License at
16 * http://www.opensource.apple.com/apsl/ and read it before using this file.
17 *
18 * The Original Code and all software distributed under the License are
19 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
20 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
21 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
22 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
23 * Please see the License for the specific language governing rights and
24 * limitations under the License.
25 *
26 * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
27 */
28/*
29 *	Copyright (c) 1996 Apple Computer, Inc.
30 *
31 *		Created April 8, 1996 by Tuyen Nguyen
32 *   Modified, March 17, 1997 by Tuyen Nguyen for MacOSX.
33 *
34 *	File: tickle.c
35 */
36
37#ifdef AURP_SUPPORT
38
39#include <sys/errno.h>
40#include <sys/types.h>
41#include <sys/param.h>
42#include <machine/spl.h>
43#include <sys/systm.h>
44#include <sys/kernel.h>
45#include <sys/proc.h>
46#include <sys/filedesc.h>
47#include <sys/fcntl.h>
48#include <sys/mbuf.h>
49#include <sys/socket.h>
50#include <sys/socketvar.h>
51#include <net/if.h>
52
53#include <netat/sysglue.h>
54#include <netat/appletalk.h>
55#include <netat/at_pcb.h>
56#include <netat/at_var.h>
57#include <netat/routing_tables.h>
58#include <netat/aurp.h>
59#include <netat/debug.h>
60
61/* */
62void AURPsndTickle(state)
63	aurp_state_t *state;
64{
65	int msize;
66	gbuf_t *m;
67	aurp_hdr_t *hdrp;
68
69	atalk_lock();
70
71	if (state->rcv_state == AURPSTATE_Unconnected) {
72		atalk_unlock();
73		return;
74        }
75	/* stop trying if the retry count exceeds the maximum retry value */
76	if (++state->tickle_retry > AURP_MaxTickleRetry) {
77		dPrintf(D_M_AURP, D_L_WARNING,
78			("AURPsndTickle: no response, %d\n", state->rem_node));
79		/*
80		 * the tunnel peer seems to have disappeared, update state info
81		 */
82		state->snd_state = AURPSTATE_Unconnected;
83		state->rcv_state = AURPSTATE_Unconnected;
84		state->tickle_retry = 0;
85		AURPcleanup(state);
86
87		/* purge all routes associated with the tunnel peer */
88		AURPpurgeri(state->rem_node);
89		atalk_unlock();
90		return;
91	}
92
93  if (state->tickle_retry > 1) {
94	msize = sizeof(aurp_hdr_t);
95	if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) {
96		gbuf_wset(m,msize);
97
98		/* construct the tickle packet */
99		hdrp = (aurp_hdr_t *)gbuf_rptr(m);
100		hdrp->connection_id = state->rcv_connection_id;
101		hdrp->sequence_number = 0;
102		hdrp->command_code = AURPCMD_Tickle;
103		hdrp->flags = 0;
104
105		/* send the packet */
106		AURPsend(m, AUD_AURP, state->rem_node);
107	}
108  }
109
110	/* start the retry timer */
111	timeout(AURPsndTickle, state, AURP_TickleRetryInterval*HZ);
112
113	atalk_unlock();
114}
115
116/* */
117void AURPrcvTickle(state, m)
118	aurp_state_t *state;
119	gbuf_t *m;
120{
121	aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
122
123	/* make sure we're in a valid state to accept it */
124	if (state->snd_state == AURPSTATE_Unconnected) {
125		dPrintf(D_M_AURP, D_L_WARNING,
126			("AURPrcvTickle: unexpected request\n"));
127		gbuf_freem(m);
128		return;
129	}
130
131	/* construct the tickle ack packet */
132	gbuf_wset(m,sizeof(aurp_hdr_t));
133	hdrp->command_code = AURPCMD_TickleAck;
134	hdrp->flags = 0;
135
136	/* send the packet */
137	AURPsend(m, AUD_AURP, state->rem_node);
138}
139
140/* */
141void AURPrcvTickleAck(state, m)
142	aurp_state_t *state;
143	gbuf_t *m;
144{
145	aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
146
147	/* make sure we're in a valid state to accept it */
148	if (state->rcv_state == AURPSTATE_Unconnected) {
149		dPrintf(D_M_AURP, D_L_WARNING,
150			("AURPrcvTickleAck: unexpected response\n"));
151		gbuf_freem(m);
152		return;
153	}
154
155	/* check for the correct connection id */
156	if (hdrp->connection_id != state->rcv_connection_id) {
157		dPrintf(D_M_AURP, D_L_WARNING,
158			("AURPrcvTickleAck: invalid connection id, r=%d, m=%d\n",
159			hdrp->connection_id, state->rcv_connection_id));
160		gbuf_freem(m);
161		return;
162	}
163	gbuf_freem(m);
164
165	/* update state info */
166	state->tickle_retry = 0;
167}
168
169#endif  /* AURP_SUPPORT */
170