home *** CD-ROM | disk | FTP | other *** search
- /* PAPI: Packet driver Common ISDN API
- Author: Dietmar Friede
- Copyright (c) 1992 D.Friede
- #include "copy"
- #include "copying.doc"
- Acknowledgement:
- It was slfp.c, a C-language driver for 8250 slip written by
- Glenn H McGregor, and William A Simpson, which served as a
- skeleton for this file
- */
-
- #define VERSION "0.20 05-Oct-1993"
-
- #include "stdio.h"
- #include <stdlib.h>
- #include <conio.h>
- #include <dos.h>
- #include <mem.h>
- #include <string.h>
- #include "types.h"
- #include "gen.h"
- #include "api.h"
-
- /* Memory layout */
- word _stklen = 2048;
- word _heaplen = 2048;
-
- /* Configuration options & defaults */
- byte ConfPackInt = 0x60;
- struct telno telno= { 0, 0x81, { 0, 0,} };
- struct telno ptelno= { 0, 0x81, { 0, 0,} };
- char status_line[80]= {' '};
- word line= 0;
- byte protokoll= 2;
- byte own_eaz= 2;
- byte headline= 0;
- byte PollInt=0;
- byte ignore=0;
- static unsigned long chrg=0;
- dword InfoMask= 3;
-
- dword IOS_PktIn = 0;
- dword IOS_PktOut = 0;
- dword IOS_ByteIn = 0;
- dword IOS_ByteOut = 0;
- dword IOS_ErrIn = 0;
- dword IOS_ErrOut = 0;
- dword IOS_PktDrop = 0;
- #define IOS_Table IOS_PktIn
-
- /* Packet Driver Hook */
- char PacketDriverHook[17];
- InterruptPtr SavePacketInt;
-
- /* Handle Table */
- typedef void (far *RecvType)(void);
-
- typedef struct
- {
- byte Hand_InUse;
- byte Hand_TypeLen;
- RecvType Hand_Receiver;
- word Hand_TypeVal;
- } HandleType;
-
- HandleType HandleTable;
-
- /* Packet Driver values */
- #define PD_version 0x0010
- #define PDV_basic 1
- #define PDV_extended 2
- #define PDT_any 0xffff
- char PDN_papi[]= "ISDNCAPI";
-
- /* Packet Driver Classes */
- #define PDC_SerialLine 6
-
- /* Function calls */
- enum PD_Functions
- {
- PDF_DriverInfo = 1,
- PDF_AccessType,
- PDF_ReleaseType,
- PDF_SendPkt,
- PDF_Terminate,
- PDF_GetAddress,
- PDF_ResetInterface,
- PDF_GetStatistics = 24,
- };
-
- /* Error codes */
- enum PD_Errors
- {
- PDE_BadHandle = 1,
- PDE_NoClass,
- PDE_NoType,
- PDE_NoNumber,
- PDE_BadType,
- PDE_NoMulticast,
- PDE_CantTerminate,
- PDE_BadMode,
- PDE_NoSpace,
- PDE_TypeInUse,
- PDE_BadCommand,
- PDE_CantSend,
- PDE_CantSet,
- PDE_BadAddress
-
- };
-
- int PassDown (byte *buf, word len);
- void init_passdown(void);
- int api_init (word bsize, word verbose);
- void api_stop(void);
- word dirps(void);
- void restore(word);
- int getopt(int argc, char *argv[], char *optionS);
- word get_Ncci(void);
- extern char *optarg;
- extern int optind;
-
- extern byte capi_int;
- extern word DisTimeout;
- extern struct dlpd dlpd;
-
- void
- PassUp(byte * buf, word len)
- {
- RecvType TempRecv;
- void *TempPtr;
-
- /* ensure a handle to return message on */
- if ( !HandleTable.Hand_InUse )
- {
- IOS_PktDrop++;
- return;
- }
-
- /* ensure receiver hasn't asked for a specific type */
- if ( HandleTable.Hand_TypeLen != 0 )
- {
- IOS_PktDrop++;
- return;
- }
-
- /* get buffer */
- TempRecv = HandleTable.Hand_Receiver;
- if ( TempRecv == NULL )
- {
- IOS_PktDrop++;
- return;
- }
-
- _AX = 0;
- _CX = len;
- _BX = 1;
- TempRecv();
- TempPtr = (void *) MK_FP ( _ES, _DI );
-
- if ( TempPtr == NULL )
- {
- IOS_PktDrop++;
- return;
- }
-
- /* move data into buffer */
- memcpy ( TempPtr, buf, len );
-
- /* pass up to receiver */
- __emit__ ( 0x1E ); /* push ds */
- _DS = FP_SEG ( TempPtr );
- _SI = FP_OFF ( TempPtr );
- _AX = 1;
- _CX = len;
- _BX = 1;
- TempRecv();
- __emit__ ( 0x1F ); /* pop ds */
- }
-
- void
- DriverInfo(IntrRegsType *IntrRegs)
- {
- /* ensure real function */
- if ( IntrRegs->b.al != 0xff )
- {
- IntrRegs->w.fl |= FL_CARRY;
- IntrRegs->b.dh = PDE_BadCommand;
- return;
- }
-
- /* return driver info */
- IntrRegs->w.fl &= ~FL_CARRY;
- IntrRegs->w.bx = PD_version;
- IntrRegs->b.ch = PDC_SerialLine;
- IntrRegs->w.dx = 0xffff;
- IntrRegs->b.cl = 0; /* number */
- IntrRegs->w.ds = FP_SEG(PDN_papi);
- IntrRegs->w.si = FP_OFF(PDN_papi);
- IntrRegs->b.al = PDV_extended;
- }
-
- void
- AccessType(IntrRegsType *IntrRegs)
- {
- /* assume error */
- IntrRegs->w.fl |= FL_CARRY;
-
- /* ensure SerialLine class request */
- if ( IntrRegs->b.al != PDC_SerialLine )
- {
- IntrRegs->b.dh = PDE_NoClass;
- return;
- }
-
- /* ensure proper type request */
- if(IntrRegs->w.bx != PDT_any )
- {
- IntrRegs->b.dh = PDE_NoType;
- return;
- }
-
- /* ensure proper number request */
- if ( ( IntrRegs->b.dl != 0 ) && ( IntrRegs->b.dl != 1 ) )
- {
- IntrRegs->b.dh = PDE_NoNumber;
- return;
- }
-
- /* ensure already not in use */
- if ( HandleTable.Hand_InUse )
- {
- IntrRegs->b.dh = PDE_TypeInUse;
- return;
- }
-
- /* type value length must be <= 8 */
- if ( IntrRegs->w.cx > 8 )
- {
- IntrRegs->b.dh = PDE_BadType;
- return;
- }
-
- /* enter info into handler table entry */
- HandleTable.Hand_InUse = TRUE;
- HandleTable.Hand_Receiver =
- (RecvType) MK_FP ( IntrRegs->w.es, IntrRegs->w.di );
- HandleTable.Hand_TypeLen = IntrRegs->w.cx;
-
- /* all done */
- IntrRegs->w.fl &= ~FL_CARRY;
- IntrRegs->w.ax = 1;
- }
-
- void
- ReleaseType(IntrRegsType *IntrRegs)
- {
- word hand;
-
- hand = IntrRegs->w.bx;
-
- /* ensure good handle */
- if ( hand != 1 )
- {
- IntrRegs->w.fl |= FL_CARRY;
- IntrRegs->b.dh = PDE_BadHandle;
- return;
- }
-
- /* clear table entry */
- HandleTable.Hand_InUse = FALSE;
- HandleTable.Hand_Receiver = (RecvType) NULL;
-
- /* all done */
- IntrRegs->w.fl &= ~FL_CARRY;
- }
-
- void
- SendPkt(IntrRegsType *IntrRegs)
- {
- /* set up */
- IntrRegs->w.fl |= FL_CARRY;
- IntrRegs->b.dh = PDE_CantSend;
-
- if(PassDown((byte *) MK_FP ( IntrRegs->w.ds, IntrRegs->w.si ), IntrRegs->w.cx))
- {
- IOS_ErrOut++;
- return;
- }
-
- /* record stats */
- IOS_PktOut++;
- IOS_ByteOut += IntrRegs->w.cx;
-
- /* all done */
- IntrRegs->w.fl &= ~FL_CARRY;
- }
-
- void
- Terminate(IntrRegsType *IntrRegs)
- {
- union REGS regs;
- struct SREGS sregs;
- int x;
-
- /* restore hardware and interrupts */
- x= dirps();
- api_stop();
- setvect ( ConfPackInt, SavePacketInt );
- restore(x);
-
- /* assume failure */
- IntrRegs->w.fl |= FL_CARRY;
- IntrRegs->b.dh = PDE_CantTerminate;
-
- /* return program block */
- regs.h.ah = 0x49;
- sregs.es = _psp;
- intdosx ( ®s, ®s, &sregs );
- if ( regs.x.cflag != 0 )
- return;
-
- /* return environment block */
- regs.h.ah = 0x49;
- sregs.es = ( (PSP_Ptr) MK_FP ( _psp, 0 ) ) -> PSP_Environment;
- intdosx ( ®s, ®s, &sregs );
- if ( regs.x.cflag != 0 )
- return;
-
- /* all OK */
- IntrRegs->w.fl &= ~FL_CARRY;
- }
-
- void interrupt
- PacketDriver(IntrRegsType IntrRegs)
- {
- enable();
-
- switch ( IntrRegs.b.ah )
- {
- case PDF_DriverInfo:
- DriverInfo ( &IntrRegs );
- break;
- case PDF_AccessType:
- AccessType ( &IntrRegs );
- break;
- case PDF_ReleaseType:
- ReleaseType ( &IntrRegs );
- break;
- case PDF_SendPkt:
- SendPkt ( &IntrRegs );
- break;
- case PDF_Terminate:
- Terminate ( &IntrRegs );
- break;
- case PDF_GetAddress:
- IntrRegs.w.fl &= ~FL_CARRY;
- IntrRegs.w.cx = 0;
- break;
- case PDF_GetStatistics:
- IntrRegs.w.fl &= ~FL_CARRY;
- IntrRegs.w.ds = FP_SEG ( &IOS_Table );
- IntrRegs.w.si = FP_OFF ( &IOS_Table );
- break;
- default:
- IntrRegs.w.fl |= FL_CARRY;
- IntrRegs.b.dh = PDE_BadCommand;
- }
- }
-
- static void
- usage(void)
- {
- printf ( "Usage: papi [-v] [-V] [-x] [-u] [-t] [-T] [-o eaz] -n telno\n"
- " [ -i ] [ -P ] [ -N telno ]\n"
- " [-p PacketIntNo] [-c CAPIIntNo] [-w Timeout] [-s BufSize]\n");
- }
-
- byte
- GetDig ( char ch )
- {
- if ( ( ch >= '0' ) && ( ch <= '9' ) ) return ch - '0';
- else if ( ( ch >= 'A' ) && ( ch <= 'F' ) ) return ch - 'A' + 10;
- else if ( ( ch >= 'a' ) && ( ch <= 'f' ) ) return ch - 'a' + 10;
- else if ( ( ch == 'x' ) || ( ch == 'X' ) ) return 'x';
- else if ( ch == '#' ) return '#';
- else if ( ch == 0 ) return '0';
- else return '?';
- }
-
- dword
- GetNum(void)
- {
- byte state;
- dword base;
- dword num;
- char ch;
- byte digit;
-
- num = 0;
- state = 0;
-
- for (;;)
- {
- ch = *optarg++;
- digit = GetDig ( ch );
- switch ( state )
- {
- case 0:
- if ( digit == 0 )
- {
- base = 8;
- state = 1;
- }
- else if ( digit == '#' )
- {
- base = 16;
- state = 3;
- }
- else if ( digit <= 9 )
- {
- base = 10;
- num = digit;
- state = 2;
- }
- else return ErrInt;
- break;
- case 1:
- if ( digit == 'x' )
- {
- if ( num == 0 )
- {
- base = 16;
- state = 3;
- }
- else return ErrInt;
- }
- else if ( digit <= 9 ) num = num * base + digit;
- else if ( digit == '0' ) return num;
- else return ErrInt;
- break;
- case 2:
- if ( digit == '#' )
- {
- base = num;
- num = 0;
- if ( ( base < 2 ) || ( base > 16 ) )
- return ErrInt;
- state = 3;
- }
- else if ( digit <= 9 ) num = num * base + digit;
- else if ( digit == '0' ) return num;
- else return ErrInt;
- break;
- case 3:
- if ( digit < base ) num = num * base + digit;
- else if ( digit == '0' ) return num;
- else return ErrInt;
- break;
- }
- }
- }
-
- void
- copytelno(struct telno *t, byte *p)
- {
- int i;
-
- for(i=0;*p && (i<15); i++,p++) t->no[i]= *p;
- if(t->no[i-1] == 'S') t->no[i-1]='s';
- if(t->no[i-1] == 's') InfoMask|= 0x40000000;
-
- t->length= i+1;
- t->no[i]= 0;
- }
-
- void
- main ( int argc, char **argv )
- {
- void *HookPtr;
- dword PSize;
- int opt;
- InterruptPtr OldPackInt;
- char PDSig[8];
- word bsize, verbose, notelno, nopassno;
-
- bsize= 2048;
- verbose= 0;
- notelno= 1;
- nopassno= 1;
-
- init_printf();
- while((opt = getopt(argc, argv, "ivxuPtTc:o:n:N:p:w:s:S:V:")) != -1)
- {
- switch ( opt )
- {
- case 'i':
- ignore++;
- break;
- case 'v':
- verbose++;
- break;
- case 'T':
- case 'x': protokoll= 1;
- break;
- case 'u': protokoll= 2;
- break;
- case 't': protokoll= 3;
- break;
- case 'c':
- capi_int = GetNum();
- break;
- case 'p':
- ConfPackInt = GetNum();
- break;
- case 'P':
- PollInt++;
- break;
- case 'o':
- own_eaz = GetNum();
- if((own_eaz < 0) || (own_eaz > 9))
- {
- printf("bad eaz\n");
- usage();
- }
- break;
- case 'n':
- copytelno(&telno, (byte *) optarg);
- notelno= 0;
- break;
- case 'N':
- copytelno(&ptelno, (byte *) optarg);
- nopassno= 0;
- break;
- case 'w':
- DisTimeout = (word) GetNum() * HZ;
- break;
- case 's':
- bsize = (word) GetNum();
- break;
- case 'S':
- dlpd.data_length= (word) GetNum();
- break;
- case 'V':
- headline++;
- line= (word) (GetNum() * 160);
- break;
- case -1: break;
- default:
- usage();
- }
- }
-
- if(notelno)
- {
- printf("No host telefon number\n");
- usage();
- }
- if(nopassno) ptelno= telno;
-
- if(verbose) printf("PAPI: version " VERSION "\n(c) 1992 D.Friede\n");
-
- /* check for packet driver already loaded */
- OldPackInt = getvect ( ConfPackInt );
- movedata(FP_SEG(OldPackInt), FP_OFF(OldPackInt)+3, FP_SEG(PDSig), FP_OFF(PDSig), 8);
- if ( strncmp ( PDSig, "PKT DRVR", 8 ) == 0 )
- {
- printf("Packet driver already loaded at 0x%X\n", ConfPackInt );
- exit(1);
- }
-
- /* clear Handle table */
- HandleTable.Hand_InUse = FALSE;
- HandleTable.Hand_Receiver = (RecvType) NULL;
-
- /* build driver hook */
- memcpy ( PacketDriverHook, "\xEB\x0A\x90PKT DRVR\0\xEA", 13 );
- HookPtr = (void *)PacketDriver;
- memcpy ( &PacketDriverHook[13], &HookPtr, 4 );
-
- /* set up packet driver vector */
- SavePacketInt = getvect ( ConfPackInt );
- setvect ( ConfPackInt, (InterruptPtr) PacketDriverHook );
-
- init_passdown();
- /* initialize isdn capi */
- if(api_init (bsize, verbose))
- {
- int x;
- x= dirps();
- setvect ( ConfPackInt, SavePacketInt );
- restore(x);
- printf("Packet driver not installed\n");
- exit(1);
- }
-
- /* terminate, stay resident */
- PSize= ((byte huge *)MK_FP(_SS,_SP+15)-(byte huge *)MK_FP(_CS,0)) / 16;
- if(verbose) printf("Packet driver loaded at 0x%x size %ldK\n",ConfPackInt,(PSize*16)/1024);
- keep(0, (unsigned)PSize);
- }
-
- int
- accept_con_ind(byte serv, byte serv_add, byte eaz, struct telno *num)
- {
- char *p;
- unsigned l;
- if((serv != 7) || ((eaz-'0') != own_eaz))
- {
- printf("PAPI: bad service %x or bad eaz %c\n",serv,eaz);
- return 0;
- }
- if(serv_add != 0) printf("PAPI: warning: strange additional service byte %x\n",serv_add);
- l= num->length; l--;
- if(l>16) l= 16;
- num->no[l]= 0;
-
- if(ignore == 0)
- if(((p= strstr((char *) num->no,(char *) ptelno.no)) == null) ||
- strcmp((char *) ptelno.no,p))
- {
- printf("PAPI: warning Intruder ? %s\n",num->no);
- return 0;
- }
- if(get_Ncci()>DIAL) return 0;
- for(l=0; l < (num->length-1); l++) status_line[40+l]= num->no[l];
- return 1;
- }
-
- void
- pass_up_info(byte *c, byte s)
- {
- int i,j,ln;
- byte no;
- char *p;
-
- c+= 2;
- no= *c;
- c+= 2;
- ln= *c;
- c++;
- c[ln]= 0;
- p= status_line;
-
- switch(no)
- {
- case 2:
- p+= 20;
- if(s)
- {
- unsigned long n;
- n=++chrg;
- for(i=5; i>= 0; i--,n/=10) p[i]= '0'+(n%10);
- if(n) chrg= 0;
- }
- p+=10;
- c++; ln--;
- if(ln>4) return;
- for(i=0;i<4;i++) p[i]='0';
- if(s==0) return;
- for(i=4-ln,j=0;i<4 ;i++,j++) p[i]=c[j];
- return;
- case 3:
- for(i=0;i<20;i++)p[i]=c[i];
- return;
- }
- }
-