/*
- * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
+ * Copyright (c) 1988-2007 Apple Inc. All rights reserved.
*
- * @APPLE_LICENSE_HEADER_START@
- *
- * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_START@
*
* This file contains Original Code and/or Modifications of Original Code
* as defined in and that are subject to the Apple Public Source License
* Version 2.0 (the 'License'). You may not use this file except in
- * compliance with the License. Please obtain a copy of the License at
- * http://www.opensource.apple.com/apsl/ and read it before using this
- * file.
+ * compliance with the License. The rights granted to you under the License
+ * may not be used to create, or enable the creation or redistribution of,
+ * unlawful or unlicensed copies of an Apple operating system, or to
+ * circumvent, violate, or enable the circumvention or violation of, any
+ * terms of an Apple operating system software license agreement.
+ *
+ * Please obtain a copy of the License at
+ * http://www.opensource.apple.com/apsl/ and read it before using this file.
*
* The Original Code and all software distributed under the License are
* distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
* Please see the License for the specific language governing rights and
* limitations under the License.
*
- * @APPLE_LICENSE_HEADER_END@
- */
-/*
- * Copyright (c) 1988-1998 Apple Computer, Inc.
+ * @APPLE_OSREFERENCE_LICENSE_HEADER_END@
*/
/*
* 0.01 05/12/94 Laurent Dumont Creation
#include <netat/sysglue.h>
#include <netat/appletalk.h>
+#include <netat/at_pcb.h>
#include <netat/at_var.h>
#include <netat/ddp.h>
#include <netat/nbp.h>
#include <netat/zip.h>
-#include <netat/at_pcb.h>
#include <netat/atp.h>
#include <netat/routing_tables.h>
+#include <netat/rtmp.h>
#include <netat/debug.h>
#include <sys/kern_event.h>
-static void zip_reply_to_getmyzone();
-extern int at_reg_mcast(), at_unreg_mcast();
-
/* globals */
extern at_ifaddr_t *ifID_table[], *ifID_home;
extern short ErrorZIPoverflow;
static int netinfo_reply_pending;
static void zip_netinfo_reply(at_x_zip_t *, at_ifaddr_t *);
static void zip_getnetinfo(at_ifaddr_t *);
-static void zip_getnetinfo_funnel(at_ifaddr_t *);
-static void send_phony_reply(gbuf_t *);
+static void zip_getnetinfo_locked(void *);
+static void send_phony_reply(void *);
+
+int zip_reply_received(gbuf_t *, at_ifaddr_t *, int);
+int zip_reply_to_getlocalzones(at_ifaddr_t *, gbuf_t *);
+int zip_reply_to_getzonelist(at_ifaddr_t *, gbuf_t *);
+static void zip_reply_to_getmyzone(at_ifaddr_t *, gbuf_t *);
+gbuf_t *zip_prep_query_packet(at_ifaddr_t *, at_net_al, at_node);
+
+static void zip_send_reply_to_query(gbuf_t *, at_ifaddr_t *);
+static void zip_send_ext_reply_to_query(gbuf_t *, at_ifaddr_t *, RT_entry *, u_short);
+static gbuf_t *prep_ZIP_reply_packet(gbuf_t *, at_ifaddr_t *);
+static void zip_send_getnetinfo_reply(gbuf_t *, at_ifaddr_t *);
/*
* zip_send_getnetinfo_reply: we received a GetNetInfo packet, we need to reply
at_ddp_t *ddp, *ddp_sent;
short ZoneNameProvided = FALSE;
short RequestIsBroadcasted = FALSE;
- u_short znumber, len, packet_length, size, status;
+ u_short znumber, len, packet_length = 0, size, status;
RT_entry *Entry;
char GNIReply[128];
bcopy(&zname->str, &GNIReply[7], zname->len);
- if (znumber = zt_find_zname(zname)) {
+ if ((znumber = zt_find_zname(zname))) {
if (ZT_ISIN_ZMAP((znumber), Entry->ZoneBitMap)) {
GNIReply[1] = 0; /* Zone Valid */
- if (len = zt_get_zmcast(ifID, zname, &GNIReply[8+zname->len]))
+ if ((len = zt_get_zmcast(ifID, zname, &GNIReply[8+zname->len])))
GNIReply[7+zname->len] = len;
else {
GNIReply[1] |= ZIP_USE_BROADCAST;
Index--;
- if (len = zt_get_zmcast(ifID, &ZT_table[Index].Zone, &GNIReply[8+zname->len]))
+ if ((len = zt_get_zmcast(ifID, &ZT_table[Index].Zone, &GNIReply[8+zname->len])))
GNIReply[7+zname->len] = len;
else {
GNIReply[1] |= ZIP_USE_BROADCAST;
zone_count -= *ZonesInPacket;
- DDPLEN_ASSIGN(ddp, reply_length + DDP_X_HDR_SIZE);
+ DDPLEN_ASSIGN(ddp, (reply_length + DDP_X_HDR_SIZE));
gbuf_winc(m,reply_length);
if ((status =
ddp_router_output(m, ifID, AT_ADDR,
*/
if (zone_count) {
- DDPLEN_ASSIGN(ddp, reply_length + DDP_X_HDR_SIZE);
+ DDPLEN_ASSIGN(ddp, (reply_length + DDP_X_HDR_SIZE));
gbuf_winc(m,reply_length);
if ((status =
ddp_router_output(m, ifID, AT_ADDR,
register at_ifaddr_t *ifID;
{
register gbuf_t *m;
- register at_ddp_t *ddp, *ddp_received;
+ register at_ddp_t *ddp = NULL, *ddp_received;
RT_entry *Entry;
short i, reply_length, Index, status;
u_char network_count;
/* access the number of nets requested in the Query */
network_count = *((char *)(ddp_received->data) + 1);
- NetAsked = (u_short *)(ddp_received->data+ 2);
+ NetAsked = (u_short *)(ddp_received->data + 2);
/* check the validity of the Query packet */
reply_length = 2; /* 1st byte is ZIP reply code, 2nd is network count */
for (i = 0 ; i < network_count ; i ++, NetAsked++) {
- Entry = rt_blookup(*NetAsked);
+ Entry = rt_blookup(ntohs(*NetAsked));
if (Entry != NULL && ((Entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) &&
RT_ALL_ZONES_KNOWN(Entry)) { /* this net is well known... */
/* we need to send the packet before, this won't fit... */
- DDPLEN_ASSIGN(ddp, reply_length + DDP_X_HDR_SIZE);
+ DDPLEN_ASSIGN(ddp, (reply_length + DDP_X_HDR_SIZE));
gbuf_winc(m,reply_length);
if ((status =
* and build a separate packet for each extended network requested
*/
- zip_send_ext_reply_to_query(mreceived, ifID, Entry, *NetAsked);
+ zip_send_ext_reply_to_query(mreceived, ifID, Entry, ntohs(*NetAsked));
}
}
*/
if ( reply_length > 2) {
- DDPLEN_ASSIGN(ddp, reply_length + DDP_X_HDR_SIZE);
+ DDPLEN_ASSIGN(ddp, (reply_length + DDP_X_HDR_SIZE));
gbuf_winc(m,reply_length);
if ((status =
ddp_router_output(m, ifID, AT_ADDR,
register at_ddp_t *ddp;
register at_atp_t *atp;
register at_zip_t *zip;
- register u_long user_bytes;
+ u_char user_bytes[4];
register u_short user_byte;
/* variables for ZipNotify processing */
register char new_zone_len;
register char *old_zone;
char *new_zone;
- void zip_sched_getnetinfo(); /* forward reference */
if (gbuf_type(m) != MSG_DATA) {
/* If this is a M_ERROR message, DDP is shutting down,
((NET_VALUE(ddp->src_net) != ifID->ifThisNode.s_net) ||
(ddp->src_node != ifID->ifThisNode.s_node)) && netinfo_reply_pending)
{
- extern void trackrouter();
dPrintf(D_M_ZIP, D_L_INPUT,
("zip_input: Received a GetNetInfo Reply from %d.%d\n",
NET_VALUE(ddp->src_net), ddp->src_node));
*/
ifID->ifNumRetries = ZIP_NETINFO_RETRIES;
netinfo_reply_pending = 1;
+ ifID->ifGNIScheduled = 1;
timeout(zip_sched_getnetinfo, (caddr_t) ifID,
2*ZIP_TIMER_INT);
/* Get the user bytes in network order */
- user_bytes = UAL_VALUE(atp->user_bytes);
- user_byte = user_bytes >> 24; /* Get the zeroth byte */
+ *((u_long*)user_bytes) = UAL_VALUE(atp->user_bytes);
+ user_byte = user_bytes[0]; /* Get the zeroth byte */
dPrintf(D_M_ZIP, D_L_INPUT,
("zip_input: received a ZIP_ATP command=%d\n", user_byte));
register at_nvestr_t *zone1, *zone2;
{
register char c1, c2;
- char upshift8();
register int i;
if (zone1->len != zone2->len)
register at_ifaddr_t *ifID;
{
u_char mcast_len;
- void zip_sched_getnetinfo(); /* forward reference */
register at_net_al this_net;
char *default_zone;
register u_char zone_name_len;
ifID->ifThisCableStart, ifID->ifThisCableEnd));
/* The packet is in response to our request */
+ ifID->ifGNIScheduled = 0;
untimeout (zip_sched_getnetinfo, (caddr_t) ifID);
netinfo_reply_pending = 0;
zone_name_len = netinfo->data[0];
switch (control) {
case ZIP_ONLINE :
case ZIP_LATE_ROUTER :
- ifID->ifNumRetries = 0;
- /* Get the desired zone name from elap and put it in
- * ifID for zip_getnetinfo() to use.
- */
- if (ifID->startup_zone.len)
- ifID->ifZoneName = ifID->startup_zone;
- zip_getnetinfo(ifID);
+ if (!ifID->ifGNIScheduled) {
+ ifID->ifNumRetries = 0;
+ /* Get the desired zone name from elap and put it in
+ * ifID for zip_getnetinfo() to use.
+ */
+ if (ifID->startup_zone.len)
+ ifID->ifZoneName = ifID->startup_zone;
+ zip_getnetinfo(ifID);
+ }
break;
case ZIP_NO_ROUTER :
ifID->ifZoneName.len = 1;
return (0);
}
-/* funnel version of zip_getnetinfo */
-static void zip_getnetinfo_funnel(ifID)
- register at_ifaddr_t *ifID;
+/* locked version of zip_getnetinfo */
+static void
+zip_getnetinfo_locked(void *arg)
{
- thread_funnel_set(network_flock, TRUE);
- zip_getnetinfo(ifID);
- thread_funnel_set(network_flock, FALSE);
+ at_ifaddr_t *ifID;
+
+ atalk_lock();
+ if (arg != NULL) { // make sure it hasn't been closed
+ ifID = (at_ifaddr_t *)arg;
+ ifID->ifGNIScheduled = 0;
+ zip_getnetinfo(ifID);
+ }
+ atalk_unlock();
}
register at_x_zip_t *zip;
gbuf_t *m;
register at_ddp_t *ddp;
- void zip_sched_getnetinfo();
register struct atalk_addr *at_dest;
register int size;
+
size = DDP_X_HDR_SIZE + ZIP_X_HDR_SIZE + ifID->ifZoneName.len + 1
+ sizeof(struct atalk_addr) + 1;
*/
dPrintf(D_M_ZIP, D_L_WARNING, ("zip_getnetinfo: no buffer, call later port=%d\n",
ifID->ifPort));
- timeout (zip_getnetinfo_funnel, (caddr_t) ifID, ZIP_TIMER_INT/10);
+ ifID->ifGNIScheduled = 1;
+ timeout (zip_getnetinfo_locked, (caddr_t) ifID, ZIP_TIMER_INT/10);
return;
}
/* let the lap fields be uninitialized, 'cause it doesn't
* matter.
*/
- DDPLEN_ASSIGN(ddp, size - (sizeof(struct atalk_addr) + 1));
+ DDPLEN_ASSIGN(ddp, (size - (sizeof(struct atalk_addr) + 1)));
UAS_ASSIGN(ddp->checksum, 0);
ddp->hopcount = ddp->unused = 0;
NET_ASSIGN(ddp->dst_net, 0); /* cable-wide broadcast */
ifID->ifNumRetries++;
netinfo_reply_pending = 1;
-
+ ifID->ifGNIScheduled = 1;
timeout (zip_sched_getnetinfo, (caddr_t) ifID, ZIP_TIMER_INT);
} /* zip_getnetinfo */
*
**********************************************************************/
-void zip_sched_getnetinfo (ifID)
- register at_ifaddr_t *ifID;
+void zip_sched_getnetinfo(void *arg)
{
- boolean_t funnel_state;
+ register at_ifaddr_t *ifID = (at_ifaddr_t *)arg;
- funnel_state = thread_funnel_set(network_flock, TRUE);
+ atalk_lock();
+
+ ifID->ifGNIScheduled = 0;
if (ifID->ifNumRetries >= ZIP_NETINFO_RETRIES) {
/* enough packets sent.... give up! */
} else
zip_getnetinfo(ifID);
- (void) thread_funnel_set(network_flock, FALSE);
+ atalk_unlock();
}
register at_atp_t *atp;
register at_ddp_t *ddp;
register at_zip_t *zip;
- register u_long user_bytes;
+ u_char user_bytes[4];
register int user_byte;
ddp = (at_ddp_t *)gbuf_rptr(m);
else
atp = (at_atp_t *)(gbuf_rptr(gbuf_cont(m)));
/* Get the user bytes in network order */
- user_bytes = UAL_VALUE(atp->user_bytes);
- user_byte = user_bytes >> 24; /* Get the zeroth byte */
+ *((u_long*)user_bytes) = UAL_VALUE(atp->user_bytes);
+ user_byte = user_bytes[0]; /* Get the zeroth byte */
if ((user_byte == ZIP_GETMYZONE) ||
(user_byte == ZIP_GETZONELIST) ||
(user_byte == ZIP_GETLOCALZONES))
r_atp->bitmap = 0;
UAS_UAS(r_atp->tid, atp->tid);
ulongtmp = 1;
- ulongtmp = htonl(ulongtmp);
- UAL_ASSIGN(r_atp->user_bytes, ulongtmp); /* no of zones */
+ UAL_ASSIGN_HTON(r_atp->user_bytes, ulongtmp); /* no of zones */
/* fill up atp data part */
bcopy((caddr_t) &ifID->ifZoneName, (caddr_t) r_atp->data, ifID->ifZoneName.len+1);
}
static void
-send_phony_reply(rm)
- gbuf_t *rm;
+send_phony_reply(arg)
+ void *arg;
{
- boolean_t funnel_state;
+ gbuf_t *rm = (gbuf_t *)arg;
- funnel_state = thread_funnel_set(network_flock, TRUE);
-
+ atalk_lock();
ddp_input(rm, ifID_home);
+ atalk_unlock();
- (void) thread_funnel_set(network_flock, FALSE);
return;
}
zip_sent = TRUE;
gbuf_winc(m,DDP_X_HDR_SIZE + Query_index);
- DDPLEN_ASSIGN(ddp, DDP_X_HDR_SIZE + Query_index);
+ DDPLEN_ASSIGN(ddp, (DDP_X_HDR_SIZE + Query_index));
if ((status =
ddp_router_output(m, ifID, AT_ADDR,
if (*ZoneCount) { /* non-full Query needs to be sent */
zip_sent = TRUE;
gbuf_winc(m,DDP_X_HDR_SIZE + Query_index);
- DDPLEN_ASSIGN(ddp, DDP_X_HDR_SIZE + Query_index);
+ DDPLEN_ASSIGN(ddp, (DDP_X_HDR_SIZE + Query_index));
if ((status =
ddp_router_output(m, ifID, AT_ADDR,
* we receive two types of replies: non extended and extended.
* For extended replies, the network count is the Total of zones for that net.
*/
-
+int
zip_reply_received(m, ifID, reply_type)
register gbuf_t *m;
register at_ifaddr_t *ifID;
/* access the number of nets provided in the ZIP Reply */
- network_count = *(u_char *)(gbuf_rptr(m) + DDP_X_HDR_SIZE + 1);
+ network_count = ntohs(*(u_char *)(gbuf_rptr(m) + DDP_X_HDR_SIZE + 1));
PacketPtr = (char *)(gbuf_rptr(m) + DDP_X_HDR_SIZE + 2);
while (payload_len > 0 && network_count >0) {
- Network = *(at_net_al *)PacketPtr;
+ Network = ntohs(*(at_net_al *)PacketPtr);
PacketPtr += 2;
zname = (at_nvestr_t *)PacketPtr;
if (payload_len)
}
if ((reply_type == ZIP_REPLY) && network_count > 0) {
+#if DEBUG
if (Entry)
dPrintf(D_M_ZIP, D_L_WARNING,
("zip_reply_received: Problem decoding zone (after net:%d-%d)\n",
Entry->NetStart, Entry->NetStop));
+#endif
ifID->ifZipNeedQueries = 1;
}
else {
ifID->ifZipNeedQueries = 0;
+#if DEBUG
if (Entry)
dPrintf(D_M_ZIP_LOW, D_L_INFO,
("zip_reply_received: entry %d-%d all zones known\n",
Entry->NetStart, Entry->NetStop));
+#endif
}
+
+ return 0;
}
/*
r_atp->bitmap = 0;
UAS_UAS(r_atp->tid, atp->tid);
ulongtmp = 1;
- ulongtmp = htonl(ulongtmp);
- UAL_ASSIGN(r_atp->user_bytes, ulongtmp); /* no of zones */
+ UAL_ASSIGN_HTON(r_atp->user_bytes, ulongtmp); /* no of zones */
data_ptr = (char *)r_atp->data;
* zip_reply_to_getzonelist: replies to ZIP GetZoneList requested from the Net
*/
+int
zip_reply_to_getzonelist (ifID, m)
register at_ifaddr_t *ifID;
register gbuf_t *m;
/* get the start index from the ATP request */
- StartPoint = (UAL_VALUE(atp->user_bytes) & 0xffff) -1;
+ StartPoint = (UAL_VALUE_NTOH(atp->user_bytes) & 0xffff) -1;
/* find the next zone to send */
ulongtmp += 0x01000000;
- UAL_ASSIGN(r_atp->user_bytes, ulongtmp); /* # of zones and flag*/
+ UAL_ASSIGN_HTON(r_atp->user_bytes, ulongtmp); /* # of zones and flag*/
size = DDP_X_HDR_SIZE + ATP_HDR_SIZE + PacketLen;
gbuf_winc(rm,size);
NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, ifID->ifPort, PacketLen));
- if (status= ddp_router_output(rm, ifID, AT_ADDR,
- NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, 0)) {
+ if ((status= ddp_router_output(rm, ifID, AT_ADDR,
+ NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, 0))) {
dPrintf(D_M_ZIP, D_L_ERROR, ("zip_reply_to_GZL: ddp_router_output returns=%d\n",
status));
return (status);
short Index, Index_wanted, ZLength;
short i,j, packet_len;
short zCount, ZoneCount, ZonesInPacket;
- char *zmap, last_flag = 0;
+ unsigned char *zmap, last_flag = 0;
RT_entry *Entry;
char *Reply;
/* get the start index from the ATP request */
- Index_wanted = (UAL_VALUE(atp->user_bytes) & 0xffff) -1;
+ Index_wanted = (UAL_VALUE_NTOH(atp->user_bytes) & 0xffff) -1;
dPrintf(D_M_ZIP_LOW, D_L_INFO,
("zip_r_GLZ: for station %d:%d Index_wanted = %d\n",
r_atp->bitmap = 0;
UAS_UAS(r_atp->tid, atp->tid);
ulongtmp = ((last_flag << 24) & 0xFF000000) + ZonesInPacket; /* # of zones and flag*/
- UAL_ASSIGN(r_atp->user_bytes, ulongtmp);
+ UAL_ASSIGN_HTON(r_atp->user_bytes, ulongtmp);
size = DDP_X_HDR_SIZE + ATP_HDR_SIZE + packet_len;
gbuf_winc(rm,size);
DDPLEN_ASSIGN(r_ddp, size);
("zip_r_GLZ: send packet to %d:%d port %d atp_len =%d\n",
NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, ifID->ifPort, packet_len));
- if (status= ddp_router_output(rm, ifID, AT_ADDR,
- NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, 0)) {
+ if ((status= ddp_router_output(rm, ifID, AT_ADDR,
+ NET_VALUE(r_ddp->dst_net), r_ddp->dst_node, 0))) {
dPrintf(D_M_ZIP, D_L_ERROR,
("zip_reply_to_GLZ: ddp_router_output returns =%d\n",
status));
int regDefaultZone(ifID)
at_ifaddr_t *ifID;
{
- int i;
char data[ETHERNET_ADDR_LEN];
if (!ifID)
zt_get_zmcast(ifID, &ifID->ifZoneName, data);
if (FDDI_OR_TOKENRING(ifID->aa_ifp->if_type))
- ddp_bit_reverse(data);
+ ddp_bit_reverse((unsigned char *)data);
bcopy((caddr_t)data, (caddr_t)&ifID->ZoneMcastAddr, ETHERNET_ADDR_LEN);
(void)at_reg_mcast(ifID, (caddr_t)&ifID->ZoneMcastAddr);
return(0);