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