|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 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. ! 11: * ! 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 ! 18: * under the License. ! 19: * ! 20: * @APPLE_LICENSE_HEADER_END@ ! 21: */ ! 22: /* ! 23: * Copyright (c) 1996 Apple Computer, Inc. ! 24: * ! 25: * Created April 8, 1996 by Tuyen Nguyen ! 26: * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. ! 27: * ! 28: * File: open.c ! 29: */ ! 30: #include <sys/errno.h> ! 31: #include <sys/types.h> ! 32: #include <sys/param.h> ! 33: #include <machine/spl.h> ! 34: #include <sys/systm.h> ! 35: #include <sys/kernel.h> ! 36: #include <sys/proc.h> ! 37: #include <sys/filedesc.h> ! 38: #include <sys/fcntl.h> ! 39: #include <sys/mbuf.h> ! 40: #include <sys/socket.h> ! 41: #include <sys/socketvar.h> ! 42: #include <net/if.h> ! 43: ! 44: #include <netat/sysglue.h> ! 45: #include <netat/appletalk.h> ! 46: #include <netat/at_var.h> ! 47: #include <netat/routing_tables.h> ! 48: #include <netat/at_pcb.h> ! 49: #include <netat/aurp.h> ! 50: #include <netat/debug.h> ! 51: ! 52: /* */ ! 53: void AURPsndOpenReq(state) ! 54: aurp_state_t *state; ! 55: { ! 56: int msize; ! 57: gbuf_t *m; ! 58: aurp_hdr_t *hdrp; ! 59: ! 60: if (aurp_gref == 0) ! 61: return; ! 62: if (state->rcv_retry && (state->rcv_state != AURPSTATE_WaitingForOpenRsp)) ! 63: return; ! 64: ! 65: /* stop trying if the retry count exceeds the maximum value */ ! 66: if (++state->rcv_retry > AURP_MaxRetry) { ! 67: dPrintf(D_M_AURP, D_L_WARNING, ! 68: ("AURPsndOpenReq: no response, node %u\n", ! 69: state->rem_node)); ! 70: state->rcv_state = AURPSTATE_Unconnected; ! 71: state->rcv_tmo = 0; ! 72: state->rcv_retry = 0; ! 73: return; ! 74: } ! 75: ! 76: msize = sizeof(aurp_hdr_t) + 3; ! 77: if ((m = (gbuf_t *)gbuf_alloc(msize, PRI_MED)) != 0) { ! 78: gbuf_wset(m,msize); ! 79: ! 80: /* construct the open request packet */ ! 81: hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 82: if (state->rcv_retry > 1) ! 83: hdrp->connection_id = state->rcv_connection_id; ! 84: else { ! 85: if (++rcv_connection_id == 0) ! 86: rcv_connection_id = 1; ! 87: hdrp->connection_id = rcv_connection_id; ! 88: } ! 89: hdrp->sequence_number = 0; ! 90: hdrp->command_code = AURPCMD_OpenReq; ! 91: hdrp->flags = (AURPFLG_NA | AURPFLG_ND | AURPFLG_NDC | AURPFLG_ZC); ! 92: *(short *)(hdrp+1) = AURP_Version; ! 93: ((char *)(hdrp+1))[2] = 0; /* option count */ ! 94: ! 95: /* update state info */ ! 96: state->rcv_connection_id = hdrp->connection_id; ! 97: state->rcv_state = AURPSTATE_WaitingForOpenRsp; ! 98: ! 99: /* send the packet */ ! 100: dPrintf(D_M_AURP, D_L_TRACE, ! 101: ("AURPsndOpenReq: sending AURPCMD_OpenReq, node %u\n", ! 102: state->rem_node)); ! 103: AURPsend(m, AUD_AURP, state->rem_node); ! 104: } ! 105: ! 106: /* start the retry timer */ ! 107: timeout(AURPsndOpenReq, state, AURP_RetryInterval*HZ); ! 108: state->rcv_tmo = 1; ! 109: } ! 110: ! 111: /* */ ! 112: void AURPrcvOpenReq(state, m) ! 113: aurp_state_t *state; ! 114: gbuf_t *m; ! 115: { ! 116: short rc, version; ! 117: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 118: unsigned short sui = hdrp->flags; ! 119: ! 120: /* make sure we're in a valid state to accept it */ ! 121: if ((update_tmo == 0) || ((state->snd_state != AURPSTATE_Unconnected) && ! 122: (state->snd_state != AURPSTATE_Connected))) { ! 123: dPrintf(D_M_AURP, D_L_WARNING, ! 124: ("AURPrcvOpenReq: unexpected request, update_tmo=0x%x, snd_state=%u\n", (unsigned int) update_tmo, state->snd_state)); ! 125: gbuf_freem(m); ! 126: return; ! 127: } ! 128: ! 129: /* check for the correct version number */ ! 130: version = *(short *)(hdrp+1); ! 131: if (version != AURP_Version) { ! 132: dPrintf(D_M_AURP, D_L_WARNING, ! 133: ("AURPrcvOpenReq: invalid version number %d, expected %d\n", version, AURP_Version)); ! 134: rc = AURPERR_InvalidVersionNumber; ! 135: } else ! 136: rc = (short)AURP_UpdateRate; ! 137: ! 138: /* construct the open response packet */ ! 139: gbuf_wset(m,sizeof(aurp_hdr_t)+sizeof(short)); ! 140: hdrp->command_code = AURPCMD_OpenRsp; ! 141: hdrp->flags = 0; ! 142: *(short *)(hdrp+1) = rc; ! 143: ((char *)(hdrp+1))[2] = 0; /* option count */ ! 144: ! 145: /* ! 146: * reset if we're in the Connected state and this is ! 147: * a completely new open request ! 148: */ ! 149: if ((state->snd_state == AURPSTATE_Connected) && ! 150: ((state->snd_connection_id != hdrp->connection_id) || ! 151: (state->snd_sequence_number != AURP_FirstSeqNum))) { ! 152: extern void AURPsndTickle(); ! 153: if (state->rcv_state == AURPSTATE_Connected) { ! 154: state->rcv_state = AURPSTATE_Unconnected; ! 155: untimeout(AURPsndTickle, state); ! 156: } ! 157: state->snd_state = AURPSTATE_Unconnected; ! 158: AURPcleanup(state); ! 159: AURPpurgeri(state->rem_node); ! 160: } ! 161: ! 162: /* update state info */ ! 163: if (state->snd_state == AURPSTATE_Unconnected) { ! 164: state->snd_state = AURPSTATE_Connected; ! 165: state->snd_sui = sui; ! 166: state->snd_connection_id = hdrp->connection_id; ! 167: state->snd_sequence_number = AURP_FirstSeqNum; ! 168: } ! 169: ! 170: /* send the packet */ ! 171: AURPsend(m, AUD_AURP, state->rem_node); ! 172: ! 173: /* open connection for the data receiver side if not yet connected */ ! 174: if (state->rcv_state == AURPSTATE_Unconnected) { ! 175: state->rcv_retry = 0; ! 176: state->tickle_retry = 0; ! 177: state->rcv_sequence_number = 0; ! 178: AURPsndOpenReq(state); ! 179: } ! 180: } ! 181: ! 182: /* */ ! 183: void AURPrcvOpenRsp(state, m) ! 184: aurp_state_t *state; ! 185: gbuf_t *m; ! 186: { ! 187: extern void AURPsndTickle(); ! 188: short rc; ! 189: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m); ! 190: ! 191: /* make sure we're in a valid state to accept it */ ! 192: if (state->rcv_state != AURPSTATE_WaitingForOpenRsp) { ! 193: dPrintf(D_M_AURP, D_L_WARNING, ! 194: ("AURPrcvOpenRsp: unexpected response\n")); ! 195: gbuf_freem(m); ! 196: return; ! 197: } ! 198: ! 199: /* check for the correct connection id */ ! 200: if (hdrp->connection_id != state->rcv_connection_id) { ! 201: dPrintf(D_M_AURP, D_L_WARNING, ! 202: ("AURPrcvOpenRsp: invalid connection id, r=%d, m=%d\n", ! 203: hdrp->connection_id, state->rcv_connection_id)); ! 204: gbuf_freem(m); ! 205: return; ! 206: } ! 207: ! 208: /* cancel the retry timer */ ! 209: untimeout(AURPsndOpenReq, state); ! 210: state->rcv_tmo = 0; ! 211: state->rcv_retry = 0; ! 212: ! 213: /* update state info */ ! 214: state->rcv_sequence_number = AURP_FirstSeqNum; ! 215: state->rcv_env = hdrp->flags; ! 216: ! 217: /* check for error */ ! 218: rc = *(short *)(hdrp+1); ! 219: gbuf_freem(m); ! 220: if (rc < 0) { ! 221: dPrintf(D_M_AURP, D_L_WARNING, ! 222: ("AURPrcvOpenRsp: error=%d\n", rc)); ! 223: return; ! 224: } ! 225: ! 226: /* update state info */ ! 227: state->rcv_update_rate = (unsigned short)rc; ! 228: state->rcv_state = AURPSTATE_Connected; ! 229: dPrintf(D_M_AURP, D_L_TRACE, ("AURPrcvOpenRsp: moved rcv_state to AURPSTATE_Connected\n")); ! 230: ! 231: /* start tickle */ ! 232: timeout(AURPsndTickle, state, AURP_TickleRetryInterval*HZ); ! 233: ! 234: /* get routing info */ ! 235: AURPsndRIReq(state); ! 236: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.