TheNetNode-CB/src/l1tcpip.c

2301 lines
81 KiB
C
Executable File
Raw Blame History

#include "tnn.h"
#ifdef L1TCPIP
T_INTERFACE ifp[MAXINTERFACE]; /* Interface-Liste. */
LHEAD tcpfrel; /* Liste der freien Linkbloecke */
LHEAD tcpactl; /* Liste der aktiven Linkbloecke. */
LHEAD tcptatl;
LHEAD rxflRX; /* Empfangsliste */
LHEAD rxflTX; /* Sendeliste */
TCPIP *tcppoi; /* "link pointer", globaler Zeiger auf */
/* den gerade aktuellen Linkblock */
TCPIP *tcptbl; /* "link table", fuer jeden moeglichen */
/* TCPIP Eintrag */
struct Sockaddr_in Myaddr_in;
struct Sockaddr_in Peeraddr_in;
static T_INTERFACE *ifpp; /* Zeiger auf das aktuelle Interface */
UWORD nmbtcp; /* Anzahl aktiver TCPIP-Links */
UWORD nmbtcp_max; /* Maximale anzahl der TCPIP-Links */
int tcp_tbl_top = 0; /* Zaehler fuer aktive TCP-User. */
static BOOLEAN CheckSocket(void); /* Pruefe, ob Socket aktiv ist. */
void InitTCP(void) /* TCPIP initialisieren. */
{
int i;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(InitTCP)";
#endif /* DEBUG_MODUS */
inithd(&tcptatl);
inithd(&tcpactl);
inithd(&tcpfrel);
inithd(&rxflRX);
inithd(&rxflTX);
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi)
{
tcppoi->ip[0] = 0;
tcppoi->rxbuf[0] = 0;
tcppoi->txbuf[0] = 0;
tcppoi->cmd[0] = 0;
tcppoi->sock = 0;
tcppoi->Upcall[0] = 0;
tcppoi->Downcall[0] = 0;
tcppoi->disflg = 0;
tcppoi->port = 0;
tcppoi->noacti = 0;
tcppoi->T3 = 0;
tcppoi->inlin = 0;
tcppoi->outlin = 0;
tcppoi->activ = 0;
tcppoi->login = 0;
tcppoi->cmdlen = 0;
tcppoi->RecvLen = 0;
tcppoi->rxc = 0;
tcppoi->txc = 0;
tcppoi->sum = 0;
tcppoi->LoginPrompt = 0;
tcppoi->state = L2MNIX;
tcppoi->cr = 0;
tcppoi->txstatus = 0;
tcppoi->Interface = 0;
#ifdef L1HTTPD
tcppoi->status = 0;
tcppoi->http = 0;
tcppoi->fp = NULL;
#endif /* L1HTTPD */
#ifdef L1IPCONV
tcppoi->CVSlink = FALSE;
tcppoi->Intern = FALSE;
#ifdef L1IRC
tcppoi->IrcMode = FALSE;
#endif /* IRC */
#endif /* L1IRC */
inithd(&tcppoi->inbuf);
inithd(&tcppoi->outbuf);
resptc(g_uid(tcppoi, TCP_USER));
relink((LEHEAD *)tcppoi, (LEHEAD *)tcpfrel.tail);
}
nmbtcp = nmbtcp_max = FALSE; /* TCPIP User/link zaehler. */
}
void InitIFC(void) /* Interface Initialisierung */
{
register int Interface;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(InitIFC)";
#endif /* DEBUG_MODUS */
/* alle Interface durchgehen und */
for (Interface = 0; Interface < MAXINTERFACE; Interface++)
{ /* Initialisieren. */
ifpp = &ifp[Interface]; /* Zeiger auf auf das akt. Interface. */
ifpp->actively = FALSE; /* Interface deaktiv */
ifpp->l2port = EOF; /* L2-Port. */
ifpp->OsSock = 0; /* OS-Socket . */
ifpp->ISock = 0; /* Interne Socket. */
ifpp->log = 0; /* Loglevel. */
#ifdef L1TELNET
if (Interface == TEL_ID)
{
ifpp->Interface = KISS_TELNET;
ifpp->tcpport = Htons(DEFAULT_TELNET_PORT); /* Default TCP-Port setzen. */
strncpy(ifpp->name, "TELNET", 10);/* Interface Name setzen. */
}
#endif /* L1TELNET */
#ifdef L1HTTPD
if (Interface == HTP_ID)
{
ifpp->Interface = KISS_HTTPD; /* HTTPD-Interface. */
ifpp->tcpport = Htons(DEFAULT_HTTPD_PORT);/* Default TCP-Port setzen. */
strncpy(ifpp->name, "HTTPD", 10); /* Interface Name setzen. */
}
#endif /* L1HTTPD */
#ifdef L1IPCONV
if (Interface == CVS_ID)
{
ifpp->Interface = KISS_IPCONV;
ifpp->tcpport = Htons(DEFAULT_IPCONV_PORT); /* Default TCP-Port setzen. */
strncpy(ifpp->name, "IPCONV", 10);/* Interface Name setzen. */
}
#endif /* L1IPCONV */
#ifdef L1IRC
if (Interface == IRC_ID)
{
ifpp->Interface = KISS_IRC;
ifpp->tcpport = Htons(DEFAULT_IRC_PORT); /* Default TCP-Port setzen. */
strncpy(ifpp->name, "IRC", 10); /* Interface Name setzen. */
}
#endif /* L1IRC */
}
}
T_INTERFACE *SearchIf(UWORD Interface) /* Das gesuchte Interface ermitteln */
{ /* und den Interfacezeiger setzen. */
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SearchIf)";
#endif /* DEBUG_MODUS */
switch(Interface)
{
#ifdef L1TELNET
case KISS_TELNET: /* TELNET Interface. */
ifpp = &ifp[TEL_ID]; /* Interfacezeiger setzen. */
break;
#endif /* L1TELNET */
#ifdef L1HTTPD
case KISS_HTTPD: /* HTTPD Interface. */
ifpp = &ifp[HTP_ID]; /* Interfacezeiger setzen. */
break;
#endif /* L1HTTPD */
#ifdef L1IPCONV
case KISS_IPCONV: /* TELNET Interface. */
ifpp = &ifp[CVS_ID]; /* Interfacezeiger setzen. */
break;
#endif /* L1IPCONV */
#ifdef L1IRC
case KISS_IRC: /* IRC Interface. */
ifpp = &ifp[IRC_ID]; /* Interfacezeiger setzen. */
break;
#endif /* L1IPCONV */
default: /* kein Interface gefunden. */
return(NULL);
}
return(ifpp); /* Aktuelles Interface liefern. */
}
/* Schliesse aktuellen Socket. */
static BOOLEAN CloseSockTCP(BOOLEAN ALL, WORD Interface)
{
int i,
j = FALSE;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CloseSockTCP)";
#endif /* DEBUG_MODUS */
#ifdef OS_STACK
if (tcppoi->mode == OS_MODE)
return(CloseSockOS(ALL, Interface));
#endif /* OS_STACK */
if (ALL == TRUE) /* ALLE Socket-Verbindungen schliessen. */
{
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi)/* TBL durchgehen*/
{
if ( Interface == tcppoi->Interface /* Interfacevergleich */
&& tcppoi->sock > TRUE) /* Socket ist aktiv. */
{
Close(tcppoi->sock); /* Socket schliessen. */
DiscTCP(); /* TCPIP-User/link aus der Liste raushaengen */
} /* bzw. Parameter wieder auf 0 setzen. */
if ( ((tcppoi->activ) /* Sind alle aktiven Sockets durchlaufen, */
&& (j++ >= tcp_tbl_top))
|| (j == tcp_tbl_top))
return(FALSE); /* brechen wir ab. */
}
}
Close(tcppoi->sock); /* Socket schliessen. */
DiscTCP(); /* TCPIP-User/Link aus der Liste raushaengen */
return(FALSE); /* bzw. Parameter wieder auf 0 setzen. */
}
void L1ExitTCP(WORD Interface) /* TCPIP-Interface schliessen. */
{
T_INTERFACE *ifpoi;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(L1ExitTCP)";
#endif /* DEBUG_MODUS */
#ifdef OS_STACK
L1ExitOS(Interface);
#endif /* OS_STACK */
if ((ifpoi = SearchIf(Interface)) == NULL) /* Zeiger auf das akt. Interface.*/
return; /* Aktuelles Interface ist deaktiv, */
/* dann zum naechsten Interface. */
if (ifpoi->actively == TRUE) /* Nur wenn Interface aktiv. */
CloseSockTCP(TRUE, ifpoi->Interface); /* Alle TCPIP-Verbind. schliessen.*/
if ((signed)ifpoi->ISock > FALSE) /* TCPIP-Socket schliessen wenn offen */
Close(ifpoi->ISock); /* Schliesse Socket. */
ifpoi->ISock = EOF;
ifpoi->actively = FALSE; /* Markiere TCPIP-Interface als deaktiv*/
T_LOGL1(TRUE, "(L1ExitTCP):\nInterface ist deaktiviert!\n");
}
/* Aktive Socket's setzen. */
static void PutSocketTCP(Fd_set *Rmask, /* Socket-liste. */
int *maxI) /* Socket-Wert. */
{
register int i;
int j = 0;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(PutSocketTCP)";
#endif /* DEBUG_MODUS */
/* TCPIP-User/Links durchgehen. */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi)
{
if (tcppoi->sock) /* Nur wenn Socket aktiv! */
{
if (CheckSocket()) /* Pruefe, ob Socket aktiv ist. */
{
CloseSockTCP(FALSE, tcppoi->Interface); /* Schliesse Socket. */
continue; /* Zum naechsten Socket. */
}
if (tcppoi->mode) /* Interner Stack. */
{
FD_SET_T((unsigned)tcppoi->sock, Rmask); /* Socket setzen. */
if (tcppoi->sock > *maxI - 1)
*maxI = tcppoi->sock + 1;
}
}
if ( ((tcppoi->activ) /* Sind alle aktiven Sockets durchlaufen, */
&& (j++ >= tcp_tbl_top))
|| (j == tcp_tbl_top))
break; /* brechen wir ab. */
}
}
/* Portinfo-String fuer den PORT-Befehl.*/
void HwstrTCP(UWORD Interface, /* Aktuelle Interface. */
int port, /* L2Port */
MBHEAD *mbp) /* Buffer */
{
T_INTERFACE *ifpoi;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(HwstrTCP)";
#endif /* DEBUG_MODUS */
if ((ifpoi = SearchIf(Interface)) == NULL) /* Zeiger auf das akt. Interface.*/
return; /* Ungueltiges Interface. */
putstr(" ", mbp);
putprintf(mbp,"%u", Ntohs(ifpoi->tcpport));
}
/* TCPIP-Port Initialisieren. */
BOOLEAN L1InitTCP(UWORD Interface, /* Aktuelle Interface. */
int port, /* L2Port */
int TCPPort) /* TCP-Port. */
{
T_INTERFACE *ifpoi;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(L1InitTCP)";
#endif /* DEBUG_MODUS */
if ((ifpoi = SearchIf(Interface)) == NULL) /* Zeiger auf das akt.Interface.*/
return(FALSE); /* Interface ist belegt. */
if (ifpoi->actively == TRUE) /* Interface ist altiv */
return(FALSE); /* Kann Filedescriptor nicht anlegen. */
if ( (TCPPort < 1)
||(TCPPort > 65535))
return(FALSE);
/* Einen neuen Filedescriptor anlegen. */
if ((ifpoi->ISock = SetupTCP(ifpoi->name, Htons((unsigned short)TCPPort))) == EOF)
return(FALSE); /* Kann Filedescriptor nicht anlegen. */
#ifdef OS_STACK
if (L1InitOS(Interface, port, (unsigned short)TCPPort) == FALSE)
return(FALSE);
#endif /* OS_STACK */
ifpoi->l2port = port; /* L2-Port setzen. */
ifpoi->actively = TRUE; /* Markiere Interface als aktiv. */
ifpoi->tcpport = TCPPort; /* Markiere TCP-Port. */
return(TRUE); /* Socket wurde erfolgreich erstellt. */
}
/* Einen Filedescriptor anlegen. */
int SetupTCP(char *name, /* Interface-Name. */
unsigned short tcp_port) /* Neuer TCP-Port. */
{
int tmp_fd = EOF; /* Temporaerer Filedescriptor */
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SetupTCP)";
#endif /* DEBUG_MODUS */
if (tcp_port == FALSE) /* Kein Port angegeben. */
{
T_LOGL1(TRUE, "(SetupTCP):\nKein TCP-Port angegeben.\n");
return(EOF); /* Abbruch. */
}
memset(&Myaddr_in, 0, sizeof(Myaddr_in)); /* Adressstruktur loeschen */
memset(&Peeraddr_in, 0, sizeof(Peeraddr_in));
Myaddr_in.sin_family = AF_INET; /* Adressstruktur fuellen */
Myaddr_in.sin_port = Htons(tcp_port); /* TCP-Port setzen. */
Myaddr_in.sin_addr._S_addr = INADDR_ANY; /* Jedes Netzwerk Geraet abfragen. */
/* Socket erstellen. */
if ((tmp_fd = Socket(AF_INET, SOCK_STREAM, 0)) == EOF)
{
printf("Error %s: Socket cannot be constructed!\r", ifpp->name);
T_LOGL1(TRUE, "(SetupTCP):\nNeuer Socket kann nicht geoeffnet werden.\n");
return(EOF); /* Keine freien Socket's. */
}
/* Bind Initialisieren. */
if (Bind (tmp_fd, (struct Sockaddr *) &Myaddr_in, sizeof (struct Sockaddr_in)) == EOF)
{
printf("Error %s: Bind cannot be initialized!\n", ifpp->name);
Close(tmp_fd); /* Schliesse Socket. */
T_LOGL1(TRUE, "(SetupTCP):\nBind Initialisierung fehlgeschlagen.\n");
return(EOF); /* Fehler beim Bind . */
}
if (Listen (tmp_fd, 3) == EOF) /* Listen Initialisieren. */
{
printf("Error %s: listen cannot be initialized!\n", ifpp->name);
Close(tmp_fd); /* Schliesse Socket. */
T_LOGL1(TRUE, "(SetupTCP):\nListen Initialisierung fehlgeschlagen.\n");
return(EOF); /* Fehler beim Listen. */
}
T_LOGL1(TRUE, "(SetupTCP):\nTCP-Port (%d) erfolgreich gesetzt.\n"
, Ntohs(tcp_port));
return(tmp_fd); /* Aktuelle Filedescriptor. */
}
void L1ctlTCP(int req, int port) /* Level 1 Kontrolle */
{
testflag[port] = 0; /* Kein TEST-Frame zulassen. */
kick[port] = 0;
}
BOOLEAN TcpDCD(int l2port) /* DCD-Status bei TCPIP ist immer FALSE. */
{
return(FALSE);
}
/* Defaultwerte setzen. */
void SetDefaultWorthTCP(unsigned sock, /* Neuer Socket. */
char *ip, /* IP-Adresse. */
int l2port, /* L2-Port. */
UWORD Interface, /* TCP-Interface. */
BOOLEAN Mode) /* Interner TCP-Stack */
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SetDefaultWorthTCP)";
#endif /* DEBUG_MODUS */
strncpy(tcppoi->ip, ip, IPADDR); /* IP-Adresse eintragen. */
tcppoi->port = l2port; /* L2-Port setzen. */
tcppoi->activ = TRUE; /* Markiere aktiv. */
tcppoi->sock = sock; /* Aktuellen Socket setzen. */
tcppoi->mode = Mode; /* Mode setzen. (Int/Ext.) */
tcppoi->cmdlen = 0; /* Zaehler fuer cmd-Buffer. */
tcppoi->inlin = 0; /* eingelaufene Zeilen auf 0 setzen. */
tcppoi->outlin = 0; /* auszugebende Zeilen auf 0 setzen. */
tcppoi->RecvLen = 0; /* Rueckgabewert fuer recv. */
tcppoi->rxc = 0; /* Zaehler fuer RX-BUFFER. */
tcppoi->LoginPrompt = FALSE; /* Markiere Prompt senden. */
tcppoi->T3 = T3PARA; /* T3-Timer setzen. */
tcppoi->noacti = ininat; /* Timeout setzen */
tcppoi->Interface = Interface; /* Interface ID setzen. */
tcppoi->state = L2MNIX; /* State setzen. */
tcppoi->cr = 0; /* Kein RETRUN empfangen. */
tcppoi->txstatus = TCP_TX_FREE; /* Sender ist frei. */
tcppoi->Upcall[0] = 0;
tcppoi->Downcall[0] = 0;
#ifdef L1HTTPD
tcppoi->status = TCP_NULL;
tcppoi->http = TCP_NULL;
tcppoi->fp = NULL;
#endif /* L1HTTPD */
#ifdef L1IPCONV
tcppoi->CVSlink = FALSE;
tcppoi->Intern = FALSE;
#ifdef L1IRC
if (Interface == KISS_IRC)
tcppoi->IrcMode = TRUE;
else
tcppoi->IrcMode = FALSE;
#endif /* L1IRC */
#endif /* L1IPCONV */
tcp_tbl_top++; /* TBL-Zaehler um 1 erhoehen. */
relink(ulink((LEHEAD *)tcppoi), /* Link aus der frei-Liste nehmen */
(LEHEAD *)tcpactl.tail);
}
int ReadSockTCP(void) /* Empfangene TCPIP Packete. */
{
Fd_set fdsI;
int ret = EOF;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(ReadSockTCP)";
#endif /* DEBUG_MODUS */
if (tcppoi->rxc >= tcppoi->RecvLen) /* Sind alle Zeichen verarbeitet. */
{
if (tcppoi->mode == INT_STACK) /* Interner Socket. */
{
FD_ZERO_T(&fdsI); /* Inhalt loeschen. */
FD_SET_T((unsigned)tcppoi->sock, &fdsI); /* Socket setzen. */
/* Pruefe auf aktivitaet. */
ret = Select(tcppoi->sock + 1, &fdsI, NULL , NULL ,NULL);
if (ret)
/* Zeichen vom Socket empfangen. */
tcppoi->RecvLen = Recv (tcppoi->sock, tcppoi->rxbuf, RXLEN,0);
else
return((int)NULL); /* Keine aktivitaet auf den Socket. */
}
if (tcppoi->RecvLen < 1) /* Fehler beim Empfang. */
{
if (tcppoi->RecvLen == EOF) /* Socket wurde mittlerweile geloes. */
{
ifpp = SetInterface(tcppoi->Interface); /* akt. Interface setzen. */
/* ggf. Logbuch fuehren. */
T_LOGL1(TRUE, "(ReadSockTCP):%s\n (Recv) Fehler beim empfang, Segment wird auf DISC gesetzt!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf DISC stellen. */
return((int)NULL);
}
if ( (ret)
&&(tcppoi->RecvLen == 0))
{
ifpp = SetInterface(tcppoi->Interface); /* akt. Interface setzen. */
/* ggf. Logbuch fuehren. */
T_LOGL1(TRUE, "(ReadSockTCP):%s\n(Recv) Keine Zeichen, Segment wird auf DISC gesetzt!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf DISC stellen. */
return((int)NULL);
}
}
tcppoi->rxc = 0; /* RX-Zaehler auf 0 setzen. */
tcppoi->rxbuf[tcppoi->RecvLen] = 0; /* Nullzeichen setzen. */
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL3(TRUE, "(ReadSockTCP):%s\nInput:\r%s\r"
, tcppoi->ip
, tcppoi->rxbuf);
}
ret = tcppoi->rxbuf[tcppoi->rxc++]; /* Zeichen vom rxbuf holen. */
return(ret); /* Aktuelle Zeichen weiterreichen. */
}
static int ReadIndicationsSockTCP(void) /* Zeichen vom Socket einlesen. */
{
TRILLIAN ok = ERRORS;
char s;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(ReadIndicationsSockTCP)";
#endif /* DEBUG_MODUS */
while(1) /* Alle Zeichen von Socket einlesen. */
{
s = ReadSockTCP(); /* Zeichen vom Socket. */
if (tcppoi->cmdlen >= RXLEN) /* Maximale Buffergroesse erreicht, */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(ReadIndicationsSockTCP):%s\nMaximale Buffergroesse erreicht!\n"
, tcppoi->ip);
return(TRUE);
}
switch(tcppoi->Interface) /* Interface. */
{
#ifdef L1TELNET
case KISS_TELNET : /* Telnet. */
if ((ok = GetContensTEL(s)) == ERRORS) /* Aktuelle Zeichen auswerten.*/
break; /* Zeichen verarbeitet, kein Return. */
else
if (ok == YES) /* Zeichen verarbeitet und Return. */
{
tcppoi->cmd[tcppoi->cmdlen] = 0; /* Nullzeichen setzen. */
return(TRUE); /* Frame ist komplett. */
}
else
continue; /* Sind noch Zeichen im RXBUF, */
/* zum naechsten Zeichen. */
break;
#endif /* L1TELNET. */
#ifdef L1HTTPD
case KISS_HTTPD : /* HTTPD-Server. */
if ((ok = GetContensHTP(s)) == ERRORS) /* Aktuelle Zeichen auswerten.*/
break; /* Zeichen verarbeitet, kein Return. */
else
if (ok == YES) /* Zeichen verarbeitet und Return. */
{
tcppoi->cmd[tcppoi->cmdlen] = 0; /* Nullzeichen setzen. */
return(TRUE); /* Frame ist komplett. */
}
else
continue; /* Sind noch Zeichen im RXBUF, */
/* zum naechsten Zeichen. */
break;
#endif /* L1HTTPD. */
#ifdef L1IPCONV
/* IPCONV */
case KISS_IPCONV :
/* Aktuelle Zeichen auswerten. */
if ((ok = GetContensCVS(s)) == ERRORS)
/* Alle Zeichen verarbeitet, aber kein Return. */
break;
else
/* Alle Zeichen verarbeitet und Return? */
if (ok == YES)
{
/* User/Link noch kein Login. */
if (!tcppoi->login)
{
/* Pruefe auf Login. */
if (!strncmp(tcppoi->cmd, "/na", 3))
/* Kein Prompt senden. */
tcppoi->LoginPrompt = TRUE;
}
tcppoi->cmd[tcppoi->cmdlen] = 0;
/* Frame komplett. */
return(TRUE);
}
else
/* Sind noch Zeichen im RXBUF,*/
/* zum naechsten Zeichen. */
continue;
break;
#endif /* L1IPCONV */
#ifdef L1IRC
/* IPCONV */
case KISS_IRC :
/* Aktuelle Zeichen auswerten. */
if ((ok = GetContensCVS(s)) == ERRORS)
/* Alle Zeichen verarbeitet, aber kein Return. */
break;
else
/* Alle Zeichen verarbeitet und Return? */
if (ok == YES)
{
tcppoi->cmd[tcppoi->cmdlen] = 0;
/* Frame komplett. */
return(TRUE);
}
else
/* Sind noch Zeichen im RXBUF,*/
/* zum naechsten Zeichen. */
continue;
break;
#endif /* L1IPCONV */
default : /* Ungueltiges Interface. */
break; /* Hier werden wir nie kommen. */
}
return(FALSE); /* Frame noch nicht komplett. */
}
return(FALSE); /* Frame noch nicht komplett. */
}
/* Zusaetzlichen CTEXT einlesen. */
void LoginTextTCP(char *filename, /* CTEXT-Datei. */
MBHEAD *tmpmbp) /* Buffer. */
{
FILE *fp;
char buffer[80 + 1];
char convfile[MAXPATH];
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(LoginTextTCP)";
#endif /* DEBUG_MODUS */
strcpy(convfile, confpath); /* Basis-Verzeichnis setzen. */
strcat(convfile, filename); /* CTEXT-Datei setzen. */
ifpp = SetInterface(tcppoi->Interface); /* aktuelles Interface */
/* setzen fuer Logging. */
if ((fp = fopen(convfile, "r")) == NULL) /* CTEXT-Datei oeffnen. */
{ /* ggf. Logbuch fuehren. */
T_LOGL1(TRUE, "(LoginTextTCP):%s\nDatei (%s) kann nicht geoeffnet werden!\n"
, tcppoi->ip
, convfile);
return; /* Laest sich nicht oeffnen. */
}
/* ggf. Logbuch fuehren. */
T_LOGL2(TRUE, "(LoginTextTCP):%s\nDatei (%s) ist geoeffnet!\n"
, tcppoi->ip
, convfile);
while (fgets(buffer, 80, fp) != NULL) /* String mit 80 Zeichen einlesen. */
putprintf(tmpmbp, "%s\r", buffer);
fclose(fp); /* Datei schliessen. */
/* ggf. Logbuch fuehren. */
T_LOGL2(TRUE, "(LoginTextTCP):%s\nDatei (%s) ist geschlossen!\n"
, tcppoi->ip
, convfile);
}
static void PromptTCP(UWORD Interface) /* Login-Prompt senden. */
{
SENDTX *STx = NULL;
char call[10];
char file[128];
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(PromptTCP)";
#endif /* DEBUG_MODUS */
switch(Interface) /* Interface. */
{
#ifdef L1TELNET
/* TELNET-Server */
case KISS_TELNET : /* Telnet. */
strcpy(file, TELNET_TXT); /* Markiere Datei (telnet.txt)*/
break;
#endif /* L1TELNET */
#ifdef L1IPCONV
/* IPCONVERS-Server */
case KISS_IPCONV : /* IPConvers */
strcpy(file, IPCONV_TXT); /* Markiere Datei (ipconv.txt)*/
break;
#endif /* L1IPCONV */
default :
tcppoi->LoginPrompt = TRUE; /* Markiere Prompt als gesend.*/
return;
}
if ((STx = (SENDTX *)allocb(ALLOC_L1TCPIP)) == NULL)/* TX-Segment besorgen. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(PromptTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return; /* Kein Segment frei, abbruch. */
}
if ((STx->Data = SetBuffer()) == NULL) /* Buffer besorgen. */
{
dealoc((MBHEAD *)ulink((LEHEAD *)STx)); /* TX-Segment entsorgen.*/
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(PromptTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return; /* Buffer ist voll, abbruch. */
}
call2str(call,myid); /* Konvertiere das MYCALL. */
putprintf(STx->Data, "%s - %s\n", call, version); /* Standardtext einfuegen.*/
LoginTextTCP(file, STx->Data); /* evl. erweiterten CTEXT einfuegen. */
putprintf(STx->Data, "\nLogin:"); /* Und zum schluss den */
/* Login Prompt einfuegen. */
rwndmb(STx->Data); /* Buffer zurueckspulen.*/
STx->Sock = tcppoi->sock; /* Socket setzen. */
STx->Interface = tcppoi->Interface; /* Interface setzen. */
STx->Mode = tcppoi->mode; /* Stack-Mode setzen. */
relink((LEHEAD *) STx, (LEHEAD *)rxflTX.tail);/* Umhaengen in die Sendeliste*/
tcppoi->LoginPrompt = TRUE; /* Markiere, Login-Prompt als gesendet. */
}
void ServTCP(void) /* Empfangene Zeichen in Frames packen. */
{
READRX *SRx;
register int i;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(ServTCP)";
#endif /* DEBUG_MODUS */
if (ReadIndicationsSockTCP()) /* Empfangene Zeichen analysieren. */
{
if(tcppoi->cmdlen > 0) /* Es sind Zeichen im Buffer.*/
{
if ((SRx = (READRX *)allocb(ALLOC_L1TCPIP)) == NULL)/* RX-Seg. besorgen */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(ServTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
return; /* Kein Segment frei, abbruch. */
}
if ((SRx->Data = SetBuffer()) == NULL) /* Buffer besorgen. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(ServTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
dealoc((MBHEAD *)ulink((LEHEAD *)SRx)); /* RX-Segment entsorgen. */
return; /* Buffer ist voll, abbruch. */
}
SRx->Sock = tcppoi->sock; /* Socket setzen. */
SRx->Interface = tcppoi->Interface; /* Inetrface setzen. */
SRx->Mode = tcppoi->mode; /* Stack-Mode setzen. */
for (i = 0; i < tcppoi->cmdlen; ++i)
putchr(tcppoi->cmd[i], SRx->Data); /* Buffer fuellen. */
tcppoi->cmdlen = 0; /* Buffer-Zaehler zuruecksetzen. */
tcppoi->cmd[0] = 0; /* Nullzeichen setzen. */
if (tcppoi->activ) /* Nur wenn Socket aktiv. */
relink((LEHEAD *) SRx, (LEHEAD *)rxflRX.tail);/* Ab in die Empf.-liste*/
else
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(ServTCP):%s\nTCP-Segment nicht mehr aktiv!\n"
, tcppoi->ip);
if (SRx->Data != NULL)
dealmb(SRx->Data); /* Buffer entsorgen. */
dealoc((MBHEAD *)ulink((LEHEAD *)SRx)); /* RX-Segment entsorgen.*/
} /* Socket ist nicht mehr aktiv. */
} /* kein Zeichen im buffer. */
} /* Frame ist noch nicht komplett. */
}
/* Neue User hinzufuegen, vorrausgesetzt es sind noch freie Sockets vorhanden.*/
int AddUserTCP(T_INTERFACE *ifpoi, /* TCP-Interface. */
unsigned NewSocket, /* Neuer Socket. */
char *ip) /* IP-Adresse. */
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(AddUserTCP)";
#endif /* DEBUG_MODUS */
if ((tcppoi = (TCPIP *)tcpfrel.head) == NULL) /* freien Eintrag besorgen. */
{
ifpp = SetInterface(ifpoi->Interface);
T_LOGL1(TRUE, "(AddUserTCP):%s\nKann kein neues TCPIP-Segment anlegen !\n"
, ip
, tcp_tbl_top);
return(TRUE); /* es gibt keinen freien Eintrag mehr! */
}
SetDefaultWorthTCP(NewSocket, /* Defaultwerte setzen, neuer Socket. */
ip, /* IP-Adresse. */
ifpoi->l2port, /* L2-Port. */
ifpoi->Interface, /* TCPIP-Interface. */
INT_STACK); /* Interner TCP-STack. */
ServTCP(); /* Empfangene Zeichen in Frames packen. */
return(FALSE);
}
/* Alle Parameter auf default zuruecksetzen und den User aus der Liste nehmen.*/
void DiscTCP(void)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(DiscTCP)";
#endif /* DEBUG_MODUS */
if (tcppoi->activ == FALSE) /* User ist deaktiv. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(DiscTCP):%s\nTCP-Segment wurde schon zurueckgesetzt!\n"
, tcppoi->ip);
return; /* Abbruch. */
}
else /* User ist aktiv. */
tcppoi->activ = FALSE; /* Markiere, User als deaktiv. */
if (tcppoi->login) /* User war eingeloggt. */
nmbtcp--; /* Ein TCPIP User weniger. */
dealml((LEHEAD *)&tcppoi->inbuf); /* Buffer leeren. */
dealml((LEHEAD *)&tcppoi->outbuf);
#ifdef L1HTTPD
if (tcppoi->fp != NULL)
{
fclose(tcppoi->fp);
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL2(TRUE, "(DiscTCP):%s\nDatei wird geschlossen.\n"
, tcppoi->ip);
}
#endif /* L1HTTPD */
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL2(TRUE, "(DiscTCP):\nVerbindung zur IP-Adresse %s wurde geschlossen.\n"
, tcppoi->ip);
tcppoi->port = 0; /* Parameter auf defaultwerte setzen. */
tcppoi->sock = 0;
tcppoi->mode = 0;
tcppoi->cmdlen = 0;
tcppoi->rxc = 0;
tcppoi->RecvLen = 0;
tcppoi->login = 0;
tcppoi->noacti = 0;
tcppoi->T3 = 0;
tcppoi->inlin = 0;
tcppoi->outlin = 0;
tcppoi->disflg = 0;
tcppoi->LoginPrompt = 0;
tcppoi->state = L2MNIX;
tcppoi->cr = 0;
tcppoi->txstatus = TCP_TX_FREE;
tcppoi->Upcall[0] = 0;
tcppoi->Downcall[0] = 0;
tcppoi->cmd[0] = 0;
tcppoi->rxbuf[0] = 0;
tcppoi->txbuf[0] = 0;
tcppoi->ip[0] = 0;
#ifdef l1HTTPD
tcppoi->status = 0;
tcppoi->http = 0;
tcppoi->fp = NULL;
#endif /* L1HTTPD */
#ifdef L1IPCONV
tcppoi->CVSlink = FALSE;
tcppoi->Intern = FALSE;
#ifdef L1IRC
tcppoi->IrcMode = FALSE;
#endif /* L1IRC */
#endif /* L1IPCONV */
tcp_tbl_top--; /* TBL-Zaehler um 1 runter. */
l2tol7(2, tcppoi, TCP_USER); /* Statusmeldung an L7 Weiterleiten. */
resptc(g_uid(tcppoi, TCP_USER)); /* patchcord-Liste zuruecksetzen */
relink(ulink((LEHEAD *)tcppoi), /* aus der aktiv-Liste nehmen */
(LEHEAD *)tcpfrel.tail); /* in die Freiliste haengen */
}
/* Rufzeichen in der MH-Liste Aktualisieren. */
void MhUpdateTCP(MBHEAD *tbp, /* Buffer */
BOOLEAN rxtx) /* Flag fuer RX/TX-Bytes. */
{
MHEARD *mhp;
char Upcall[10 + 1];
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(MhUpdateTCP)";
#endif /* DEBUG_MODUS */
if (tcppoi->Upcall[0] == FALSE)
return;
if (updmheard((int)tcppoi->port)) /* Pruefen ob die MH-Liste */
{ /* auf den L2-Port aktiv ist. */
if (valcal(tcppoi->Upcall) == ERRORS) /* Rufzeichen auf Gueltigkeit pruef.*/
{
ifpp = SetInterface(tcppoi->Interface);
call2str(Upcall, tcppoi->Upcall);
T_LOGL1(TRUE, "(MhUpdateTCP):%s\nRufzeichen (%s) ist ungueltig!\n"
, tcppoi->ip
, Upcall);
return; /* Ungueltiges Rufzeichen. */
}
/* Rufzeichen in der MHListe aktual.*/
if ((mhp = mh_lookup_port(&l2heard, tcppoi->Upcall, tcppoi->port, FALSE)) == NULL)
mhp = mh_add(&l2heard); /* Neuen MH-Eintrag taetigen. */
if (mhp) /* Eintrag gefunden. . */
/* User/Link Aktualisieren. */
mh_update(&l2heard, mhp, tcppoi->Upcall, tcppoi->port);
if (tbp == NULL) /* Kein Eintrag fuer RX/TX-Bytes. */
return; /* Kein Aktualisierung moeglich. */
if (rxtx) /* RX/TX-Bytes Aktualisieren. */
mhp->rx_bytes += (tbp->mbpc); /* RX-Bytes Aktualiseren. */
else
mhp->tx_bytes += (tbp->mbpc); /* TX-Bytes Aktualisieren. */
}
}
void SendTCP(void) /* Frame vorbereiten fuer Sendeliste. */
{
MBHEAD *Data = NULL;
SENDTX *NewSTx = NULL;
char c;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SendTCP)";
#endif /* DEBUG_MODUS */
/* Zeiger auf den Inhalt des Frames. */
Data = (MBHEAD *)ulink((LEHEAD *)tcppoi->outbuf.head);
--tcppoi->outlin; /* Ein Frame weniger. */
if ((NewSTx = (SENDTX *)allocb(ALLOC_L1TCPIP)) == NULL) /* Neues Seg.anlegen*/
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(SendTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return; /* Kein TX-Segment frei.*/
}
if ((NewSTx->Data = SetBuffer()) == NULL) /* Buffer besorgen. */
{
dealoc((MBHEAD *)ulink((LEHEAD *)NewSTx)); /* TX-Segment entsorgen.*/
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(SendTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return; /* Buffer voll, abbruch.*/
}
NewSTx->Sock = tcppoi->sock; /* Socket setzen. */
NewSTx->Interface = tcppoi->Interface; /* Interface setzen. */
NewSTx->Mode = tcppoi->mode; /* Stack-Mode setzen. */
while (Data->mbgc != Data->mbpc) /* Alle Zeichen im Buffer lesen und */
{ /* vorbereiten zum Senden. */
c = getchr(Data); /* Zeichen aus den Buffer lesen. */
switch (tcppoi->Interface) /* Interface. */
{
#ifdef L1TELNET
case KISS_TELNET : /* TELNET-Interface. */
if ( (c == CR) /* CR-Return */
||(c == LF)) /* oder LF-Return. */
putchr(LF, NewSTx->Data); /* Setze nur LF-Return. */
break;
#endif /* L1TELNET */
#ifdef L1HTTPD
case KISS_HTTPD : /* HTTPD-Interface. */
if (tcppoi->http == TCP_CMD) /* Befehl via HTTPD. */
{
/* Schreibe Zeichen in Buffer. */
putv(NewSTx->Data, c);
/* zum naechsten Zeichen. */
continue;
}
break;
#endif /* L1HTTPD */
#ifdef L1IPCONV
case KISS_IPCONV : /* IPCONV-Interface. */
if ( (c == CR) /* CR-Return */
||(c == LF)) /* oder LF-Return. */
putchr(LF, NewSTx->Data); /* Setze nur LF-Return. */
break;
#endif /* L1IPCONV */
#ifdef L1IRC
case KISS_IRC : /* IRC-Interface. */
if ( (c == CR) /* CR-Return */
||(c == LF)) /* oder LF-Return. */
putchr(LF, NewSTx->Data); /* Setze nur LF-Return. */
break;
#endif /* L1IRC */
default : /* Unbekanntes Interface. */
break;
}
putchr(c, NewSTx->Data); /* Zeichen in Buffer setzen. */
}
rwndmb(NewSTx->Data); /* Buffer zurueckspulen. */
relink((LEHEAD *) NewSTx, (LEHEAD *)rxflTX.tail); /* In Sendeliste umhaengen*/
dealmb(Data); /* Alten Buffer leeren/entsorgen. */
tcppoi->cmdlen = 0; /* Komandozeile leeren. */
tcppoi->cmd[0] = 0; /* Nullzeichen setzen. */
}
void SenTCP(void) /* Informationstransfer von TCPIP nach Layer X */
{
MBHEAD *mbp;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SenTCP)";
#endif /* DEBUG_MODUS */
while (tcppoi->inlin != 0) /* Frame fuer Layer X? */
{
mbp = (MBHEAD *)tcppoi->inbuf.head; /* Hole Frame. */
mbp->l2link = (LNKBLK *)tcppoi;
mbp->type = TCP_USER;
mbp->l2fflg = L2CPID;
if (!fmlink(FALSE, mbp)) /* Frame fuer Layer X weiterreichen. */
break; /* Link ist verstopft, abbruch. */
--tcppoi->inlin; /* Ein Frame weniger. */
}
}
/* Frame aus der Sendeliste senden. */
static BOOLEAN PutflushSockTCP(void)
{
int ok = FALSE;
int ret = FALSE;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(PutflushSockTCP)";
#endif /* DEBUG_MODUS */
#ifdef OS_STACK
if (tcppoi->mode == OS_MODE)
return(PutflushSockOS());
#endif /* OS_STACK */
if (tcppoi->txc) /* Gibt es was zu senden. */
{
while (1) /* Gibt es was zu senden. */
{
Fd_set wfdsI;
if (tcppoi->mode) /* Interner TCP-Stack. */
{
FD_ZERO_T(&wfdsI); /* Loesche inhalt. */
FD_SET_T((unsigned)tcppoi->sock, &wfdsI); /* Socket setzen. */
if (Select(tcppoi->sock + 1, NULL, &wfdsI, NULL ,NULL))/* Sender frei.*/
{
if (tcppoi->txstatus == TCP_TX_BUSY) /* Sender ist auf Busy. */
tcppoi->txstatus = TCP_TX_FREE; /* Sender auf frei stellen. */
/* Frame senden */
if ((ok = Send(tcppoi->sock, tcppoi->txbuf + tcppoi->sum, tcppoi->txc - tcppoi->sum,0)) < 0)
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(PutflushSockTCP):%s\nFrame senden fehlgeschlagen!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return(TRUE); /* Abbruch. */
}
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL3(TRUE, "(PutflushSockTCP):%s\nOutput:\r%s\r"
, tcppoi->ip
, tcppoi->txbuf);
tcppoi->sum += ok; /* Markiere, gesendete Zeichen. */
if (tcppoi->sum == tcppoi->txc) /* Alle Zeichen gesendet. */
break; /* Schleife verlassen. */
}
if (ret == FALSE) /* Sender ist nicht frei. */
{
tcppoi->txstatus = TCP_TX_BUSY; /* Sender auf Busy stellen. */
return(FALSE);
}
}
}
tcppoi->sum = 0; /* Zuruecksetzen. */
tcppoi->txc = 0;
tcppoi->txbuf[0] = 0;
}
return(FALSE);
}
/* Pruefen ob noch Frame in der Warteschlage haengen. */
static int NotContensTCP(void)
{
BOOLEAN result = TRUE; /* Keine weiteren Aufgaben. */
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(NotContensTCP)";
#endif /* DEBUG_MODUS */
switch(tcppoi->Interface)
{
#ifdef L1TELNET
case KISS_TELNET :
if (!tcppoi->LoginPrompt) /* Noch kein Prompt gesendet */
PromptTCP(tcppoi->Interface); /* Login-Text senden. */
break;
#endif /* L1TELNET */
#ifdef L1IPCONV
case KISS_IPCONV :
if (!tcppoi->LoginPrompt) /* Noch kein Prompt gesendet */
PromptTCP(tcppoi->Interface); /* Login-Text senden. */
break;
#endif /* L1IPCONV */
default :
break;
}
#ifdef L1HTTPD
/* HTTPD, Uri laden? Nur wenn Sender frei. */
if ( (tcppoi->Interface == KISS_HTTPD)
&&(tcppoi->status == TCP_URI)
&&(tcppoi->txstatus != TCP_BUSY))
{
/* uri laden. */
if (load_uri())
{
tcppoi->T3 = T3PARA;
tcppoi->noacti = ininat;
/* Aufgabe bearbeitet. */
result = FALSE;
}
}
#endif /* L1HTTPD */
while (tcppoi->outlin != 0) /* Es sind noch Frames in der Warteschlange */
{
SendTCP(); /* Frame vorbereiten zum senden */
result = FALSE; /* Aufgabe bearbeitet. */
#ifdef L1HTTPD
if (tcppoi->Interface == KISS_HTTPD)
{
if (tcppoi->outlin == 0)
{
tcppoi->disflg |= 0x80;
PutHtmlEnd();
}
}
#endif /* L1HTTPD */
}
if (tcppoi->inlin != 0) /* Frame fuer Layer X. */
{
SenTCP(); /* Frame fuer Layer X weiterreichen. */
result = FALSE; /* Aufgabe bearbeitet. */
}
if (tcppoi->txstatus == TCP_TX_BUSY) /* Sender ist Busy. */
{
PutflushSockTCP(); /* Frame erneuert senden. */
result = FALSE; /* Aufgabe bearbeitet. */
}
if ( (tcppoi->disflg) /* Steht Segment auf Disc */
&&(result)) /* und liegen keine weiteren Aufgaben an, */
return(TRUE); /* Socket Schliessen. */
return(FALSE);
}
/* Pruefe Logindaten. */
static WORD CheckData(MBHEAD *tbp, /* Buffer mit Logindaten. */
char *scall, /* Zeiger fuer Rufzeichen. */
char *contens) /* Zeiger fuer weiterte Login-Daten. */
{
char ch;
UWORD len = 0;
register int j = 0;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckData)";
#endif /* DEBUG_MODUS */
rwndmb(tbp); /* Bufferdaten zurueckspulen. */
if ((tbp->mbpc - tbp->mbgc) > 256) /* Maximale Logindaten 256 Zeichen. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckData):%s\nMaximale Logindaten (%d) ueberschritten!\n"
, tcppoi->ip
, tbp->mbgc - tbp->mbpc);
return(FALSE); /* Spielmatz, abbruch. */
}
while (tbp->mbgc != tbp->mbpc) /* Alle Zeichen aus den Buffer lesen. */
{
ch = getchr(tbp); /* Zeichen holen. */
if ( (ch == CR) /* Zeichen ein CR-Return, */
||(ch == LF) /* oder LF-Return, */
||(ch == '#')) /* oder Route. */
break; /* Brechen wir ab. */
scall[len++] = ch; /* Zeichen eintragen. */
}
scall[len] = '\0'; /* Nullzeichen setzen. */
while (tbp->mbgc != tbp->mbpc) /* Restliche Zeichen aus den Buffer lesen. */
contens[j++] = getchr(tbp); /* Zeichen holen. */
contens[j] = '\0'; /* Nullzeichen setzen. */
#ifdef L1IRC
if (tcppoi->IrcMode)
{
IrcLinkUser(scall);
IrcLinkNick(contens);
len = L2CALEN;
}
#endif /* L1IRC */
return(len); /* Rufzeichenlaenge. */
}
/***********************************************/
/* Rufzeichen suchen. */
/* ERRORS - Es wurde kein Rufzeichen gefunden. */
/* NO - Rufzeichen ohne SSID-Vergleich */
/* gefunden. */
/* YES - Rufzeichen mit SSID-Vergleich */
/* gefunden. */
/***********************************************/
static TRILLIAN SearchCall(char *call, BOOLEAN ssid)
{
TCPIP *tpoi;
int i = FALSE;
int j = FALSE;
TRILLIAN found = ERRORS;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SearchCall)";
#endif /* DEBUG_MODUS */
for (i = 0, tpoi = tcptbl; i < MAXTCPIP; ++i, ++tpoi) /* TBL durchgehen. */
{
if (tpoi->activ == TRUE) /* Nur wenn aktiv! */
{
if ( (cmpcal(tpoi->Upcall, call) /* Callvergleich. */
&&(tpoi->port == tcppoi->port))) /* Portvergleich. */
{
if (ssid == TRUE) /* SSID-Bereich pruefen. */
{
if (cmpid(tpoi->Upcall, call)) /* Callvergleich mit SSID. */
{
found = YES; /* Markiere, */
break; /* Eintrag gefunden. */
}
found = NO; /* Rufzeichen ohne SSID gefunden. */
}
else
found = NO; /* Rufzeichen ohne SSID gefunden. */
}
if ( ((tcppoi->activ) /* Sind alle aktiven Sockets durchlaufen, */
&& (j++ >= tcp_tbl_top))
|| (j == tcp_tbl_top))
break; /* brechen wir ab. */
}
}
return(found);
}
/* Pruefen der SSID. */
static int CheckSSID(char *scall)
{
char ssid = 0;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckSSID)";
#endif /* DEBUG_MODUS */
while (SearchCall(scall, TRUE) == TRUE)/* Suche Rufzeichen mit SSID-Bereich */
{
ssid++; /* Es gibt SCHON ein Rufzeichen mit der SSID, um 1 erhoehen. */
if (ssid > 15) /* SSID ist groesser als 15. */
return(EOF); /* Abbruch! */
scall[L2IDLEN-1] = (ssid << 1) | 0x60; /* SSID setzen. */
}
return((int)ssid); /* SSID ist noch nicht vergeben. */
}
/***********************************************/
/* Ist das Rufzeichen schon mindestens einmal */
/* eingeloggt, vergeben wir anhand des letzten */
/* Call ,mit der hoehsten SSID, die SSID. */
/***********************************************/
char *CheckCallSSID(char *scall)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckCallSSID)";
#endif /* DEBUG_MODUS */
if (SearchCall(scall,FALSE) == NO) /* Suche Rufzeichen ohne Beachtung */
{ /* der SSID. */
if (CheckSSID(scall) != EOF) /* Pruefe Rufzeichen auf SSID, */
/* gegebenfalls neue SSID vergeben. */
return(scall); /* Rufzeichen mit aktueller SSID. */
else
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCallSSID):%s\nAlle SSID-Nummern vergeben!\n"
, tcppoi->ip);
return(NULL); /* Alle SSID-Nummern sind belegt. */
}
}
else /* Rufzeichen ohne SSID gefunden. */
return(scall); /* Rufzeichen setzen. */
}
/* Pruefe Loginrufzeichen. */
static BOOLEAN CheckCall(MBHEAD *tbp, /* Buffer mit Logindaten. */
char *contens) /* Zeiger fuer erweitere Logibdaten. */
{
char scall[256];
char *call = scall;
char logincall[L2IDLEN];
char *pcall = logincall;
WORD len = FALSE;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckCall)";
#endif /* DEBUG_MODUS */
if ((len = CheckData(tbp, scall, contens)) == FALSE) /* Rufzeichen holen. */
return(TRUE); /* Ungueltiges Rufzeichen. */
if (getcal(&len,&call,FALSE,logincall) == YES) /* Rufzeichen pruefen */
{
if (valcal(logincall) == ERRORS) /* Pruefe Rufzeichen auf Gueltigkeit. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCall):%s\n%s : Ungueltiges Rufzeichen\n"
, tcppoi->ip
, pcall);
return(TRUE); /* Rufzeichen ungueltig. */
}
/* Pruefen ob das Rufzeichen als suspend markiert ist. */
if (is_down_suspended(logincall, tcppoi->port) == TRUE)
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCall):%s\n%s : Rufzeichen ist gesperrt!\n"
, tcppoi->ip
, pcall);
return(TRUE); /* Rufzeichen ist gesperrt. */
}
if (cmpcal(logincall, myid)) /* Pruefen ob Rufzeichen unser Node ist. */
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCall):%s\n%s : Rufzeichen ist user NODE!\n"
, tcppoi->ip
, pcall);
return(TRUE); /* Rufzeichen wird Missbrauch. */
}
/***********************************************/
/* Ist das Rufzeichen schon mindestens einmal */
/* eingeloggt, vergeben wir anhand des letzten */
/* Call, mit der hoehsten SSID, die SSID oder */
/* die angegebene SSID im Rufzeichen. */
/***********************************************/
if ((pcall = CheckCallSSID(logincall)) != NULL)
{
cpyid(tcppoi->Upcall, pcall); /* Quellrufzeichen. */
cpyid(usrcal, pcall); /* Aktuelle Rufzeichen setzen. */
cpyid(tcppoi->Downcall, myid); /* Zielrufzeichen. */
return(FALSE); /* Gueltiges Rufzeichen gefunden. */
}
else
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCall):%s\nSSID ausserhalb des Gueltigkeitsbereiches.\n"
, tcppoi->ip);
return(TRUE); /* SSID ausserhalb des Gueltigkeitsbereich. */
}
}
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckCall):%s\n%s : Ungueltiges Rufzeichen\n"
, tcppoi->ip
, call);
return(TRUE); /* Ungueltiges Rufzeichen. */
}
/* Rufzeichen anmelden. */
BOOLEAN LoginTCP(MBHEAD *tbp)
{
char buffer[256 + 1]; /* Buffer fuer erweiterte Logindaten. */
char Upcall[10 + 1];
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(LoginTCP)";
#endif /* DEBUG_MODUS */
buffer[0] = 0;
if (CheckCall(tbp, buffer)) /* Pruefe Loginrufzeichen. */
{
dealmb(tbp); /* Loginrufzeichen ist ungueltig, */
return(TRUE); /* Buffer entsorgen. */
}
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
call2str(Upcall, tcppoi->Upcall);
T_LOGL2(TRUE, "(LoginTCP):%s\nEingeloggt als %s.\n"
, tcppoi->ip
, Upcall);
tcppoi->login = TRUE; /* Markiere, User als eingeloggt. */
if (++nmbtcp > nmbtcp_max) /* Maximalwert fuer die Statistik */
nmbtcp_max = nmbtcp;
tcppoi->state = L2MCONNT; /* Statusmeldung an den L7 Melden. */
#ifdef L1IPCONV
/* Ist Interface IPConvers? */
if (tcppoi->Interface == KISS_IPCONV)
{
int i = 0,
j = 0;
if (buffer[0] != FALSE)
{
buffer[256] = 0; /* Maximale Buffergrenze. */
tcppoi->cmdlen = strlen(buffer); /* Laenge setzen. */
if (tcppoi->cmdlen > 0) /* Kanalangabe. */
{
while(tcppoi->cmdlen--)
tcppoi->cmd[i++] = buffer[j++]; /* Channel setzen. */
tcppoi->cmd[i++] = 0; /* Nullzeichen setzen. */
ifpp = SetInterface(tcppoi->Interface); /* akt. Interface setzen. */
T_LOGL2(TRUE, "(LoginTCP):%s\nMit Channelangabe (%s).\n"
, tcppoi->ip
, tcppoi->cmd);
}
}
}
#endif /* L1IPCONV */
dealmb(tbp); /* Buffer entsorgen. */
return(FALSE);
}
/* Packet umhaengen. */
void RelinkTCP(MBHEAD *tbp)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(RelinkTCP)";
#endif /* DEBUG_MODUS */
if (tbp->mbpc) /* Es g<>bt daten. */
{
rwndmb(tbp); /* Buffer zurueckspulen. */
/* Packet umhaengen. */
relink((LEHEAD *)tbp, (LEHEAD *)tcppoi->inbuf.tail);
++tcppoi->inlin; /* Eingabebuffer hat Daten */
if (tcppoi->login == TRUE)
MhUpdateTCP(tbp, TRUE); /* MH-Liste Aktualisieren. */
tcppoi->noacti = ininat; /* Timeout neu aufziehen. */
tcppoi->T3 = T3PARA; /* T3-Timer neu aufziehen. */
tcppoi->cmdlen = 0; /* Zaehler zuruecksetzen. */
}
}
/* Anhand des Sockets den User aus der Liste holen. */
TCPIP *FdReadTCP(Fd_set Rmask)
{
int i, j = FALSE;
LHEAD *h_llp;
h_llp = &tcpactl;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(FdReadTCP)";
#endif /* DEBUG_MODUS */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi) /* TBL durchgehen.*/
{
if (tcppoi->mode != INT_STACK)
continue;
if (tcppoi->activ) /* Nur wenn aktiv. */
{
if (CheckSocket()) /* Pruefe, ob Socket aktiv ist. */
{
CloseSockTCP(FALSE, tcppoi->Interface); /* Schliesse Socket. */
return(NULL); /* Socket deaktiv, Segment auf DISC stellen. */
}
if (FD_ISSET_T(tcppoi->sock, &Rmask)) /* Socketvergleich. */
{
ulink((LEHEAD *)tcppoi); /* wir haben einen Link gefunden. */
relink((LEHEAD *)tcppoi, (LEHEAD *)h_llp->tail);
return(tcppoi);
}
}
if ( ((tcppoi->activ) /* Socket ist aktiv, */
&& (j++ >= tcp_tbl_top)) /* merken und pruefen, */
|| (j == tcp_tbl_top)) /* alle aktiven Socket's bearbeitet*/
break; /* koennen wir abbrechen. */
}
return(NULL); /* Keinen Eintrag gefunden. */
}
/* Anhand des Sockets den User aus der Liste holen. */
TCPIP *FdReadSockTCP(int Sock, UWORD Interface, UWORD Mode)
{
int i, j = FALSE;
LHEAD *h_llp;
h_llp = &tcpactl;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(FdReadSockTCP)";
#endif /* DEBUG_MODUS */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi) /*TBL durchgehen. */
{
if (tcppoi->activ) /* Nur wenn aktiv. */
{
if ( (tcppoi->sock == Sock) /* Socketvergleich. */
&&(tcppoi->Interface == Interface)
&&(tcppoi->mode == Mode))
{
if (CheckSocket()) /* Pruefe, ob Socket aktiv ist. */
{
CloseSockTCP(FALSE, tcppoi->Interface); /* Schliesse Socket. */
return(NULL); /* Socket deaktiv, Segment auf DISC stellen. */
}
ulink((LEHEAD *)tcppoi); /* wir haben einen Link gefunden. */
relink((LEHEAD *)tcppoi, (LEHEAD *)h_llp->tail);
return(tcppoi);
}
}
if ( ((tcppoi->activ) /* Socket ist aktiv, */
&& (j++ >= tcp_tbl_top)) /* merken und pruefen, */
|| (j == tcp_tbl_top)) /* alle aktiven Socket's bearbeitet*/
break; /* koennen wir abbrechen. */
}
return(NULL); /* Keinen Eintrag gefunden. */
}
/* Sender bis max. TXLEN fuellen. */
static BOOLEAN PutvSockTCP(int c)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(PutvSockTCP)";
#endif /* DEBUG_MODUS */
if (tcppoi->txc >= TXLEN) /* Maximale TXLEN erreicht. */
{
tcppoi->txbuf[tcppoi->txc] = 0;
if (PutflushSockTCP()) /* Frame senden. */
return(TRUE);
}
tcppoi->txbuf[tcppoi->txc++] = c; /* Fuelle txbuffer. */
return(FALSE);
}
/* Eingehende Frames bearbeiten. */
void TcpipRX(void)
{
READRX *SRx;
READRX *SRxPrev;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(TcpipRX)";
#endif /* DEBUG_MODUS */
for (SRx = (READRX *)rxflRX.head; /* Alle RX-Segmente durchgehen. */
SRx != (READRX *)&rxflRX;
SRx = SRxPrev)
{
SRxPrev = SRx->next;
/* Aktuellen User aus der Liste holen. */
if ((tcppoi = FdReadSockTCP(SRx->Sock, SRx->Interface, SRx->Mode)) == NULL)
{
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(SRx->Interface);
T_LOGL1(TRUE, "(TcpipRX):\nKein User gefunden (Sock:%d, Interface:%d, Mode:%d\n"
"RX-Segment entsorgen.\n"
, SRx->Sock
, SRx->Interface
, SRx->Mode);
if (SRx->Data != NULL) /* Wenn es daten gibt, */
dealmb(SRx->Data); /* entsorgen. */
dealoc((MBHEAD *)ulink((LEHEAD *)SRx)); /* RX-Segment entsorgen. */
continue;
}
switch(tcppoi->Interface)
{
#ifdef L1HTTPD
case KISS_HTTPD :
/* HTTPD-Service. */
TcpipHttpd(SRx->Data);
/* Buffer entsorgen. */
if (SRx->Data != NULL)
dealmb(SRx->Data);
dealoc((MBHEAD *)ulink((LEHEAD *)SRx)); /* TX-Segment entsorgen. */
/* naechstes Frame aus der Liste holen. */
break;
#endif /* L1HTTPD */
default :
if (!tcppoi->login) /* Nicht angemeldet. */
{
if (LoginTCP(SRx->Data)) /* User/Link anmelden. */
tcppoi->disflg |= 0x80; /* Anmeldung war nicht erfolgreich. */
}
else /* User-Link ist angemeldet.*/
RelinkTCP(SRx->Data); /* Frame weiterleiten. */
dealoc((MBHEAD *)ulink((LEHEAD *)SRx)); /* RX-Segment entsorgen. */
break;
}
}
}
/* Ausgehende Frames senden. */
void TcpipTX(void)
{
SENDTX *STx;
SENDTX *STxPrev;
char buf;
int len = 0;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(TcpipTX)";
#endif /* DEBUG_MODUS */
for (STx = (SENDTX *)rxflTX.head; /* Alle TX-Segmente durchgehen. */
STx != (SENDTX *)&rxflTX;
STx = STxPrev)
{
STxPrev = STx->next;
/* Aktuellen User aus der Liste holen. */
if ((tcppoi = FdReadSockTCP(STx->Sock, STx->Interface, STx->Mode)) == NULL)
{
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(STx->Interface);
T_LOGL1(TRUE, "(TcpipRX):\nKein User gefunden (Sock:%d, Interface:%d, Mode:%d\n"
"TX-Segment entsorgen.\n"
, STx->Sock
, STx->Interface
, STx->Mode);
if (STx->Data != NULL) /* Wenn es daten gibt, */
dealmb(STx->Data); /* entsorgen. */
dealoc((MBHEAD *)ulink((LEHEAD *)STx)); /* TX-Segment entsorgen. */
continue; /* zum naechsten Segment. */
}
if (tcppoi->txstatus == TCP_TX_BUSY) /* Sender steht auf Busy. */
continue; /* zum naechsten eintrag. */
if (tcppoi->login == TRUE)
MhUpdateTCP(STx->Data, FALSE); /* MH-Liste updaten */
/* solange Daten vorhanden sind */
while (STx->Data->mbgc != STx->Data->mbpc)
{
if (PutvSockTCP(buf = getchr(STx->Data))) /* Zeichen in sendebuffer. */
{
if (STx->Data != NULL) /* Wenn es daten gibt, */
dealmb(STx->Data); /* entsorgen. */
dealoc((MBHEAD *)ulink((LEHEAD *)STx)); /* TX-Segment entsorgen. */
continue; /* zum naechsten eintrag. */
}
}
tcppoi->txbuf[tcppoi->txc] = 0;
PutflushSockTCP(); /* Frame senden. */
if (STx->Data != NULL) /* Wenn es daten gibt, */
dealmb(STx->Data); /* entsorgen. */
dealoc((MBHEAD *)ulink((LEHEAD *)STx)); /* TX-Segment entsorgen. */
len = 0; /* Zuruecksetzen. */
}
}
T_INTERFACE *SetInterface(UWORD Interface)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SetInterface)";
#endif /* DEBUG_MODUS */
switch(Interface)
{
case KISS_TELNET :
ifpp = &ifp[TEL_ID];
break;
case KISS_HTTPD :
ifpp = &ifp[HTP_ID];
break;
case KISS_IPCONV :
ifpp = &ifp[CVS_ID];
break;
default :
break;
}
return(ifpp);
}
/*********************************/
/* Statusaenderungen, */
/* Frame vorbereiten zum Senden. */
/* evl. Socket schliessen. */
/*********************************/
void TcpipSV(void)
{
int i, j = FALSE;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(TcpipSV)";
#endif /* DEBUG_MODUS */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi) /*TBL durchgehen. */
{
if (tcppoi->activ) /* Socket ist aktiv. */
{
if (tcppoi->state != L2MNIX) /* Statusaenderung. */
{
l2tol7(tcppoi->state, tcppoi, TCP_USER); /* Statusmeldungen an L7. */
tcppoi->state = L2MNIX; /* Status auf 0 setzen. */
cpyid(tcppoi->Upcall, usrcal); /* Quellrufzeichen setzen. */
#ifdef L1IPCONV
if ( (tcppoi->Interface == KISS_IPCONV)
&&(tcppoi->Intern == FALSE))
IPConvLogin();
#endif /* L1IPCONV */
#ifdef L1IRC
if ( (tcppoi->Interface == KISS_IRC)
&&(tcppoi->Intern == FALSE))
IPConvLogin();
#endif /* L1IRC */
}
if (NotContensTCP()) /* Frame vorbereiten zum Senden. */
CloseSockTCP(FALSE, tcppoi->Interface); /* Socket schliessen. */
}
if ( ((tcppoi->activ) /* Socket ist aktiv, */
&& (j++ >= tcp_tbl_top)) /* merken und pruefen, */
|| (j == tcp_tbl_top)) /* alle aktiven Socket's bearbeitet.*/
break; /* koennen wir abbrechen. */
}
}
/* Lausche auf TCP-Stack. */
void ListenTCP(void)
{
UWORD Interface = KISS_TCPIP;
int count,
max_fdI = 0,
i;
Fd_set Rmask;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(ListenTCP)";
#endif /* DEBUG_MODUS */
FD_ZERO_T(&Rmask);
/* fuer alle Interfaces die benutzten Filedescriptoren fuer select() */
/* ermitteln und eintragen */
for (i = 0; i < MAXINTERFACE; i++, Interface++)
{ /* Zeiger auf das aktuelle Interface. */
if ((ifpp = SearchIf(Interface)) == NULL)
continue; /* Zum naechsten Interface. */
if (ifpp->actively == FALSE) /* Interface ist nicht aktiv.*/
continue; /* Zum naechsten Interface. */
FD_SET_T((unsigned)ifpp->ISock, &Rmask); /* Socket setzen. */
if (ifpp->ISock > max_fdI - 1)
max_fdI = ifpp->ISock + 1;
}
PutSocketTCP(&Rmask, &max_fdI); /* Socket setzen. */
/* Pruefe auf Aktivitaet, Int.Stack. */
count = Select(max_fdI, &Rmask, NULL, NULL, NULL);
if (!count) /* Keine Aktivitaet. */
return; /* Zur Hauptschleife. */
Interface = KISS_TCPIP; /* 1. TCPIP-Interface setzen. */
for (i = 0; i < MAXINTERFACE; i++, Interface++)
{ /* Zeiger auf das aktuelle Interface. */
if ((ifpp = SearchIf(Interface)) == NULL)
continue; /* Zum naechsten Interface. */
if (ifpp->actively == FALSE) /* Interface ist nicht aktiv. */
continue; /* Zum naechsten Interface. */
if (FD_ISSET_T(ifpp->ISock, &Rmask))
{
char ip[IPADDR + 1];
int NewSock = EOF;
Socklen_t addrlen = EOF;
ULONG peerip = 0;
char *p = (char *) &peerip;
addrlen = sizeof Peeraddr_in; /* Neuen Socket anlegen. */
if ((NewSock = Accept(ifpp->ISock, (struct Sockaddr *) &Peeraddr_in, &addrlen)) != EOF)
{
peerip = Peeraddr_in.sin_addr._S_addr; /* IP-Adresse ermitteln. */
sprintf (ip, "%d.%d.%d.%d",(p[3] & 255)
,(p[2] & 255)
,(p[1] & 255)
,(p[0] & 255));
}
if (AddUserTCP(ifpp, NewSock, ip)) /* Neuen User hinzufuegen */
{
Close(NewSock);
continue; /* zum naechsten Interface. */
}
T_LOGL2(TRUE, "(RecvTCP):\n"
"Verbindung zur IP-Adresse %s angenommen.\n"
"Neu erzeugter Socket ist (%d).\n"
, ip
, NewSock);
continue; /* zum naechsten Interface. */
} /* Interface-Schnittstelle. */
if ((tcppoi = FdReadTCP(Rmask)) != NULL) /* Den User aus der Liste Holen */
{
T_LOGL3(TRUE, "(ListenTCP):%s\nAktuellen Socket (%d) in der Liste gefunden.\n"
, tcppoi->ip
, tcppoi->sock);
ServTCP(); /* Eingehende TCPIP Packete verarbeiten. */
continue; /* zum naechsten Interface. */
} /* Socket suchen. */
} /* for-schleife. */
}
/* TCPIP-Service. */
void TcpipSRV(void)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(TcpipSRV)";
#endif /* DEBUG_MODUS */
#ifdef OS_STACK
ListenTCP_OS();
#endif /* OS_STACK */
ListenTCP(); /* Lausche auf TCP-Stack. */
TcpipTX(); /* ausstehende Frames senden wenn vorhanden */
TcpipRX(); /* eingehende Frame analysieren. */
/* Frames in der Warteschlange umhaengen. */
TcpipSV(); /* Pruefe auf Status, Informationstransfer und ggf */
}
/* Aktuelle TCPIP-Daten sichern. */
void DumpTCP(MBHEAD* mbp)
{
T_INTERFACE *ifpoi;
UWORD Interface = KISS_TCPIP;
int i;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(DumpTCP)";
#endif /* DEBUG_MODUS */
for (i = 0; i < MAXINTERFACE; i++, ifpoi++) /* INTERFACE-TBL durchgehen. */
{
if ((ifpoi = SearchIf(Interface++)) == NULL) /* Zeiger auf das akt. Inter.*/
continue; /* Zum naechsten Interface. */
if (ifpoi->actively == TRUE) /* Nur wenn Interface aktiv. */
{
putprintf(mbp,";\r; %s-Server\r;\r", ifpoi->name);
putprintf(mbp,"%s P ", ifpoi->name);
putnum(Ntohs(ifpoi->tcpport), mbp);
putprintf(mbp,"\r%s L %u",ifpoi->name, ifpoi->log);
putstr("\r;\r",mbp);
}
}
#ifdef L1IPCONV
IPConvDump(mbp);
#endif /* L1IPCONV */
}
/* Pruefe Loginzeichen. */
BOOLEAN CheckContens(char contents)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckContens)";
#endif /* DEBUG_MODUS */
if ( !(contents >= 'A' && contents <= 'Z')
&& !(contents >= 'a' && contents <= 'z')
&& !(contents >= '0' && contents <= '9')
&& !(contents == '-')
&& !(contents == '/')
#ifdef L1TELNET
&& !((contents == '#') && (tcppoi->Interface != KISS_TELNET))
#endif /* L1TELNET. */
#ifdef L1IPCONV
&& !((contents == ' ') && (tcppoi->Interface == KISS_IPCONV))
#endif /* L1IPCONV */
#ifdef L1IRC
&& !((contents == ' ') && (tcppoi->Interface == KISS_IRC))
#endif /* L1IRC */
&& !(contents == CR )
&& !(contents == LF ))
return(TRUE);
else
return(FALSE);
}
/* Info vom L7 an TCPIP-Interface senden */
BOOLEAN itoTCP(BOOLEAN conflg, MBHEAD *ublk)
{
TCPIP *tcppoi = (TCPIP *)ublk->l2link;
int mem = (nmbfre_max / 2);
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(itoTCP)";
#endif /* DEBUG_MODUS */
if ( (conflg == TRUE)
||(tcppoi->outlin < conctl))
{
if ((ublk->mbpc - ublk->mbgc) == 0) /* Frames ohne Info ignorieren */
{
T_LOGL1(TRUE, "(itoTCP):%s\nFrames ohne Info ignorieren.\n"
, tcppoi->ip);
dealmb((MBHEAD *)ulink((LEHEAD *)ublk)); /* Frame entsorgen.*/
return (TRUE); /* Frame verarbeitet. */
}
if ( (nmbfre < 300)
||(mem < (nmbfre_max - nmbfre)))
{
dealmb((MBHEAD *)ulink((LEHEAD *)ublk)); /* Frame entsorgen.*/
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(itoTCP):%s\nSpeicher (%d) ist voll!\n"
, tcppoi->ip
, nmbfre);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
return (TRUE); /* Frame verarbeitet. */
}
/* Markiere das es was zu senden gibt */
relink(ulink((LEHEAD *)ublk), (LEHEAD *)tcppoi->outbuf.tail);
ublk->type = L2MNIX; /* Info-Frame (keine Meldung) */
ublk->l4type = HMRINFO;
++tcppoi->outlin; /* Frame in die Warteschlange haengen. */
return (TRUE); /* Frame verarbeitet. */
}
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(itoTCP):%s\nLink ist verstopft!\n"
, tcppoi->ip);
return (FALSE); /* Link ist verstopft. */
}
/* User hat ein Disconnect eingeleitet. */
void SetDiscTCP(void)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SetDiscTCP)";
#endif /* DEBUG_MODUS */
/* ggf. Logbuch fuehren. */
ifpp = SetInterface(tcppoi->Interface);
T_LOGL2(TRUE, "(SetDiscTCP):%s\nTCP-Segment auf Disconnect setzen!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
}
/* TCPIP-Timer */
void TimerTCP(void)
{
int i,
j = 0;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(TimerTCP)";
#endif /* DEBUG_MODUS */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi)/* TBL durchgehen. */
{
if (tcppoi->activ) /* Nur wenn aktiv. */
{
if ( (tcppoi->noacti != FALSE) /* Noactivity-Timer reduzieren */
&&(--tcppoi->noacti == FALSE)) /* und ggf. User disconnecten. */
{
ifpp = SetInterface(tcppoi->Interface);
/* ggf. Logbuch fuehren. */
T_LOGL1(TRUE, "(TimerTCP):%s\nNoactivity-Timer abgelaufen, Segment auf DISC stellen!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf Disconnect setzen. */
continue;
}
if (tcppoi->T3 == 0) /* T3-Timer abgelaufen. */
{
MhUpdateTCP(NULL, TRUE); /* MH-Liste updaten. */
tcppoi->T3 = T3PARA; /* T3-Timer neusetzen */
}
else
tcppoi->T3--; /* T3-Timer ist noch nicht abgelaufen, */
/* weiter runterzaehlen. */
}
if ( ((tcppoi->activ) /* Sind alle aktiven Sockets durchlaufen, */
&& (j++ >= tcp_tbl_top))
|| (j == tcp_tbl_top))
break; /* brechen wir ab. */
}
}
/* System- und Errormeldungen in einer Logdatei schreiben. */
void WriteLogTCP(BOOLEAN flag, const char *format, ...)
{
FILE *fp = NUL;
va_list arg_ptr;
struct tm *lt;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(WriteLogTCP)";
#endif /* DEBUG_MODUS */
if (ifpp == NULL) /* Kein Interface angegeben!!!. */
{
printf("(WriteLogTCP): ACHTUNG, kein Interface angegeben!!!\n");
return; /* keine Meldung schreiben. */
}
switch(ifpp->Interface)
{
#ifdef L1TELNET
case KISS_TELNET:
{
if (!ifpp->log) /* Loglevel ist nicht eingeschaltet. */
return; /* Keine Logmeldungen schreiben. */
fp = fopen(TELNETLOG, "a+"); /* Datei oeffnen. */
break;
}
#endif /* L1TELNET */
#ifdef L1HTTPD
case KISS_HTTPD:
{
if (!ifpp->log) /* Loglevel ist nicht eingeschaltet. */
return; /* Keine Logmeldungen schreiben. */
fp = fopen(HTTPDLOG, "a+"); /* Datei oeffnen. */
break;
}
#endif /* L1HTTPD */
#ifdef L1IPCONV
case KISS_IPCONV:
{
if (!ifpp->log) /* Loglevel ist nicht eingeschaltet. */
return; /* Keine Logmeldungen schreiben. */
fp = fopen(IPCONVLOG, "a+"); /* Datei oeffnen. */
break;
}
#endif /* L1IPCONV */
#ifdef L1IRC
case KISS_IRC:
{
if (!ifpp->log) /* Loglevel ist nicht eingeschaltet. */
return; /* Keine Logmeldungen schreiben. */
fp = fopen(IRCLOG, "a+"); /* Datei oeffnen. */
break;
}
#endif /* L1IPCONV */
default :
break;
}
if (fp == NULL) /* Fehler beim oeffnen der Datei. */
{
printf("(WriteLogTCP):\nLOG-Datei kann nicht geoeffnet werden!\n");
return; /* Abbruch. */
}
lt = localtime(&sys_time);
if (flag) /* Datum/Zeit schreiben. */
fprintf(fp, "%16.16s ", ctime(&sys_time));
va_start(arg_ptr, format);
vfprintf(fp, format, arg_ptr);
va_end(arg_ptr);
fprintf(fp, "\n");
fclose(fp); /* Datei schliessen. */
}
/* TCPIP-Sockets killen. */
int KillTCP(UWORD port, char *call, WORD what)
{
int i = FALSE;
UWORD kill_zaehler = FALSE;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(KillTCP)";
#endif /* DEBUG_MODUS */
/* Alle Aktive Sockets durchlaufen. */
for (i = 0, tcppoi = tcptbl; i < MAXTCPIP; ++i, ++tcppoi) /* TBL durchgehen */
{
if ( (tcppoi->activ) /* Nur wenn aktiv. */
&&((tcppoi->port == port) /* Port gleich. */
|| (port == 255))) /* oder alle Port's. */
{
switch(what)
{
case 1 : /* Rufzeichen disconnecten. */
if (!cmpid (call, tcppoi->Upcall)) /* Callvergleich. */
continue; /* zum naechsten eintrag. */
break;
case 3 : /* Alle TCPIP-Links disconnecten. */
break;
default: /* Ungueltige option. */
continue; /* Zum naechsten eintrag. */
}
ifpp = SetInterface(tcppoi->Interface); /* akt. Interface setzen. */
/* ggf. Logbuch fuehren. */
T_LOGL1(TRUE, "(KillTCP):%s\nSegment wird auf DISC gesetzt!\n"
, tcppoi->ip);
tcppoi->disflg |= 0x80; /* Segment auf DISC stellen. */
kill_zaehler++; /* Killzaehler um eins hoeher. */
}
}
return(kill_zaehler);
}
/* Buffer besorgen. */
MBHEAD *SetBuffer(void)
{
MBHEAD *tbp = NULL;
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(SetBuffer)";
#endif /* DEBUG_MODUS */
if (nmbfre < 300) /* Buffer liegt unterhalb des Grenzbereich. */
return(NULL); /* Kein Buffer zur Verfuegung. */
if ((tbp = (MBHEAD *) allocb(ALLOC_L1TCPIP)) == NULL) /* Buffer besorgen. */
return(NULL); /* Es steht kein buffer zur Verfuegung. */
return(tbp);
}
/* Pruefe, ob Socket aktiv ist. */
static BOOLEAN CheckSocket(void)
{
#ifdef DEBUG_MODUS
lastfunc = "l1tcpip(CheckSocket)";
#endif /* DEBUG_MODUS */
#ifdef OS_STACK
if (tcppoi->mode == OS_MODE)
return(CheckSocketOS());
#endif /* OS_STACK */
if (Send(tcppoi->sock, "", 0, 0) < 0)
{
ifpp = SetInterface(tcppoi->Interface);
T_LOGL1(TRUE, "(CheckSocket):%s\nSocket ist nicht mehr aktiv!\n"
, tcppoi->ip);
/* Segment auf DISC setzen. */
tcppoi->disflg |= 0x80;
return(TRUE);
}
else
return(FALSE);
return(TRUE);
}
#endif /* L1TCPIP */
/* End of src/l1tcpip.c */