Version 2.6

Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
Sami Kerola 2008-05-10 00:00:00 +02:00
parent 8904b5b82c
commit 4f000e7ab6
14 changed files with 374 additions and 268 deletions

View file

@ -58,7 +58,7 @@ parse_leases (void)
char *line, *ipstring;
struct in_addr inp;
struct stat lease_file_stats;
num_leases = 0;
num_touches = num_leases = 0;
dhcpd_leases = fopen (config.dhcpdlease_file, "r");
if (dhcpd_leases == NULL)
@ -80,6 +80,9 @@ parse_leases (void)
leases =
safe_malloc (sizeof (long int) *
((lease_file_stats.st_size / 250) + MAXLEN));
touches =
safe_malloc (sizeof (long int) *
((lease_file_stats.st_size / 250) + MAXLEN));
line = safe_malloc (sizeof (long int) * MAXLEN);
ipstring = safe_malloc (sizeof (long int) * MAXLEN);
@ -100,6 +103,13 @@ parse_leases (void)
leases[num_leases] = htonl (inp.s_addr);
num_leases++;
}
if (strstr (line, " binding state free"))
{
nth_field (2, ipstring, ipstring);
inet_aton (ipstring, &inp);
touches[num_touches] = htonl (inp.s_addr);
num_touches++;
}
}
return 0;
@ -141,23 +151,21 @@ nth_field (int n, char *dest, const char *src)
return 0;
}
/* UUTTA */
/* dhcpd.conf interesting words */
int
is_interesting_config_clause (char *s)
{
if (strstr (s, "range"))
if (strstr (s, "shared-network"))
{
return 1;
}
else if (strstr (s, "shared-network"))
else if (strstr (s, "range"))
{
return 2;
return 3;
}
else if (strstr (s, "include"))
{
return 3;
return 4;
}
else
{
@ -165,25 +173,27 @@ is_interesting_config_clause (char *s)
}
}
/* This function is far too long. */
int
parse_config (char *config_file)
parse_config (char *config_file, char *current_shared_name,
char *next_free_shared_name, struct shared_network_t *shared_p)
{
FILE *dhcpd_config;
int ret = 0, i = 0, newclause = 1, comment = 0, braces = 0;
int i = 0, newclause = 1, argument = 0, comment = 0, braces = 0, quote = 0;
char word[MAXLEN], c;
char *current_shared_name, *next_free_shared_name, *last_shared_name;
int braces_shared = 1000;
struct shared_network_t *shared_p;
struct in_addr inp;
struct range_t *range_p;
shared_p = shared_networks;
current_shared_name = shared_net_names;
next_free_shared_name = shared_net_names + strlen (shared_net_names) + 1;
char *last_shared_name;
last_shared_name = SHARED_NETWORKS_NAMES + shared_net_names;
/* Default place holder for ranges "All networks" */
/* Default place holder for ranges "All networks".
* If this is include file basicly nothing happens. */
shared_p->name = current_shared_name;
shared_p->available = 0;
shared_p->used = 0;
shared_p->touched = 0;
/* Open configuration file */
dhcpd_config = fopen (config_file, "r");
@ -193,61 +203,93 @@ parse_config (char *config_file)
exit (EXIT_FAILURE);
}
/* Parse file with a bit hairy style */
/* Hairy stuff begins. */
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Certain characters are magical */
switch (c)
{
/* Handle comments if they are not quoted */
case '#':
comment = 1;
if (quote == false)
{
comment = true;
}
continue;
case '"':
if (comment == false)
{
quote++;
/* Either one or zero */
quote = quote % 2;
}
continue;
case '\n':
comment = 0;
continue;
case ';':
if (comment == 0)
/* New line resets comment section, but not if quoted */
if (quote == false)
{
newclause = 1;
comment = false;
}
break;
case ';':
/* Quoted colon does not mean new clause */
if (quote == true)
{
break;
}
if (comment == false && argument != 2 && argument != 4)
{
newclause = true;
i = 0;
}
continue;
case '{':
if (comment == 0)
if (quote == true)
{
break;
}
if (comment == false)
{
braces++;
newclause = 1;
newclause = true;
}
continue;
case '}':
if (comment == 0)
if (quote == true)
{
break;
}
if (comment == false)
{
braces--;
/* End of shared-network */
if (braces_shared == braces)
{
current_shared_name = shared_net_names;
braces_shared = 1000;
shared_p = shared_networks;
}
newclause = 1;
/* Not literally true, but works for this program */
newclause = true;
}
continue;
default:
break;
}
/* Either inside comment or Nth word of clause. */
if (comment == 1 || newclause == 0)
if (comment == true || (newclause == false && argument == 0))
{
continue;
}
/* Strip white spaces before new clause word. */
if (newclause == 1 && isspace (c) && i == 0)
if ((newclause == true || argument != 0) && isspace (c) && i == false)
{
continue;
}
/* Save to word which clause this is. */
if (newclause == 1 && !isspace (c))
if ((newclause == true || argument != 0) && (!isspace (c) || quote == true))
{
word[i] = c;
i++;
@ -255,189 +297,95 @@ parse_config (char *config_file)
* this program is looking for are this long. */
if (i > MAXLEN)
{
newclause = 0;
newclause = false;
i = 0;
continue;
}
}
/* See if clause is something that parser is looking for. */
else
else if (newclause == true)
{
/* Insert string end & set state */
word[i] = '\0';
newclause = 0;
newclause = false;
i = 0;
ret = is_interesting_config_clause (word);
switch (ret)
argument = is_interesting_config_clause (word);
}
/* words after range, shared-network or include */
else if (argument != 0)
{
word[i] = '\0';
newclause = false;
i = 0;
switch (argument)
{
case 0:
/* printf ("nothing interesting: %s\n", word); */
argument = 0;
break;
case 1:
/* printf ("range %s\n", shared_p->name); */
save_range (dhcpd_config, shared_p);
break;
case 2:
/* printf("shared-network\n"); */
braces_shared = braces;
/* printf ("shared-network named: %s\n", word); */
strcpy (next_free_shared_name, word);
shared_p = shared_networks + num_shared_networks;
num_shared_networks++;
shared_p++;
save_shared_network (dhcpd_config, next_free_shared_name,
last_shared_name,
shared_networks + num_shared_networks);
current_shared_name = next_free_shared_name;
/* printf ("current name: %s \n", current_shared_name); */
next_free_shared_name += strlen (next_free_shared_name) + 1;
shared_p = shared_networks + num_shared_networks;
shared_p->name = next_free_shared_name;
shared_p->available = 0;
shared_p->used = 0;
shared_p->touched = 0;
/* Temporary abuse of argument variable */
argument = strlen (next_free_shared_name) + 1;
if (last_shared_name > next_free_shared_name + argument)
{
next_free_shared_name += argument;
}
else
{
/* TODO: make this go away by reallocationg more space. */
eprintf
("End of shared-network space, increase SHARED_NETWORKS_NAMES and recompile");
}
argument = 0;
break;
case 3:
/* printf ("include\n"); */
follow_include (dhcpd_config);
break;
default:
eprintf ("This cannot happen, report a bug!");
exit (EXIT_FAILURE);
}
}
}
// mitvit num_ranges--;
return 0;
}
int
save_range (FILE * dhcpd_config, char *shared_p)
{
char c, ipstr[17];
/* ip string index */
int i = 0;
/* white spaces before first IP detector */
int j = 0;
/* index is it first or second IP */
int k = 0;
/* wishful thingking that this could make performance better */
int space = 0;
struct in_addr inp;
struct range_t *range_p;
range_p = ranges + num_ranges;
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Avoid constantly running same syscall by saving result. */
space = isspace (c);
/* white spaces before first IP */
if (space != 0 && j == 0)
{
continue;
/* save IP string */
}
else if (space == 0)
{
ipstr[i] = c;
i++;
j = 1;
continue;
}
/* Put IP to structure where it will be analyzed. */
if ((space != 0) && i > 0)
{
ipstr[i] = '\0';
/* Remove possible trailing colon */
if (ipstr[i - 1] == ';')
{
ipstr[i - 1] = '\0';
}
/* Convert string to decimal */
inet_aton (ipstr, &inp);
if (k == 0)
{
range_p->first_ip = htonl (inp.s_addr) - 1;
}
else
{
case 2:
/* printf ("range 2nd ip: %s\n", word); */
range_p = ranges + num_ranges;
inet_aton (word, &inp);
argument = 0;
range_p->last_ip = htonl (inp.s_addr) + 1;
range_p->count = 0;
range_p->touched = 0;
range_p->shared_net = shared_p;
num_ranges++;
}
/* This needs to be convert to a dynamic memory engrowing. */
if (num_ranges > RANGES)
{
eprintf
("parse_config: Range space full! Increase RANGES and recompile.");
if (num_ranges > RANGES)
{
eprintf
("parse_config: Range space full! Increase RANGES and recompile.");
exit (EXIT_FAILURE);
}
newclause = true;
break;
case 3:
/* printf ("range 1nd ip: %s\n", word); */
range_p = ranges + num_ranges;
inet_aton (word, &inp);
range_p->first_ip = htonl (inp.s_addr) - 1;
argument = 2;
break;
case 4:
/* printf ("include file: %s\n", word); */
argument = 0;
parse_config (word, current_shared_name,
next_free_shared_name, shared_p);
newclause = true;
break;
default:
eprintf ("This cannot happpen, report a bug!");
exit (EXIT_FAILURE);
}
/* Reset IP string index and start looking for next one */
i = 0;
k++;
}
if (k > 1)
{
return 0;
}
}
eprintf ("This cannot happen, report a bug!");
exit (EXIT_FAILURE);
}
int
save_shared_network (FILE * dhcpd_config, char *name, char *last,
struct shared_network_t *shared_p)
{
char c;
/* Name in quotes must be saved with spaces */
int quoted = 0;
/* name string index */
int i = 0;
/* white spaces before name detector */
int j = 0;
/* wishful thingking that this could make performance better */
int space = 0;
while (!feof (dhcpd_config))
{
c = fgetc (dhcpd_config);
/* Avoid constantly running same syscall by saving result. */
space = isspace (c);
/* Skip initial white spaces */
if (space != 0 && j == 0)
{
continue;
}
if (c == '"')
{
quoted++;
j = 1;
continue;
}
if (space != 0 && quoted != 1)
{
if (&name[i] == last)
{
eprintf ("Shared network name space out of memory");
exit (1);
}
name[i] = '\0';
j = strlen (name);
break;
}
name[i] = c;
i++;
j = 1;
}
shared_p->name = name;
shared_p->available = 0;
shared_p->used = 0;
return 0;
}
int
follow_include (FILE * dhcpd_config)
{
return 0;
}