/*******************************************************************************/
/* */
/* Copyright 2004 Pascal Gloor */
/* */
/* Licensed under the Apache License, Version 2.0 (the "License"); */
/* you may not use this file except in compliance with the License. */
/* You may obtain a copy of the License at */
/* */
/* http://www.apache.org/licenses/LICENSE-2.0 */
/* */
/* Unless required by applicable law or agreed to in writing, software */
/* distributed under the License is distributed on an "AS IS" BASIS, */
/* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. */
/* See the License for the specific language governing permissions and */
/* limitations under the License. */
/* */
/*******************************************************************************/
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <pwd.h>
#include <stdlib.h>
#include <string.h>
#include <p_defs.h>
#include <p_config.h>
/* reading configuration file */
int p_config_load(struct config_t *config, struct peer_t *peer, uint32_t mytime)
{
FILE *fd;
char line[128];
/* cleaning 'newallow' */
{
int a;
for(a=0; a<MAX_PEERS; a++)
{
peer[a].newallow = 0;
}
}
config->uid = -1;
config->gid = -1;
if ( ( fd = fopen(config->file, "r") ) == NULL )
{
printf("error: failed to read %s\n",config->file);
return -1;
}
while(fgets(line, sizeof(line), fd))
{
char *s = line;
if ( strncmp(s, "#", 1) == 0 ) { continue; }
s = strtok(s, " ");
if ( !strcmp(s,"bgp_router_id"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 16 )
{
config->routerid = inet_addr(s);
#ifdef DEBUG
printf("DEBUG: config bgp_router_id %s",s);
#endif
}
}
else if ( !strcmp(s,"local_ip"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 16 )
{
config->ip = inet_addr(s);
#ifdef DEBUG
printf("DEBUG: config local_ip %s",s);
#endif
}
}
else if ( !strcmp(s,"user"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 50 )
{
struct passwd *mypwd;
memcpy(s+strlen(s)-1,"\0",1);
mypwd = getpwnam(s);
if ( mypwd == NULL )
{
config->uid = -1;
config->gid = -1;
}
else
{
config->uid = mypwd->pw_uid;
config->gid = mypwd->pw_gid;
}
#ifdef DEBUG
printf("DEBUG: config user %i/%i (uid/gid) %s\n",config->uid,config->gid,s);
#endif
}
}
else if ( !strcmp(s,"local_as"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 6 )
{
config->as = atoi(s);
#ifdef DEBUG
printf("DEBUG: config local_as %s",s);
#endif
}
}
else if ( !strcmp(s,"local_port"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 6 )
{
config->port = atoi(s);
#ifdef DEBUG
printf("DEBUG: config local_port %s",s);
#endif
}
}
else if ( !strcmp(s,"bgp_holdtime"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 4 )
{
config->holdtime = atoi(s);
#ifdef DEBUG
printf("DEBUG: config bgp_holdtime %s",s);
#endif
}
}
else if ( !strcmp(s,"neighbor"))
{
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 16 )
{
uint32_t peer_ip = inet_addr(s);
#ifdef DEBUG
printf("DEBUG: config neighbor ip %s(%u) ",s,peer_ip);
#endif
s = strtok(NULL, " ");
if ( s != NULL && strlen(s) > 0 && strlen(s) <= 6 )
{
uint16_t peer_as = atoi(s);
#ifdef DEBUG
printf("as %s",s);
#endif
p_config_add_peer(peer,peer_ip,peer_as,mytime);
}
#ifdef DEBUG
else { printf("\n"); }
#endif
}
}
}
fclose(fd);
/* clearning no more allowed peers */
{
int a;
for(a=0; a<MAX_PEERS; a++)
{
if ( peer[a].newallow == 0 )
{
peer[a].status = 0;
peer[a].allow = 0;
}
}
}
/* check that all required values are set */
if ( config->routerid == 0 )
{
printf("configuration error: no bgp router id set\n");
return -1;
}
if ( config->as == 0 )
{
printf("configuration error: no local AS set\n");
return -1;
}
if ( config->uid == -1 || config->gid == -1 )
{
printf("configuration error: could not find user\n");
return -1;
}
return 0;
}
/* add, update of peers */
void p_config_add_peer(struct peer_t *peer, uint32_t ip, uint16_t as, uint32_t mytime)
{
int a;
if ( ip == 0 || as == 0 ) { return; }
for(a = 0; a<MAX_PEERS; a++)
{
if ( peer[a].ip == ip && peer[a].allow == 1 )
{
if ( peer[a].as != as )
{
peer[a].as = as;
peer[a].cts = mytime;
peer[a].status = 0;
}
peer[a].newallow = 1;
return;
}
}
for(a = 0; a<MAX_PEERS; a++)
{
if ( peer[a].allow == 0 )
{
peer[a].ip = ip;
peer[a].as = as;
peer[a].allow = 1;
peer[a].newallow = 1;
peer[a].status = 0;
peer[a].sock = 0;
peer[a].cts = mytime;
return;
}
}
}