Commit 8eea2855 authored by Damien Lucas's avatar Damien Lucas

Cleaned netork directory: only VLANbridge and VLANserver

VLANbridge is unchanged.

Subdirectoriesof VLANserver are:
db/        The database
doc/       Few config sample files
config/    Parser of the config file
old-tools/ Just mini-vlanserver and soon commandline vlanclient
server/    The client-server part
snmp/      snmp interface



Sorry, second cvs commit because a community string was committed.
parent a29a2e15
CCOMPILER=cc
CFLAGS=-D_REENTRANT -Wall -O6 -fomit-frame-pointer
LDLIBS=-lpthread -lsnmp
#In order to parse the configuration file
LEXERGENERATOR=flex
LEXFLAGS=-s -Ce -PCFG_yy -oconfig/config.c
SOURCES=server/server.c server/connect.c server/request_handler.c main.c db/db.c snmp/snmp.c snmp/if_snmp.c types.c logger.c
main: $(SOURCES:.c=.o) config/config.o
%.d: %.c
set -e; $(CC) $(CFLAGS) -MM $(CPPFLAGS) $< | sed 's#\($*\)\.o[ :]*#\1.o $@ : #g' > $@; [ -s$@ ] || rm -f $@
include $(SOURCES:.c=.d)
config/config.o: config_c
$(CCOMPILER) $(CFLAGS) -o config/config.o -c config/config.c
config_c: config_fl
$(LEXERGENERATOR) $(LEXFLAGS) config/config.fl
config_fl: config_h logger_h cfg_config_h
cfg_config_h: types_h
types_h: types.h
logger_h: logger.h
config_h: config.h
clean:
rm -f $(SOURCES:.c=.o) $(SOURCES:.c=.d) main config/config.o config/config.c
(snmp 1):
Gérer les numéros de ports de la meme manière que les vlans et non
avec ce putain de #define
(snmp 2):
Faire le test à la fin de SNMP_switch_init pour vérifier les bonnes
initialisations.
(snmp 3): FOR GURU
Chopper les traps snmp ...
(snmp 4):
Gerer les vlans initiaux pour la db.
(snmp 5): URGENT
Convention de nombre de ports par switch.
(cfg 1):
faire des fonctions de libération des ressources
(cfg 2):
Faire une fonction pour restituer les ressources utilisées par la
config. A priori, il suffit d'appeler la fonction cleanup() de config.fl
(cfg 3):
Demander a l'equipe client ce qu'ils aimeraient voir figurer dans le
champ raw_data.
(cfg 4):
Vérifier à la fin de la config qu'on a bien toutes les infos dont on a
besoin (IP, login, passwd du vlb, par exemple)
(cfg 4):
permettre d'utiliser des DNS au lieu des IPs dans le fichier de config
(cfg 5):
ptet un jour mettre au point un protocole a la con pour qu'il y ait
detection automatique du (des ?) vls. ptet un jour :)
(main 1):
Appeler VS_close à la fin.
(db 1):
Modifier les fonctions DB_S_insert et DB_M_insert pour qu'elles
cherchent avant si une entrée de la base ne va pas être dupliquée, et le
cas échéant, écrasent l'entrée existante
(db 2):
Ne plus passer par le moteur de base de données pour les requêtes
unlock, c'est débile
(db 3):
Fonction d'arrêt de la base avec cleanup et quand même terminaison des
threads en attente
(db 4):
Implémenter la fonction DB_switchs_delete (for real men ! :=)
/* VideoLAN VLAN operations: definitions of all codes for messages exchange between
* VLANserver, VLANclient and VLANbridge
*
* Regis Duchesne, VIA, ECP, France <regis@via.ecp.fr>, 23/09/97
* Arnaud Bienvenu, VIA, ACP, France <fred@@via.ecp.fr>, 23/09/97
* Benoit Steiner, VIA, ECP, France <benny@via.ecp.fr>, 13/10/98
*
*/
/***************************************************************************/
/* Format of a message: ASCII control code and then arguments written next */
/* to the message code below (<XXX> <YYY>) if needed */
/***************************************************************************/
/* Message format definition */
#define VLAN_MSG_LEN 256 /* Maximum length of a message */
#define VLAN_CODE_LEN 2 /* Control code values range from 0 to 99 */
#define VLAN_MAC_SIZE 18 /* Length of a MAC field (including final NULL char) */
#define VLAN_IP_SIZE 16 /* Lentgh of an IP field (including final NULL char) */
/* Error msg (common for VLANserver, client and bridge) */
#define VLAN_BAD_COMMAND 4 /* Invalid request: bad command */
#define VLAN_BAD_FORMAT 5 /* Invalid request: bad format */
#define VLAN_BUSY 6 /* Server is busy, request ignored */
#define VLAN_ERROR 7 /* A global unrecoverable error occured */
/* login msg (common for all) */
#define VLAN_LOGIN_REQUEST 98 /* <soft version> <login> <passwd> */
#define VLAN_LOGIN_OK 97 /* Login accepted */
#define VLAN_LOGIN_KO 96 /* Login rejected */
/* logout (common for all too) */
#define VLAN_BYE 99 /* Logout msg */
/* VLANbridge <> VLANserver msg */
#define VLAN_ROUTE_REQUEST 11 /* <MAC> [IP] <VLAN Dest> [VLAN Src */
#define VLAN_ROUTE_OK 13 /* Route request succesfully completed */
#define VLAN_ROUTE_KO 14 /* Request failed to be processed */
#define VLAN_ROUTE_NOMOVE 18 /* Request not processed: client didn't move */
/* VLANserver <> client msg */
#define VLAN_MOVE_REQUEST 21 /* <MAC> [IP] <VLAN Dest> [VLAN Src] */
#define VLAN_MOVE_OK 22 /* Move request succesfully completed */
#define VLAN_MOVE_KO 23 /* Request failed to be processed */
/* VLANserver <> VLANclient */
#define VLAN_LOCATION_REQUEST 31 /* No argument */
#define VLAN_LOCATION_ANSWER 32 /* <switch> <port> <vlan> <sharers> */
#define VLAN_LOCATION_UNKNOW 33 /* VLANserver don't know */
#ifndef __CONFIG_H__
#define __CONFIG_H__
/* Server version pas <3.1 */
#define VERSION "3.1"
/* Time between 2 atempts to contact the VLANbridge */
#define BRIDGE_SLEEPTIME 120
/* default VLANbridge port */
#define DEFAULT_ROUTER_PORT 2000
/* default server port */
#define DEFAULT_PORT 6010
/* number of retries when trying to reconnect to the VLANbridge when unable
* to close the connection */
#define VS_CNX_RETRIES 5
/* timeout before the server stops waiting for VLANbridge's answer when trying
* to log in */
#define VS_VLB_TIMEOUT 30
/* default config file location */
#define CFG_FILE_PATH "./vlanserver.conf"
#endif
%pointer
%{
#include <string.h>
#include "../types.h"
#include "../logger.h"
#include "../config.h"
#include "config.h"
struct CFG_SWITCH_TYPE *CFG_switch_type(struct VS_config *cfg,\
char *switch_type_name)
{
struct CFG_SWITCH_TYPE *z;
for (z=cfg->switch_types;z!=NULL;z=z->next)
if (!strcmp(CFG_SWITCH_TYPE_NAME(*z),switch_type_name))
break;
return z;
}
#define YY_DECL static ERR_CODE CFG_yylex(struct VS_config *cfg,char *filename)
inline int CFG_yywrap(void) {return 1;}
%}
BL [ \t]+
FB [ \t]*
INT [0-9]+
NONBLANK [^ \t\n]
IP ([0-9]{1,3}[.]){3}([0-9]{1,3})
%x in_channel_raw_data
%x in_switch_type
%x in_switch
%%
%{
unsigned long ul1;
unsigned long ul2;
unsigned int ui1;
unsigned int i;
unsigned int line_num;
unsigned int eof_expected;
unsigned int raw_data_allowed;
struct CFG_SWITCH_TYPE **st;
struct CFG_SWITCH **s;
struct CFG_SWITCH_TYPE *z;
VS_SwitchId ip;
struct CFG_PORT *ports;
char c;
line_num=1;
eof_expected=1;
for(st=&(cfg->switch_types);*st!=NULL;st=&((*st)->next));
for(s=&(cfg->zwitches);*s!=NULL;s=&((*s)->next));
ports=((struct CFG_PORT *)NULL)-1;
%}
<*>^{BL} ;
<*>{FB}\n line_num++;
nchannels{BL}{INT} {
if (cfg->nchannels)
{
VS_log_error("CFG: parse error in %s on line %u : nchannels has "\
"already been defined\n",filename,line_num);
return VS_R_PARSE;
}
sscanf(CFG_yytext+sizeof("nchannels")/sizeof(char)-1," %lu",&ul1);
if (!ul1)
{
VS_log_error("CFG: parse error in %s on line %u : nchannels can't "\
"be 0\n",filename,line_num);
return VS_R_PARSE;
}
cfg->nchannels=(VS_CHANNEL)ul1;
VS_log_info("CFG: number of channels set to : %lu\n",ul1);
cfg->chan_map=malloc(ul1*sizeof(struct CFG_CHANNEL));
if (cfg->chan_map==NULL)
{
VS_log_error("CFG: unable to allocate memory to create the channels "\
" table\n");
return VS_R_MEMORY;
}
do
{
ul1--;
cfg->chan_map[ul1].raw_data=NULL;
cfg->chan_map[ul1].protection=(VS_PROTECTION_LEVEL)VS_PL_UNSPECIFIED;
// TODO I guess the following line is useless, it should probably be
// removed
cfg->chan_map[ul1].vlan=0;
} while(ul1);
}
vlanbridge{BL}{IP} {
if (cfg->vlanbridge[0])
{
VS_log_error("CFG: parse error in %s on line %u : duplicated "\
"vlanbridge address defition\n",filename,line_num);
return VS_R_PARSE;
}
for (ui1=CFG_yyleng-1;\
CFG_yytext[ui1-1]!=' ' && CFG_yytext[ui1-1]!='\t';ui1--);
memcpy(cfg->vlanbridge,CFG_yytext+ui1,CFG_yyleng-ui1);
cfg->vlanbridge[CFG_yyleng-ui1]=0;
}
vlanbridge_login{BL}{NONBLANK}+ {
if (cfg->vlanbridge_login!=NULL)
{
VS_log_error("CFG: parse error in %s on line %u : duplicated "\
"vlanbridge login\n",filename,line_num);
return VS_R_PARSE;
}
for (ui1=CFG_yyleng-1;\
CFG_yytext[ui1-1]!=' ' && CFG_yytext[ui1-1]!='\t';ui1--);
cfg->vlanbridge_login=malloc((CFG_yyleng-ui1+1)*sizeof(char));
if (cfg->vlanbridge_login==NULL)
{
VS_log_error("CFG: unable to allocate memory to store vlanbridge "\
"login\n");
return VS_R_MEMORY;
}
memcpy(cfg->vlanbridge_login,CFG_yytext+ui1,CFG_yyleng-ui1);
cfg->vlanbridge_login[CFG_yyleng-ui1]=0;
}
vlanbridge_password{BL}{NONBLANK}+ {
if (cfg->vlanbridge_password!=NULL)
{
VS_log_error("CFG: parse error in %s on line %u : duplicated "\
"vlanbridge password\n",filename,line_num);
return VS_R_PARSE;
}
for (ui1=CFG_yyleng-1;\
CFG_yytext[ui1-1]!=' ' && CFG_yytext[ui1-1]!='\t';ui1--);
cfg->vlanbridge_password=malloc((CFG_yyleng-ui1+1)*sizeof(char));
if (cfg->vlanbridge_password==NULL)
{
VS_log_error("CFG: unable to allocate memory to store VLB "\
"password\n");
return VS_R_MEMORY;
}
memcpy(cfg->vlanbridge_password,CFG_yytext+ui1,CFG_yyleng-ui1);
cfg->vlanbridge_password[CFG_yyleng-ui1]=0;
}
channel{BL}{INT}{BL}vlan{BL}{INT}{BL}protection{BL}{INT}{BL} {
sscanf(CFG_yytext+sizeof("channel")/sizeof(char)-1,\
" %lu vlan %lu protection %u",&ul1,&ul2,&ui1);
BEGIN(in_channel_raw_data);
eof_expected=0;
raw_data_allowed=1;
}
channel{BL}{INT}{BL}vlan{BL}{INT}{BL}protection{BL}{INT} {
sscanf(CFG_yytext+sizeof("channel")/sizeof(char)-1,\
" %lu vlan %lu protection %u",&ul1,&ul2,&ui1);
BEGIN(in_channel_raw_data);
eof_expected=0;
raw_data_allowed=0;
}
<in_channel_raw_data>.*\n {
if ((VS_CHANNEL)ul1>=cfg->nchannels)
{
VS_log_error("CFG: parse error in %s on line %u : invalid channel "\
"number\n",filename,line_num);
return VS_R_PARSE;
}
if (cfg->chan_map[ul1].protection!=VS_PL_UNSPECIFIED)
{
VS_log_error("CFG: parse error in %s on line %u : channel %lu has"\
" already been defined\n",filename,line_num,ul1);
return VS_R_PARSE;
}
if ((VS_PROTECTION_LEVEL)ui1>=VS_PL_NUMBER)
{
VS_log_error("CFG: parse error in %s on line %u : protection levels "\
"range from 0 to %lu\n",filename,line_num,\
(unsigned long)VS_PL_NUMBER-1);
return VS_R_PARSE;
}
if (!raw_data_allowed && CFG_yyleng)
{
VS_log_error("CFG: parse error in %s on line %u : expecting "\
"integer\n",filename,line_num);
return VS_R_PARSE;
}
cfg->chan_map[ul1].raw_data=malloc((CFG_yyleng+1)*sizeof(char));
if (cfg->chan_map[ul1].raw_data==NULL)
{
VS_log_error("CFG: unable to allocate memory to store raw data for "\
"channel %lu\n",ul1);
return VS_R_MEMORY;
}
memcpy(cfg->chan_map[ul1].raw_data,CFG_yytext,\
(CFG_yyleng-1)*sizeof(char));
cfg->chan_map[ul1].raw_data[CFG_yyleng]=0;
cfg->chan_map[ul1].vlan=(VS_VLAN)ul2;
cfg->chan_map[ul1].protection=(VS_PROTECTION_LEVEL)ui1;
line_num++;
BEGIN(INITIAL);
eof_expected=1;
VS_log_info("CFG: successfuly defined channel %lu on vlan "\
"%lu protection %u %s",ul1,ul2,ui1,CFG_yytext);
}
switch{BL}type{BL}{NONBLANK}+ {
for (i=CFG_yyleng-1;CFG_yytext[i-1]!=' ' && CFG_yytext[i-1]!='\t';i--);
*st=malloc(sizeof(struct CFG_SWITCH_TYPE)+\
(CFG_yyleng-i+1)*sizeof(char));
if (*st==NULL)
{
VS_log_error("CFG: unable to allocate memory to create a switch "\
"type\n");
return VS_R_MEMORY;
}
(*st)->nports=(VS_PORT)0;
(*st)->ports=NULL;
(*st)->next=NULL;
memcpy(CFG_SWITCH_TYPE_NAME(**st),CFG_yytext+i,\
(CFG_yyleng-i)*sizeof(char));
CFG_SWITCH_TYPE_NAME(**st)[CFG_yyleng-i]=0;
BEGIN(in_switch_type);
eof_expected=0;
}
<in_switch_type>nports{BL}{INT} {
if ((*st)->nports)
{
VS_log_error("CFG: parse error in %s on line %u : nports has "\
"already been defined\n",filename,line_num);
return VS_R_PARSE;
}
sscanf(CFG_yytext+sizeof("nports")/sizeof(char)-1," %lu",&ul1);
(*st)->nports=(VS_PORT)ul1;
(*st)->ports=malloc(ul1*sizeof(struct CFG_PORT));
/* UGLY, but we don't wanna waste memory nor cpu, do we ? */
(*st)->ports--;
if ((((*st)->ports)+1)==NULL)
{
VS_log_error("CFG: unable to allocate memory to store a switch "\
"type's ports table\n");
return VS_R_MEMORY;
}
do
{
(*st)->ports[ul1].protection=VS_PL_UNSPECIFIED;
ul1--;
} while (ul1);
}
<in_switch_type>model{BL}{NONBLANK}+ {
{
unsigned int i;
i=6;
while (CFG_yytext[i]==' ' || CFG_yytext[i]=='\t')
{
i++;
}
if (!strncmp(CFG_yytext+i,"3C1000",CFG_yyleng-i))
{
(*st)->type=VS_ST_3C1000;
}
else if (!strncmp(CFG_yytext+i,"3C1100",CFG_yyleng-i))
{
(*st)->type=VS_ST_3C1100;
}
else if (!strncmp(CFG_yytext+i,"3C3300",CFG_yyleng-i))
{
(*st)->type=VS_ST_3C3300;
}
else
{
VS_log_error("CFG: parse error in %s on line %u : unknown switch "\
"type\n",filename,line_num);
return VS_R_PARSE;
}
}
}
<in_switch_type>default{BL}{INT} {
sscanf(CFG_yytext+sizeof("default")/sizeof(char)-1," %u",&ui1);
if (ui1>=VS_PL_NUMBER)
{
VS_log_error("CFG: parse error in %s on line %u : protection levels "\
"range from 0 to %lu\n",filename,line_num,\
(unsigned long)VS_PL_NUMBER-1);
return VS_R_PARSE;
}
i=0;
for (ul1=(unsigned long)(*st)->nports;ul1;ul1--)
if ((*st)->ports[ul1].protection==VS_PL_UNSPECIFIED)
{
(*st)->ports[ul1].protection=(VS_PROTECTION_LEVEL)ui1;
i=1;
}
if (!i)
VS_log_error("CFG: warning, in %s on line %u : useless 'default' "\
"statement in switch type definition, going on "\
"however\n",filename,line_num);
}
<in_switch_type>port{BL}{INT}{BL}{INT} {
sscanf(CFG_yytext+sizeof("port")/sizeof(char)-1," %lu %u",&ul1,&ui1);
if (!ul1 || (VS_PORT)ul1>(*st)->nports)
{
VS_log_error("CFG: parse error in %s on line %u : invalid port "\
"number\n",filename,line_num);
return VS_R_PARSE;
}
if ((VS_PROTECTION_LEVEL)ui1>=VS_PL_NUMBER)
{
VS_log_error("CFG: parse error in %s on line %u : protection levels"\
"range from 0 to %u\n",filename,line_num,\
(unsigned int)VS_PL_NUMBER-1);
return (VS_R_PARSE);
}
(*st)->ports[ul1].protection=(VS_PROTECTION_LEVEL)ui1;
}
<in_switch_type>end{BL}switch{BL}type {
for (ul1=1;(VS_PORT)ul1<=(*st)->nports;ul1++)
if ((*st)->ports[ul1].protection==VS_PL_UNSPECIFIED)
{
VS_log_error("CFG: parse error in %s on line %u : switch type %s "\
"has not been completely specified\n",filename,\
line_num,CFG_SWITCH_TYPE_NAME(**st));
return VS_R_PARSE;
}
VS_log_info("CFG: switch type %s defined with the %lu following ports "\
":\n",CFG_SWITCH_TYPE_NAME(**st),\
(unsigned long)(*st)->nports);
for (ul1=1;(VS_PORT)ul1<=(*st)->nports;ul1++)
VS_log_info("CFG: port %lu :\tprotection %lu\n",ul1,\
(unsigned long)(*st)->ports[ul1].protection);
st=&((*st)->next);
BEGIN(INITIAL);
eof_expected=1;
}
{NONBLANK}+{BL}{IP} {
for (i=0;CFG_yytext[i]!=' ' && CFG_yytext[i]!='\t';i++);
c=CFG_yytext[i];
CFG_yytext[i]=0;
z=CFG_switch_type(cfg,CFG_yytext);
if (z==NULL)
{
VS_log_error("CFG: parse error in %s on line %u : unknown switch "\
"type\n",filename,line_num);
return VS_R_PARSE;
}
CFG_yytext[i]=c;
for(i=CFG_yyleng-1;CFG_yytext[i-1]!=' ' && CFG_yytext[i-1]!='\t';i--);
if (!VS_A2SID(CFG_yytext+i,ip))
{
VS_log_error("CFG: parse error in %s on line %u : invalid IP "\
"address\n",filename,line_num);
return VS_R_PARSE;
}
// need to malloc s
*s=malloc(sizeof(struct CFG_SWITCH));
if(*s==NULL)
{
VS_log_error("CFG: unable to allocate memory to create a new "\
"switch in the database\n");
return VS_R_MEMORY;
}
// and complete s
(*s)->ip=ip;
(*s)->nports=z->nports;
(*s)->ports=NULL;
(*s)->type=z->type;
(*s)->next=NULL;
(*s)->community=NULL;
ports=malloc(z->nports*sizeof(VS_PORT));
/* UGLY, but we don't wanna waste memory nor cpu, do we ? */
if (ports==NULL)
{
VS_log_error("CFG: unable to allocate memory to create a new switch "\
"in the database\n");
return VS_R_MEMORY;
}
ports--;
for (ul2=1;(VS_PORT)ul2<=z->nports;ul2++)
ports[ul2].protection=z->ports[ul2].protection;
VS_log_info("CFG: creating switch %s with type %s (%lu ports)...\n",\
CFG_yytext+i,CFG_SWITCH_TYPE_NAME(*z),ul2-1);
BEGIN(in_switch);
eof_expected=0;
}
<in_switch>community{BL}{NONBLANK}+ {
for (i=CFG_yyleng-1;CFG_yytext[i-1]!=' ' && CFG_yytext[i]!='\t';i--);
(*s)->community=malloc((CFG_yyleng-i+1)*sizeof(char));
if ((*s)->community==NULL)
{
ports++;
free(ports);
VS_log_error("CFG: unable to allocate memory to store a switch's "\
"community string\n");
}
memcpy((*s)->community,CFG_yytext+i,CFG_yyleng-i);
(*s)->community[CFG_yyleng-i]=0;
}
<in_switch>port{BL}{INT}{BL}{INT} {
sscanf(CFG_yytext+sizeof("port")/sizeof(char)-1," %lu %u",&ul1,&ui1);
if ((VS_PORT)ul1>z->nports || !ul1)
{
VS_log_error("CFG: parse error in %s on line %u : invalid port "\
"number\n",filename,line_num);
ports++;
free(ports);
return VS_R_PARSE;
}
if ((VS_PROTECTION_LEVEL)ui1>=VS_PL_NUMBER)
{
VS_log_error("CFG: parse error in %s on line %u : protection levels"\
"range from 0 to %u\n",filename,line_num,\
(unsigned int)ui1);
ports++;
free(ports);
return VS_R_PARSE;
}
ports[ul1].protection=(VS_PROTECTION_LEVEL)ui1;
VS_log_info("CFG: protection of port %lu set to %u\n",ul1,ui1);
}
<in_switch>end{BL}switch {
if ((*s)->community==NULL)
{
VS_log_error("CFG: parse error in %s on line %u : community string "\
"unspecified\n",filename,line_num);
free(ports);
free(*s);
return VS_R_PARSE;
}
(*s)->ports=ports;
ports=NULL;
s=&((*s)->next);
BEGIN(INITIAL);
eof_expected=1;
}
<*>{FB}#.*\n line_num++;
<*>{NONBLANK}+ {
VS_log_error("CFG: parse error in %s on line %u\n",filename,line_num);
if (ports+1!=NULL)
free(ports+1);
return VS_R_PARSE;
}
<*><<EOF>> {
if (!eof_expected)
{
VS_log_error("CFG: parse error in %s on line %u : unexpected end of "\
"file\n",filename,line_num);
if (ports+1!=NULL)
free(ports+1);
return VS_R_PARSE;
}
VS_log_info("CFG: parsing of %s over, %u lines parsed\n",filename,\
line_num);
return 0;
}
%%
#include <stdio.h>
void cleanup(struct VS_config *cfg)
{
unsigned long l;
struct CFG_SWITCH_TYPE *z;
void *y;
if (cfg->chan_map!=NULL)
{
for (l=0;(VS_CHANNEL)l<cfg->nchannels;l++)
if (cfg->chan_map[l].raw_data!=NULL)
free(cfg->chan_map[l].raw_data);
free(cfg->chan_map);
}
for (z=cfg->switch_types;z!=NULL;)
{
if ((z->ports+1)!=NULL)
free(z->ports+1);
y=z;
z=z->next;
free(y);
}
}
ERR_CODE CFG_init(struct VS_config *cfg,int argc,char *argv[])
{
ERR_CODE ret;
char *filepath=CFG_FILE_PATH;