Commit 112d479e authored by Benoit Steiner's avatar Benoit Steiner

Correction de quelques messages d'erreur plus a jour

Refonte du fichier de configuration
Initialisation des tables ARP au boot pour pouvoir joindre n'importe qui a
n'importe quel moment
Le champ MAC du routeur est maintenant aussi initialise au boot
Nouvelle gestion du probleme du VLANsrc == VLANdst~

Rien n'a ete teste, je ne tiens pas a risquer de voir mon kernel degager
avant de commiter.


Benny
parent 1feb2b93
......@@ -16,7 +16,7 @@ CFLAGS += -DDEBUG
CFLAGS += -g
# Profile with gprof. Don't strip the executable file !
#CFLAGS += -g -pg
CFLAGS += -pg
# Compiler parameters style
CFLAGS += -Wall
......@@ -38,7 +38,7 @@ LIB += -lpthread
#LIB += -ldmalloc
# Use ccmalloc to check memory use
LIB += -lccmalloc -ldl
#LIB += -lccmalloc -ldl
############ Beginning of the files description section ############
......@@ -58,7 +58,8 @@ OBJ = \
route.o \
arp.o \
connect.o \
cfgfile.o
cfgfile.o \
convert.o
SRC := $(OBJ:%.o=%.c)
......
......@@ -57,7 +57,7 @@ int ConfigBridge(FILE* hCfgFile, char** pstrLogFile, char** pstrPort)
ASSERT(pstrPort);
/* Find the right section */
iRc = FindCfg(hCfgFile, "Bridge");
iRc = FindCfg(hCfgFile, "Globals");
if (iRc == CFG_OK)
{
......@@ -157,9 +157,15 @@ int main(int argc, char **argv)
exit(1);
}
if (!getprotobyname("tcp"))
{
printf("TCP protocol unknown: stopping\n");
exit(1);
}
if (!getprotobyname("icmp"))
{
printf("ICMP protocol is not known: stopping\n");
printf("ICMP protocol unknown: stopping\n");
exit(1);
}
......@@ -238,19 +244,17 @@ int main(int argc, char **argv)
/* Initialisation of the mapping structures used by all performer threads */
iRc |= ConfigPerformer(pfdCfgFile);
/* Setup routing tables in order the bridge to work */
LogScreen(LOG_NOTE, MOD_NAME, "Setting up routing and arp tables...");
iRc |= InitRouting(pfdCfgFile);
iRc |= InitArp(pfdCfgFile);
}
/* Close cfg file */
iRc |= CloseCfg(pfdCfgFile);
}
if (!iRc)
{
/* Setup routing tables in order the bridge to work */
LogScreen(LOG_NOTE, MOD_NAME, "Setting up routing and arp tables...");
iRc |= InitRouting();
}
if (!iRc)
{
/* Create and init the thread that will manage the requests from VLANserver */
......
......@@ -2,18 +2,27 @@
#La section Bridge ne sert a rien pour le moment
BEGIN Bridge
BEGIN Globals # Config generale du bridge
Port = 2000
Log = /home/benny
END
BEGIN Performer # Config du performer
Router = 138.195.136.1 # IP du router
BEGIN Interfaces # Config du performer
VLANcount = 16 # Nombre de VLANs
VLANdefault = 2 # VLAN par defaut
VLAN2 = eth0 # Mapping VLAN / If
VLAN3 = eth1
# VLAN3 = eth1
# VLAN15 = eth2
# VLAN16 = eth3
END
BEGIN Router
IP = 138.195.136.1 # IP du router
MAC = # MAC du router
END
BEGIN Hosts # Definitions des clients potentiels
Start = 138.195.136.2
End = 138.195.137.255
Forbidden = 138.195.136.1
END
......@@ -75,7 +75,7 @@ int Arp_Add(struct sockaddr_in* psaAddr, char* strDev, int iSockFd)
}
if (iRc)
Log (LOG_ERROR, MOD_NAME, "Proxy ARP entry for host %s on if %s not deleted: %s",
Log (LOG_ERROR, MOD_NAME, "Proxy ARP entry for host %s on if %s not added: %s",
inet_ntoa(((struct sockaddr_in *)psaAddr)->sin_addr), strDev, strerror (errno));
return iRc;
......@@ -116,7 +116,7 @@ int Arp_Del (struct sockaddr_in* psaAddr, char* strDev, int iSockFd)
#endif
if (iRc)
Log (LOG_ERROR, MOD_NAME, "Pproxy ARP entry for host %s on if %s not deleted: %s",
Log (LOG_ERROR, MOD_NAME, "Proxy ARP entry for host %s on if %s not deleted: %s",
inet_ntoa(((struct sockaddr_in *)psaAddr)->sin_addr), strDev, strerror (errno));
return iRc;
......
......@@ -200,7 +200,7 @@ int OpenWaitingSocket (const char* strWaitPort)
}
/* Listen for incoming connections */
if (!iRc)
if (!iRc)
{
if (listen(iWaitSockFd, MAX_IN_CONN) < 0)
{
......
......@@ -23,6 +23,7 @@
#include "debug.h"
#include "log.h"
#include "convert.h"
#include "performer.h"
#include "manager.h"
#include "connect.h"
......@@ -66,48 +67,6 @@ int InitListener(struct s_Listener* listener)
}
/*****************************************************************************/
/* */
/*****************************************************************************/
inline int ascii2hexa (char s)
{
if (s >= 'a' && s <='f') /* Do uppercase */
s -= ('a' - 'A');
return (s > '9')?10 + s - 'A':s - '0';
}
/*****************************************************************************/
/* */
/*****************************************************************************/
int mac_atob (char* MAC, unsigned char* mac_addr)
{
int hex, n;
int iRc = 0;
ASSERT(MAC);
ASSERT(mac_addr);
if (strlen (MAC) == 17) /* Good MAC address length */
{
for (n = 0; n < 6; n++)
{
hex = 16 * ascii2hexa (MAC[3*n]) + ascii2hexa (MAC[3*n+1]);
if (hex < 0 || hex > 255)
iRc = 1; /* Bad MAC address format */
else
mac_addr[n] = hex; /* Good MAC address format */
}
}
else
iRc = 1; /* Bad MAC address format */
return iRc;
}
/*****************************************************************************/
/* */
/*****************************************************************************/
......
......@@ -18,6 +18,7 @@
#include "debug.h"
#include "log.h"
#include "convert.h"
#include "listener.h"
#include "performer.h"
#include "sender.h"
......
......@@ -20,9 +20,8 @@ struct s_Manager
{
/* Thread id */
pthread_t tId;
/* Predicate, mutex used to test it, and condition variable */
//int iWorkPredicate;
pthread_mutex_t WorkLock;
pthread_cond_t WorkSignal;
......
......@@ -25,6 +25,7 @@
#include <netdb.h>
#include "debug.h"
#include "convert.h"
#include "pinger.h"
#include "arp.h"
#include "route.h"
......@@ -54,7 +55,7 @@ struct sockaddr* asaMapToMAC;
struct sockaddr_in saRouterIP;
struct sockaddr saRouterMAC;
/**/
/* To get in touch with the manager thread */
extern struct s_Manager manager;
......@@ -66,8 +67,6 @@ int ConfigPerformer(FILE* hCfgFile)
{
int iIndex;
char* strToken;
unsigned long lInAddr;
struct hostent* heInAddr;
int iRc = 0;
char* strVarName = NULL;
char* strVarVal = NULL;
......@@ -85,39 +84,12 @@ int ConfigPerformer(FILE* hCfgFile)
else
{
/* Find the right section */
iRc = FindCfg(hCfgFile, "Performer");
iRc = FindCfg(hCfgFile, "Interfaces");
if (iRc == CFG_OK)
{
/* Read the IP of the router */
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
if (!iRc && !strcmp(strVarName, "Router"))
{
saRouterIP.sin_family = AF_INET;
if ((lInAddr = inet_addr(strVarVal)) != -1/*INADDR_NONE*/)
{
/* it's dotted-decimal */
bcopy(&lInAddr, &saRouterIP.sin_addr, sizeof(lInAddr));
}
else
{
if ((heInAddr = gethostbyname(strVarVal)) == NULL)
iRc = -1;
else
bcopy(heInAddr->h_addr, &saRouterIP.sin_addr, heInAddr->h_length);
}
}
else
{
iRc = 1;
Log(LOG_ERROR, MOD_NAME, "Router must be the first entry in the Performer section");
}
/* Read the number of VLANs handled by the bridge */
if (!iRc)
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
if (!iRc && !strcmp(strVarName, "VLANcount"))
{
......@@ -141,7 +113,7 @@ int ConfigPerformer(FILE* hCfgFile)
else
{
iRc = 1;
Log(LOG_ERROR, MOD_NAME, "VLANcount must be the second entry in the Performer section");
Log(LOG_ERROR, MOD_NAME, "VLANcount must be the first entry in the Performer section");
}
/* Read the default VLAN */
......@@ -163,7 +135,7 @@ int ConfigPerformer(FILE* hCfgFile)
else
{
iRc = 1;
Log(LOG_ERROR, MOD_NAME, "VLANdefault must be the third entry in the Performer section");
Log(LOG_ERROR, MOD_NAME, "VLANdefault must be the second entry in the Performer section");
}
/* Read the entries to fill in the map structure */
......@@ -246,15 +218,62 @@ int ConfigPerformer(FILE* hCfgFile)
/***************************************************************************/
/* Setup the routing tables to suit the bridge needs */
/***************************************************************************/
int InitRouting()
int InitRouting(FILE* hCfgFile)
{
int iSockFd, iIndex;
int iRc = 0;
// struct sockaddr_in saRouterIP;
struct hostent* heInAddr;
char* strVarName = NULL, *strVarVal = NULL;
ASSERT(hCfgFile);
/* Find the right section */
iRc = FindCfg(hCfgFile, "Router");
if (iRc == CFG_OK)
{
/* Read the IP of the router */
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
if (!iRc && !strcmp(strVarName, "IP"))
{
saRouterIP.sin_family = AF_INET;
if (inet_aton(strVarVal, &saRouterIP.sin_addr) == 0/*INADDR_NONE*/)
{
/* it's not dotted-decimal, try to ask the DNS server */
if ((heInAddr = gethostbyname(strVarVal)) == NULL)
iRc = -1;
else
bcopy(heInAddr->h_addr, &saRouterIP.sin_addr, heInAddr->h_length);
}
}
else
{
iRc = 1;
Log(LOG_ERROR, MOD_NAME, "Router must be the first entry in the Router section");
}
/* Get its MAC address */
if (!iRc)
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
if (!iRc && !strcmp(strVarName, "MAC"))
{
/* Bug possible, car la conversion ne respecte pas le network byte order */
iRc = mac_atob(strVarVal, (unsigned char *)&saRouterMAC.sa_data);
}
}
else
{
iRc = 1;
Log(LOG_ERROR, MOD_NAME, "No Router section in the Cfg file");
}
/* Open a socket to manipulate the routing tables */
iSockFd = socket(AF_INET, SOCK_DGRAM, 0);
/* Add an ARP entry for the router on each interface exept the default one */
/* Add an ARP entry for the router on each interface except the default one */
for (iIndex = 1; iIndex < iVLANNumber; iIndex++)
{
if (strMapToDev[iIndex] != "" && iIndex != iVLANDflt)
......@@ -264,7 +283,7 @@ int InitRouting()
if (iRc)
break;
}
/* Close the socket */
if (close(iSockFd))
Log(LOG_WARN, MOD_NAME, "Unable to close temporary socket: %s", strerror(errno));
......@@ -273,6 +292,80 @@ int InitRouting()
}
/***************************************************************************/
/* Setup the routing tables to suit the bridge needs */
/* If not done, only clients known by the bridge (ie which sent a request) */
/* can be join from another VLAN */
/***************************************************************************/
int InitArp(FILE* hCfgFile)
{
int iIndex, iRc = 0;
int iSockFd;
char* strVarName = NULL;
char* strVarVal = NULL;
struct sockaddr_in saStartAddr;
struct sockaddr_in saStopAddr;
unsigned long lStartAddr;
unsigned long lStopAddr;
unsigned long lAddr;
ASSERT(hCfgFile);
/* Find the right section */
iRc = FindCfg(hCfgFile, "Hosts");
if (iRc == CFG_OK)
{
/* Read the IP of the first host */
iRc = ReadCfg(hCfgFile, &strVarName, &strVarVal);
if (!iRc && !strcmp(strVarName, "Start"))
{
bzero(&saStartAddr, sizeof(saStartAddr));
saStartAddr.sin_family = AF_INET;
iRc = inet_aton(strVarVal, &saStartAddr.sin_addr);
}
else if (!iRc && !strcmp(strVarName, "End"))
{
bzero(&saStartAddr, sizeof(saStopAddr));
saStopAddr.sin_family = AF_INET;
iRc = inet_aton(strVarVal, &saStopAddr.sin_addr);
}
}
iSockFd = socket (AF_INET, SOCK_DGRAM, 0);
if (iSockFd < 0)
{
iRc = errno;
Log (LOG_ERROR, MOD_NAME, "Unable to open socket: %s", strerror(iRc));
}
else
{
/* Loop commence ici */
lStartAddr = ntohl(saStartAddr.sin_addr.s_addr);
lStopAddr = ntohl(saStopAddr.sin_addr.s_addr);
printf("Startaddr: %d, %s\n", lStartAddr, inet_ntoa(saStartAddr.sin_addr));
printf("Stopaddr: %d, %s\n", lStopAddr, inet_ntoa(saStopAddr.sin_addr));
for (lAddr = lStartAddr; lAddr < lStopAddr; lAddr++)
{
saStartAddr.sin_addr.s_addr = htonl(lAddr);
for (iIndex = 1; iIndex < iVLANNumber; iIndex++)
{
if (strMapToDev[iIndex] != "" && iIndex != iVLANDflt)
Arp_Add(&saStartAddr, strMapToDev[iIndex], iSockFd);
}
}
}
/* Close the socket */
if (close(iSockFd))
Log(LOG_WARN, MOD_NAME, "Unable to close temporary socket: %s", strerror(errno));
return iRc;
}
/***************************************************************************/
/* */
......@@ -318,20 +411,31 @@ int UpdateTables (struct s_Request* psrJob)
if (psrJob->iVLANdst != iVLANDflt)
iRc = Route_Add(iSockFd, &psrJob->saClientIP, strMapToDev[psrJob->iVLANdst]);
if (iRc && psrJob->iVLANsrc != iVLANDflt && psrJob->iFirstTime != 1)
if (iRc)
{
/* Error: Cancel route modification */
iRc = Route_Add(iSockFd, &psrJob->saClientIP, strMapToDev[psrJob->iVLANsrc]);
/* Error: Cancel all modifications
As it won't be the first time anymore, create entries in the ARP and routing
tables even if they didn't exist before the request */
iRc |= Arp_Add(&psrJob->saClientIP, strMapToDev[psrJob->iVLANsrc], iSockFd);
if (psrJob->iVLANsrc != iVLANDflt)
iRc = Route_Add(iSockFd, &psrJob->saClientIP, strMapToDev[psrJob->iVLANsrc]);
}
else
{
/* Update ARP table */
iRc = Arp_Add(&psrJob->saClientIP, strMapToDev[psrJob->iVLANdst], iSockFd);
/* Update ARP table
If VLANdst == VLANsrc, we won't proxy for the host on the VLAN on which
it stays, so don't add any entry */
if (psrJob->iVLANdst != psrJob->iVLANsrc)
iRc = Arp_Add(&psrJob->saClientIP, strMapToDev[psrJob->iVLANdst], iSockFd);
if (iRc && psrJob->iFirstTime != 1)
if (iRc)
{
/* Error: cancel ARP modification */
/* Error: cancel all modifications even if it's the first time */
iRc = Arp_Add(&psrJob->saClientIP, strMapToDev[psrJob->iVLANsrc], iSockFd);
if (psrJob->iVLANdst != iVLANDflt)
iRc |= Route_Del(iSockFd, &psrJob->saClientIP, strMapToDev[psrJob->iVLANdst]);
if (psrJob->iVLANsrc != iVLANDflt)
iRc |= Route_Add(iSockFd, &psrJob->saClientIP, strMapToDev[psrJob->iVLANsrc]);
}
}
}
......@@ -380,14 +484,14 @@ int WarnNetwork (const struct s_Request* psrJob)
};
/* Tell the client how to reach the router */
if (psrJob->iVLANdst != 2)
if (psrJob->iVLANdst != iVLANDflt)
{
#ifdef DEBUG
Log (LOG_NOTE, MOD_NAME, "The router, it's now me on VLAN %d",
psrJob->iVLANdst);
#endif
iRc = Gratuitous_Send (&psrJob->saClientIP, &asaMapToMAC[psrJob->iVLANdst],
strMapToDev[psrJob->iVLANdst]);
strMapToDev[psrJob->iVLANdst]);
}
else
{
......@@ -420,17 +524,9 @@ void* PerformerThread (void* pvArg)
Log (LOG_NOTE, MOD_NAME, "Performer thread %d is running", psrJob->ptId);
//sleep(20);
#endif
/* Check that VLANsrc and VLANdst are not equal (to avoid problems
in the ARP table) */
if (psrJob->iVLANsrc == psrJob->iVLANdst)
{
Log (LOG_NOTE, MOD_NAME, "VLANsrc = VLANdst: nothing to do for host %s",
inet_ntoa(psrJob->saClientIP.sin_addr));
}
/* Init the pinger */
else if ((iRc = Pinger_Init(&psrJob->saClientIP, &spPingerCfg)))
if ((iRc = Pinger_Init(&psrJob->saClientIP, &spPingerCfg)))
{
psrJob->iStatus = VLAN_ERROR;
Log (LOG_ERROR, MOD_NAME, "Could not init pinger for %s: aborting",
......
......@@ -35,7 +35,8 @@ struct s_Request
int ConfigPerformer(FILE* hCfgFile);
int InitRouting();
int InitRouting(FILE* hCfgFile);
int InitArp(FILE* hCfgFile);
int RunPerformer(struct s_Request *psrPerformer);
int FreePerformer(const struct s_Request *psrPerformer);
......
......@@ -22,6 +22,7 @@
#include "debug.h"
#include "log.h"
#include "convert.h"
#include "performer.h"
#include "manager.h"
#include "connect.h"
......@@ -97,40 +98,6 @@ int InitSender (struct s_Sender* sender)
}
/*****************************************************************************/
/* Convert an hexadecimal integer between 0 and 16 to the corresponding */
/* ascii char (in uppercase) */
/*****************************************************************************/
inline char hexa2ascii(int i)
{
return (i > 9)?'A' + (i-10):'0' + i;
}
/*****************************************************************************/
/**/
/*****************************************************************************/
int mac_btoa (char* MAC, unsigned char* mac_addr)
{
int n;
int iRc = 0;
ASSERT(MAC);
ASSERT(mac_addr);
/* Write down separators between octets */
for (n = 0; n < 5; n++)
MAC[3*n+2] = ':';
/* Write the octets in hexadecimal format */
for (n = 0; n < 6; n++)
{
MAC[3*n] = hexa2ascii((mac_addr[n]>>4)&15); /* mac_addr[n] & 11110000 */
MAC[3*n+1] = hexa2ascii((mac_addr[n]&15)); /* mac_addr[n] & 00001111 */
}
return iRc;
}
/*****************************************************************************/
......@@ -275,7 +242,10 @@ void* SenderThread (void* arg)
{
if (iConnectionState == 0 || iConnectionState != sender->iSockFd)
{
/* The sender has already handled the connection lost, and the VLANserver is either waiting for a new connection (iIsConnected == 0) or has already set up another connection: so there is nothing to do */
/* The sender has already handled the connection lost, and the
VLANserver is either waiting for a new connection
(iIsConnected == 0) or has already set up another connection:
so there is nothing to do */
}
else
iRc = HandleDeadSocket(sender->iSockFd);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment