2 * nbtscanner -- a tool for scanning large networks for SMB servers.
4 * configfile.c: Functions for parsing the configuration file.
5 * Copyright (C) 2000 Steinar H. Gunderson
7 * Large amounts of code adapted from Samba (http://www.samba.org/)
8 * Copyright (C) Andrew Tridgell 1994-1998, and others.
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License as published by
12 * the Free Software Foundation; either version 2 of the License, or
13 * (at your option) any later version.
15 * This program is distributed in the hope that it will be useful,
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
18 * GNU General Public License for more details.
20 * You should have received a copy of the GNU General Public License
21 * along with this program; if not, write to the Free Software
22 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
25 #include "configfile.h"
26 #include "nbtscanner.h"
27 #include "mysql_interface.h"
32 #include <sys/socket.h>
33 #include <netinet/in.h>
34 #include <arpa/inet.h>
45 struct in_addr scanrange[NUM_RANGES];
46 int scanrangesize[NUM_RANGES];
51 char mysql_username[32];
52 char mysql_password[32];
54 void parse_configfile()
56 FILE *configfile = fopen("nbtscanner.conf", "r");
59 if (configfile == NULL) {
60 perror("nbtscanner.conf");
68 ghost_lifetime = 1800;
74 strcpy(mysql_host, "no_host_given");
75 strcpy(mysql_username, "no_username_given");
76 strcpy(mysql_password, "no_password_given");
78 while (!feof(configfile)) {
83 fgets(buf, 1024, configfile);
84 while (buf[strlen(buf) - 1] == '\n' || buf[strlen(buf) - 1] == '\r') {
85 buf[strlen(buf) - 1] = '\0';
88 if (buf[0] == '#' || buf[0] == '\0') {
89 /* comment or blank line */
92 if (strspn(buf, " \t") == strlen(buf)) {
97 parse_line(buf, lineno);
103 void parse_line(char *buf, int lineno)
105 char *ptr = strchr(buf, '=');
107 if (ptr == NULL || strchr(ptr + 1, '=') != NULL) {
108 line_error(lineno, "Malformed line (must be exactly one `=' sign)");
111 /* split the line into a keyword and a value */
116 * trim any trailing spaces, make sure there are no spaces in
120 char *ptr2 = strchr(ptr, ' ');
122 /* must only be spaces from here */
123 if (strspn(ptr2 + 1, " ") != strlen(ptr2 + 1)) {
124 line_error(lineno, "Malformed value (can't have any spaces)");
131 /* make sure both the parameter and the value is non-empty */
132 if (buf[0] == '\0') {
133 line_error(lineno, "Malformed keyword (can't be empty)");
135 if (ptr[0] == '\0') {
136 line_error(lineno, "Malformed value (can't be empty)");
139 /* finally pass it on to the keyword checker */
140 parse_keyword(buf, ptr, lineno);
143 void parse_keyword(char *keyword, char *value, int lineno)
145 if (strcasecmp(keyword, "num_retries") == 0) {
146 parse_int(value, &num_retries, lineno);
147 } else if (strcasecmp(keyword, "retry_time") == 0) {
148 parse_int(value, &retry_time, lineno);
149 } else if (strcasecmp(keyword, "delay_time") == 0) {
150 parse_int(value, &delay_time, lineno);
151 } else if (strcasecmp(keyword, "ghost_lifetime") == 0) {
152 parse_int(value, &ghost_lifetime, lineno);
153 } else if (strcasecmp(keyword, "verbosity") == 0) {
154 parse_int(value, &verbosity, lineno);
155 } else if (strcasecmp(keyword, "scan_interval") == 0) {
156 parse_int(value, &scan_interval, lineno);
157 } else if (strcasecmp(keyword, "scan_wait") == 0) {
158 parse_int(value, &scan_wait, lineno);
159 } else if (strcasecmp(keyword, "use_mysql") == 0) {
160 parse_int(value, &use_mysql, lineno);
161 } else if (strcasecmp(keyword, "mysql_host") == 0) {
162 strcpy(mysql_host, value);
163 } else if (strcasecmp(keyword, "mysql_username") == 0) {
164 strcpy(mysql_username, value);
165 } else if (strcasecmp(keyword, "mysql_password") == 0) {
166 strcpy(mysql_password, value);
167 } else if (strcasecmp(keyword, "range") == 0) {
168 parse_range(value, lineno);
171 sprintf(buf, "Unknown keyword `%s'", keyword);
172 line_error(lineno, buf);
176 void parse_int(char *string, int *retval, int lineno)
178 if (strspn(string, "0123456789") != strlen(string)) {
180 sprintf(buf, "`%s' isn't a positive integer", string);
181 line_error(lineno, buf);
184 *retval = atoi(string);
187 void parse_range(char *string, int lineno)
189 /* exactly one / is allowed */
190 char *ptr = strchr(string, '/');
194 if (ptr != NULL && strchr(ptr + 1, '/') != NULL) {
195 line_error(lineno, "Malformed range (only one `/' allowed)");
198 /* lots and lots of code :-) */
199 if (ptr == NULL) { /* single IP */
205 /* find out whether this is a pure integer or not */
206 if (strspn(ptr, "0123456789") == strlen(ptr)) {
207 rangesize = atoi(ptr);
208 if (rangesize < 0 || rangesize > 32) {
209 line_error(lineno, "Malformed range (significant bits must be between 0 and 32, inclusive)");
211 } else if (strspn(ptr, "0123456789.") == strlen(ptr)) {
213 struct in_addr netmask;
216 if (inet_aton(ptr, &netmask) == 0) {
217 line_error(lineno, "Malformed range (malformed netmask)");
220 /* find the rightmost 1-bit (by finding the leftmost 0-bit) */
222 for (i = 31; i >= 0; i--) {
223 if ((netmask.s_addr & (1 << i)) == 0) {
229 rangesize = 32; /* 255.255.255.255 */
231 unsigned int clean_mask = htonl(~((1 << (31-i)) - 1));
235 /* verify that this is a `clean' netmask */
236 if (netmask.s_addr != clean_mask) {
237 line_error(lineno, "Malformed range (netmask must be `clean')");
241 line_error(lineno, "Malformed range (malformed netmask)");
242 rangesize = 32; /* will never reach this, but for gcc */
246 /* try to scan the IP part */
247 if (inet_aton(string, &in) == 0) {
248 line_error(lineno, "Malformed range (malformed IP address)");
251 /* check that the IP address and the netmask match */
252 if (rangesize != 32) {
253 /* not really the netmask, actually it's the inverted netmask */
254 unsigned int netmask = htonl((1 << (31-rangesize)) - 1);
256 if ((in.s_addr & netmask) != 0) {
257 line_error(lineno, "Malformed range (IP address doesn't match netmask)");
261 memcpy((char *)(&(scanrange[ranges])), (char *)(&in), sizeof(in));
262 scanrangesize[ranges++] = rangesize;
265 void line_error(int lineno, char *err_str)
267 fprintf(stderr, "nbtscanner.conf:%d: %s\n", lineno, err_str);