|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /*
23: * Copyright (c) University of British Columbia, 1984
24: * Copyright (C) Computer Science Department IV,
25: * University of Erlangen-Nuremberg, Germany, 1992
26: * Copyright (c) 1991, 1992, 1993
27: * The Regents of the University of California. All rights reserved.
28: *
29: * This code is derived from software contributed to Berkeley by the
30: * Laboratory for Computation Vision and the Computer Science Department
31: * of the the University of British Columbia and the Computer Science
32: * Department (IV) of the University of Erlangen-Nuremberg, Germany.
33: *
34: * Redistribution and use in source and binary forms, with or without
35: * modification, are permitted provided that the following conditions
36: * are met:
37: * 1. Redistributions of source code must retain the above copyright
38: * notice, this list of conditions and the following disclaimer.
39: * 2. Redistributions in binary form must reproduce the above copyright
40: * notice, this list of conditions and the following disclaimer in the
41: * documentation and/or other materials provided with the distribution.
42: * 3. All advertising materials mentioning features or use of this software
43: * must display the following acknowledgement:
44: * This product includes software developed by the University of
45: * California, Berkeley and its contributors.
46: * 4. Neither the name of the University nor the names of its contributors
47: * may be used to endorse or promote products derived from this software
48: * without specific prior written permission.
49: *
50: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60: * SUCH DAMAGE.
61: *
62: * @(#)pk_output.c 8.1 (Berkeley) 6/10/93
63: */
64:
65: #include <sys/param.h>
66: #include <sys/systm.h>
67: #include <sys/mbuf.h>
68: #include <sys/socket.h>
69: #include <sys/socketvar.h>
70: #include <sys/protosw.h>
71: #include <sys/errno.h>
72:
73: #include <net/if.h>
74:
75: #include <netccitt/x25.h>
76: #include <netccitt/pk.h>
77: #include <netccitt/pk_var.h>
78:
79: struct mbuf_cache pk_output_cache = {0 }, pk_input_cache;
80: struct mbuf *nextpk ();
81:
82: pk_output (lcp)
83: register struct pklcd *lcp;
84: {
85: register struct x25_packet *xp;
86: register struct mbuf *m;
87: register struct pkcb *pkp = lcp -> lcd_pkp;
88:
89: if (lcp == 0 || pkp == 0) {
90: printf ("pk_output: zero arg\n");
91: return;
92: }
93:
94: while ((m = nextpk (lcp)) != NULL) {
95: xp = mtod (m, struct x25_packet *);
96:
97: switch (pk_decode (xp) + lcp -> lcd_state) {
98: /*
99: * All the work is already done - just set the state and
100: * pass to peer.
101: */
102: case CALL + READY:
103: lcp -> lcd_state = SENT_CALL;
104: lcp -> lcd_timer = pk_t21;
105: break;
106:
107: /*
108: * Just set the state to allow packet to flow and send the
109: * confirmation.
110: */
111: case CALL_ACCEPTED + RECEIVED_CALL:
112: lcp -> lcd_state = DATA_TRANSFER;
113: break;
114:
115: /*
116: * Just set the state. Keep the LCD around till the clear
117: * confirmation is returned.
118: */
119: case CLEAR + RECEIVED_CALL:
120: case CLEAR + SENT_CALL:
121: case CLEAR + DATA_TRANSFER:
122: lcp -> lcd_state = SENT_CLEAR;
123: lcp -> lcd_retry = 0;
124: /* fall through */
125:
126: case CLEAR + SENT_CLEAR:
127: lcp -> lcd_timer = pk_t23;
128: lcp -> lcd_retry++;
129: break;
130:
131: case CLEAR_CONF + RECEIVED_CLEAR:
132: case CLEAR_CONF + SENT_CLEAR:
133: case CLEAR_CONF + READY:
134: lcp -> lcd_state = READY;
135: break;
136:
137: case DATA + DATA_TRANSFER:
138: SPS(xp, lcp -> lcd_ssn);
139: lcp -> lcd_input_window =
140: (lcp -> lcd_rsn + 1) % MODULUS;
141: SPR(xp, lcp -> lcd_input_window);
142: lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
143: lcp -> lcd_ssn = (lcp -> lcd_ssn + 1) % MODULUS;
144: if (lcp -> lcd_ssn == ((lcp -> lcd_output_window + lcp -> lcd_windowsize) % MODULUS))
145: lcp -> lcd_window_condition = TRUE;
146: break;
147:
148: case INTERRUPT + DATA_TRANSFER:
149: #ifdef ancient_history
150: xp -> packet_data = 0;
151: #endif
152: lcp -> lcd_intrconf_pending = TRUE;
153: break;
154:
155: case INTERRUPT_CONF + DATA_TRANSFER:
156: break;
157:
158: case RR + DATA_TRANSFER:
159: case RNR + DATA_TRANSFER:
160: lcp -> lcd_input_window =
161: (lcp -> lcd_rsn + 1) % MODULUS;
162: SPR(xp, lcp -> lcd_input_window);
163: lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
164: break;
165:
166: case RESET + DATA_TRANSFER:
167: lcp -> lcd_reset_condition = TRUE;
168: break;
169:
170: case RESET_CONF + DATA_TRANSFER:
171: lcp -> lcd_reset_condition = FALSE;
172: break;
173:
174: /*
175: * A restart should be only generated internally. Therefore
176: * all logic for restart is in the pk_restart routine.
177: */
178: case RESTART + READY:
179: lcp -> lcd_timer = pk_t20;
180: break;
181:
182: /*
183: * Restarts are all handled internally. Therefore all the
184: * logic for the incoming restart packet is handled in the
185: * pk_input routine.
186: */
187: case RESTART_CONF + READY:
188: break;
189:
190: default:
191: m_freem (m);
192: return;
193: }
194:
195: /* Trace the packet. */
196: pk_trace (pkp -> pk_xcp, m, "P-Out");
197:
198: /* Pass the packet on down to the link layer */
199: if (pk_input_cache.mbc_size || pk_input_cache.mbc_oldsize) {
200: m->m_flags |= 0x08;
201: mbuf_cache(&pk_input_cache, m);
202: }
203: (*pkp -> pk_lloutput) (pkp -> pk_llnext, m, pkp -> pk_rt);
204: }
205: }
206:
207: /*
208: * This procedure returns the next packet to send or null. A
209: * packet is composed of one or more mbufs.
210: */
211:
212: struct mbuf *
213: nextpk (lcp)
214: struct pklcd *lcp;
215: {
216: register struct mbuf *m, *n;
217: struct socket *so = lcp -> lcd_so;
218: register struct sockbuf *sb = & (so ? so -> so_snd : lcp -> lcd_sb);
219:
220: if (lcp -> lcd_template) {
221: m = lcp -> lcd_template;
222: lcp -> lcd_template = NULL;
223: } else {
224: if (lcp -> lcd_rnr_condition || lcp -> lcd_window_condition ||
225: lcp -> lcd_reset_condition)
226: return (NULL);
227:
228: if ((m = sb -> sb_mb) == 0)
229: return (NULL);
230:
231: sb -> sb_mb = m -> m_nextpkt;
232: m->m_act = 0;
233: for (n = m; n; n = n -> m_next)
234: sbfree (sb, n);
235: }
236: return (m);
237: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.