|
|
1.1 root 1: /*
2: * Mach Operating System
3: * Copyright (c) 1991,1990,1989,1988,1987 Carnegie Mellon University
4: * All Rights Reserved.
5: *
6: * Permission to use, copy, modify and distribute this software and its
7: * documentation is hereby granted, provided that both the copyright
8: * notice and this permission notice appear in all copies of the
9: * software, derivative works or modified versions, and any portions
10: * thereof, and that both notices appear in supporting documentation.
11: *
12: * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS"
13: * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR
14: * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
15: *
16: * Carnegie Mellon requests users of this software to return to
17: *
18: * Software Distribution Coordinator or [email protected]
19: * School of Computer Science
20: * Carnegie Mellon University
21: * Pittsburgh PA 15213-3890
22: *
23: * any improvements or extensions that they make and grant Carnegie Mellon
24: * the rights to redistribute these changes.
25: */
26:
27: /*** NETWORK INTERFACE IMPLEMENTATION CORE ***/
28:
29: #ifndef STUB
30: #include <chips/nc.h>
31: #else
32: #include "nc.h"
33: #endif
34:
35: /*** Types and data structures ***/
36:
37: #if PRODUCTION
38: #define MAX_HASH 701
39: #define MAX_HOST 4000
40: #else
41: #define MAX_HASH 7
42: #define MAX_HOST 4
43: #endif
44:
45: nw_dev_entry_s nc_failure_entry_table = {nc_fail, nc_fail,
46: nc_null, nc_null,
47: nc_null_poll, nc_null_send, nc_null_rpc,
48: nc_null_signal, nc_open_fail, nc_accept_fail,
49: nc_close_fail, nc_open_fail, nc_open_fail};
50:
51: nw_dev_entry_s nc_local_entry_table = {nc_succeed, nc_succeed,
52: nc_null, nc_null,
53: nc_null_poll, nc_local_send, nc_local_rpc,
54: nc_null_signal, nc_open_fail, nc_accept_fail,
55: nc_close_fail, nc_open_fail, nc_open_fail};
56:
57:
58: typedef struct {
59: nw_address_s address;
60: int name_next:16;
61: int ip_next:16;
62: int nw_next:16;
63: nw_ep line:16;
64: } nw_alist_s, *nw_alist_t;
65:
66:
67: boolean_t nc_initialized = FALSE;
68: nw_tx_header_s nw_tx[MAX_EP/2];
69: nw_tx_header_t nw_free_tx_header;
70: nw_rx_header_s nw_rx[2*MAX_EP];
71: nw_rx_header_t nw_free_rx_header;
72: nw_plist_s nw_peer[MAX_EP];
73: nw_plist_t nw_free_peer;
74:
75: nw_devcb devct[MAX_DEV];
76:
77: nw_ecb ect[MAX_EP];
78:
79: int nw_free_ep_first, nw_free_ep_last;
80: int nw_free_line_first, nw_free_line_last;
81:
82: nw_alist_s nw_address[MAX_HOST];
83: int nw_free_address;
84:
85: int nw_name[MAX_HASH];
86: int nw_ip[MAX_HASH];
87: int nw_nw[MAX_HASH];
88:
89: int nw_fast_req;
90:
91: /*** System-independent functions ***/
92:
93: void nc_initialize() {
94: int ep, last_ep;
95:
96: if (!nc_initialized) {
97: last_ep = sizeof(nw_tx)/sizeof(nw_tx_header_s) - 1;
98: for (ep = 0; ep < last_ep; ep++)
99: nw_tx[ep].next = &nw_tx[ep+1];
100: nw_tx[last_ep].next = NULL;
101: nw_free_tx_header = &nw_tx[0];
102: last_ep = sizeof(nw_rx)/sizeof(nw_rx_header_s) - 1;
103: for (ep = 0; ep < last_ep; ep++)
104: nw_rx[ep].next = &nw_rx[ep+1];
105: nw_rx[last_ep].next = NULL;
106: nw_free_rx_header = &nw_rx[0];
107: last_ep = sizeof(nw_peer)/sizeof(nw_plist_s) - 1;
108: for (ep = 0; ep < last_ep; ep++)
109: nw_peer[ep].next = &nw_peer[ep+1];
110: nw_peer[last_ep].next = NULL;
111: nw_free_peer = &nw_peer[0];
112: for (ep = 0; ep < MAX_DEV; ep++) {
113: devct[ep].status = NW_FAILURE;
114: devct[ep].type = NW_CONNECTIONLESS;
115: devct[ep].addr = NULL;
116: devct[ep].local_addr_1 = 0;
117: devct[ep].local_addr_2 = 0;
118: devct[ep].entry = &nc_failure_entry_table;
119: devct[ep].fast_req = 0;
120: }
121: devct[NW_NULL].status = NW_SUCCESS;
122: devct[NW_NULL].entry = &nc_local_entry_table;
123: last_ep = sizeof(ect)/sizeof(nw_ecb);
124: for (ep = 0; ep < last_ep; ep++) {
125: ect[ep].state = NW_INEXISTENT;
126: ect[ep].id = ep;
127: ect[ep].seqno = 0;
128: ect[ep].previous = ep - 1;
129: ect[ep].next = ep + 1;
130: }
131: ect[0].next = ect[0].previous = 0;
132: ect[last_ep-1].next = 0;
133: nw_free_ep_first = 1;
134: nw_free_ep_last = last_ep - 1;
135: nw_free_line_first = nw_free_line_last = 0;
136: for (ep = 0; ep < MAX_HOST; ep++) {
137: nw_address[ep].nw_next = ep + 1;
138: }
139: nw_address[MAX_HOST - 1].nw_next = -1;
140: nw_free_address = 0;
141: for (ep = 0; ep < MAX_HASH; ep++) {
142: nw_name[ep] = -1;
143: nw_ip[ep] = -1;
144: nw_nw[ep] = -1;
145: }
146: nw_fast_req = 0;
147: h_initialize();
148: nc_initialized = TRUE;
149: }
150: }
151:
152: nw_tx_header_t nc_tx_header_allocate() {
153: nw_tx_header_t header;
154:
155: header = nw_free_tx_header;
156: if (header != NULL)
157: nw_free_tx_header = header->next;
158: return header;
159: }
160:
161: void nc_tx_header_deallocate(nw_tx_header_t header) {
162: nw_tx_header_t first_header;
163:
164: first_header = header;
165: while (header->next != NULL)
166: header = header->next;
167: header->next = nw_free_tx_header;
168: nw_free_tx_header = first_header;
169: }
170:
171: nw_rx_header_t nc_rx_header_allocate() {
172: nw_rx_header_t header;
173:
174: header = nw_free_rx_header;
175: if (header != NULL)
176: nw_free_rx_header = header->next;
177: return header;
178: }
179:
180: void nc_rx_header_deallocate(nw_rx_header_t header) {
181:
182: header->next = nw_free_rx_header;
183: nw_free_rx_header = header;
184: }
185:
186: nw_plist_t nc_peer_allocate() {
187: nw_plist_t peer;
188:
189: peer = nw_free_peer;
190: if (peer != NULL)
191: nw_free_peer = peer->next;
192: return peer;
193: }
194:
195: void nc_peer_deallocate(nw_plist_t peer) {
196: nw_plist_t first_peer;
197:
198: first_peer = peer;
199: while (peer->next != NULL)
200: peer = peer->next;
201: peer->next = nw_free_peer;
202: nw_free_peer = first_peer;
203: }
204:
205:
206: nw_result nc_device_register(u_int dev, nw_dev_type type, char *dev_addr,
207: nw_dev_entry_t dev_entry_table) {
208: nw_result rc;
209:
210: if (dev >= MAX_DEV) {
211: rc = NW_FAILURE;
212: } else {
213: devct[dev].status = NW_SUCCESS;
214: devct[dev].type = type;
215: devct[dev].addr = dev_addr;
216: devct[dev].entry = dev_entry_table;
217: devct[dev].fast_req = 0;
218: rc = NW_SUCCESS;
219: }
220: return rc;
221: }
222:
223: nw_result nc_device_unregister(u_int dev, nw_result status) {
224: nw_result rc;
225:
226: if (dev >= MAX_DEV) {
227: rc = NW_FAILURE;
228: } else {
229: devct[dev].status = status;
230: devct[dev].addr = NULL;
231: devct[dev].entry = &nc_failure_entry_table;
232: devct[dev].fast_req = 0;
233: rc = NW_SUCCESS;
234: }
235: return rc;
236: }
237:
238: void nc_slow_sweep() {
239: int dev;
240:
241: for (dev = 0; dev < MAX_DEV; dev++) {
242: if (devct[dev].status == NW_SUCCESS) {
243: (*(devct[dev].entry->slow_sweep)) (dev);
244: }
245: }
246: }
247:
248: void nc_fast_timer_set(int dev) {
249:
250: devct[dev].fast_req++;
251: if (nw_fast_req++ == 0)
252: h_fast_timer_set();
253: }
254:
255: void nc_fast_timer_reset(int dev) {
256:
257: devct[dev].fast_req--;
258: if (nw_fast_req-- == 0)
259: h_fast_timer_reset();
260: }
261:
262:
263: void nc_fast_sweep() {
264: int dev;
265:
266: for (dev = 0; dev < MAX_DEV; dev++) {
267: if (devct[dev].status == NW_SUCCESS &&
268: devct[dev].fast_req > 0) {
269: devct[dev].fast_req = 0;
270: (*(devct[dev].entry->fast_sweep)) (dev);
271: }
272: }
273: }
274:
275: int nc_hash_name(char *cp) {
276: int h;
277: char ch;
278: char *cp_end;
279:
280: cp_end = cp + 19;
281: *cp_end = '\0';
282: h = 0;
283: ch = *cp++;
284: while (ch != '\0') {
285: h = (h << 7) + ch;
286: ch = *cp++;
287: if (ch != '\0') {
288: h = (h << 7) + ch;
289: ch = *cp++;
290: if (ch != '\0') {
291: h = (h << 7) + ch;
292: ch = *cp++;
293: }
294: }
295: h %= MAX_HASH;
296: }
297: return h;
298: }
299:
300:
301: nw_result nc_update(nw_update_type up_type, int *up_info) {
302: nw_result rc;
303: nw_alist_t ad;
304: int h, slot, previous_slot, found_slot;
305: nw_address_1 n1;
306: nw_address_2 n2;
307:
308: if (up_type == NW_HOST_ADDRESS_REGISTER) {
309: if (nw_free_address == -1) {
310: rc = NW_NO_RESOURCES;
311: } else {
312: slot = nw_free_address;
313: ad = &nw_address[slot];
314: nw_free_address = ad->nw_next;
315: ad->address = *((nw_address_t) up_info);
316: h = nc_hash_name(ad->address.name);
317: ad->name_next = nw_name[h];
318: nw_name[h] = slot;
319: h = ad->address.ip_addr % MAX_HASH;
320: ad->ip_next = nw_ip[h];
321: nw_ip[h] = slot;
322: h = (ad->address.nw_addr_1 % MAX_HASH + ad->address.nw_addr_2)
323: % MAX_HASH;
324: ad->nw_next = nw_nw[h];
325: nw_nw[h] = slot;
326: ad->line = 0;
327: rc = NW_SUCCESS;
328: }
329: } else if (up_type == NW_HOST_ADDRESS_UNREGISTER) {
330: n1 = ((nw_address_t) up_info)->nw_addr_1;
331: n2 = ((nw_address_t) up_info)->nw_addr_2;
332: h = (n1 % MAX_HASH + n2) % MAX_HASH;
333: slot = nw_nw[h];
334: previous_slot = -1;
335: ad = &nw_address[slot];
336: while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
337: ad->address.nw_addr_2 != n2)) {
338: previous_slot = slot;
339: slot = ad->nw_next;
340: ad = &nw_address[slot];
341: }
342: if (slot == -1) {
343: rc = NW_BAD_ADDRESS;
344: } else {
345: if (previous_slot == -1)
346: nw_nw[h] = ad->nw_next;
347: else
348: nw_address[previous_slot].nw_next = ad->nw_next;
349: ad->nw_next = nw_free_address;
350: nw_free_address = slot;
351: found_slot = slot;
352: if (ad->address.ip_addr != 0) {
353: h = ad->address.ip_addr % MAX_HASH;
354: slot = nw_ip[h];
355: previous_slot = -1;
356: while (slot != -1 && slot != found_slot) {
357: previous_slot = slot;
358: slot = nw_address[slot].ip_next;
359: }
360: if (slot == found_slot) {
361: if (previous_slot == -1)
362: nw_ip[h] = ad->ip_next;
363: else
364: nw_address[previous_slot].ip_next = ad->ip_next;
365: }
366: }
367: if (ad->address.name[0] != '\0') {
368: h = nc_hash_name(ad->address.name);
369: slot = nw_name[h];
370: previous_slot = -1;
371: while (slot != -1 && slot != found_slot) {
372: previous_slot = slot;
373: slot = nw_address[slot].name_next;
374: }
375: if (slot == found_slot) {
376: if (previous_slot == -1)
377: nw_name[h] = ad->name_next;
378: else
379: nw_address[previous_slot].name_next = ad->name_next;
380: }
381: }
382: rc = NW_SUCCESS;
383: }
384: } else {
385: rc = NW_INVALID_ARGUMENT;
386: }
387: return rc;
388: }
389:
390: nw_result nc_lookup(nw_lookup_type lt, int *look_info) {
391: nw_result rc;
392: nw_address_t addr;
393: nw_alist_t ad;
394: int h, slot;
395: ip_address ip;
396: nw_address_1 n1;
397: nw_address_2 n2;
398:
399: if (lt == NW_HOST_ADDRESS_LOOKUP) {
400: addr = (nw_address_t) look_info;
401: if (addr->ip_addr != 0) {
402: ip = addr->ip_addr;
403: h = ip % MAX_HASH;
404: slot = nw_ip[h];
405: ad = &nw_address[slot];
406: while (slot != -1 && ad->address.ip_addr != ip) {
407: slot = ad->ip_next;
408: ad = &nw_address[slot];
409: }
410: if (slot != -1) {
411: strcpy(addr->name, ad->address.name);
412: addr->nw_addr_1 = ad->address.nw_addr_1;
413: addr->nw_addr_2 = ad->address.nw_addr_2;
414: return NW_SUCCESS;
415: }
416: }
417: if (addr->name[0] != '\0') {
418: h = nc_hash_name(addr->name);
419: slot = nw_name[h];
420: ad = &nw_address[slot];
421: while (slot != -1 && strcmp(ad->address.name, addr->name) != 0) {
422: slot = ad->name_next;
423: ad = &nw_address[slot];
424: }
425: if (slot != -1) {
426: addr->ip_addr = ad->address.ip_addr;
427: addr->nw_addr_1 = ad->address.nw_addr_1;
428: addr->nw_addr_2 = ad->address.nw_addr_2;
429: return NW_SUCCESS;
430: }
431: }
432: if (addr->nw_addr_1 != 0 || addr->nw_addr_2 != 0) {
433: n1 = addr->nw_addr_1;
434: n2 = addr->nw_addr_2;
435: h = (n1 % MAX_HASH + n2) % MAX_HASH;
436: slot = nw_nw[h];
437: ad = &nw_address[slot];
438: while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
439: ad->address.nw_addr_2 != n2)) {
440: slot = ad->nw_next;
441: ad = &nw_address[slot];
442: }
443: if (slot != -1) {
444: strcpy(addr->name, ad->address.name);
445: addr->ip_addr = ad->address.ip_addr;
446: return NW_SUCCESS;
447: }
448: }
449: rc = NW_BAD_ADDRESS;
450: } else {
451: rc = NW_INVALID_ARGUMENT;
452: }
453: return rc;
454: }
455:
456: nw_result nc_line_update(nw_peer_t peer, nw_ep line) {
457: nw_result rc;
458: nw_alist_t ad;
459: int h, slot;
460: nw_address_1 n1;
461: nw_address_2 n2;
462:
463: n1 = peer->rem_addr_1;
464: n2 = peer->rem_addr_2;
465: h = (n1 % MAX_HASH + n2) % MAX_HASH;
466: slot = nw_nw[h];
467: ad = &nw_address[slot];
468: while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
469: ad->address.nw_addr_2 != n2)) {
470: slot = ad->nw_next;
471: ad = &nw_address[slot];
472: }
473: if (slot == -1) {
474: rc = NW_FAILURE;
475: } else {
476: ad->line = line;
477: rc = NW_SUCCESS;
478: }
479: return rc;
480: }
481:
482: nw_ep nc_line_lookup(nw_peer_t peer) {
483: nw_ep lep;
484: nw_alist_t ad;
485: int h, slot;
486: nw_address_1 n1;
487: nw_address_2 n2;
488:
489: n1 = peer->rem_addr_1;
490: n2 = peer->rem_addr_2;
491: h = (n1 % MAX_HASH + n2) % MAX_HASH;
492: slot = nw_nw[h];
493: ad = &nw_address[slot];
494: while (slot != -1 && (ad->address.nw_addr_1 != n1 ||
495: ad->address.nw_addr_2 != n2)) {
496: slot = ad->nw_next;
497: ad = &nw_address[slot];
498: }
499: if (slot == -1) {
500: lep = -1;
501: } else {
502: lep = ad->line;
503: }
504: return lep;
505: }
506:
507: nw_result nc_endpoint_allocate(nw_ep_t epp, nw_protocol protocol,
508: nw_acceptance accept,
509: char *buffer_address, u_int buffer_size) {
510: nw_result rc;
511: nw_ep ep;
512: nw_ecb_t ecb;
513:
514: if (ect[(ep = *epp)].state != NW_INEXISTENT) {
515: rc = NW_BAD_EP;
516: } else if (nw_free_ep_first == 0) {
517: *epp = nw_free_line_first;
518: rc = NW_NO_EP;
519: } else {
520: if (ep == 0) {
521: ecb = &ect[nw_free_ep_first];
522: *epp = ep = ecb->id;
523: nw_free_ep_first = ecb->next;
524: if (nw_free_ep_first == 0)
525: nw_free_ep_last = 0;
526: } else {
527: ecb = &ect[ep];
528: if (ecb->previous == 0)
529: nw_free_ep_first = ecb->next;
530: else
531: ect[ecb->previous].next = ecb->next;
532: if (ecb->next == 0)
533: nw_free_ep_last = ecb->previous;
534: else
535: ect[ecb->next].previous = ecb->previous;
536: }
537: if (protocol == NW_LINE) {
538: if (nw_free_line_last == 0)
539: nw_free_line_first = ep;
540: else
541: ect[nw_free_line_last].next = ep;
542: ecb->previous = nw_free_line_last;
543: ecb->next = 0;
544: nw_free_line_last = ep;
545: }
546: ecb->protocol = protocol;
547: ecb->accept = accept;
548: ecb->state = NW_UNCONNECTED;
549: ecb->conn = NULL;
550: ecb->buf_start = buffer_address;
551: ecb->buf_end = buffer_address + buffer_size;
552: ecb->free_buffer = (nw_unused_buffer_t) buffer_address;
553: ecb->free_buffer->buf_used = 0;
554: ecb->free_buffer->buf_length = buffer_size;
555: ecb->free_buffer->previous = NULL;
556: ecb->free_buffer->next = NULL;
557: ecb->overrun = 0;
558: ecb->seqno = 0;
559: ecb->tx_first = NULL;
560: ecb->tx_last = NULL;
561: ecb->tx_initial = NULL;
562: ecb->tx_current = NULL;
563: ecb->rx_first = NULL;
564: ecb->rx_last = NULL;
565: rc = NW_SUCCESS;
566: }
567: return rc;
568: }
569:
570: nw_result nc_endpoint_deallocate(nw_ep ep) {
571: nw_ecb_t ecb;
572: nw_rx_header_t rx_header;
573:
574: ecb = &ect[ep];
575: if (ecb->conn != NULL)
576: nc_peer_deallocate(ecb->conn);
577: if (ecb->tx_first != NULL)
578: nc_tx_header_deallocate(ecb->tx_first);
579: if (ecb->tx_initial != NULL)
580: nc_tx_header_deallocate(ecb->tx_initial);
581: while (ecb->rx_first != NULL) {
582: rx_header = ecb->rx_first;
583: ecb->rx_first = rx_header->next;
584: nc_rx_header_deallocate(rx_header);
585: }
586: if (ecb->protocol == NW_LINE) {
587: if (ecb->previous == 0)
588: nw_free_line_first = ecb->next;
589: else
590: ect[ecb->previous].next = ecb->next;
591: if (ecb->next == 0)
592: nw_free_line_last = ecb->previous;
593: else
594: ect[ecb->next].previous = ecb->previous;
595: }
596: ecb->next = 0;
597: ecb->previous = nw_free_ep_last;
598: if (nw_free_ep_last == 0)
599: nw_free_ep_first = ep;
600: else
601: ect[nw_free_ep_last].next = ep;
602: nw_free_ep_last = ep;
603: ecb->id = ep;
604: ecb->state = NW_INEXISTENT;
605: return NW_SUCCESS;
606: }
607:
608: void nc_buffer_coalesce(nw_ecb_t ecb) {
609: nw_unused_buffer_t p, q, buf_free, buf_start, buf_end;
610:
611: buf_start = p = (nw_unused_buffer_t) ecb->buf_start;
612: buf_end = (nw_unused_buffer_t) ecb->buf_end;
613: buf_free = NULL;
614: while (p >= buf_start && p < buf_end) {
615: if (p->buf_length & 0x3)
616: goto trash_area;
617: if (p->buf_used) {
618: p = (nw_unused_buffer_t) ((char *) p + p->buf_length);
619: } else {
620: q = (nw_unused_buffer_t) ((char *) p + p->buf_length);
621: while (q >= buf_start && q < buf_end && !q->buf_used) {
622: if (q->buf_length & 0x3)
623: goto trash_area;
624: p->buf_length += q->buf_length;
625: q = (nw_unused_buffer_t) ((char *) q + q->buf_length);
626: }
627: p->next = buf_free;
628: p->previous = NULL;
629: if (buf_free != NULL)
630: buf_free->previous = p;
631: buf_free = p;
632: p = q;
633: }
634: }
635: ecb->free_buffer = buf_free;
636: return;
637:
638: trash_area:
639: ecb->free_buffer = NULL;
640: return;
641: }
642:
643:
644: nw_buffer_t nc_buffer_allocate(nw_ep ep, u_int size) {
645: nw_ecb_t ecb;
646: nw_unused_buffer_t buf, buf_start, buf_end;
647:
648: ecb = &ect[ep];
649: buf_start = (nw_unused_buffer_t) ecb->buf_start;
650: buf_end = (nw_unused_buffer_t) (ecb->buf_end - sizeof(nw_buffer_s));
651: if (size < sizeof(nw_buffer_s))
652: size = sizeof(nw_buffer_s);
653: else
654: size = ((size + 3) >> 2) << 2;
655: buf = ecb->free_buffer;
656: if (buf != NULL) {
657: while (buf->buf_length < size) {
658: buf = buf->next;
659: if (buf < buf_start || buf > buf_end || ((int) buf & 0x3)) {
660: buf = NULL;
661: break;
662: }
663: }
664: }
665: if (buf == NULL) {
666: nc_buffer_coalesce(ecb);
667: buf = ecb->free_buffer;
668: while (buf != NULL && buf->buf_length < size)
669: buf = buf->next;
670: }
671: if (buf == NULL) {
672: ecb->overrun = 1;
673: } else {
674: if (buf->buf_length < size + sizeof(nw_buffer_s)) {
675: if (buf->previous == NULL)
676: ecb->free_buffer = buf->next;
677: else
678: buf->previous->next = buf->next;
679: if (buf->next != NULL)
680: buf->next->previous = buf->previous;
681: } else {
682: buf->buf_length -= size;
683: buf = (nw_unused_buffer_t) ((char *) buf + buf->buf_length);
684: buf->buf_length = size;
685: }
686: buf->buf_used = 1;
687: }
688: return (nw_buffer_t) buf;
689: }
690:
691: nw_result nc_buffer_deallocate(nw_ep ep, nw_buffer_t buffer) {
692: nw_ecb_t ecb;
693: nw_unused_buffer_t buf;
694:
695: ecb = &ect[ep];
696: buf = (nw_unused_buffer_t) buffer;
697: buf->buf_used = 0;
698: buf->previous = NULL;
699: buf->next = ecb->free_buffer;
700: if (ecb->free_buffer != NULL)
701: ecb->free_buffer->previous = buf;
702: ecb->free_buffer = buf;
703: return NW_SUCCESS;
704: }
705:
706: nw_result nc_endpoint_status(nw_ep ep, nw_state_t state, nw_peer_t peer) {
707: nw_result rc;
708: nw_ecb_t ecb;
709:
710: ecb = &ect[ep];
711: *state = ecb->state;
712: if (ecb->conn)
713: *peer = ecb->conn->peer;
714: if (ecb->overrun) {
715: ecb->overrun = 0;
716: rc = NW_OVERRUN;
717: } else if (ecb->rx_first != NULL) {
718: rc = NW_QUEUED;
719: } else {
720: rc = NW_SUCCESS;
721: }
722: return rc;
723: }
724:
725:
726: nw_result nc_local_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
727: nw_result rc;
728: nw_ep receiver;
729: int length;
730: nw_buffer_t buffer;
731: nw_tx_header_t first_header;
732: nw_rx_header_t rx_header;
733: char *bufp;
734: nw_ecb_t ecb;
735:
736: receiver = header->peer.remote_ep;
737: length = header->msg_length;
738: buffer = nc_buffer_allocate(receiver, sizeof(nw_buffer_s) + length);
739: if (buffer == NULL) {
740: rc = NW_OVERRUN;
741: } else {
742: buffer->buf_next = NULL;
743: buffer->block_offset = sizeof(nw_buffer_s);
744: buffer->block_length = length;
745: buffer->peer.rem_addr_1 = NW_NULL << 28;
746: buffer->peer.rem_addr_2 = 0;
747: buffer->peer.remote_ep = ep;
748: buffer->peer.local_ep = receiver;
749: bufp = (char *) buffer + sizeof(nw_buffer_s);
750: first_header = header;
751: while (header != NULL) {
752: length = header->block_length;
753: bcopy(header->block, bufp, length);
754: bufp += length;
755: if (header->buffer != NULL)
756: nc_buffer_deallocate(ep, header->buffer);
757: header = header->next;
758: }
759: nc_tx_header_deallocate(first_header);
760: ecb = &ect[receiver];
761: if (options == NW_URGENT) {
762: buffer->msg_seqno = 0;
763: if (nc_deliver_result(receiver, NW_RECEIVE_URGENT, (int) buffer))
764: rc = NW_SUCCESS;
765: else
766: rc = NW_NO_RESOURCES;
767: } else {
768: if (ecb->seqno == 1023)
769: buffer->msg_seqno = ecb->seqno = 1;
770: else
771: buffer->msg_seqno = ++ecb->seqno;
772: if (nc_deliver_result(receiver, NW_RECEIVE, (int) buffer))
773: rc = NW_SUCCESS;
774: else
775: rc = NW_NO_RESOURCES;
776: }
777: }
778: return rc;
779: }
780:
781: nw_buffer_t nc_local_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
782: nw_buffer_t buf;
783: nw_ecb_t ecb;
784: nw_rx_header_t rx_header;
785:
786: ecb = &ect[ep];
787: rx_header = ecb->rx_first;
788: if (nc_local_send(ep, header, options) != NW_SUCCESS) {
789: buf = NW_BUFFER_ERROR;
790: } else if (rx_header == NULL) {
791: buf = NULL;
792: } else {
793: buf = rx_header->buffer;
794: ecb->rx_first = rx_header->next;
795: if (ecb->rx_first == NULL)
796: ecb->rx_last = NULL;
797: nc_rx_header_deallocate(rx_header);
798: }
799: return buf;
800: }
801:
802:
803: nw_result nc_succeed(int dev) {
804:
805: return NW_SUCCESS;
806: }
807:
808: void nc_null(int dev) {
809:
810: }
811:
812: nw_result nc_fail(int dev) {
813:
814: return NW_FAILURE;
815: }
816:
817: int nc_null_poll(int dev) {
818:
819: return 1000000;
820: }
821:
822: nw_result nc_null_send(nw_ep ep, nw_tx_header_t header, nw_options options) {
823:
824: return NW_FAILURE;
825: }
826:
827: nw_buffer_t nc_null_rpc(nw_ep ep, nw_tx_header_t header, nw_options options) {
828:
829: return NW_BUFFER_ERROR;
830: }
831:
832: void nc_null_signal(nw_buffer_t msg) {
833:
834: }
835:
836: nw_result nc_open_fail(nw_ep lep, nw_address_1 a1,
837: nw_address_2 a2, nw_ep rep) {
838:
839: return NW_FAILURE;
840: }
841:
842: nw_result nc_close_fail(nw_ep ep) {
843:
844: return NW_FAILURE;
845: }
846:
847: nw_result nc_accept_fail(nw_ep ep, nw_buffer_t msg, nw_ep_t epp) {
848:
849: return NW_FAILURE;
850: }
851:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.