home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 35 Internet / 35-Internet.zip / pktsend.zip / PKTDRVR.C < prev    next >
C/C++ Source or Header  |  1990-08-28  |  5KB  |  214 lines

  1. /* Turbo C Driver for FTP Software's packet driver interface.
  2.  * Graciously donated to the public domain by Phil Karn.
  3.  */
  4. #include <stdio.h>
  5. #include <dos.h>
  6. #include "pktdrvr.h"
  7.  
  8. static int access_type __ARGS((int intno,int if_class,int if_type,int if_number,
  9.     char *type,unsigned typelen,INTERRUPT (*receiver) __ARGS((void)) ));
  10. static int driver_info __ARGS((int intno,int handle,int *version,
  11.     int *class,int *type,int *number,int *basic));
  12. static int release_type __ARGS((int intno,int handle));
  13. static int get_address __ARGS((int intno,int handle,char *buf,int len));
  14. static int get_parameters __ARGS((int intno));
  15. static int send_pkt __ARGS((int intno,char *buffer,unsigned length));
  16.  
  17. static INTERRUPT (*Pkvec[])() = { pkvec0,pkvec1,pkvec2 };
  18. static struct pktdrvr Pktdrvr[PK_MAX];
  19. static int Npk;
  20. static int Derr;
  21. static char Pkt_sig[] = "PKT DRVR";    /* Packet driver signature */
  22.  
  23. char buffer[1514];
  24.  
  25. /* Packet driver receive routine. Called from an assembler hook that pushes
  26.  * the caller's registers on the stack so we can access and modify them.
  27.  * This is a rare example of call-by-location in C.
  28.  */
  29. void
  30. pkint(dev,di,si,bp,dx,cx,bx,ax,ds,es)
  31. int dev;
  32. unsigned short di,si,bp,dx,cx,bx,ax,ds,es;
  33. {
  34.     register struct pktdrvr *pp;
  35.     struct phdr *phdr;
  36.  
  37.     if(dev >= Npk)
  38.         return;    /* Unknown packet */
  39.     pp = &Pktdrvr[dev];
  40.  
  41.     switch(ax){
  42.     case 0:    /* Space allocate call */
  43.         if((pp->buffer = alloc_mbuf(cx+sizeof(struct phdr))) != NULLBUF){
  44.             es = FP_SEG(buffer);
  45.             di = FP_OFF(buffer);
  46.         } else {
  47.             es = di = 0;
  48.         }
  49.         break;
  50.     case 1:    /* Packet complete call */
  51.         enqueue(&Hopper,pp->buffer);
  52.         pp->buffer = NULLBUF;
  53.         break;
  54.     default:
  55.         break;
  56.     }
  57. }
  58.  
  59. /* Test for the presence of a packet driver at an interrupt number.
  60.  * Return 0 if no packet driver.
  61.  */
  62. int
  63. test_for_pd(intno)
  64. unsigned int intno;
  65. {
  66.     long drvvec;
  67.     char sig[8];    /* Copy of driver signature "PKT DRVR" */
  68.  
  69.     /* Verify that there's really a packet driver there, so we don't
  70.      * go off into the ozone (if there's any left)
  71.      */
  72.     drvvec = (long)getvect(intno);
  73.     movblock(FP_OFF(drvvec)+3, FP_SEG(drvvec),
  74.         FP_OFF(sig),FP_SEG(sig),strlen(Pkt_sig));
  75.     return !strncmp(sig,Pkt_sig,strlen(Pkt_sig));
  76. }
  77.  
  78. static int
  79. access_type(intno,if_class,if_type,if_number,type,typelen,receiver)
  80. int intno;
  81. int if_class;
  82. int if_type;
  83. int if_number;
  84. char *type;
  85. unsigned typelen;
  86. INTERRUPT (*receiver)();
  87. {
  88.     union REGS regs;
  89.     struct SREGS sregs;
  90.  
  91.     segread(&sregs);
  92.     regs.h.dl = if_number;        /* Number */
  93.     sregs.ds = FP_SEG(type);    /* Packet type template */
  94.     regs.x.si = FP_OFF(type);
  95.     regs.x.cx = typelen;        /* Length of type */
  96.     sregs.es = FP_SEG(receiver);    /* Address of receive handler */
  97.     regs.x.di = FP_OFF(receiver);
  98.     regs.x.bx = if_type;        /* Type */
  99.     regs.h.ah = ACCESS_TYPE;    /* Access_type() function */
  100.     regs.h.al = if_class;        /* Class */
  101.     int86x(intno,®s,®s,&sregs);
  102.     if(regs.x.cflag){
  103.         Derr = regs.h.dh;
  104.         return -1;
  105.     } else
  106.         return regs.x.ax;
  107. }
  108. static int
  109. release_type(intno,handle)
  110. int intno;
  111. int handle;
  112. {
  113.     union REGS regs;
  114.  
  115.     regs.x.bx = handle;
  116.     regs.h.ah = RELEASE_TYPE;
  117.     int86(intno,®s,®s);
  118.     if(regs.x.cflag){
  119.         Derr = regs.h.dh;
  120.         return -1;
  121.     } else
  122.         return 0;
  123. }
  124. static int
  125. send_pkt(intno,buffer,length)
  126. int intno;
  127. char *buffer;
  128. unsigned length;
  129. {
  130.     union REGS regs;
  131.     struct SREGS sregs;
  132.  
  133.     segread(&sregs);
  134.     sregs.ds = FP_SEG(buffer);
  135.     sregs.es = FP_SEG(buffer); /* for buggy univation pkt driver - CDY */
  136.     regs.x.si = FP_OFF(buffer);
  137.     regs.x.cx = length;
  138.     regs.h.ah = SEND_PKT;
  139.     int86x(intno,®s,®s,&sregs);
  140.     if(regs.x.cflag){
  141.         Derr = regs.h.dh;
  142.         return -1;
  143.     } else
  144.         return 0;
  145. }
  146. static int
  147. driver_info(intno,handle,version,class,type,number,basic)
  148. int intno;
  149. int handle;
  150. int *version,*class,*type,*number,*basic;
  151. {
  152.     union REGS regs;
  153.  
  154.     regs.x.bx = handle;
  155.     regs.h.ah = DRIVER_INFO;
  156.     regs.h.al = 0xff;
  157.     int86(intno,®s,®s);
  158.     if(regs.x.cflag){
  159.         Derr = regs.h.dh;
  160.         return -1;
  161.     }
  162.     if(version != NULL)
  163.         *version = regs.x.bx;
  164.     if(class != NULL)
  165.         *class = regs.h.ch;
  166.     if(type != NULL)
  167.         *type = regs.x.dx;
  168.     if(number != NULL)
  169.         *number = regs.h.cl;
  170.     if(basic != NULL)
  171.         *basic = regs.h.al;
  172.     return 0;
  173. }
  174. static int
  175. get_parameters(intno)
  176. int intno;
  177. {
  178.     union REGS regs;
  179.     struct SREGS sregs;
  180.     char far *param;
  181.  
  182.     regs.h.ah = GET_PARAMETERS;
  183.     int86x(intno,®s,®s,&sregs);
  184.     if(regs.x.cflag){
  185.         Derr = regs.h.dh;
  186.         return -1;
  187.     }
  188.     param = MK_FP(sregs.es, regs.x.di);
  189.     return uchar(param[4]) + 256 * uchar(param[5]);
  190. }
  191. static int
  192. get_address(intno,handle,buf,len)
  193. int intno;
  194. int handle;
  195. char *buf;
  196. int len;
  197. {
  198.     union REGS regs;
  199.     struct SREGS sregs;
  200.  
  201.     segread(&sregs);
  202.     sregs.es = FP_SEG(buf);
  203.     regs.x.di = FP_OFF(buf);
  204.     regs.x.cx = len;
  205.     regs.x.bx = handle;
  206.     regs.h.ah = GET_ADDRESS;
  207.     int86x(intno,®s,®s,&sregs);
  208.     if(regs.x.cflag){
  209.         Derr = regs.h.dh;
  210.         return -1;
  211.     }
  212.     return 0;
  213. }
  214.