# #include "../h/param.h" #include "../h/user.h" #include "../h/buf.h" #include "../h/net.h" #include "../h/netbuf.h" #include "../h/imp.h" #include "../h/file.h" #include "../h/ncp.h" #include "../h/contab.h" #include "../h/proc.h" #include "../h/src.h" /* defines for dealing with host to host protocol */ #define hhnop 0 /* nop */ #define hhall 4 /* allocate */ #define hhinr 7 /* interrupt by receiver */ #define hhins 8 /* interrupt by sender */ char hhsize[14]; char host_map[32]; /*name: flushimp function: increment number of imp flushes and reload imp interface with buffer to dump data into algorithm: set impflushing flag handle statistics reload imp interface with black hole parameters: none returns: nothing globals: impflushing= imp_stat.i_flushes= calls: emerbuf to get address of black hole impread to load imp interface with address of hole called by: imp_input hh history: initial coding 1/7/75 by Steve Holmgren */ flushimp() { /* repeatedly called when we want imp interface cleaned out */ impflushing = 1; imp_stat.i_flushes++; impread( emerbuf(),net_b_size ); } /*name: ihbget function: To reload the imp interface with a buffer to store data into algorithm: If a buffer is available set impmsg to address call impread to reload imp interface registers else couldnt get a buffer start flushing data parameters: none returns: nothing globals: impmsg= calls: appendb to add another buffer to impmsg impread to load imp interface registers flushimp to flush imp data if couldnt get buffer called by: imp_input hh history: initial coding 1/7/75 by Steve Holmgren */ ihbget() /* stands for imp host buffer getter */ { register struct netbuf *bp; /* called when there is data to buffer from the imp */ /* appendb returns 0 if cant get buffer */ if( bp=appendb( impmsg ) ) { impmsg = bp; impread( bp->b_data,net_b_size ); } else { printf("flush bfr\n"); flushimp(); } } /* */ struct salloc /* structure to lay over an allocate command */ { char a_op; char a_link; int a_msgs; int a_bitshi; int a_bitslo; }; /*name: hh1 function: To search through host to host protocol messages strip out any that apply to the user ( allocates for now ) algorithm: loops thru looking for hh commands in IMPMSG it copies a command at a time to HHPROTO, process the protocol if it is an allocate, inr, or ins. If it is none of the above, it is stuck in an output message. once all of the input has been messed with, if there is an output message it is sent to the ncpdaemon with our blessing. parameters: none returns: nothing globals: impmsg implen hhsize[] impncp calls: allocate to deal with allocate commands rcvd from net to_ncp to send uninteresting protocol to ncpdaemon ipc_trans to send ins or inr psignal if old style i/o to send ins or inr called by: hh history: initial coding 1/7/75 by Steve Holmgren modified to send events when ins or inr arrives 12/8/76 by David Healy re-written (the pile before had mucho bugs) Feb 1977 S. F. Holmgren */ hh1() { register char hhcom; register cnt; register char *sktp; static char *daemsg; static char hhproto[96]; daemsg = 0; while( implen > 0 ) /* while things in msg */ { hhcom = (impmsg->b_qlink)->b_data[0] & 0377; if( hhcom > NUMHHOPS ) { daemsg = catmsg( daemsg,impmsg ); goto fordaemon; } cnt = hhsize[ hhcom ]; /* get bytes in this command */ implen =- cnt; /* decrement implen */ if( bytesout( &impmsg,&hhproto,cnt,1 )) /* msg not long enough */ { printf("imp bad protocol msg\n"); implen = 0; /* force msg empty */ continue; } else if( hhcom == hhall && (sktp=imphostlink( hhproto[1]|0200 )) ) { allocate( sktp,&hhproto ); continue; } else if( hhcom == hhins && (sktp=imphostlink( hhproto[1]&0177 )) ) { if( &proc[sktp->r_pid]->p_stat ) /* there ? */ { if( sktp->r_flags&n_nbio ) ipc_trans( SRC_INS | ( 1 << 8 ), sktp->r_pid,sktp->r_ufid,0 ); else psignal( &proc[sktp->r_pid],SIGINR ); } continue; } else if( hhcom == hhinr && (sktp=imphostlink( hhproto[1]|0200 )) ) { if( &proc[sktp->r_pid]->p_stat ) { if( sktp->w_flags&n_nbio ) ipc_trans( SRC_INR | ( 1 << 8 ),sktp->w_pid,sktp->w_ufid,0 ); else psignal( &proc[sktp->w_pid],SIGINR ); } continue; } else if( hhcom == hhnop ) continue; vectomsg( &hhproto,cnt,&daemsg,1 ); /* got here then give it to daemon */ } if( daemsg != 0 ) /* something in msg */ fordaemon: to_ncp( impncp,5,daemsg ); /* send to daemon */ } /*name: allocate function: To look over host to host allocate protocol messages . determine whether they are going to ncpdaemon or user send off to ncpdaemon, inc appropriate user fields. algorithm: if host_link in conn tab if socket flags say to ncpdaemon send to ncpdaemon with imp to host leader else update num of messages alocated update number of bits allocated tell user allocate came in let user run parameters: allocp pointer to a host host allocate returns: nothing globals: impncp sktp->w_msgs= sktp->w_falloc= sktp->w_flags= calls: imphostlink to get pointer to socket inode from host link vectomsg to build a msg from vec passed to send to ncp daemon to_ncp to ship the allocate off to the ncp daemon dpadd (sys) to add two double precision words wakeup (sys) to let the user run called by: hh1 history: initial coding 1/7/75 by Steve Holmgren modified to implement nbio 12/8/76 by Dave Healy */ allocate( skt_ptr,allocp ) struct wrtskt *skt_ptr; { /* called from hh1 when a hh allocate is received */ register char *ap; register struct wrtskt *sktp; int nbytes; /* allocation */ struct netbuf *msgp; sktp = skt_ptr; ap = allocp; msgp = 0; if (sktp->w_flags & n_toncp) { vectomsg( allocp,8,&msgp,1 ); to_ncp( impncp,5,msgp ); } else { sktp->w_msgs =+ swab( ap->a_msgs ); dpadd(sktp->w_falloc,swab(ap->a_bitslo)); sktp->w_falloc[0] =+ swab( ap->a_bitshi ); sktp->w_flags =| n_allocwt; if ((sktp -> w_flags & n_waiting) == 0) { if( (sktp->w_flags&n_open) == 0 ) return; if ((sktp -> w_flags & n_event) && ((nbytes = anyalloc (sktp)) != 0)) { sktp -> w_flags =& ~n_event; ipc_trans (SRC_WRITE | (1 << 8), sktp -> w_pid, sktp -> w_ufid, nbytes); } else wakeup( sktp ); } } } /*name: rmovepad function: To remove the padding attached to every host host protocol msg and standard message by the imp algorithm: given a bytesize in number of bytes in that size, calculate the number of 8 bit bytes. set the message length to that size run through the message a buffer at a time subtracting the buffer length from the calculated size. eventually it will go negative, since the number of bytes calculated is less that the actual number of bytes in the msg subtract the number of pad bytes from the last buffer in the message to setthe number of actual number of data bytes then free any remaining buffers. set impmsg to the new last buffer. parameters: none returns: nothing globals: implen= impmsg= calls: swab (sys) to switch top and bottom bytes freebuf to release the last buffer from the message called by: hh history: initial coding 1/7/75 by Steve Holmgren */ int last_nbytes; rmovepad() { /* calculates number of bytes from impleader then runs through impsg buffers adding up counts until number calculated or end of msg is reached. sets impcnt tothe min of amt in msg and calculated and discards any excess bytes */ register struct netbuf *bfrp; register cnt; impmsg = bfrp = impmsg->b_qlink; /* point at first bfr */ implen = swab( imp.bcnt ); /* get num bytes */ cnt = imp.bsize * implen; /* calc number of bits */ cnt = ( cnt+7 ) / 8; while( (cnt =- bfrp->b_len) > 0 ) { if( bfrp->b_qlink == impmsg ) /* wrapped around? */ { printf("imp msg wrap\n"); break; } bfrp = bfrp->b_qlink; } if( cnt < 0 ) bfrp->b_len = (bfrp->b_len & 0377) + cnt; while( bfrp->b_qlink != impmsg ) freebuf( bfrp ); impmsg = bfrp; if( cnt > 0 ) /* didnt eat them all? */ { printf("IMP: missing %d data bytes\n",cnt); return(1); } return(0); } /*name: imphostlink function: Checks to see if the current host and link are in the connection table (conn tab). Checks to see if the socket is open, if so returns a pointer to the socket. If not in conn tab or socket not open returns zero algorithm: if host link in conn tab if skt open return socket ptr return zero parameters: link link to be checked with current host returns: zero if not in conn tab or socket not open socket ptr if in conn tab and socket open globals: imp.host sktp->r_flags calls: incontab to see if host link is in conn tab called by: imp_input siguser allocate history: initial coding 1/7/75 by Steve Holmgren */ imphostlink( link ) char link; { register sktp; if( sktp = incontab( ((imp.host<<8) | (link & 0377)),0 )) { sktp = sktp->c_siptr; /* contab returns ptr to entry must get skt pointer */ return( sktp ); } return( 0 ); }