1 /* nsp_subr.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 extern int nspidebug; 15 #define printd if(nspidebug)printf 16 17 /* 18 * NSP initialization 19 */ 20 nsp_init() 21 { 22 init queues 23 what else? 24 } 25 26 /* 27 * Nsp_chkaddr performs many functions common to the processing 28 * of input packets. The arguments are: 29 * m - the mbuf with the packet in it 30 * srcnode - the srcnode from the transport header 31 * type - the packet type, one of: 32 * NSP_DATA, NSP_LS, NSP_INTR, NSP_DATACK, NSP_OTHACK 33 * sp - pointer to a short to receive the segment number 34 * 35 * It performs the following functions: 36 * 1. verify that the packet is of the correct minimum length 37 * 2. find the associated NSP control block (by calling dn_addrtonspcb()) 38 * 3. process any ack or nak and force retransmission or remove 39 * acked data from the retransmit queue, as required 40 * 4. update the mbuf to point past the segnum field 41 * 5. return the segnum and nspcb pointer 42 */ 43 struct nspcb * 44 nsp_chkaddr(m, srcnode, type, sp) 45 struct mbuf *m; 46 short srcnode; 47 int type; 48 u_short *sp; 49 { 50 register struct nspcb *np; 51 struct nspd *n; 52 u_short dstaddr; 53 int ack, qual, num; 54 55 /* make sure we are accessing valid data */ 56 if (m->m_len < sizeof (struct nspd) - sizeof (d_short)) { 57 m_freem(m); 58 return (0); 59 } 60 n = mtod(m, struct nspd *); 61 dstaddr = D_SHORT(n->nsp_dstaddr); 62 np = dn_addrtonspcb(dstaddr); 63 if (np == 0) { 64 no such address, return "no link" message 65 } 66 if (np->n_node != srcnode) { 67 printf("nsp_chkaddr: n_node %d, srcnode %d\n", np->n_node, 68 scrnode); 69 m_freem(m); 70 return (0); 71 } 72 /* make sure remote addresses match (consistency check) */ 73 if (np->n_rem != D_SHORT(n->nsp_srcaddr)) { 74 printf("nsp_chkaddr: n_rem %d, srcaddr %d\n", np->n_rem, 75 D_SHORT(n->nsp_srcaddr)); 76 m_freem(m); 77 return (0); 78 } 79 ack = D_SHORT(n->nsp_acknum); 80 if (ack & NSPA_ACK) { 81 qual = ack & NSPA_QUAL; 82 num = ack & NSPA_NUM; 83 printd(", qual 0x%x, num %d", qual, num); 84 /* make sure there's room for a segnum */ 85 if (m->m_len < sizeof (struct nspd)) { 86 m_freem(m); 87 return (0); 88 } 89 if (type == NSP_DATA) { 90 if (SEQ_GTR(num, np->na_rcvdat) && 91 SEQ_LEQ(num, np->nn_high)) { 92 np->n_retrans = 0; 93 np->nf_remdat -= SEQ_SUB(num, np->na_rcvdat); 94 } 95 if (qual == NSPA_NAK || SEQ_LEQ(np->nn_dat, num)) 96 np->nn_dat = SEQ_ADD(num, 1); 97 np->na_rcvdat = num; 98 nsp_purgertq(np, type); 99 } else if (n == np->nn_oth && (np->n_flags&NF_OTHSENT)) { 100 if (qual == NSPA_NAK) { 101 /* force retransmission of other data seg */ 102 printf("nsp_chkaddr: NAK other\n"); 103 } else { 104 np->n_flags &= ~NF_OTHSENT; 105 np->nn_oth = SEQ_ADD(np->nn_oth, 1); 106 if (np->n_flags & NF_OTHINTR) { 107 np->n_flags &= 108 ~(NF_OTHINTR|NF_INTAVAIL); 109 if (np->nb_xmt) 110 m_freem(np->nb_xmt); 111 } else 112 np->nf_locdat = 0; 113 nsp_purgertq(np, type); 114 } 115 } 116 *sp = D_SHORT(n->nsp_segnum); 117 num = sizeof (struct nspd); 118 } else { 119 *sp = (u_short)ack; 120 num = sizeof (struct nspd) - sizeof (u_short); 121 } 122 m->m_len -= num; 123 m->m_off += num; 124 return (np); 125 } 126