/* server.c */ #define TCPIPMASTER /* * Includes */ #include #include #include "vtcpip.h" #include "dfault.h" #include "evtdef.h" #include "hstdef.h" #include "prodef.h" #include "prodat.h" #include "tcpdat.h" #include "server.h" #include "srvutl.h" #include "termio.h" #include "inisrv.h" #include "suspnd.h" #include "datime.h" #define DBUGTRUE -1 static char *usetxt[] = { "", #ifdef DEBUGOPTION " TCPIP [?] [-d level] [-f filename]", " ? List this Help Text and Exit TCPIP", " d level Debug Level", " 1 - enable event printing", " 2 - enable packet type printing", " 4 - enable general packet dumping to disk", " 8 - enable ntsleep process printing", " 16 - enable transq sequence printing", " 32 - enable arp/rarp packet dumping to disk", " 64 - enable udp packet dumping to disk", " 128 - enable icmp packet dumping to disk", " 256 - enable tcp packet dumping to disk", " Enter level as sum of debug values", #else " TCPIP [?] [-f filename]", " ? List this Help Text and Exit TCPIP", #endif " f filename Configuration File", "", 0 }; extern Sreadhosts(); extern fndbrk; static FILE *logfp = NULL; /* * main - main procedure. Displays opening message, parses arguments, * initializes network, reads user commands and executes them, and * cleans up. */ main(argc,argv) int argc; char *argv[]; { int c,i,j,k; /* * Initialize for TSX+ servers */ inisrv(); /* * Initialize tt handler * Set the break character to ^C */ tt_init(0x03); /* * identify self */ printtxt(vrstxt); /* * parse arguments */ for(i=1; i TCPIP message events * - SYSTEM -> TCPIP job terminations * - network events */ int dosess() { register struct socket *skt; register struct machinfo *mp; char s[80]; register int i; int cl,ev,dat,jobnum,sknum; /* * Check for any relevant events * that need to be handled by me */ ev = Sgetevent(USERCLASS | CONCLASS | SCKTCLASS | TCPCLASS | MSGCLASS | ERRCLASS | ABORTCLASS | SCKTABORT | SRVCCLASS | SRVCATTACH | SRVCABORT, &cl, &dat); if(ev!=0) { switch(cl) { case SCKTCLASS: switch(ev) { case REQSCKT: /* request a TCPIP socket */ sknum = makesocket(dat); if(sknum<0) { ntptevent(ERRCLASS,500,-1); sv_xmit(dat,ERRCLASS,500,-1); } sv_xmit(dat,SCKTCLASS,USRSCKT,sknum); break; default: break; } break; case SCKTABORT: /* abort the socket connection */ skt = (struct socket *) skvalid(dat); if(skt==-1) break; if(ev == sktlist[dat].jobnum) { sktlist[dat].inport = sktlist[dat].outport = sktlist[dat].jobnum = 0; for(i=0; i<4; i++) sktlist[dat].remoteip[i] = '\0'; skt->state = SCLOSED; } break; case TCPCLASS: skt = (struct socket *) skvalid(dat); if(skt==-1) break; jobnum = sktlist[dat].jobnum; if(jobnum>0) { switch(ev) { case REQCONNECT: /* request a connection */ addsess(dat,skt->request); break; case REQLISTEN: /* request to listen */ ntlisten(dat); break; case CLOSING: /* closing connection */ ntclose(dat); if(skt->state==SCLOSED) { sktlist[dat].jobnum = 0; } break; case DEQUEUE: /* read activated */ skt->in.rdptr = skt->in.queue; if(skt->in.rdptr==skt->in.wtptr || (skt->in.size<=LOWWATER && inroom(skt)>=QUEUESIZE-LOWWATER)) { skt->out.lasttime = 0L; } break; case ENQUEUE: /* write activated */ if(skt->out.wtptr!=skt->out.queue) { if(skt->out.wtptr==skt->out.rdptr) { skt->out.lasttime = 0L; } skt->out.wtptr = skt->out.queue; } break; case LOGSESSION: /* log the session */ if(logfp != NULL) { logprocess(skt); } break; default: break; } } break; case SRVCATTACH: /* attach to a service */ skt = -1; jobnum = -dat; for(i=0; istate == SEST) ntptuev(CONCLASS,CONOPEN,i); break; } } if(skt==-1) sv_xmit(jobnum,SRVCCLASS,ATTACHED,-1); break; case SRVCABORT: /* abort attach request */ for(i=0; i0) { sv_xmit(jobnum,cl,ev,dat); } break; case USERCLASS: /* domain class */ skt = (struct socket *) skvalid(dat); if(skt==-1) break; jobnum = sktlist[dat].jobnum; if(jobnum>0) { switch(ev) { case DOMFAIL: ntptevent(ERRCLASS,16,dat); sv_xmit(jobnum,CONCLASS,CONFAIL,dat); break; case DOMOK: mp = skt->mpp; if(mp) { ntptevent(MSGCLASS,17,dat); if(mp->sname) { if(mp->port!=skt->sktport) { sprintf(s,"%s #%u",mp->sname,mp->port); mp->port = skt->sktport; addsess(dat,s); } else { addsess(dat,mp->sname); } } else { if(mp->port!=skt->sktport) { sprintf(s,"%s #%u",mp->hname,mp->port); mp->port = skt->sktport; addsess(dat,s); } else { addsess(dat,mp->hname); } } } else { ntptevent(ERRCLASS,16,dat); sv_xmit(jobnum,CONCLASS,CONFAIL,dat); } break; default: break; } } break; case MSGCLASS: /* message class */ printf("MSGCLASS #%s\n", nterrstring(ev)); break; case ERRCLASS: /* error class */ printf("ERRCLASS #%s\n", nterrstring(ev)); break; case ABORTCLASS: /* abort class */ printf("ABORTCLASS: "); switch(ev) { case CLIENT: printf("Terminating Client Sessions\n"); ntabort(); break; case SERVER: fndbrk = 1; break; default: break; } break; default: break; } } return(ev); } /* * addsess * * Add a session to a named machine */ int addsess(sknum,st) int sknum; char *st; { register struct machinfo *mp; int i,jobnum,new,pflag,port; jobnum = sktlist[sknum].jobnum; if(st==NULL) { ntptevent(ERRCLASS,10,sknum); sv_xmit(jobnum,CONCLASS,CONFAIL,sknum); return(-1); } pflag = 0; port = 0; /* * Find out what port to open to */ for (i=0; (st[i]!=' ') && (st[i]!='#') && (st[i]!='\0'); i++); if((st[i]==' ') || (st[i]=='#')) { st[i++] = '\0'; for( ; (st[i]==' ') || (st[i]=='#') ; i++); new = i; for( ; (st[i]!='\0') && isdigit(st[i]) ; i++); if((st[i]=='\0') && (new!=i)) { pflag = 1; port = (unsigned int)atoi(&st[new]); } } mp = Sgethost(sknum,st); /* gain access to host information */ errhandle(sknum); if(!mp) { if(pflag) /* Append port number */ sprintf(&st[strlen(st)]," #%u",port); i = Sdomain(sknum,st); if(i>=0) { /* Querying the DOMAIN name server */ ntptevent(MSGCLASS,11,sknum); } else { /* Some error */ ntptevent(ERRCLASS,-i,sknum); sv_xmit(jobnum,CONCLASS,CONFAIL,sknum); return(-1); } } else { /* * Trying to open TCP connection */ ntptevent(MSGCLASS,14,sknum); if(!pflag) port = mp->port; /* * try to serve the request */ if(0>Snetopen(sknum,port)) { /* * Could not open new connection */ ntptevent(ERRCLASS,15,sknum); sv_xmit(jobnum,CONCLASS,CONFAIL,sknum); errhandle(sknum); return(-1); } } return(0); } /* * errhandle * * check for error messages */ VOID errhandle(sknum) int sknum; { register char *errmsg; int cl,ev,dat; while((ev = Sgetevent(ERRCLASS|MSGCLASS,&cl,&dat))!=0) { switch(cl) { case MSGCLASS: /* message class */ printf("MSGCLASS #%s\n", nterrstring(ev)); break; case ERRCLASS: /* error class */ printf("ERRCLASS #%s\n", nterrstring(ev)); break; default: break; } } /* * Restore the socket mapping after Sgetevent */ mapskt(sknum); } /* * Open the TCPIP LOG file */ VOID tcplog(fname) char *fname; { logfp = fopen(fname,"w"); } /* * Log the Process */ VOID logprocess(skt) struct socket *skt; { register char *xxip; /* * Get Current Date and Time */ fprintf(logfp,"%s ", datime()); /* * Machines Communicating */ xxip = skt->tcpout.i.ipsource; fprintf(logfp,"[%d.%d.%d.%d] <<-", *(xxip+0)&0xFF, *(xxip+1)&0xFF, *(xxip+2)&0xFF, *(xxip+3)&0xFF); xxip = skt->tcpout.i.ipdest; fprintf(logfp,"->> [%d.%d.%d.%d]\n", *(xxip+0)&0xFF, *(xxip+1)&0xFF, *(xxip+2)&0xFF, *(xxip+3)&0xFF); /* * Logging String */ fprintf(logfp,"%s\n\n", &skt->request); } /* * printout text */ VOID printtxt(txt) char **txt; { char **dp; for (dp = txt; *dp; dp++) { printf("%s\n", *dp); } }