TheNetNode-CB/src/l7ip.c

1006 lines
32 KiB
C
Executable File

/************************************************************************/
/* */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* ***** ***** */
/* *************** *************** */
/* ***************** ***************** */
/* *************** *************** */
/* ***** ***** TheNetNode */
/* ***** ***** Portable */
/* ***** ***** Network */
/* ***** ***** Software */
/* */
/* File src/l7ip.c (maintained by: DG1KWA) */
/* */
/* This file is part of "TheNetNode" - Software Package */
/* */
/* Copyright (C) 1998 - 2008 NORD><LINK e.V. Braunschweig */
/* */
/* This program is free software; you can redistribute it and/or modify */
/* it under the terms of the NORD><LINK ALAS (Allgemeine Lizenz fuer */
/* Amateurfunk Software) as published by Hans Georg Giese (DF2AU) */
/* on 13/Oct/1992; either version 1, or (at your option) any later */
/* version. */
/* */
/* This program is distributed WITHOUT ANY WARRANTY only for further */
/* development and learning purposes. See the ALAS (Allgemeine Lizenz */
/* fuer Amateurfunk Software). */
/* */
/* You should have received a copy of the NORD><LINK ALAS (Allgemeine */
/* Lizenz fuer Amateurfunk Software) along with this program; if not, */
/* write to NORD><LINK e.V., Hinter dem Berge 5, D-38108 Braunschweig */
/* */
/* Dieses Programm ist PUBLIC DOMAIN, mit den Einschraenkungen durch */
/* die ALAS (Allgemeine Lizenz fuer Amateurfunk Software), entweder */
/* Version 1, veroeffentlicht von Hans Georg Giese (DF2AU), */
/* am 13.Oct.1992, oder (wenn gewuenscht) jede spaetere Version. */
/* */
/* Dieses Programm wird unter Haftungsausschluss vertrieben, aus- */
/* schliesslich fuer Weiterentwicklungs- und Lehrzwecke. Naeheres */
/* koennen Sie der ALAS (Allgemeine Lizenz fuer Amateurfunk Software) */
/* entnehmen. */
/* */
/* Sollte dieser Software keine ALAS (Allgemeine Lizenz fuer Amateur- */
/* funk Software) beigelegen haben, wenden Sie sich bitte an */
/* NORD><LINK e.V., Hinter dem Berge 5, D-38108 Braunschweig */
/* */
/************************************************************************/
#include "tnn.h"
#ifdef IPROUTE
/* fuer "IPA" zur Meldung von Aenderungen an die INP-Nachbarn */
extern void send_inp_nodebeacon(PEER *);
/************************************************************************
* Function : ccpipr - The IProute command
*
* Inputs : clipoi/clicnt
*
* Outputs : Routing Tabelle updaten bzw fuer den User anzeigen
*
* Operation : Verwaltung der Routing-Tabellen
*----------------------------------------------------------------------*/
void ccpipr(void)
{
ipaddr host = 0L;
ipaddr gateway = 0L;
UWORD metric;
WORD port;
int bits = 32;
MBHEAD *mbp;
IP_ROUTE *ipr;
unsigned i = 1;
int flags = 0;
mbp = getmbp();
/* nachschaun, ob Parameter angegeben wurden */
if (clicnt > 0)
{
/* eine gueltige IP-Addresse muss der erste Parameter sein,
* danach folgt die Anzahl der Host-bits
*/
if (get_ip_addr(&host, &clicnt, &clipoi))
{
i = 0;
if (skipsp(&clicnt, &clipoi))
{
if (*clipoi == '/')
{
clipoi++;
clicnt--;
if ((bits = nxtnum(&clicnt, &clipoi)) > 32)
bits = 32;
}
/* the sysop only commands are '+' and '-'
*/
if (issyso())
{
skipsp(&clicnt, &clipoi);
switch (*clipoi)
{
case '-':
rt_drop(host, bits, FALSE);
break;
case '+':
clipoi++;
clicnt--;
if (skipsp(&clicnt, &clipoi))
{
if (clicnt >= 2 && clipoi[1] == ' ')
if (toupper(*clipoi) == 'D') {
clipoi += 2;
clicnt -= 2;
flags |= RTDYNAMIC;
}
if (getport(&clicnt, &clipoi, &port) == FALSE)
{
#ifdef KERNELIF
if (toupper(*clipoi) == 'K')
{
nextspace(&clicnt, &clipoi);
port = KERNEL_PORT;
}
else
{
nextspace(&clicnt, &clipoi);
port = NETROM_PORT;
}
#else
nextspace(&clicnt, &clipoi);
port = NETROM_PORT;
#endif
}
get_ip_addr(&gateway, &clicnt, &clipoi);
metric = nxtnum(&clicnt, &clipoi);
host >>= (32 - bits);
host <<= (32 - bits);
rt_add(host, bits, gateway, port, metric, 0, flags, FALSE);
}
}
}
}
}
} else
if (issyso())
putstr("IPROUTE DestIP/HostBts [+/-] [Port/NETROM] GateIP Metric\r", mbp);
host &= ~0L << (32 - bits);
#ifdef SPEECH
putstr(speech_message(264), mbp);
#else
putstr("IP-Routes of ", mbp);
#endif
putalt(alias, mbp);
putid(myid, mbp);
#ifdef SPEECH
putstr(speech_message(265), mbp);
#else
putstr("\rDestination------Len--Flags-Interface--Gateway----------Metric----\r", mbp);
#endif
while (mbp->mbpc < 17) putchr(' ', mbp);
for (ipr = (IP_ROUTE *)IP_Routes.head;
ipr != (IP_ROUTE *)&IP_Routes;
ipr = (IP_ROUTE *)ipr->nextip)
if ((host == ipr->dest &&
bits == ipr->bits) || i) {
showroute(ipr, mbp);
}
prompt(mbp);
seteom(mbp);
}
/************************************************************************
* Function : Einen IPRoute-Eintrag anzeigen
*
* Inputs : Zeiger auf den Eintrag
*
* Outputs : nix
*
* Operation :
*----------------------------------------------------------------------*/
void showroute(IP_ROUTE *rp, MBHEAD *bufpoi)
{
bufpoi->l4time = bufpoi->mbpc; /* Position merken */
show_ip_addr(rp->dest, bufpoi); /* Adresse anzeigen */
putspa(17, bufpoi);
putnum(rp->bits, bufpoi); /* Bitmaske zeigen */
putspa(22, bufpoi);
#ifdef __WIN32__
putchr((char)(rp->flags & RTDYNAMIC ? 'D' : ' '), bufpoi);
#else
putchr(rp->flags & RTDYNAMIC ? 'D' : ' ', bufpoi);
#endif /* >WIN32 */
putspa(28, bufpoi);
#ifndef KERNELIF
putstr(rp->port == NETROM_PORT ?
"NET/ROM" :
portpar[rp->port].name, bufpoi);
#else
switch(rp->port)
{
case NETROM_PORT: putstr("NET/ROM", bufpoi);
break;
case KERNEL_PORT: putstr("KERNEL", bufpoi);
break;
default : putstr(portpar[rp->port].name, bufpoi);
}
#endif
putspa(39, bufpoi);
if (rp->gateway != 0)
show_ip_addr(rp->gateway, bufpoi); /* Gateway */
putspa(58, bufpoi);
if (rp->metric != 0) /* if metric set, */
putnum(rp->metric, bufpoi); /* show metric */
putchr('\r', bufpoi);
return;
}
/************************************************************************
* Function : eine IP-Addresse anzeigen
*
* Inputs : Die IP-Addresse und ein IP-Buffer
*
* Outputs : nix
*
* Operation :
*----------------------------------------------------------------------*/
void show_ip_addr(ipaddr address, MBHEAD *bufpoi)
{
#ifdef __WIN32__
ULONG adr[4];
#else
UWORD adr[4];
#endif /* WIN32 */
int i;
for (i = 0; i < 4; i++) adr[i] = ((address >> 8 * i) & 0xff);
putprintf(bufpoi, "%d.%d.%d.%d", adr[3], adr[2], adr[1], adr[0]);
}
/* **********************************************************************
* Function : Eine IP-Addresse aus der Kommandozeile lesen
*
* Inputs : clipoi/clicnt
*
* Outputs : FALSE bei Fehler, TRUE wenn ok
*
* Operation :
* ---------------------------------------------------------------------*/
BOOLEAN get_ip_addr(ipaddr *target, WORD *count, char **ptr)
{
UWORD num;
ULONG adr;
int i;
for (adr = 0, i = 0; i < 4; i++) {
if ((num = nxtnum(count, ptr)) > 255)
return(FALSE);
adr = (adr << 8) | num;
if (i < 3) {
if ((*count < 1) || (**ptr != '.'))
return(FALSE);
else
{
(*ptr)++;
(*count)--;
}
}
}
*target = adr;
return(TRUE);
}
/************************************************************************
* Function : ARP - Der ARP-Befehl
*
* Inputs : clicnt, clipoi & arp table
*
* Outputs : Updates table.
*
* Operation : Eintrag Hinzufuegen (Sysop) oder Tabelle anzeigen
* ---------------------------------------------------------------------*/
void ccparp(void)
{
ipaddr host;
WORD hwport = 0, dgmode = 0;
unsigned i;
MBHEAD *mbp;
ARP_TAB *arp;
char call[L2IDLEN];
char digi[65];
/* wieso 65??? */
unsigned publish;
unsigned ttl;
mbp = getmbp();
digi[0] = 0;
publish = FALSE;
host = 0;
ttl = 0;
if (issyso())
{
if (skipsp(&clicnt, &clipoi))
{
#ifndef IPROUTEMOD
if (!get_ip_addr(&host, &clicnt, &clipoi))
host = 0L;
#else
if (get_ip_addr(&host, &clicnt, &clipoi) == FALSE)
{
#ifdef SPEECH
putmsg(speech_message(267));
#else
putmsg("\rERROR : Invalid IP-Adresse !\r");
#endif /* SPEECH */
return;
}
else
{
/* Wir puerfen den Host ob dieser Gueltig ist.*/
if (host == FALSE)
{
/* Host ist 0, keine Gueltig IP-Adresse. */
#ifdef SPEECH
putmsg(speech_message(267));
#else
putmsg("\rERROR : Invalid IP-Adresse !\r");
#endif /* SPEECH */
return;
}
}
#endif /* IPROUTEMOD */
skipsp(&clicnt, &clipoi);
switch (*clipoi)
{
case '-':
clipoi++;
clicnt--;
if (!host) break;
if (skipsp(&clicnt, &clipoi))
if (getport(&clicnt, &clipoi, &hwport) == FALSE)
hwport = NETROM_PORT;
arp_drop(host, hwport, FALSE);
break;
case '+':
clipoi++;
clicnt--;
if (skipsp(&clicnt, &clipoi)) {
if (clipoi[1] == ' ') {
publish = toupper(*clipoi++) == 'P';
clicnt--;
nextspace(&clicnt, &clipoi);
}
}
if (skipsp(&clicnt, &clipoi)) {
if (getport(&clicnt, &clipoi, &hwport) == FALSE) {
hwport = NETROM_PORT;
nextspace(&clicnt, &clipoi);
} else
if (skipsp(&clicnt, &clipoi)) {
if (clicnt > 2 && clipoi[2] == ' ') {
if (toupper(*clipoi) == 'D') dgmode = 1;
else if (toupper(*clipoi) == 'V') dgmode = 2;
nextspace(&clicnt, &clipoi);
}
}
}
if (getcal(&clicnt, &clipoi, TRUE, call) == YES) {
getdig(&clicnt, &clipoi, TRUE, digi);
digi[14] = 0; /* auf 2 Hops begrenzen */
arp_add(host, hwport, call, digi, dgmode, ttl, publish, FALSE);
}
else /* Fehler */
#ifdef SPEECH
putstr(speech_message(258),mbp);
#else
putstr("\rERROR : Port or Call invalid !\r",mbp);
#endif
}
} else
if (issyso())
putstr("ARP DestIP + [Publ.] PORT [DG/VC] CALL [DIGI1[DIGI2]]\r"
"ARP DestIP - PORT\r", mbp);
}
/* ARP-Tabelle ausgeben */
#ifdef SPEECH
putstr(speech_message(259), mbp);
#else
putstr("ARP-Table of ", mbp);
#endif
putalt(alias, mbp);
putid(myid, mbp);
#ifdef SPEECH
putstr(speech_message(260), mbp);
#else
putstr("\rDestination P Interface Callsign Digi Mode Timer\r", mbp);
#endif
i = (host == 0L);
for (arp = (ARP_TAB *)Arp_tab.head;
arp != (ARP_TAB *)&Arp_tab;
arp = (ARP_TAB *)arp->nextar)
if ((i != 0) ||
(host == arp->dest))
showarp(arp, mbp);
prompt(mbp);
seteom(mbp);
}
/************************************************************************
* Function : showarp()
*
* Inputs : Zeiger auf einen arp-Eintrag und einen Buffer
*
* Outputs : Text...
*
* Operation :
*----------------------------------------------------------------------*/
void showarp(ARP_TAB *arp, MBHEAD *bufpoi)
{
const char *dgmode_tab[] = {"", "DG", "VC"};
bufpoi->l4time = bufpoi->mbpc;
show_ip_addr(arp->dest, bufpoi);
putspa(17, bufpoi);
putstr((arp->publish_flag ? "P " : " "), bufpoi);
putstr((arp->port == NETROM_PORT ?
"NET/ROM" : portpar[arp->port].name) , bufpoi);
putspa(30, bufpoi);
putid(arp->callsign, bufpoi);
putspa(39, bufpoi);
putdil(arp->digi, bufpoi);
putspa(64, bufpoi);
putstr(dgmode_tab[(int)arp->dgmode], bufpoi);
if (arp->timer != 0)
{
putspa(70, bufpoi);
putnum(arp->timer, bufpoi);
}
putchr('\r', bufpoi);
}
/************************************************************************/
/* */
/* Function : Die IP-Adresse und Bits fuer Subnetz-Maske des Knotens */
/* anzeigen bzw. aendern */
/* */
/* Inputs : clipoi/clicnt */
/* */
/* Outputs : nix, my_ip_address und my_ip_bits wird geaendert bzw. */
/* angezeigt */
/* */
/* Operation: nur wenn Sysop Aenderung erlaubt */
/* */
/************************************************************************/
void
ccpipa(void)
{
MBHEAD *bufpoi;
PEER *pp;
int i;
int iCalls = 0;
int max_peers = netp->max_peers;
BOOLEAN bChanges = FALSE;
ipaddr t_ip_addr = 0L; /* temporaere IP */
int t_ip_bits = 32; /* temporaere Subnetzbits */
if (issyso()) /* nur als Sysop duerfen wir aendern */
{
if (get_ip_addr(&t_ip_addr, &clicnt, &clipoi) == TRUE) /* IP lesen */
{
/* Unmoegliche IP-Adressen abfangen (nur niederwertigstes Byte) */
/* eigentlich muesste man die anderen auch noch pruefen... */
if (((t_ip_addr & 0xFF) == 0L) || ((t_ip_addr & 0xFF) == 0xFF))
{
#ifdef SPEECH
putmsg(speech_message(266));
#else
putmsg("Invalid IP address!\r");
#endif
return;
}
if (skipsp(&clicnt, &clipoi)) /* sind noch weitere Zeichen da? */
{
if (*clipoi++ == '/') /* Subnetz-Trenner vorhanden? */
{
clicnt--;
/* Subnetz-Bits lesen und Idiotencheck machen */
t_ip_bits = nxtnum(&clicnt, &clipoi);
if (t_ip_bits > 32 || t_ip_bits < 1)
t_ip_bits = 32;
}
}
my_ip_addr = t_ip_addr;
if (t_ip_addr == 0L)
my_ip_bits = 0;
else
my_ip_bits = t_ip_bits; /* Subnetz-Bits uebernehmen */
bChanges = TRUE; /* es gibt Aenderungen */
}
}
bufpoi = getmbp();
#ifdef SPEECH
putstr(speech_message(261), bufpoi);
#else
putstr("My IP address: ", bufpoi);
#endif
show_ip_addr(my_ip_addr, bufpoi);
if ((issyso()) && (bChanges == TRUE))
{
/* INP-Nachbarn die Aenderung mitteilen */
for (i = 0, pp = netp->peertab; i < max_peers; ++i, ++pp)
{
if (!pp->used)
continue;
if (pp->typ != INP)
continue;
if (iCalls == 0)
putprintf(bufpoi, "Notifying INP-neighbours about changes. (");
if (++iCalls > 1)
putprintf(bufpoi, " ");
putid(pp->l2link->call, bufpoi); /* Node Call ausgeben */
send_inp_nodebeacon(pp);
}
if (iCalls != 0)
putprintf(bufpoi, ")\r");
}
putprintf(bufpoi, "/%d\r", my_ip_bits);
prompt(bufpoi);
seteom(bufpoi);
}
void ccp_ip_help(ipaddr *ip_addr, const char *name)
{
MBHEAD *bufpoi;
if (issyso())
get_ip_addr(ip_addr, &clicnt, &clipoi);
bufpoi = putals(name);
#ifdef SPEECH
putstr(speech_message(262), bufpoi);
#else
putstr(" IP address : ", bufpoi);
#endif
show_ip_addr(*ip_addr, bufpoi);
putchr('\r', bufpoi);
prompt(bufpoi);
seteom(bufpoi);
}
/************************************************************************
* Function : Die Knoten Broadcast-Addresse aendern
*
* Inputs : clipoi/clicnt
*
* Outputs : bcast_ip_address wird geaendert und angezeigt
*
* Operation : nur wenn Sysop Aenderung erlaubt
* ---------------------------------------------------------------------*/
/* erstmal gesperrt - weil man's laut doku sowieso nicht verwenden darf */
#if 0
void ccpipb()
{
ccp_ip_help(&bcast_ip_addr, "Broadcast");
}
#endif
/*partyp iptab[] = {
&Ip_mib[0].value.integer, 0, MAXPORTMASK,
&Ip_mib[1].value.integer, 0, 1,
&Ip_mib[2].value.integer, 2, MAXTTL,
&Ip_mib[3].value.integer, 0, 0,
&Ip_mib[4].value.integer, 0, 0,
&Ip_mib[5].value.integer, 0, 0,
&Ip_mib[6].value.integer, 0, 0,
&Ip_mib[7].value.integer, 0, 0,
&Ip_mib[8].value.integer, 0, 0,
&Ip_mib[9].value.integer, 0, 0,
&Ip_mib[10].value.integer, 0, 0,
&Ip_mib[11].value.integer, 0, 0,
&Ip_mib[12].value.integer, 0, 0,
&Ip_mib[13].value.integer, 1, 65535,
&Ip_mib[14].value.integer, 0, 0,
&Ip_mib[15].value.integer, 0, 0,
&Ip_mib[16].value.integer, 0, 0,
&Ip_mib[17].value.integer, 0, 0,
&Ip_mib[18].value.integer, 0, 0,
&Ip_mib[19].value.integer, 0, 0
};
partyp arptab[] =
{
&ARPrunning, 0, 1,
&ARPtimer, 15, 24*60
};
*/
/* ***********************************************************************
* as per iptab, this is the ICMP MIB. It is not currently used
*/
#ifdef ICMPSTATS
partyp icmptab[] = {
&Icmp_mib[1].value.integer, 0, 0,
&Icmp_mib[2].value.integer, 0, 0,
&Icmp_mib[3].value.integer, 0, 0,
&Icmp_mib[4].value.integer, 0, 0,
&Icmp_mib[5].value.integer, 0, 0,
&Icmp_mib[6].value.integer, 0, 0,
&Icmp_mib[7].value.integer, 0, 0,
&Icmp_mib[8].value.integer, 0, 0,
&Icmp_mib[9].value.integer, 0, 0,
&Icmp_mib[10].value.integer, 0, 0,
&Icmp_mib[11].value.integer, 0, 0,
&Icmp_mib[12].value.integer, 0, 0,
&Icmp_mib[13].value.integer, 0, 0,
&Icmp_mib[14].value.integer, 0, 0,
&Icmp_mib[15].value.integer, 0, 0,
&Icmp_mib[16].value.integer, 0, 0,
&Icmp_mib[17].value.integer, 0, 0,
&Icmp_mib[18].value.integer, 0, 0,
&Icmp_mib[19].value.integer, 0, 0,
&Icmp_mib[20].value.integer, 0, 0,
&Icmp_mib[21].value.integer, 0, 0,
&Icmp_mib[22].value.integer, 0, 0,
&Icmp_mib[23].value.integer, 0, 0,
&Icmp_mib[24].value.integer, 0, 0,
&Icmp_mib[25].value.integer, 0, 0,
&Icmp_mib[26].value.integer, 0, 0
};
/* ***************************************************************************
* Function : ccpics() - the icmp stats parameters command
*
* Inputs : none - reads ICMP MIB passes it on to ccp_par()
*
* Outputs : as per ccp_par
*
* Operation : updates and / or displays ICMP MIB data
* -------------------------------------------------------------------------*/
void ccpics(void)
{
ccp_par(icmptab, (sizeof(icmptab) / sizeof(struct param)));
}
#endif
/************************************************************************
* Function : Einen Ping absenden
*
* Inputs : clipoi/clicnt
*
* Outputs : nix, bis auf ein Ping-Frame
*
* Operation : Die Antwort erfolgt dann durch das Echo-Frame
* ---------------------------------------------------------------------*/
void ccpping(void)
{
ipaddr ip_addr;
MBHEAD *mbp;
mbp = putals("");
if (get_ip_addr(&ip_addr, &clicnt, &clipoi))
{
if (pingem(ip_addr, 0, 0, 0, NULL)) {
putstr("ping ", mbp);
show_ip_addr(ip_addr, mbp);
putstr(" ...\r", mbp);
} else {
#ifdef SPEECH
putstr(speech_message(263), mbp);
#else
putstr("No route to ", mbp);
#endif
show_ip_addr(ip_addr, mbp);
putstr("\r", mbp);
}
} else putstr("Syntax: PING <ipaddr>\r", mbp);
prompt(mbp);
seteom(mbp);
}
/************************************************************************
* Function : rt_add
*
* Inputs : Host-Addressen
* Hostbits in der Addresse
* Gateway-Addresse ( 0 wenn kein Gateway )
* Port-Nummer ( NETROM_PORT oder L2-Port )
* Metric
* Time to Live fuer diesen Eintrag
* Flag fuer private Routen (kein Publish)
*
* Returns : TRUE / FALSE ob die Tabelle gaendert wurde
*
* Operation : Eintrag hinzufuegen oder aendern
*----------------------------------------------------------------------*/
BOOLEAN rt_add(ipaddr target, unsigned bits, ipaddr gateway, int port,
unsigned metric, unsigned ttl, int flags, BOOLEAN automatic)
{
IP_ROUTE *iprp;
IP_ROUTE *iprp2;
ipaddr temp;
BOOLEAN new_entry = FALSE;
/* Tabelle durchsuchen, wenn ein Eintrag existiert dann diesen updaten, */
/* sonst neuen Eintrag erzeugen */
if (!route_find(&iprp, &temp, target, bits))
{
iprp2 = (IP_ROUTE *)allocb(ALLOC_IP_ROUTE);
relink((LEHEAD *)iprp2, (LEHEAD *)iprp->previp);
iprp = iprp2;
new_entry = TRUE;
}
iprp2 = iprp;
iprp2->dest = target;
iprp2->gateway = gateway;
iprp2->bits = bits;
iprp2->port = port;
iprp2->metric = metric;
iprp2->timer = ttl;
iprp2->flags = flags;
/* neuer Eintrag, nur dann dieses Flag anfassen */
if (new_entry == TRUE)
iprp2->automatic_flag = automatic;
return(TRUE);
}
/************************************************************************
* Function : route_find() - Sucht nach einer Route fuer eine IP-Addresse
*
* Inputs : Zeiger auf den IP-Route-Buffer, Zeiger auf das Ergebnis
* Zeiger auf die gewuenschte Ziel-Addresse und die Hostbits
*
* Returns : BOOLEAN, die maskierte Addresse, und der Eintrag,
* falls gefunden
*
* Operation : Sucht nach einem exakt passenden Eintrag nach Hostbits
* und Addresse
*----------------------------------------------------------------------*/
BOOLEAN route_find(IP_ROUTE **iprptr, ipaddr *temp, ipaddr target,
unsigned bits)
{
IP_ROUTE *iprp;
(*temp) = target;
if (bits > 32)
bits = 32;
(*temp) &= (~0L) << (32 - bits);
for (iprp = (IP_ROUTE *)IP_Routes.head;
iprp != (IP_ROUTE *)&IP_Routes && bits <= iprp->bits;
iprp = (IP_ROUTE *)iprp->nextip)
if (iprp->dest == (*temp) && iprp->bits == bits)
{
*iprptr = iprp;
return(TRUE);
}
*iprptr = iprp;
return(FALSE);
}
/************************************************************************
* Function : Einen Eintrag aus der Route-Tabelle loeschen
*
* Inputs : Die IP-Addresse und die Bitmaske
*
* Returns : Ergebnis BOOLEAN, veraendert die Routing-Tabelle
*
* Operation : Eintrag suchen und loeschen
* ---------------------------------------------------------------------*/
BOOLEAN rt_drop(ipaddr target, unsigned bits, BOOLEAN automatic)
{
IP_ROUTE *iprp;
ipaddr temp;
if (route_find(&iprp, &temp, target, bits))
{
/* nicht automatisch gemachte Eintrage nicht anfassen wenn */
/* wir von einer Automatik aufgerufen worden sind */
if ((automatic == TRUE) && (iprp->automatic_flag != TRUE))
return(FALSE);
dealoc((MBHEAD *) ulink((LEHEAD *) iprp));
return(TRUE);
}
return(FALSE);
}
/************************************************************************
* Function : Einen Eintrag in der ARP-Tabelle machen
*
* Inputs : Die IP-Addresse, der Hardware-Port, die Hardware-
* Addresse (Rufzeichen), Datagram-Flag, Time_to_Live
* und Publish-Flag
* WICHTIG: digi darf nicht zu lang sein, sonst krachts!
* (Dies erledigt die aufrufende Routine!)
*
* Returns : Ergebnis BOOLEAN, aber in Wirklichkeit immer TRUE
*
* Operation : Den passenden Eintrag finden und aendern, sonst einen
* neuen anlegen.
* WICHTIG - Die Tabelle ist in absteigender Reihenfolge
* der Hostbits gespeichert.
*----------------------------------------------------------------------*/
BOOLEAN arp_add(ipaddr target, WORD port, char *callsign, const char *digi,
unsigned dgmode, unsigned ttl, BOOLEAN publish, BOOLEAN automatic)
{
ARP_TAB *arprp;
ARP_TAB *arprp2;
BOOLEAN new_entry = FALSE;
/* Tabelle durchsuchen, wenn ein Eintrag existiert dann diesen updaten, */
/* sonst neuen Eintrag erzeugen */
if (!find_arp(&arprp, target, port))
{
arprp = (ARP_TAB *)allocb(ALLOC_ARP_TAB);
relink((LEHEAD *)arprp, (LEHEAD *)Arp_tab.tail);
new_entry = TRUE;
}
arprp2 = arprp;
arprp2->dest = target;
#ifdef __WIN32__
arprp2->port = (unsigned char)port;
#else
arprp2->port = port;
#endif /* WIN32 */
arprp2->hwtype = port == NETROM_PORT ? ARP_NETROM : ARP_AX25;
arprp2->timer = ttl;
arprp2->publish_flag = publish;
arprp2->dgmode = dgmode;
/* neuer Eintrag, nur dann dieses Flag anfassen */
if (new_entry == TRUE)
arprp2->automatic_flag = automatic;
cpyid(arprp2->callsign, callsign);
cpyidl(arprp2->digi, digi);
return(TRUE);
}
#ifdef NOTUSE
/****************************************************************************
* Function : Ist eine IP-Addresse als ARP bekannt?
*
* Inputs : die IP-Addresse
*
* Returns : Ergebnis BOOLEAN
*-------------------------------------------------------------------------*/
static BOOLEAN is_ipaddr_inuse(ipaddr target)
{
ARP_TAB *arprp;
for (arprp = (ARP_TAB *)Arp_tab.head;
arprp != (ARP_TAB *)&Arp_tab;
arprp = (ARP_TAB *)arprp->nextar)
if (arprp->dest == target)
return(TRUE);
return(FALSE);
}
/****************************************************************************
* Function : Ist auf einem Port ein User als ARP bekannt?
*
* Inputs : die AX25-Addresse, Port
*
* Returns : Ergebnis BOOLEAN
*-------------------------------------------------------------------------*/
static ipaddr is_hwaddr_inuse(char *hwaddr, WORD hwport)
{
ARP_TAB *arprp;
for (arprp = (ARP_TAB *)Arp_tab.head;
arprp != (ARP_TAB *)&Arp_tab;
arprp = (ARP_TAB *)arprp->nextar)
if (cmpid(arprp->callsign, hwaddr) && arprp->port == hwport)
return(arprp->dest);
return(0L);
}
#endif
/****************************************************************************
* Function : Eine IP-Addresse aufloesen
*
* Inputs : Zeiger auf das Ergebnis, die IP-Addresse
*
* Returns : Ergebnis BOOLEAN, arpptr wird gesetzt
*
* Operation : Die ARP-Tabelle nach einem passenden Eintrag absuchen
*-------------------------------------------------------------------------*/
BOOLEAN find_arp(ARP_TAB **arpptr, ipaddr target, WORD hwport)
{
ARP_TAB *arprp;
for (arprp = (ARP_TAB *)Arp_tab.head;
arprp != (ARP_TAB *)&Arp_tab;
arprp = (ARP_TAB *)arprp->nextar)
if ((arprp->dest == target) &&
(hwport == arprp->port))
{
*arpptr = arprp;
return(TRUE);
}
return(FALSE);
}
/************************************************************************
* Function : Einen ARP-Eintrag loeschen
*
* Inputs : Die IP-Nummer und die Hostbits
*
* Returns : Ergebnis BOOLEAN, ARP-Tabelle wird geandert
*
* Operation : Den passenden Eintrag suchen und ab in den Muell
*----------------------------------------------------------------------*/
BOOLEAN arp_drop(ipaddr target, WORD hwport, BOOLEAN automatic)
{
ARP_TAB *arprp;
if (find_arp(&arprp, target, hwport))
{
/* nicht automatisch gemachte Eintrage nicht anfassen wenn */
/* wir von einer Automatik aufgerufen worden sind */
if ((automatic == TRUE) && (arprp->automatic_flag != TRUE))
return(FALSE);
dealoc((MBHEAD *)ulink((LEHEAD *)arprp));
return(TRUE);
}
return(FALSE);
}
/*- End of IP router switch commands ---------------------------------------*/
/*- Start of IP router timer service routine--------------------------------*/
void arpsrv(void)
{
ARP_TAB *arprp;
ARP_TAB *arp;
if (--ARPcounter == 0)
{
ARPcounter = 60;
for (arprp = (ARP_TAB *)Arp_tab.head;
arprp != (ARP_TAB *)&Arp_tab; )
{
if (IPpar[arprp->port].ipMode & ARP_OK) {
arp = arprp;
arprp = (ARP_TAB *)arprp->nextar;
/* ARP-Eintrag entfernen */
if (arp->timer != 0 && --arp->timer == 0)
{
/* eventuell zusaetzlich angelegte Route entfernen */
rt_drop(arp->dest, 32, TRUE);
arp_drop(arp->dest, arp->port, FALSE);
}
}
}
}
}
/*- End of IP router timer service routine------------------------------*/
#endif
/* End of src/l7ip.c */