1*8409Swnj /* nsp_subr.c 1.3 82/10/09 */
26829Ssam
36829Ssam #include "../h/param.h"
46829Ssam #include "../h/systm.h"
56829Ssam #include "../h/mbuf.h"
66829Ssam #include "../h/protosw.h"
76829Ssam #include "../h/socket.h"
86829Ssam #include "../h/socketvar.h"
9*8409Swnj #include "../netdecnet/dn_systm.h"
10*8409Swnj #include "../netdecnet/nsp.h"
11*8409Swnj #include "../netdecnet/nsp_var.h"
12*8409Swnj #include <errno.h>
136829Ssam
146829Ssam extern int nspidebug;
156829Ssam #define printd if(nspidebug)printf
166829Ssam
176829Ssam /*
186829Ssam * NSP initialization
196829Ssam */
nsp_init()206829Ssam nsp_init()
216829Ssam {
226829Ssam init queues
236829Ssam what else?
246829Ssam }
256829Ssam
266829Ssam /*
276829Ssam * Nsp_chkaddr performs many functions common to the processing
286829Ssam * of input packets. The arguments are:
296829Ssam * m - the mbuf with the packet in it
306829Ssam * srcnode - the srcnode from the transport header
316829Ssam * type - the packet type, one of:
326829Ssam * NSP_DATA, NSP_LS, NSP_INTR, NSP_DATACK, NSP_OTHACK
336829Ssam * sp - pointer to a short to receive the segment number
346829Ssam *
356829Ssam * It performs the following functions:
366829Ssam * 1. verify that the packet is of the correct minimum length
376829Ssam * 2. find the associated NSP control block (by calling dn_addrtonspcb())
386829Ssam * 3. process any ack or nak and force retransmission or remove
396829Ssam * acked data from the retransmit queue, as required
406829Ssam * 4. update the mbuf to point past the segnum field
416829Ssam * 5. return the segnum and nspcb pointer
426829Ssam */
436829Ssam struct nspcb *
nsp_chkaddr(m,srcnode,type,sp)446829Ssam nsp_chkaddr(m, srcnode, type, sp)
456829Ssam struct mbuf *m;
466829Ssam short srcnode;
476829Ssam int type;
486829Ssam u_short *sp;
496829Ssam {
506829Ssam register struct nspcb *np;
516829Ssam struct nspd *n;
526829Ssam u_short dstaddr;
536829Ssam int ack, qual, num;
546829Ssam
556829Ssam /* make sure we are accessing valid data */
566829Ssam if (m->m_len < sizeof (struct nspd) - sizeof (d_short)) {
576829Ssam m_freem(m);
586829Ssam return (0);
596829Ssam }
606829Ssam n = mtod(m, struct nspd *);
616829Ssam dstaddr = D_SHORT(n->nsp_dstaddr);
626829Ssam np = dn_addrtonspcb(dstaddr);
636829Ssam if (np == 0) {
646829Ssam no such address, return "no link" message
656829Ssam }
666829Ssam if (np->n_node != srcnode) {
676829Ssam printf("nsp_chkaddr: n_node %d, srcnode %d\n", np->n_node,
686829Ssam scrnode);
696829Ssam m_freem(m);
706829Ssam return (0);
716829Ssam }
726829Ssam /* make sure remote addresses match (consistency check) */
736829Ssam if (np->n_rem != D_SHORT(n->nsp_srcaddr)) {
746829Ssam printf("nsp_chkaddr: n_rem %d, srcaddr %d\n", np->n_rem,
756829Ssam D_SHORT(n->nsp_srcaddr));
766829Ssam m_freem(m);
776829Ssam return (0);
786829Ssam }
796829Ssam ack = D_SHORT(n->nsp_acknum);
806829Ssam if (ack & NSPA_ACK) {
816829Ssam qual = ack & NSPA_QUAL;
826829Ssam num = ack & NSPA_NUM;
836829Ssam printd(", qual 0x%x, num %d", qual, num);
846829Ssam /* make sure there's room for a segnum */
856829Ssam if (m->m_len < sizeof (struct nspd)) {
866829Ssam m_freem(m);
876829Ssam return (0);
886829Ssam }
896829Ssam if (type == NSP_DATA) {
906829Ssam if (SEQ_GTR(num, np->na_rcvdat) &&
916829Ssam SEQ_LEQ(num, np->nn_high)) {
926829Ssam np->n_retrans = 0;
936829Ssam np->nf_remdat -= SEQ_SUB(num, np->na_rcvdat);
946829Ssam }
956829Ssam if (qual == NSPA_NAK || SEQ_LEQ(np->nn_dat, num))
966829Ssam np->nn_dat = SEQ_ADD(num, 1);
976829Ssam np->na_rcvdat = num;
986829Ssam nsp_purgertq(np, type);
996829Ssam } else if (n == np->nn_oth && (np->n_flags&NF_OTHSENT)) {
1006829Ssam if (qual == NSPA_NAK) {
1016829Ssam /* force retransmission of other data seg */
1026829Ssam printf("nsp_chkaddr: NAK other\n");
1036829Ssam } else {
1046829Ssam np->n_flags &= ~NF_OTHSENT;
1056829Ssam np->nn_oth = SEQ_ADD(np->nn_oth, 1);
1066829Ssam if (np->n_flags & NF_OTHINTR) {
1076829Ssam np->n_flags &=
1086829Ssam ~(NF_OTHINTR|NF_INTAVAIL);
1096829Ssam if (np->nb_xmt)
1106829Ssam m_freem(np->nb_xmt);
1116829Ssam } else
1126829Ssam np->nf_locdat = 0;
1136829Ssam nsp_purgertq(np, type);
1146829Ssam }
1156829Ssam }
1166829Ssam *sp = D_SHORT(n->nsp_segnum);
1176829Ssam num = sizeof (struct nspd);
1186829Ssam } else {
1196829Ssam *sp = (u_short)ack;
1206829Ssam num = sizeof (struct nspd) - sizeof (u_short);
1216829Ssam }
1226829Ssam m->m_len -= num;
1236829Ssam m->m_off += num;
1246829Ssam return (np);
1256829Ssam }
126