702 lines
26 KiB
C
Executable File
702 lines
26 KiB
C
Executable File
/************************************************************************/
|
|
/* */
|
|
/* ***** ***** */
|
|
/* ***** ***** */
|
|
/* ***** ***** */
|
|
/* ***** ***** */
|
|
/* *************** *************** */
|
|
/* ***************** ***************** */
|
|
/* *************** *************** */
|
|
/* ***** ***** TheNetNode */
|
|
/* ***** ***** Portable */
|
|
/* ***** ***** Network */
|
|
/* ***** ***** Software */
|
|
/* */
|
|
/* File src/l3inp.c (maintained by: ???) */
|
|
/* */
|
|
/* 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"
|
|
#include "l3local.h"
|
|
|
|
|
|
static BOOLEAN update_options(INDEX, const char *, ULONG, UBYTE, MBHEAD *);
|
|
UWORD max_lt = 30; /* maximaler HopCounter */
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* Wenn sich die Info zu einem Node aendert, werden alle INP-Routes zur */
|
|
/* Aktualisierung ausgeschrieben. */
|
|
/* */
|
|
/************************************************************************/
|
|
void
|
|
propagate_node_update(INDEX index)
|
|
{
|
|
PEER *pp;
|
|
ROUTE *rp;
|
|
unsigned int max_peers = netp->max_peers;
|
|
unsigned int i = 0;
|
|
|
|
for (pp = netp->peertab; i < max_peers; i++, pp++)
|
|
{
|
|
if (!pp->used) /* nur benutzte Eintraege */
|
|
continue;
|
|
if (pp->typ != INP) /* nur INP-Links */
|
|
continue;
|
|
rp = pp->routes + index; /* Zeiger auf Route */
|
|
|
|
if (rp->reported_quality) /* nur wenn wir gemeldet hatten */
|
|
rp->reported_quality = DIRTY;
|
|
}
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* Auswertung von empfangenen INP-Routinginformationen */
|
|
/* */
|
|
/************************************************************************/
|
|
BOOLEAN
|
|
rx_inp_broadcast(PEER *rxpp, MBHEAD *mbp)
|
|
{
|
|
char desnod[L2IDLEN]; /* Callsign */
|
|
char beaide[L2CALEN], /* Alias */
|
|
*bp;
|
|
|
|
UBYTE uHopCounter; /* Hops */
|
|
UWORD uTransportTime; /* Laufzeit */
|
|
UBYTE uOptionCode; /* Optionscode */
|
|
UBYTE uOptionLength; /* Optionslaenge */
|
|
UBYTE uOptionData[256]; /* Daten der INP-Option */
|
|
MBHEAD *pOptions; /* Optionszeiger */
|
|
|
|
ULONG uIP_Adr; /* IP-Adresse */
|
|
UBYTE uBits; /* Subnetz-Bits */
|
|
|
|
int i;
|
|
UBYTE ch;
|
|
PEER *pp;
|
|
INDEX index;
|
|
|
|
BOOLEAN bValid; /* Eintrag verwendbar ? */
|
|
|
|
#if MAX_TRACE_LEVEL > 0
|
|
char notify_call1[10];
|
|
#if MAX_TRACE_LEVEL > 2
|
|
char notify_call2[10];
|
|
#endif
|
|
#endif
|
|
|
|
if (*mbp->mbbp != INP_RIF) /* Kennung INP-Routing-Paket? */
|
|
return (FALSE); /* Nein, dann Puffer ungelesen zurueckgeben */
|
|
|
|
getchr(mbp); /* RIF-Kenner uebergehen */
|
|
|
|
/* Ist noch mind. ein RIP (ohne Optionen) im RIF ? */
|
|
/* (Call + Hop + Time + EOP = 7 + 1 + 2 + 1 = 11) */
|
|
while ((mbp->mbpc - mbp->mbgc) > 10)
|
|
{
|
|
/* Nodeseintrag lesen ggf. incl. Alias, IP-Nr./Subnet und anderen */
|
|
/* INP-Options. Fehler werden zunaechst ignoriert. */
|
|
bValid = TRUE; /* Eintrag gueltig */
|
|
cpyals(beaide, DONT_CHANGE_ALIAS); /* Default: kein Alias */
|
|
uIP_Adr = 0L; /* und keine IP-Adresse */
|
|
uBits = 0; /* keine IP-Subnetzbits */
|
|
pOptions = NULL; /* sowie keine Options */
|
|
uHopCounter = 0; /* Hop Counter */
|
|
uTransportTime = 0; /* Laufzeit */
|
|
memset(desnod, 0, sizeof(desnod)); /* Noch kein Zielknoten */
|
|
|
|
if (!getfidc(desnod, mbp)) /* Call holen */
|
|
bValid = FALSE; /* Eintrag ungueltig */
|
|
|
|
if (valcal(desnod) == ERRORS) /* Call gueltig ? */
|
|
bValid = FALSE; /* Eintrag ungueltig */
|
|
|
|
uHopCounter = getchr(mbp); /* Hop-Counter lesen */
|
|
uTransportTime = get16(mbp); /* Laufzeit lesen */
|
|
|
|
if (uHopCounter == 0) /* HopCount 0 darf nie gesendet werden, */
|
|
uHopCounter = DEFAULT_LT; /* korrigieren */
|
|
else
|
|
++uHopCounter; /* Hop-Counter erhoehen */
|
|
|
|
/* Endekriterium fuer den Nodeseintrag ist das EOP-Byte (0x00) */
|
|
/* des RIP-Blocks. Danach koennen weitere Nodeseintraege folgen. */
|
|
while (mbp->mbpc > mbp->mbgc)
|
|
{
|
|
/* Einzelnen Options-Eintrag lesen und auswerten */
|
|
/* Laenge der Option holen */
|
|
uOptionLength = getchr(mbp);
|
|
|
|
if (uOptionLength == INP_EOP) /* EOP ? */
|
|
break; /* alle Optionen gelesen */
|
|
|
|
--uOptionLength; /* Laengenbyte von der Optionslaenge abziehen */
|
|
|
|
/* Sind noch genug Zeichen da ? */
|
|
if ((mbp->mbpc - mbp->mbgc) < uOptionLength) /* INP-Fehler! */
|
|
{
|
|
/* Der Fehler wird gemeldet, die fehlerhaften Options werden */
|
|
/* komplett verworfen, damit wir keinen Muell weitermelden. */
|
|
#if MAX_TRACE_LEVEL > 0
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
notify(1, "INP: frame error received from %s, "
|
|
"len = %u, left = %u", notify_call1, uOptionLength,
|
|
(UWORD)(mbp->mbpc - mbp->mbgc));
|
|
#endif
|
|
/* Unbekannte Optionen ? Dann diese loeschen */
|
|
if (pOptions != NULL)
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
|
|
/* nicht zu gebrauchen */
|
|
bValid = FALSE;
|
|
|
|
break;
|
|
}
|
|
|
|
uOptionCode = getchr(mbp); /* Optionstyp holen */
|
|
--uOptionLength; /* Typenfeld von der Optionslaenge abziehen */
|
|
|
|
/* Daten der Option holen */
|
|
memset(uOptionData, 0, sizeof(uOptionData));
|
|
for (i = 0; i < uOptionLength; ++i)
|
|
uOptionData[i] = getchr(mbp);
|
|
|
|
/* Option bestimmen */
|
|
switch (uOptionCode)
|
|
{
|
|
/* Alias */
|
|
case INP_ALIAS:
|
|
|
|
/* Laengencheck */
|
|
if (uOptionLength > L2CALEN)
|
|
{
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
notify(3, "alias from %s too long (cut)", notify_call1);
|
|
#endif
|
|
}
|
|
|
|
/* Alias kopieren und checken */
|
|
for (i = 0, bp = beaide; (i < uOptionLength) && (i <= L2CALEN); ++i)
|
|
{
|
|
ch = uOptionData[i];
|
|
|
|
/* Pruefung auf ungueltige Zeichen */
|
|
if ((ch < ' ') || (ch > 127))
|
|
{
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
notify(3, "invalid alias from %s (flushed)", notify_call1);
|
|
#endif
|
|
/* Unbekannte Optionen loeschen wenn vorhanden */
|
|
if (pOptions != NULL)
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
|
|
/* nicht zu gebrauchen */
|
|
bValid = FALSE;
|
|
}
|
|
|
|
/* Zeichen gueltig, uebernehmen */
|
|
*bp++ = ch;
|
|
}
|
|
|
|
/* Der Nachbar posaunt seine Secrets durch die Gegend ... */
|
|
if (beaide[0] == '#')
|
|
{
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
call2str(notify_call2, desnod);
|
|
notify(3, "%s sent secret node %s", notify_call1, notify_call2);
|
|
#endif
|
|
/* XNet hat (derzeit ?) einen Fehler, der Nodes mit Geheim-Aliassen */
|
|
/* sendet. Da diese Nodes nicht wirklich geheim sind nehmen wir sie */
|
|
/* trotzdem, loeschen aber ihre Aliasse. */
|
|
if ( (strncasecmp(&beaide[1], "temp", 4) == 0)
|
|
|| (strncasecmp(&beaide[1], "tmp", 3) == 0)
|
|
)
|
|
{
|
|
/* fehlerhaften Alias loeschen */
|
|
cpyals(beaide, DONT_CHANGE_ALIAS); /* Alias loeschen */
|
|
i = L2CALEN; /* brauchen wir nicht mehr auffuellen */
|
|
#if MAX_TRACE_LEVEL > 2
|
|
notify(3, "not real secret node, corrected");
|
|
#endif
|
|
}
|
|
else
|
|
{
|
|
/* Ein echter Secret Node, normal behandeln (loeschen) */
|
|
if (pOptions != NULL)
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
#if MAX_TRACE_LEVEL > 2
|
|
notify(3, "secret node flushed");
|
|
#endif
|
|
/* Eintrag ist nicht zu gebrauchen */
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
|
|
for (; i < L2CALEN; ++i) /* auffuellen mit ' ' */
|
|
*bp++ = ' ';
|
|
|
|
break;
|
|
|
|
/* IP-Adresse */
|
|
case INP_IPA:
|
|
|
|
/* Option lang genug ? */
|
|
if (uOptionLength == 5)
|
|
{
|
|
/* IP-Adresse lesen */
|
|
uIP_Adr = uOptionData[0] << 24;
|
|
uIP_Adr |= uOptionData[1] << 16;
|
|
uIP_Adr |= uOptionData[2] << 8;
|
|
uIP_Adr |= uOptionData[3];
|
|
|
|
/* Hostbits lesen */
|
|
uBits = uOptionData[4];
|
|
}
|
|
else
|
|
{
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
notify(3, "invalid ipa-length %u from %s (flushed)", uOptionLength, notify_call1);
|
|
#endif
|
|
if (pOptions != NULL)
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
|
|
bValid = FALSE;
|
|
}
|
|
|
|
/* Rudimentaerer Check der Subnetz-Bits, sind diese falsch */
|
|
/* wird die IP fuer diesen Node nicht uebernommen, die IP */
|
|
/* wird an anderer Stelle je nach Einstellung ueberprueft */
|
|
if ((uBits == 0) || (uBits > 32))
|
|
{
|
|
uIP_Adr = 0L;
|
|
uBits = 0;
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, desnod);
|
|
notify(3, "invalid subnet-bits for %s, ip not stored", notify_call1);
|
|
#endif
|
|
}
|
|
break;
|
|
|
|
/* unbekannte Option - in Buffer speichern */
|
|
default:
|
|
/* Buffer besorgen wenn nicht schon geschehen */
|
|
if (pOptions == NULL)
|
|
pOptions = (MBHEAD *)allocb(ALLOC_INPOPT);
|
|
|
|
/* Option speichern */
|
|
#ifdef __WIN32__
|
|
putchr((char)(uOptionLength + 2), pOptions); /* Laenge */
|
|
#else
|
|
putchr(uOptionLength + 2, pOptions); /* Laenge */
|
|
#endif /* WIN32 */
|
|
putchr(uOptionCode, pOptions); /* Typ */
|
|
|
|
for (i = 0; i < uOptionLength; ++i) /* Daten */
|
|
putchr(uOptionData[i], pOptions);
|
|
} /* switch (uOptionCode) */
|
|
} /* while (mbp->mbpc > mbp->mbgc) */
|
|
|
|
/* Hat der Nachbar mich selbst gemeldet ? */
|
|
if (cmpid(myid, desnod) || iscall(desnod, NULL, NULL, VC))
|
|
{
|
|
#if MAX_TRACE_LEVEL > 2
|
|
call2str(notify_call1, myid);
|
|
call2str(notify_call2, rxpp->l2link->call);
|
|
notify(3, "destination %s received from %s (ignored)",
|
|
notify_call1, notify_call2);
|
|
#endif
|
|
if (pOptions != NULL)
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
continue;
|
|
}
|
|
|
|
#if MAX_TRACE_LEVEL > 8
|
|
call2str(notify_call1, rxpp->l2link->call);
|
|
call2str(notify_call2, desnod);
|
|
notify(9, "%-9.9s>%-6.6s:%-9.9s Time:%u Hops:%u Valid:%u",
|
|
notify_call1, beaide, notify_call2, uTransportTime, uHopCounter,
|
|
(bValid == TRUE ? 1 : 0));
|
|
|
|
/* IP-Adresse */
|
|
if (uIP_Adr != 0L)
|
|
notify(9, "IP:%u.%u.%u.%u/%u",
|
|
(uIP_Adr >> 24) & 0xFF,
|
|
(uIP_Adr >> 16) & 0xFF,
|
|
(uIP_Adr >> 8) & 0xFF,
|
|
uIP_Adr & 0xFF,
|
|
uBits);
|
|
|
|
if (pOptions)
|
|
notify(9, "unknown options: %u bytes", pOptions->mbpc);
|
|
#endif
|
|
|
|
/* Erhaltenen Eintrag pruefen */
|
|
if (uHopCounter > max_lt) /* Nach Lifetime runterzwingen */
|
|
{
|
|
uTransportTime = 0; /* Knoten nicht annehmen */
|
|
bValid = FALSE;
|
|
}
|
|
|
|
if (cmpid(rxpp->l2link->call, desnod)) /* der Nachbar selbst */
|
|
{
|
|
uTransportTime = 1; /* 10ms auf die Linklaufzeit */
|
|
uHopCounter = 1; /* immer ein Hop entfernt */
|
|
}
|
|
|
|
/* Den Node in der Nodetabelle suchen, ist er schon vorhanden dann */
|
|
/* wird der Eintrag geupdated, ansonsten neu angelegt. */
|
|
if ((index = add_route(rxpp, desnod, uTransportTime)) != NO_INDEX)
|
|
{
|
|
/* Ziele mit diesen Laufzeiten sollen abgemeldet werden */
|
|
if ((uTransportTime == 60000) || (uTransportTime == 0))
|
|
update_lt(rxpp, index, 0);
|
|
else
|
|
/* alle anderen Laufzeiten normaler HopCounter */
|
|
update_lt(rxpp, index, uHopCounter);
|
|
|
|
/* Optionen nehmen wir nur vom primaeren Partner an, */
|
|
/* haben wir noch keine, dann nehmen wir von jedem. */
|
|
/* Haben wir schon optionale Infos ueber den Node ? */
|
|
/* (Alias, IP-Adresse/Subnetzbits, sonstiges) */
|
|
if ( (!cmpcal(netp->nodetab[index].alias, nulide))
|
|
|| (netp->nodetab[index].ipa != 0L)
|
|
)
|
|
{
|
|
if (find_best_qual(index, &pp, DG) > 0) /* beste Qualitaet */
|
|
{
|
|
if (pp != rxpp) /* bester Nachbar ist dieser ? */
|
|
{
|
|
/* Nein, nicht bester Nachbar */
|
|
if (pOptions != NULL) /* eventuelle Optionen loeschen */
|
|
{
|
|
dealmb(pOptions);
|
|
pOptions = NULL;
|
|
}
|
|
bValid = FALSE;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* Der primaere Weg hat sich geaendert, wir uebernehmen Node-Info */
|
|
/* sofern vorhanden (Alias, IP-Nr., Options). Wird keine Zusatzinfo */
|
|
/* gemeldet, bleibt die bisher bekannte Info erhalten. */
|
|
if ( (bValid == TRUE)
|
|
&& (update_options(index, beaide, uIP_Adr, uBits, pOptions))
|
|
)
|
|
{
|
|
propagate_node_update(index);
|
|
pOptions = NULL;
|
|
}
|
|
} /* if (index = add_route(...) ... )*/
|
|
} /* while (...) bis Frameende */
|
|
|
|
/* Wir waren erfolgreich */
|
|
return (TRUE);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* Uebernehmen neuer Zusatzinfos zu einem Node (Alias, IP-Nr./Subnet, */
|
|
/* weitere unbekannte Options). Wird nichts gemeldet, bleiben bekannte */
|
|
/* Daten gespeichert. Wird etwas neu gemeldet, muessen ALLE Daten neu */
|
|
/* gemeldet werden. Alles was nicht mehr gemeldet wird, wird geloescht. */
|
|
/* */
|
|
/************************************************************************/
|
|
static BOOLEAN
|
|
update_options(INDEX index, const char *alias,
|
|
ULONG ip_adr, UBYTE bits, MBHEAD *options)
|
|
{
|
|
NODE *np;
|
|
BOOLEAN res = FALSE;
|
|
BOOLEAN ip_valid = TRUE;
|
|
int len;
|
|
char temp[1];
|
|
ipaddr host;
|
|
|
|
temp[0] = 0; /* damit arp_add() zufrieden ist */
|
|
|
|
if ( !cmpcal(alias, nulide) /* nur wenn ueberhaupt INP- */
|
|
|| ip_adr != 0L /* Options uebertragen wurden */
|
|
|| options != NULL) /* kann sich etwas aendern */
|
|
{
|
|
/* Es wurden Options uebertragen - also muessen alle Options auf den */
|
|
/* neuen Wert gesetzt werden, oder geloescht, falls nicht mehr gemeldet */
|
|
np = netp->nodetab + index;
|
|
res = !cmpcal(np->alias, alias);
|
|
cpyals(np->alias, alias);
|
|
|
|
if ( ip_adr != np->ipa
|
|
|| bits != np->bits)
|
|
res = TRUE;
|
|
|
|
/* ARP- und IPR-Eintrag erneuern */
|
|
/* nur austragen wenn schon was eingetragen gewesen ist und die */
|
|
/* automatische Modifikation erlaubt */
|
|
if (np->ipa != 0L && autoipr != 0)
|
|
{
|
|
arp_drop(np->ipa, NETROM_PORT, TRUE);
|
|
rt_drop(np->ipa, np->bits, TRUE);
|
|
}
|
|
|
|
/* neue Eintraege nur machen wenn nicht leer gemeldet und wir selber */
|
|
/* eine IP-Adresse haben und wir das ueberhaupt duerfen (Param. 12) */
|
|
if (ip_adr != 0L && my_ip_addr != 0L && autoipr != 0)
|
|
{
|
|
/* bevor wir die IP uebernehmen erst mal pruefen wenn wir das sollen */
|
|
if (autoipr >= 2)
|
|
{
|
|
/* elementare Pruefung immer machen */
|
|
if (((ip_adr & 0xFF) == 0L) || ((ip_adr & 0xFF) == 0xFF))
|
|
ip_valid = FALSE;
|
|
|
|
/* nur IPs uebernehmen, die im gleichen Netz sind */
|
|
if ( (autoipr >= 3)
|
|
&& ((ip_adr & 0xFF000000L) != (my_ip_addr & 0xFF000000L)))
|
|
ip_valid = FALSE;
|
|
}
|
|
|
|
if (ip_valid)
|
|
{
|
|
arp_add(ip_adr, NETROM_PORT, np->id, temp, 0, 0, FALSE, TRUE);
|
|
host = ip_adr;
|
|
host >>= (32 - bits);
|
|
host <<= (32 - bits);
|
|
rt_add(host, bits, ip_adr, NETROM_PORT, 0, 0, 0, TRUE);
|
|
}
|
|
}
|
|
|
|
np->ipa = ip_adr;
|
|
np->bits = bits;
|
|
|
|
if (options == NULL) /* keine unbekannten Options? */
|
|
{
|
|
if (np->options != NULL) /* war aber was bekannt? */
|
|
{
|
|
dealmb(np->options);
|
|
np->options = NULL;
|
|
res = TRUE;
|
|
}
|
|
return (res);
|
|
}
|
|
|
|
if (np->options == NULL) /* bisher nix bekannt */
|
|
{
|
|
np->options = options;
|
|
return (TRUE);
|
|
}
|
|
|
|
if ((len = options->mbpc) == np->options->mbpc)
|
|
{
|
|
/* alte und neue Options sind gleich lang - also vergleichen, ob sich */
|
|
/* etwas geaendert hat (wir gehen mal davon aus, dass die Reihenfolge */
|
|
/* unveraendert bleibt) */
|
|
rwndmb(options);
|
|
rwndmb(np->options);
|
|
while (--len >= 0)
|
|
{
|
|
if (getchr(options) != getchr(np->options))
|
|
break;
|
|
}
|
|
|
|
if (len < 0)
|
|
{
|
|
dealmb(options); /* keine neuen Options */
|
|
return (res);
|
|
}
|
|
}
|
|
dealmb(np->options); /* alte Options vergessen */
|
|
np->options = options; /* neue merken */
|
|
return (TRUE); /* Aenderung */
|
|
}
|
|
|
|
return (res);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* "add internode protocol route information" */
|
|
/* */
|
|
/* Einen Weg zu dem Routing-Info-Frame fuer einen Nachbarn hinzufuegen. */
|
|
/* Das Frame wird gesendet, sobald es voll ist oder in brosrv() wenn */
|
|
/* der Timeout abgelaufen ist. */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
void
|
|
add_inp_info(MBHEAD **mbpp, NODE *node, PEER *topp, unsigned qualit,
|
|
unsigned last_qualit, int lt)
|
|
{
|
|
char buf[256],
|
|
*bp,
|
|
*bp2;
|
|
int len;
|
|
|
|
bp = buf;
|
|
|
|
/* Laufzeit 0 entspricht einer Abmeldung */
|
|
if (qualit == 0)
|
|
qualit = HORIZONT;
|
|
|
|
*bp++ = lt; /* Hops eintragen */
|
|
*bp++ = qualit >> 8; /* Laufzeit eintragen */
|
|
*bp++ = qualit & 0xFF;
|
|
|
|
/* Wurde dieser Node schon mal gemeldet ? Falls ja, dann */
|
|
/* die Optionen nicht noch einmal melden. Ausnahme ist nur, */
|
|
/* wenn sich Daten geaendert haben. */
|
|
if ( (qualit && last_qualit == 0)
|
|
|| last_qualit == DIRTY)
|
|
{
|
|
/* Laenge des Alias feststellen */
|
|
for (len = 0; len < L2CALEN; ++len)
|
|
if (node->alias[len] == ' ')
|
|
break;
|
|
|
|
/* Alias uebernehmen */
|
|
if (len != 0)
|
|
{
|
|
*bp++ = len + 2; /* Laenge */
|
|
*bp++ = INP_ALIAS; /* Typ */
|
|
|
|
memcpy(bp, node->alias, (size_t)len); /* Daten */
|
|
bp += len;
|
|
}
|
|
|
|
/* IP-Adresse und Subnetzbits uebernehmen */
|
|
if (node->ipa != 0L)
|
|
{
|
|
*bp++ = 7; /* Laenge */
|
|
*bp++ = INP_IPA; /* Typ */
|
|
|
|
/* IP-Adresse und Subnetzbits eintragen */
|
|
#ifdef __WIN32__
|
|
*bp++ = (unsigned char)(node->ipa >> 24);
|
|
*bp++ = (unsigned char)((node->ipa >> 16) & 0xff);
|
|
*bp++ = (unsigned char)((node->ipa >> 8) & 0xff);
|
|
*bp++ = (unsigned char)(node->ipa & 0xff);
|
|
#else
|
|
*bp++ = node->ipa >> 24;
|
|
*bp++ = (node->ipa >> 16) & 0xff;
|
|
*bp++ = (node->ipa >> 8) & 0xff;
|
|
*bp++ = node->ipa & 0xff;
|
|
#endif /* WIN32 */
|
|
*bp++ = node->bits;
|
|
}
|
|
|
|
/* uns unbekannte Optionen anhaengen */
|
|
if (node->options != NULL)
|
|
{
|
|
rwndmb(node->options);
|
|
while (node->options->mbpc > node->options->mbgc)
|
|
*bp++ = getchr(node->options);
|
|
}
|
|
}
|
|
|
|
*bp++ = 0; /* Ende der Meldung (EOP) */
|
|
len = (int)(bp - buf) + L2IDLEN; /* Laenge berechnen */
|
|
|
|
if (*mbpp) /* noch ein Buffer in Arbeit ? */
|
|
if ((*mbpp)->mbpc + len > 256) /* passt nicht mehr ? */
|
|
brosnd(mbpp, topp); /* dann senden */
|
|
|
|
/* war der Buffer voll so wurde er gesendet und entsorgt, */
|
|
/* *mbpp ist jetzt NULL, das hat brosnd() erledigt */
|
|
|
|
if (*mbpp == NULL) /* noch kein Buffer besorgt */
|
|
{ /* neues I-Frame holen */
|
|
(*mbpp = (MBHEAD *)allocb(ALLOC_MBHEAD))->l3_typ = L2CI;
|
|
#ifdef __WIN32__
|
|
putchr((char)0xFF, *mbpp); /* Kennung (RIF) */
|
|
#else
|
|
putchr(0xFF, *mbpp); /* Kennung (RIF) */
|
|
#endif /* WIN32 */
|
|
}
|
|
|
|
putfid(node->id, *mbpp);
|
|
for (bp2 = buf; bp2 < bp; bp2++)
|
|
putchr(*bp2, *mbpp);
|
|
}
|
|
|
|
/************************************************************************/
|
|
/* */
|
|
/* "send own node's inp beacon" */
|
|
/* */
|
|
/* Den direkten Nachbarn unsere Daten per INP mitteilen, z.B. nach */
|
|
/* einem Linkaufbau, oder wenn sich unsere Daten (IP-Adresse oder */
|
|
/* Subnetzbits) aendern. */
|
|
/* */
|
|
/*----------------------------------------------------------------------*/
|
|
void send_inp_nodebeacon(PEER* pPeer)
|
|
{
|
|
NODE node;
|
|
MBHEAD* inpmbp = NULL;
|
|
|
|
/* nur INP-Nachbarn duerfen hier rein */
|
|
if (pPeer->typ != INP)
|
|
return;
|
|
|
|
/* uns selber melden */
|
|
cpyid(node.id, myid); /* unsere ID */
|
|
cpyals(node.alias, alias); /* unser Alias */
|
|
|
|
node.ipa = my_ip_addr; /* usere IP */
|
|
node.bits = my_ip_bits; /* unsere Subnetzbits */
|
|
node.options = NULL; /* keine Options */
|
|
|
|
add_inp_info(&inpmbp, &node, pPeer, 1, 0, 1); /* INP-Frame erstellen */
|
|
brosnd(&inpmbp, pPeer); /* und senden */
|
|
}
|
|
|
|
/* End of src/l3inp.c */
|