|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights ! 7: * Reserved. This file contains Original Code and/or Modifications of ! 8: * Original Code as defined in and that are subject to the Apple Public ! 9: * Source License Version 1.1 (the "License"). You may not use this file ! 10: * except in compliance with the License. Please obtain a copy of the ! 11: * License at http://www.apple.com/publicsource and read it before using ! 12: * this file. ! 13: * ! 14: * The Original Code and all software distributed under the License are ! 15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER ! 16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the ! 19: * License for the specific language governing rights and limitations ! 20: * under the License. ! 21: * ! 22: * @APPLE_LICENSE_HEADER_END@ ! 23: */ ! 24: ! 25: ! 26: /* ! 27: * Copyright (c) 1988, 1989 Apple Computer, Inc. ! 28: * ! 29: * The information contained herein is subject to change without ! 30: * notice and should not be construed as a commitment by Apple ! 31: * Computer, Inc. Apple Computer, Inc. assumes no responsibility ! 32: * for any errors that may appear. ! 33: * ! 34: * Confidential and Proprietary to Apple Computer, Inc. ! 35: * Modified, March 17, 1997 by Tuyen Nguyen for Rhapsody. ! 36: */ ! 37: ! 38: /****************************************************************/ ! 39: /* */ ! 40: /* */ ! 41: /* S I P */ ! 42: /* System Information Protocol */ ! 43: /* */ ! 44: /* */ ! 45: /****************************************************************/ ! 46: ! 47: /* System Information Protocol -- implemented to handle Responder ! 48: * Queries. The queries are ATP requests, but the ATP responses are faked ! 49: * here in a DDP level handler routine. The responder socket is always ! 50: * the 1st socket in the dynamic socket range (128) and it is assumed ! 51: * that the node will be registered on that socket. ! 52: * ! 53: * In A/UX implementation, this implies that /etc/appletalk program will ! 54: * register the node name on socket DDP_SOCKET_1st_DYNAMIC (128). ! 55: */ ! 56: ! 57: #include <sysglue.h> ! 58: ! 59: #include <at/appletalk.h> ! 60: #include <lap.h> ! 61: #include <at/ddp.h> ! 62: #include <at/atp.h> ! 63: ! 64: #include <at/at_lap.h> ! 65: #include <at_ddp.h> ! 66: ! 67: #define SIP_SYSINFO_CMD 1 ! 68: #define SIP_DATALINK_CMD 6 ! 69: ! 70: #define SIP_GOOD_RESPONSE 0x1 ! 71: #define SIP_BAD_RESPONSE 0xff ! 72: ! 73: #define SIP_DRIVER_VERSION 0x0001 ! 74: #define SIP_RESPONDER_VERSION 0x0001 ! 75: ! 76: typedef struct { ! 77: u_char response; ! 78: u_char unused; ! 79: u_short responder_version; ! 80: } sip_userbytes_t; ! 81: ! 82: static void ! 83: sip_input(mp, ifID) ! 84: gbuf_t *mp; ! 85: at_if_t ifID; /* not used */ ! 86: { ! 87: /* Packets arriving here are actually ATP packets, but since ! 88: * A/UX only send dummy responses, we're implementing responder as ! 89: * a DDP handler ! 90: */ ! 91: register at_ddp_t *ddp; ! 92: register at_atp_t *atp; ! 93: register gbuf_t *tmp; ! 94: u_char *resp; ! 95: sip_userbytes_t ubytes; ! 96: ! 97: ddp = (at_ddp_t *)gbuf_rptr(mp); ! 98: ! 99: /* Make sure the packet we got is an ATP packet */ ! 100: if (ddp->type != ATP_DDP_TYPE) { ! 101: gbuf_freem(mp); ! 102: return; ! 103: } ! 104: ! 105: /* assuming that the whole packet is in one contiguous buffer */ ! 106: atp = (at_atp_t *)ddp->data; ! 107: ! 108: switch(UAL_VALUE(atp->user_bytes)) { ! 109: case SIP_SYSINFO_CMD : ! 110: /* Sending a response with "AppleTalk driver version" (u_short) ! 111: * followed by 14 zeros will pacify the interpoll. ! 112: * What? You don't understand what it means to send 14 zeroes? ! 113: * Tsk, tsk, look up SIP protocol specs for details!! ! 114: */ ! 115: if ((tmp = (gbuf_t *)ddp_growmsg(mp, 16)) == NULL) { ! 116: /* dont have buffers */ ! 117: gbuf_freem(mp); ! 118: return; ! 119: } ! 120: if (tmp == mp) ! 121: /* extra space allocated on the same buffer block */ ! 122: resp = atp->data; ! 123: else ! 124: resp = (u_char *)gbuf_rptr(tmp); ! 125: bzero(resp, 16); ! 126: *(u_short *)resp = SIP_DRIVER_VERSION; ! 127: ! 128: ubytes.response = SIP_GOOD_RESPONSE; ! 129: ubytes.unused = 0; ! 130: ubytes.responder_version = SIP_RESPONDER_VERSION; ! 131: break; ! 132: case SIP_DATALINK_CMD : ! 133: /* In this case, the magic spell is to send 2 zeroes after ! 134: * the "AppleTalk driver version". ! 135: */ ! 136: if ((tmp = (gbuf_t *)ddp_growmsg(mp, 4)) == NULL) { ! 137: /* dont have buffers */ ! 138: gbuf_freem(mp); ! 139: return; ! 140: } ! 141: if (tmp == mp) ! 142: /* extra space allocated on the same buffer block */ ! 143: resp = atp->data; ! 144: else ! 145: resp = (u_char *)gbuf_rptr(tmp); ! 146: bzero(resp, 16); ! 147: *(u_short *)resp = SIP_DRIVER_VERSION; ! 148: ! 149: ubytes.response = SIP_GOOD_RESPONSE; ! 150: ubytes.unused = 0; ! 151: ubytes.responder_version = SIP_RESPONDER_VERSION; ! 152: break; ! 153: default : ! 154: /* bad request, send a bad command response back */ ! 155: ubytes.response = SIP_BAD_RESPONSE; ! 156: ubytes.unused = 0; ! 157: ubytes.responder_version = SIP_RESPONDER_VERSION; ! 158: } ! 159: ! 160: NET_NET(ddp->dst_net, ddp->src_net); ! 161: ddp->dst_node = ddp->src_node; ! 162: ddp->dst_socket = ddp->src_socket; ! 163: bcopy((caddr_t) &ubytes, (caddr_t) atp->user_bytes, sizeof(ubytes)); ! 164: atp->cmd = ATP_CMD_TRESP; ! 165: atp->eom = 1; ! 166: atp->sts = 0; ! 167: atp->bitmap = 0; ! 168: ! 169: if (ddp_output(&mp, DDP_SOCKET_1st_DYNAMIC, NULL) != 0) ! 170: gbuf_freem(mp); ! 171: ! 172: return; ! 173: } ! 174: ! 175: ! 176: void sip_init() ! 177: { ! 178: /* Open a "well known" dynamic socket with sip_input as the handler ! 179: * routine. ! 180: */ ! 181: ddp_socket_t socket; ! 182: ! 183: ! 184: socket.number = DDP_SOCKET_1st_DYNAMIC; ! 185: socket.flags = DDP_CALL_HANDLER; ! 186: socket.sock_u.handler = sip_input; ! 187: socket.dev = NULL; ! 188: ! 189: ddp_bind_socket(&socket); ! 190: return; ! 191: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.