mirror of
git://git.code.sf.net/p/dhcpd-pools/code
synced 2025-12-18 08:47:00 +00:00
Version 2.6
Signed-off-by: Sami Kerola <kerolasa@iki.fi>
This commit is contained in:
parent
8904b5b82c
commit
4f000e7ab6
14 changed files with 374 additions and 268 deletions
322
src/getdata.c
322
src/getdata.c
|
|
@ -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;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue