2301 lines
81 KiB
C
Executable File
2301 lines
81 KiB
C
Executable File
#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 */
|