|
|
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: * Copyright (c) 1996 Apple Computer, Inc.
27: *
28: * The information contained herein is subject to change without
29: * notice and should not be construed as a commitment by Apple
30: * Computer, Inc. Apple Computer, Inc. assumes no responsibility
31: * for any errors that may appear.
32: *
33: * Confidential and Proprietary to Apple Computer, Inc.
34: *
35: * File: zi.c
36: */
37: #include <sysglue.h>
38: #include <at/appletalk.h>
39: #include <lap.h>
40: #include <routing_tables.h>
41: #define _AURP
42: #include <at_aurp.h>
43: #include <at/aurp.h>
44:
45: /* */
46: void AURPsndZReq(state)
47: aurp_state_t *state;
48: {
49: gbuf_t *m;
50: int msize;
51: aurp_hdr_t *hdrp;
52: short *net, nets_cnt, net_sent=0, entry_num=0;
53: RT_entry *entry = RT_table;
54:
55: if (!state->get_zi || (state->rcv_state == AURPSTATE_Unconnected))
56: return;
57:
58: l_more:
59: msize = sizeof(aurp_hdr_t);
60: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
61: dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndZReq: node=%d, out of mblk\n",
62: state->rem_node));
63: return;
64: }
65: gbuf_wset(m,msize);
66:
67: /* construct the ZI request packet */
68: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
69: hdrp->connection_id = state->rcv_connection_id;
70: hdrp->sequence_number = 0;
71: hdrp->command_code = AURPCMD_ZReq;
72: hdrp->flags = 0;
73: *(short *)(hdrp+1) = AURPSUBCODE_ZoneInfo1;
74: gbuf_winc(m,sizeof(short));
75:
76: net = (short *)gbuf_wptr(m);
77: nets_cnt = 0;
78:
79: while (entry_num < RT_maxentry) {
80: /*
81: * scan the router table, and build the ZI request packet
82: * with the right entries, i.e.,
83: * - entry in use and not of the net_port
84: * - with no zones and in an active state
85: * - talking to the right router
86: */
87: if ( (entry->NetPort == net_port) && entry->NetStop &&
88: ((entry->EntryState & 0x0F) >= RTE_STATE_SUSPECT) &&
89: (!RT_ALL_ZONES_KNOWN(entry)) ) {
90: *net++ = (entry->NetStart) ? entry->NetStart : entry->NetStop;
91: nets_cnt++;
92: }
93:
94: if (nets_cnt >= 640) {
95: /* query only 640 networks per packet */
96: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZReq: node=%d\n",
97: state->rem_node));
98: gbuf_winc(m,(nets_cnt * sizeof(short)));
99: AURPsend(m, AUD_AURP, state->rem_node);
100: net_sent = 1;
101: goto l_more;
102: }
103:
104: entry_num++;
105: entry++;
106: }
107:
108: if (nets_cnt) {
109: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZReq: node=%d\n",
110: state->rem_node));
111: gbuf_winc(m,(nets_cnt * sizeof(short)));
112: AURPsend(m, AUD_AURP, state->rem_node);
113: net_sent = 1;
114: } else
115: gbuf_freeb(m);
116:
117: if (!net_sent)
118: state->get_zi = 0;
119: }
120:
121: /* */
122: void AURPsndZRsp(state, dat_m, flag)
123: aurp_state_t *state;
124: gbuf_t *dat_m;
125: int flag;
126: {
127: short len;
128: int msize, next_entry = 0;
129: gbuf_t *m;
130: aurp_hdr_t *hdrp;
131:
132: if ((state->snd_state == AURPSTATE_Unconnected) || (dat_m == 0))
133: return;
134: msize = sizeof(aurp_hdr_t);
135:
136: do {
137: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
138: dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndZRsp: node=%d, out of mblk\n",
139: state->rem_node));
140: return;
141: }
142: gbuf_wset(m,msize);
143:
144: /* construct the ZI response packet */
145: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
146: hdrp->connection_id = state->snd_connection_id;
147: hdrp->sequence_number = 0;
148: hdrp->command_code = AURPCMD_ZRsp;
149: hdrp->flags = 0;
150:
151: /* get zone info of the local networks */
152: next_entry = AURPgetzi(next_entry, gbuf_wptr(m), &len, dat_m, flag);
153: gbuf_winc(m,len);
154:
155: /* send the packet */
156: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndZRsp: len=%d\n", len));
157: AURPsend(m, AUD_AURP, state->rem_node);
158:
159: } while (next_entry);
160:
161: gbuf_freem(dat_m);
162: }
163:
164: /* */
165: void AURPsndGZN(state, dat_m)
166: aurp_state_t *state;
167: gbuf_t *dat_m;
168: {
169: short zname_len;
170: int msize;
171: gbuf_t *m;
172: aurp_hdr_t *hdrp;
173:
174: if (state->snd_state == AURPSTATE_Unconnected)
175: return;
176:
177: msize = sizeof(aurp_hdr_t);
178: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
179: dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndGZN: node=%d, out of mblk\n",
180: state->rem_node));
181: return;
182: }
183: gbuf_wset(m,msize);
184:
185: /* construct the GZN response packet */
186: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
187: hdrp->connection_id = state->snd_connection_id;
188: hdrp->sequence_number = 0;
189: hdrp->command_code = AURPCMD_ZRsp;
190: hdrp->flags = 0;
191: *(short *)(gbuf_wptr(m)) = AURPSUBCODE_GetZoneNets;
192: gbuf_winc(m,sizeof(short));
193: zname_len = gbuf_len(dat_m);
194: bcopy(gbuf_rptr(dat_m), gbuf_wptr(m), zname_len);
195: gbuf_winc(m,zname_len);
196: *(short *)(gbuf_wptr(m)) = -1; /* number of tuples - proto not supported */
197: gbuf_winc(m,sizeof(short));
198:
199: /* send the packet */
200: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndGZN: count=%d\n", -1));
201: AURPsend(m, AUD_AURP, state->rem_node);
202: }
203:
204: /* */
205: void AURPsndGDZL(state, dat_m)
206: aurp_state_t *state;
207: gbuf_t *dat_m;
208: {
209: int msize;
210: gbuf_t *m;
211: aurp_hdr_t *hdrp;
212:
213: if (state->snd_state == AURPSTATE_Unconnected)
214: return;
215:
216: msize = sizeof(aurp_hdr_t);
217: if ((m = (gbuf_t *)gbuf_alloc(msize+AURP_MaxPktSize, PRI_MED)) == 0) {
218: dPrintf(D_M_AURP, D_L_WARNING, ("AURPsndGDZL: node=%d, out of mblk\n",
219: state->rem_node));
220: return;
221: }
222: gbuf_wset(m,msize);
223:
224: /* construct the GDZL response packet */
225: hdrp = (aurp_hdr_t *)gbuf_rptr(m);
226: hdrp->connection_id = state->snd_connection_id;
227: hdrp->sequence_number = 0;
228: hdrp->command_code = AURPCMD_ZRsp;
229: hdrp->flags = 0;
230: *(short *)(gbuf_wptr(m)) = AURPSUBCODE_GetDomainZoneList;
231: gbuf_winc(m,sizeof(short));
232: *(short *)(gbuf_wptr(m)) = -1; /* start index - proto not supported */
233: gbuf_winc(m,sizeof(short));
234:
235: /* send the packet */
236: dPrintf(D_M_AURP, D_L_INFO, ("AURPsndGDZL: index=%d\n", -1));
237: AURPsend(m, AUD_AURP, state->rem_node);
238: }
239:
240: /* */
241: void AURPrcvZReq(state, m)
242: aurp_state_t *state;
243: gbuf_t *m;
244: {
245: short sub_code;
246: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
247:
248: /* make sure we're in a valid state to accept it */
249: if (state->snd_state == AURPSTATE_Unconnected) {
250: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvZReq: unexpected response\n"));
251: gbuf_freem(m);
252: return;
253: }
254:
255: /* check for the correct connection id */
256: if (hdrp->connection_id != state->snd_connection_id) {
257: dPrintf(D_M_AURP, D_L_WARNING,
258: ("AURPrcvZReq: invalid connection id, r=%d, m=%d\n",
259: hdrp->connection_id, state->snd_connection_id));
260: gbuf_freem(m);
261: return;
262: }
263:
264: gbuf_rinc(m,sizeof(*hdrp));
265: sub_code = *(short *)gbuf_rptr(m);
266: gbuf_rinc(m,sizeof(short));
267:
268: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvZReq: len=%d\n", gbuf_len(m)));
269:
270: switch (sub_code) {
271: case AURPSUBCODE_ZoneInfo1:
272: AURPsndZRsp(state, m, 0);
273: return;
274:
275: case AURPSUBCODE_GetZoneNets:
276: AURPsndGZN(state, m);
277: break;
278:
279: case AURPSUBCODE_GetDomainZoneList:
280: AURPsndGDZL(state, m);
281: break;
282: }
283:
284: gbuf_freem(m);
285: }
286:
287: /* */
288: void AURPrcvZRsp(state, m)
289: aurp_state_t *state;
290: gbuf_t *m;
291: {
292: short sub_code, tuples_cnt;
293: aurp_hdr_t *hdrp = (aurp_hdr_t *)gbuf_rptr(m);
294:
295: /* make sure we're in a valid state to accept it */
296: if (state->rcv_state == AURPSTATE_Unconnected) {
297: dPrintf(D_M_AURP, D_L_WARNING, ("AURPrcvZRsp: unexpected response\n"));
298: gbuf_freem(m);
299: return;
300: }
301:
302: /* check for the correct connection id */
303: if (hdrp->connection_id != state->rcv_connection_id) {
304: dPrintf(D_M_AURP, D_L_WARNING,
305: ("AURPrcvZRsp: invalid connection id, r=%d, m=%d\n",
306: hdrp->connection_id, state->rcv_connection_id));
307: gbuf_freem(m);
308: return;
309: }
310:
311: gbuf_rinc(m,sizeof(*hdrp));
312: sub_code = *(short *)gbuf_rptr(m);
313: gbuf_rinc(m,sizeof(short));
314:
315: dPrintf(D_M_AURP, D_L_INFO, ("AURPrcvZRsp: len=%d\n", gbuf_len(m)));
316:
317: switch (sub_code) {
318: case AURPSUBCODE_ZoneInfo1:
319: case AURPSUBCODE_ZoneInfo2:
320: tuples_cnt = *(short *)gbuf_rptr(m);
321: gbuf_rinc(m,sizeof(short));
322: if (AURPsetzi(state->rem_node, m, sub_code, tuples_cnt)) {
323: dPrintf(D_M_AURP, D_L_ERROR,
324: ("AURPrcvZRsp: AURPsetzi() error\n"));
325: }
326: break;
327:
328: case AURPSUBCODE_GetZoneNets:
329: break;
330:
331: case AURPSUBCODE_GetDomainZoneList:
332: break;
333: }
334:
335: gbuf_freem(m);
336: }
337:
338: /* */
339: int AURPgetzi(next_entry, buf, len, dat_m, flag)
340: int next_entry;
341: unsigned char *buf;
342: short *len;
343: gbuf_t *dat_m;
344: int flag;
345: {
346: static int i_sav=ZT_BYTES-1, j_sav=0, idx_sav=-1;
347: unsigned char ev, zname_len, *zmap, *zname_base, *zname_sav, *tuples_ptr;
348: unsigned short net_num, *net, zname_offset;
349: short *sub_codep, *tuples_cntp, tuples_cnt, dat_len;
350: int i, j, idx, nets_cnt;
351: RT_entry *entry;
352:
353: sub_codep = (short *)buf;
354: buf += sizeof(short);
355: tuples_cntp = (short *)buf;
356: buf += sizeof(short);
357: *len = sizeof(short) + sizeof(short);
358: zname_base = buf + sizeof(short);
359: dat_len = 0;
360:
361: /* set the subcode in the ZI response packet */
362: *sub_codep = next_entry ? AURPSUBCODE_ZoneInfo2 : AURPSUBCODE_ZoneInfo1;
363:
364: switch (flag) {
365: case 0: /* zone info in response to ZI request */
366: net = (unsigned short *)gbuf_rptr(dat_m);
367: nets_cnt = (gbuf_len(dat_m))/2;
368: break;
369: case 1: /* zone info in response to Ack of RI response */
370: tuples_ptr = gbuf_rptr(dat_m);
371: nets_cnt = (gbuf_len(dat_m))/3;
372: next_entry = 0;
373: break;
374: case 2: /* zone info in response to Ack of RI update */
375: tuples_ptr = gbuf_rptr(dat_m);
376: nets_cnt = (gbuf_len(dat_m))/4;
377: next_entry = 0;
378: break;
379: }
380:
381: /*
382: * for each network, find all the zones that it belongs to
383: */
384: for (tuples_cnt=0; next_entry < nets_cnt; next_entry++) {
385: switch(flag) {
386: case 0:
387: net_num = net[next_entry];
388: break;
389: case 1:
390: net_num = *(unsigned short *)tuples_ptr;
391: tuples_ptr += 3;
392: gbuf_rinc(dat_m,3);
393: if (tuples_ptr[-1] & 0x80) {
394: tuples_ptr += 3;
395: gbuf_rinc(dat_m,3);
396: next_entry++;
397: }
398: break;
399: case 2:
400: if (gbuf_len(dat_m) <= 0) {
401: next_entry = nets_cnt;
402: goto l_done;
403: }
404: ev = *tuples_ptr++;
405: net_num = *(unsigned short *)tuples_ptr;
406: tuples_ptr += 3;
407: gbuf_rinc(dat_m,4);
408: if (tuples_ptr[-1] & 0x80) {
409: tuples_ptr += 2;
410: gbuf_rinc(dat_m,2);
411: }
412: if (ev != AURPEV_NetAdded)
413: continue;
414: break;
415: }
416:
417: /*
418: * find the RT entry associated with the network
419: */
420: if ((entry = RT_lookup(net_num)) == 0) {
421: dPrintf(D_M_AURP, D_L_WARNING, ("AURPgetzi: invalid net, %d\n",
422: net_num));
423: continue;
424: }
425: if ( ((entry->EntryState & 0x0F) < RTE_STATE_SUSPECT) ||
426: !RT_ALL_ZONES_KNOWN(entry) ||
427: (entry->AURPFlag & AURP_NetHiden) ) {
428: dPrintf(D_M_AURP_LOW, D_L_INFO, ("AURPgetzi: zombie net, net=%d\n",
429: net_num));
430: continue;
431: }
432:
433: if (entry->NetStart == 0) {
434: if ((idx = ZT_get_zindex(entry->ZoneBitMap)) == 0)
435: continue;
436: idx--; /* index in the zone table */
437: zname_len = ZT_table[idx].Zone.len;
438: if (zname_len) {
439: *(unsigned short *)buf = net_num;
440: buf += sizeof(short);
441: if (idx == idx_sav) {
442: /* use the optimized format */
443: zname_offset = zname_sav - zname_base;
444: *(unsigned short *)buf = (0x8000 | zname_offset);
445: buf += sizeof(short);
446: dat_len += 4;
447: } else {
448: /* use the long format */
449: zname_sav = buf;
450: *buf++ = zname_len;
451: bcopy(ZT_table[idx].Zone.str, buf, zname_len);
452: buf += zname_len;
453: dat_len += (3 + zname_len);
454: }
455: tuples_cnt++;
456: idx_sav = idx;
457: }
458:
459: } else {
460: zmap = entry->ZoneBitMap;
461: for (i=i_sav; i >=0; i--) {
462: if (!zmap[i])
463: continue;
464:
465: for (j=j_sav; j < 8; j++) {
466: if (!((zmap[i] << j) & 0x80))
467: continue;
468:
469: idx = i*8 + j; /* index in the zone table */
470: zname_len = ZT_table[idx].Zone.len;
471: if (zname_len) {
472: if ((dat_len+3+zname_len) > AURP_MaxPktSize) {
473: i_sav = i;
474: j_sav = j;
475: goto l_done;
476: }
477:
478: *(unsigned short *)buf = net_num;
479: buf += sizeof(short);
480: if (idx == idx_sav) {
481: /* use the optimized format */
482: zname_offset = zname_sav - zname_base;
483: *(unsigned short *)buf = (0x8000 | zname_offset);
484: buf += sizeof(short);
485: dat_len += 4;
486: } else {
487: /* use the long format */
488: zname_sav = buf;
489: *buf++ = zname_len;
490: bcopy(ZT_table[idx].Zone.str, buf, zname_len);
491: buf += zname_len;
492: dat_len += (3 + zname_len);
493: }
494: tuples_cnt++;
495: idx_sav = idx;
496: }
497: }
498: }
499: }
500: if ((dat_len+3+32) > AURP_MaxPktSize) {
501: next_entry++;
502: break;
503: }
504: }
505: i_sav = ZT_BYTES-1;
506: j_sav = 0;
507:
508: l_done:
509: *len += dat_len;
510: if (next_entry == nets_cnt)
511: next_entry = 0;
512:
513: /* set the subcode in the ZI response packet */
514: if (next_entry)
515: *sub_codep = AURPSUBCODE_ZoneInfo2;
516:
517: /* set the tuples count in the ZI response packet */
518: *tuples_cntp = tuples_cnt;
519:
520: idx_sav = -1;
521: return next_entry;
522: }
523:
524: /* */
525: int AURPsetzi(node, m, sub_code, tuples_cnt)
526: unsigned char node;
527: gbuf_t *m;
528: short sub_code;
529: short tuples_cnt;
530: {
531: int rc, tuple_fmt;
532: unsigned short net_num, zname_offset;
533: unsigned char *buf = gbuf_rptr(m), *zname_base;
534: RT_entry *entry;
535: at_nvestr_t *zname;
536:
537: /* compute the base of the zone names of the optimized tuples */
538: zname_base = buf + sizeof(short);
539:
540: /* process all tuples */
541: while (tuples_cnt-- > 0) {
542: net_num = *(unsigned short *)buf;
543: buf += sizeof(short);
544: if (*buf & 0x80) {
545: /* optimized-format tuple */
546: zname_offset = (*(unsigned short *)buf) & 0x7fff;
547: buf += sizeof(short);
548: zname = (at_nvestr_t *)(zname_base + zname_offset);
549: tuple_fmt = 0;
550: dPrintf(D_M_AURP_LOW, D_L_INFO,
551: ("AURPsetzi: optimized fmt, net=%d. zlen=%d, zoffset=%d\n ",
552: net_num, zname->len, zname_offset));
553: } else {
554: /* long-format tuple */
555: zname = (at_nvestr_t *)buf;
556: tuple_fmt = 1;
557: dPrintf(D_M_AURP_LOW, D_L_INFO,
558: ("AURPsetzi: long fmt, net=%d, zlen=%d\n ",
559: net_num, zname->len));
560: }
561:
562: /*
563: * find the RT entry associated with the specified network
564: */
565: if ((entry = RT_lookup(net_num)) == 0) {
566: dPrintf(D_M_AURP, D_L_WARNING,
567: ("AURPsetzi: invalid net, net=%d\n", net_num));
568: } else { /* entry found */
569: if (entry->EntryState >= RTE_STATE_SUSPECT) {
570: if ((rc = ZT_add_zname(zname)) == ZT_MAXEDOUT) {
571: dPrintf(D_M_AURP, D_L_WARNING,
572: ("AURPsetzi: ZT_table full\n"));
573: } else {
574: ZT_set_zmap(rc, entry->ZoneBitMap);
575: RT_SET_ZONE_KNOWN(entry);
576: }
577: }
578: }
579: if (tuple_fmt)
580: buf += zname->len+1;
581: }
582: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.