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