* "DCP" a uucp clone. Copyright Richard H. Lamb 1985,1986,1987 */ /* original 1-window "g" protocol */ #include "dcp.h" #define PKTSIZE 64 #define PKTSIZ2 2 #define HDRSIZE 6 #define MAXTRY 10 static int pkrec,pksent; /**/ /******************SUB SUB SUB PACKET HANDLER************/ gclosepk() { char tmp[PKTSIZE]; gspack(1,0,0,0,tmp); gspack(1,0,0,0,tmp); return(0); } gopenpk() { int i,j,n1,n2,len; char tmp[PKTSIZE]; pkrec=0; pksent=1; pktsize=PKTSIZE; msgtime=MSGTIME; j=7; gsta: if(j == 4 ) return(0); /* if ok */ for(i=0;i 0) printmsg(" send REJ %d ",pkrec); break; } */ pkrec = (pkrec+1)%8; *len = nlen; gspack(4,pkrec,0,0,tmp); return(0); /*case 2: if(debug > 0) printmsg(" extra REJ %d ",npkrec); return(0); case 4: if(debug > 0) printmsg(" extra RR %d ",npkrec); return(0); case -1: gspack(4,pkrec,0,0,tmp); if(debug > 0) printmsg(" unknown rec packet - send ack "); break; case -2: gspack(2,pkrec,0,0,tmp); if(debug > 0) printmsg(" send REJ %d ",pkrec); break; */ default: break; } } return(-1); } /* * * sendpkt * ***** description: Put at most a packet's worth of data in the pkt state ***** machine for xmission. ***** May have to run the pkt machine a few times to get ***** an available output slot. * * on input: char *data int len,flg; len=length of data in data. * flg=2 just send the packet with no wait for ack. * flg>0 zero out the unused part of the buffer. (for UUCP "msg" * pkts) * flg=0 normal data * return: ret(0) if alls well ret(-1) if problems (fail) * */ gsendpkt(data,len,msg) int len,msg; char data[]; { int nlen,npkrec,npksent,i; char tmp[PKTSIZE]; if(msg) {len=PKTSIZE; for(i=strlen(data);i 0) printmsg(" wrong RR %d (%d) ",pksent,npkrec); break; } */ pksent = (1+pksent)%8; return(0); /*case 2: if(debug > 0) printmsg(" REJ %d ",npkrec); break; case 0: return(0); case -1: break; */ default: break; } } return(-1); } /**/ /*************** FRAMMING *****************************/ /* * * * send a packet * nt2=type nt3=pkrec nt4=pksent len=length<=PKTSIZE cnt1= data * ret(0) always */ gspack(nt2,nt3,nt4,len,cnt1) int nt2,nt3,nt4,len; char cnt1[]; { unsigned int check,i; unsigned char c2,pkt[HDRSIZE]; if(len > 64) len = 64; if(len == 0) cnt1[0] = '\0'; if(debug > 0) { printmsg("send packet type %d",nt2); printmsg(" num = %d n = %d",nt3,nt4); printmsg(" len = %d data =\n|%s|",len,cnt1); } c2 = '\0'; pkt[0] = '\020'; pkt[4] = nt2<<3; nt2 &= 7; switch(nt2) { case 1: break; /* stop protocol */ case 2: pkt[4] += nt3; break; /* reject */ case 3: break; case 4: pkt[4] += nt3; break; /* ack */ case 5: pkt[4] += 3; break; /* 3 windows */ case 6: pkt[4] += 1; break; /* pktsiz = 64 (1) */ case 7: pkt[4] += 3; break; /* 3 windows */ case 0: pkt[4] += 0x80 + nt3 + (nt4<<3); c2 = (PKTSIZE - len)&0xff; if(c2) { pkt[4] += 0x40; /* if len < PKTSIZE */ for(i=PKTSIZE-1;i>0;i--) cnt1[i]=cnt1[i-1]; cnt1[0]=c2; } break; } pkt[4] &= 0xff; if(nt2) { pkt[1] = 9; /* control packet size = 0 (9) */ check = (0xaaaa - pkt[4])&0xffff; } else { pkt[1] = PKTSIZ2; /* data packet size = 64 (2) */ check = checksum(cnt1,PKTSIZE); i = pkt[4];/* got to do this on PC for ex-or high bits */ i &= 0xff; check = (check ^ i) & 0xffff; check = (0xaaaa - check) & 0xffff; } pkt[2] = check & 0xff; pkt[3] = (check>>8) & 0xff; pkt[5] = (pkt[1]^pkt[2]^pkt[3]^pkt[4])&0xff; swrite(pkt,HDRSIZE); /* header is 6-bytes long */ /* write(flog,pkt,HDRSIZE); */ if(pkt[1] != 9) { swrite(cnt1,PKTSIZE); /* data is always 64 bytes long */ /* write(flog,cnt1,PKTSIZE); */ } } /**/ /* * * read packet * on return: nt3=pkrec nt4=pksent len=length <=PKTSIZE cnt1=data * ret(type) ok; ret(-1) input buf empty; ret(-2) bad header; * ret(-3) lost pkt timeout; ret(-4) checksum error;ret(-5) ? */ grpack(nt3,nt4,len,cnt1) int *nt3,*nt4,*len; char cnt1[]; { unsigned int nt1,check,checkchk,i; unsigned char c,c2,pkt[HDRSIZE]; int ii; c = '\0'; while((c & 0x7f) != '\020') if(sread(&c,1,msgtime) < 1) return(-1); if(sread(&pkt[1],HDRSIZE-1,msgtime) < (HDRSIZE-1)) return(-1); /*write(flog,&c,1); write(flog,&pkt[1],HDRSIZE-1); */ /* header is 6-bytes long */ i = pkt[1]^pkt[2]^pkt[3]^pkt[4]^pkt[5]; i &= 0xff; if(i) { /* bad header */ printmsg("****bad header****"); return(-2); } if((pkt[1] &=0x7f) == 9) { /* control packet */ *len = 0; c = pkt[4] & 0xff; nt1 = c>>3; *nt3 = c & 7; *nt4 = 0; check = 0; checkchk = 0; cnt1[*len] = '\0'; } else { /* data packet */ if(pkt[1] != PKTSIZ2) return(-5); /* cant handle other than 64*/ nt1 = 0; c2 = pkt[4] & 0xff; c = c2&0x3f; *nt4 = c>>3; *nt3 = c & 7; if(sread(cnt1,PKTSIZE,msgtime) < PKTSIZE) return(-3); /* write(flog,cnt1,PKTSIZE); */ /* 64 byte packets even if partial */ i = pkt[3]; i = (i<<8)&0xff00; check = pkt[2]; check = i|(check&0xff); checkchk = checksum(cnt1,PKTSIZE); i = pkt[4]|0x80; i &= 0xff; checkchk = 0xaaaa - (checkchk^i); checkchk &= 0xffff; if(checkchk != check) { printmsg("***checksum error***"); return(-4); } *len = PKTSIZE; if(c2&0x40) { ii = (cnt1[0]&0xff); *len = (*len-ii)&0xff; for(ii=0;ii<*len;ii++) cnt1[ii] = cnt1[ii+1]; } cnt1[*len] = '\0'; } if(debug > 0) { printmsg("receive packet type %d ",nt1); printmsg(" num = %d n = %d",*nt3,*nt4); printmsg(" checksum rec = %x comp = %x",check,checkchk); printmsg(" len = %d data =\n|%s|",*len,cnt1); } ii = nt1; return(ii); } unsigned checksum(data,len) int len; char data[]; { unsigned int i,j,tmp,chk1,chk2; chk1 = 0xffff; chk2 = 0; j = len; for(i=0;i