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/* 30 * Copyright (c) 1988, 1989 Apple Computer, Inc. 31 * 32 * Modified, March 17, 1997 by Tuyen Nguyen for MacOSX. 33 */ 34 35#ifndef lint 36/* static char sccsid[] = "@(#)sip.c: 2.0, 1.3; 10/18/93; Copyright 1988-89, Apple Computer, Inc."; */ 37#endif /* lint */ 38 39/****************************************************************/ 40/* */ 41/* */ 42/* S I P */ 43/* System Information Protocol */ 44/* */ 45/* */ 46/****************************************************************/ 47 48/* System Information Protocol -- implemented to handle Responder 49 * Queries. The queries are ATP requests, but the ATP responses are faked 50 * here in a DDP level handler routine. The responder socket is always 51 * the 1st socket in the dynamic socket range (128) and it is assumed 52 * that the node will be registered on that socket. 53 * 54 * In A/UX implementation, this implies that /etc/appletalk program will 55 * register the node name on socket DDP_SOCKET_1st_DYNAMIC (128). 56 */ 57 58#include <sys/errno.h> 59#include <sys/types.h> 60#include <sys/param.h> 61#include <machine/spl.h> 62#include <sys/systm.h> 63#include <sys/kernel.h> 64#include <sys/proc.h> 65#include <sys/filedesc.h> 66#include <sys/fcntl.h> 67#include <sys/mbuf.h> 68#include <sys/ioctl.h> 69#include <sys/malloc.h> 70#include <sys/socket.h> 71#include <sys/socketvar.h> 72 73#include <net/if.h> 74 75#include <netat/sysglue.h> /* nbp.h needs the gbuf definiton */ 76#include <netat/appletalk.h> 77#include <netat/ddp.h> 78#include <netat/at_pcb.h> 79#include <netat/at_var.h> 80#include <netat/nbp.h> 81#include <netat/atp.h> 82 83#define SIP_SYSINFO_CMD 1 84#define SIP_DATALINK_CMD 6 85 86#define SIP_GOOD_RESPONSE 0x1 87#define SIP_BAD_RESPONSE 0xff 88 89#define SIP_DRIVER_VERSION 0x0001 90#define SIP_RESPONDER_VERSION 0x0001 91 92typedef struct { 93 u_char response; 94 u_char unused; 95 u_short responder_version; 96} sip_userbytes_t; 97 98void sip_input( 99 gbuf_t *mp, 100 __unused at_ifaddr_t *ifID) 101{ 102 /* Packets arriving here are actually ATP packets, but since 103 * A/UX only send dummy responses, we're implementing responder as 104 * a DDP handler 105 */ 106 register at_ddp_t *ddp; 107 register at_atp_t *atp; 108 register gbuf_t *tmp; 109 u_char *resp; 110 sip_userbytes_t ubytes; 111 112 ddp = (at_ddp_t *)gbuf_rptr(mp); 113 114 /* Make sure the packet we got is an ATP packet */ 115 if (ddp->type != DDP_ATP) { 116 gbuf_freem(mp); 117 return; 118 } 119 120 /* assuming that the whole packet is in one contiguous buffer */ 121 atp = (at_atp_t *)ddp->data; 122 123 switch(UAL_VALUE_NTOH(atp->user_bytes)) { 124 case SIP_SYSINFO_CMD : 125 /* Sending a response with "AppleTalk driver version" (u_short) 126 * followed by 14 zeros will pacify the interpoll. 127 * What? You don't understand what it means to send 14 zeroes? 128 * Tsk, tsk, look up SIP protocol specs for details!! 129 */ 130 if ((tmp = (gbuf_t *)ddp_growmsg(mp, 16)) == NULL) { 131 /* dont have buffers */ 132 gbuf_freem(mp); 133 return; 134 } 135 if (tmp == mp) 136 /* extra space allocated on the same buffer block */ 137 resp = atp->data; 138 else 139 resp = (u_char *)gbuf_rptr(tmp); 140 bzero(resp, 16); 141 *(u_short *)resp = htons(SIP_DRIVER_VERSION); 142 143 ubytes.response = SIP_GOOD_RESPONSE; 144 ubytes.unused = 0; 145 ubytes.responder_version = htons(SIP_RESPONDER_VERSION); 146 break; 147 case SIP_DATALINK_CMD : 148 /* In this case, the magic spell is to send 2 zeroes after 149 * the "AppleTalk driver version". 150 */ 151 if ((tmp = (gbuf_t *)ddp_growmsg(mp, 4)) == NULL) { 152 /* dont have buffers */ 153 gbuf_freem(mp); 154 return; 155 } 156 if (tmp == mp) 157 /* extra space allocated on the same buffer block */ 158 resp = atp->data; 159 else 160 resp = (u_char *)gbuf_rptr(tmp); 161 bzero(resp, 16); 162 *(u_short *)resp = htons(SIP_DRIVER_VERSION); 163 164 ubytes.response = SIP_GOOD_RESPONSE; 165 ubytes.unused = 0; 166 ubytes.responder_version = htons(SIP_RESPONDER_VERSION); 167 break; 168 default : 169 /* bad request, send a bad command response back */ 170 ubytes.response = SIP_BAD_RESPONSE; 171 ubytes.unused = 0; 172 ubytes.responder_version = htons(SIP_RESPONDER_VERSION); 173 } 174 175 NET_NET(ddp->dst_net, ddp->src_net); 176 ddp->dst_node = ddp->src_node; 177 ddp->dst_socket = ddp->src_socket; 178 UAL_ASSIGN_HTON(atp->user_bytes, &ubytes); 179 atp->cmd = ATP_CMD_TRESP; 180 atp->eom = 1; 181 atp->sts = 0; 182 atp->bitmap = 0; 183 184 (void)ddp_output(&mp, DDP_SOCKET_1st_DYNAMIC, FALSE); 185 return; 186} /* sip_input */ 187