1 /* nsp_input.c 1.3 82/10/09 */ 2 3 #include "../h/param.h" 4 #include "../h/systm.h" 5 #include "../h/mbuf.h" 6 #include "../h/protosw.h" 7 #include "../h/socket.h" 8 #include "../h/socketvar.h" 9 #include "../netdecnet/dn_systm.h" 10 #include "../netdecnet/nsp.h" 11 #include "../netdecnet/nsp_var.h" 12 #include <errno.h> 13 14 int nspidebug = 1; 15 #define printd if(nspidebug)printf 16 /* 17 * NSP input routine: decode incoming packet and dispatch 18 * to appropriate socket. Called from the software interrupt 19 * at splnet. 20 * 21 * TODO: 22 * count occurances of various error conditions. 23 */ 24 25 nspintr() 26 { 27 struct mbuf *m; 28 struct tprh *t; 29 int s, bom, eom; 30 u_short srcnode; 31 char *p; 32 struct nspcb *np; 33 34 /* 35 * Loop pulling packets off the interrupt queue. 36 */ 37 next: 38 s = splimp(); 39 IF_DEQUEUE(&nspintrq, m); 40 splx(s); 41 printd("nsp_input: m 0x%x", m); 42 if (m == 0) 43 return; 44 t = mtod(m, struct tprh *); 45 srcnode = t->tprh_srcnode; 46 m->m_len -= sizeof (struct tprh); /* use m_adj??? */ 47 m->m_off += sizeof (struct tprh); 48 printd(", srcnode %d, len %d", srcnode, m->m_len); 49 if (m->m_len <= 0) { 50 m_freem(m); 51 goto next; 52 } 53 54 /* 55 * Switch on the type of the message. 56 */ 57 p = mtod(m, char *); 58 switch (*p) { 59 60 /* 61 * Got a Data message, possibly with EOM and 62 * BOM flags set. Call nsp_chkaddr to do ack 63 * and flow controll processing, then pass the 64 * data to the user. 65 */ 66 case NSP_DATA|NSP_EOM|NSP_BOM: 67 eom = bom = 1; 68 goto data; 69 70 case NSP_DATA|NSP_EOM: 71 eom = 1; 72 goto data; 73 74 case NSP_DATA|NSP_BOM: 75 bom = 1; 76 77 case NSP_DATA: 78 data: 79 printd(", DATA (%d,%d)", bom, eom); 80 np = nsp_chkaddr(m, srcnode, NSP_DATA, &segnum); 81 if (np == 0) { 82 m_freem(m); 83 goto next; 84 } 85 86 /* 87 * Data messages only valid in Run state 88 */ 89 if (np->n_state != NS_RUN) { 90 printf(", !RUN (%d)\n", np->n_state); 91 m_freem(m); 92 goto next; 93 } 94 if (SEQ_GTR(segnum, np->na_xmtdat)) { 95 /* SHOULD DO SEGMENT RECONSTRUCTION HERE */ 96 printd(", got data!"); 97 sbpappend(m, &np->n_socket->sb_rcv); 98 } else 99 np->n_flags |= NF_DATACK; 100 break; 101 102 /* 103 * Got an interrupt message. Call nsp_chkaddr 104 * (as usual). Save the interrupt data for the 105 * user. 106 * GENERATE A SIGNAL OF SOME SORT??? 107 */ 108 case NSP_INTR: 109 printd(", INTR"); 110 np = nsp_chkaddr(m, srcnode, NSP_INTR, &segnum); 111 if (np == 0) { 112 m_freem(m); 113 goto next; 114 } 115 116 /* 117 * If we are in the Connect Confirm state then 118 * this Interrupt packet causes the transition 119 * to the Run state. Otherwise we better be in 120 * the Run state already. 121 */ 122 if (np->n_state == NS_CC) 123 np->n_state = NS_RUN; 124 else if (np->n_state != NS_RUN) { 125 printf(", !RUN %d\n", np->n_state); 126 m_freem(m); 127 goto next; 128 } 129 130 /* 131 * If this segment is the one after the last 132 * other data segment we acked, and there is 133 * no waiting interrupt message, then queue 134 * this one up. 135 */ 136 if (segnum == SEQ_ADD(np->na_xmtoth, 1) && 137 np->nf_locint == NFL_EMPTY) { 138 if (np->nb_rcv) { 139 printd(", flush old intr data"); 140 m_freem(np->nb_rcv); 141 } 142 if (m->m_len > 16) { 143 printd(", intr data too long\n"); 144 m_freem(m); 145 goto next; 146 } 147 np->nb_rcv = m; 148 np->nf_locint = NFL_INTR; 149 np->na_xmtoth = segnum; /* really += 1 */ 150 np->n_flags |= NF_OTHACK; 151 } else if (SEQ_LEQ(segnum, np->na_xmtoth)) 152 np->n_flags |= NF_OTHACK; 153 break; 154 155 /* 156 * Got a Link Service message. Process options 157 * to modify flow control values. 158 */ 159 case NSP_LS: 160 printd(", LS"); 161 np = nsp_chkaddr(m, srcnode, NSP_LS, &segnum); 162 if (np == 0) { 163 m_freem(m); 164 goto next; 165 } 166 167 /* 168 * If we are in the Connect Confirm state then 169 * this Link Service packet causes the transition 170 * to the Run state. Otherwise we better be in 171 * the Run state already. 172 */ 173 if (np->n_state == NS_CC) 174 np->n_state = NS_RUN; 175 else if (np->n_state != NS_RUN) { 176 printd(", !RUN %d\n", np->n_state); 177 m_freem(m); 178 goto next; 179 } 180 p = mtod(m, char *); 181 lsf = *p++; 182 fcval = *p; 183 printd(", lsf 0x%x, fcval %d", lsf, fcval); 184 switch (lsf & NSPLS_FCVALINT) { 185 case NSPLS_DATREQ: 186 if (seqnum == SEQ_ADD(np->na_xmtoth, 1)) { 187 if (np->nf_remdat + fcval >= -128 && 188 np->nf_remdat + fcval <= 127) { 189 np->nf_remdat += fcval; 190 np->na_xmtoth = segnum; 191 np->n_flags |= NF_OTHACK; 192 switch (lsf & NSPLS_FCMOD) { 193 case NSPLS_NOCHANGE: 194 break; 195 case NSPLS_ON: 196 np->n_flags &= ~NF_DATOFF; 197 break; 198 case NSPLS_OFF: 199 np->n_flags |= NF_DATOFF; 200 break; 201 default: 202 printd(", bad fcmod"); 203 } 204 } 205 } else if (SEQ_LEQ(segnum, np->na_xmtoth)) 206 np->n_flags |= NF_OTHACK; 207 break; 208 209 case NSPLS_INTREQ: 210 if (seqnum == SEQ_ADD(np->na_xmtoth, 1)) { 211 if (fcval >= 0 && np->nf_remint+fcval <= 127) { 212 np->nf_remint += fcval; 213 np->na_xmtoth = segnum; 214 np->n_flags |= NF_OTHACK; 215 } else if (SEQ_LEQ(segnum, np->na_xmtoth)) 216 np->n_flags |= NF_OTHACK; 217 break; 218 219 default: 220 printd(", bad fcvalint"); 221 } 222 break; 223 224 /* 225 * Got an acknowledgement for a Data message. 226 * Nsp_chkaddr processes the ack, nothing else 227 * to do. 228 */ 229 case NSP_DATACK: 230 printd(", DATACK"); 231 np = nsp_chkaddr(m, srcnode, NSP_DATACK, &segnum); 232 if (np == 0) { 233 m_freem(m); 234 goto next; 235 } 236 break; 237 238 /* 239 * Got an acknowledgement for an Other Data message. 240 * Nsp_chkaddr processes the ack, nothing else to do. 241 */ 242 case NSP_OTHACK: 243 printd(", OTHACK"); 244 np = nsp_chkaddr(m, srcnode, NSP_OTHACK, &segnum); 245 if (np == 0) { 246 m_freem(m); 247 goto next; 248 } 249 break; 250 251 /* 252 * Got a Connect Acknowledgement. Just verify 253 * the address and perform the state transition. 254 */ 255 case NSP_CONACK: 256 DOIT 257 break; 258 259 /* 260 * Got an unknown message, count it and flush it. 261 */ 262 default: 263 printd(", UNKNOWN!!!"); 264 m_freem(m); 265 break; 266 } 267 printd("\n"); 268 goto next; 269 } 270