commit 7b7b87db5922ec30903da6c62479ee8c400e7d9c Author: Olaf Rempel Date: Tue Nov 14 00:12:11 2006 +0100 initial commit diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..6d3bb98 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +*.o +urlfilter +urlfilter.db diff --git a/Makefile b/Makefile new file mode 100644 index 0000000..487cc92 --- /dev/null +++ b/Makefile @@ -0,0 +1,15 @@ +CFLAGS := -O2 -Wall -g + +all: urlfilter urlfilter.db + +urlfilter: urlfilter.o + $(CC) $(CFLAGS) -lsqlite3 -o $@ $^ + +urlfilter.db: urlfilter.sql + sqlite3 $@ < $^ + +%.o: %.c + $(CC) $(CFLAGS) -c $^ + +clean: + rm -rf urlfilter urlfilter.db *.o diff --git a/urlfilter.c b/urlfilter.c new file mode 100644 index 0000000..7e37d10 --- /dev/null +++ b/urlfilter.c @@ -0,0 +1,191 @@ +#include +#include +#include +#include + +#include +#include +#include + +#include + +#define DATABASE "urlfilter.db" +#define BUF_SIZE 1024 + +struct callback_args { + char *urlstr; + int urlstr_len; + int flags; +}; + +static int daemon_callback(void *data, int cols, char **values, char **colnames) +{ + struct callback_args *args = data; + + char *dburl = values[0]; + int dburl_len = strlen(dburl); + + if (args->urlstr_len >= dburl_len) { + char *p = args->urlstr; + p += (args->urlstr_len - dburl_len); + + if (!strncmp(p , dburl, dburl_len)) + args->flags |= 1; + } + + return 0; +} + +static int daemon_loop(sqlite3 *db) +{ + char *query = malloc(BUF_SIZE); + if (query == NULL) { + perror("malloc():"); + return -1; + } + + char *line = malloc(BUF_SIZE); + if (line == NULL) { + perror("malloc():"); + return -1; + } + + setvbuf(stdout, NULL, _IOLBF, 0); + + while (fgets(line, BUF_SIZE, stdin)) { + int ret; + + char *cp = strchr(line, '\n'); + if (cp != NULL) + *cp= '\0'; + + char *ipstr = strtok(line, " \t"); + char *urlstr = strtok(NULL, " \t"); + if (ipstr == NULL || urlstr == NULL) { + puts("ERR\n"); + continue; + } + + struct in_addr addr; + ret = inet_aton(ipstr, &addr); + if (ret == 0) { + puts("ERR\n"); + continue; + } + + ret = snprintf(query, BUF_SIZE, "SELECT url FROM urlfilter WHERE (ip & mask) == (%u & mask);", addr.s_addr); + if (ret < 0 || ret >= BUF_SIZE) { + puts("ERR\n"); + continue; + } + + struct callback_args args; + args.urlstr = urlstr; + args.urlstr_len = strlen(args.urlstr); + args.flags = 0; + + ret = sqlite3_exec(db, query, daemon_callback, &args, NULL); + if (ret != SQLITE_OK) { + puts("ERR\n"); + continue; + } + + if (args.flags) + puts("ERR\n"); + else + puts("OK\n"); + } +} + +static int show_callback(void *data, int cols, char **values, char **colnames) +{ + struct in_addr ip; + struct in_addr mask; + ip.s_addr = atoi(values[0]); + mask.s_addr = atoi(values[1]); + + printf("%15s/", inet_ntoa(ip)); + printf("%-15s ", inet_ntoa(mask)); + printf("%s (%s)\n", values[2], values[3]); + return 0; +} + +static void show_db(sqlite3 *db) +{ + char *errstr; + + int ret = sqlite3_exec(db, "SELECT ip, mask, url, info FROM urlfilter", show_callback, NULL, &errstr); + if (ret != SQLITE_OK) { + fprintf(stderr, "SQL error: %s\n", errstr); + sqlite3_free(errstr); + } +} + +static void add_db(sqlite3 *db, char *ipstr, char *maskstr, char *url, char *info) +{ + int ret; + + char *query = malloc(BUF_SIZE); + if (query == NULL) { + perror("malloc():"); + return; + } + + struct in_addr ip; + ret = inet_aton(ipstr, &ip); + if (ret == 0) { + fprintf(stderr, "invalid IP"); + return; + } + + struct in_addr mask; + ret = inet_aton(maskstr, &mask); + if (ret == 0) { + fprintf(stderr, "invalid Mask"); + return; + } + + ret = snprintf(query, BUF_SIZE, "INSERT INTO urlfilter VALUES(NULL,'%u','%u','%s','%s');", ip.s_addr, mask.s_addr, url, info); + if (ret < 0 || ret >= BUF_SIZE) { + puts("ERR\n"); + return; + } + + char *errstr; + + ret = sqlite3_exec(db, query, NULL, NULL, &errstr); + if (ret != SQLITE_OK) { + fprintf(stderr, "SQL error: %s\n", errstr); + sqlite3_free(errstr); + } + +} + +int main(int argc, char *argv[]) +{ + sqlite3 *db; + int rc = sqlite3_open(DATABASE, &db); + if (rc) { + fprintf(stderr, "Can't open database: %s\n", sqlite3_errmsg(db)); + sqlite3_close(db); + exit(-1); + } + + if (argc == 1) { + fprintf(stderr, "USAGE:\nurlfilter daemon\nurlfilter show\nurlfilter add \n\n"); + exit(-1); + + } else if (argc == 2) { + if (!strcmp(argv[1], "daemon")) + daemon_loop(db); + + else if (!strcmp(argv[1], "show")) + show_db(db); + + } else if ((argc = 6) && !strcmp(argv[1], "add")) { + add_db(db, argv[2], argv[3], argv[4], argv[5]); + } + + sqlite3_close(db); + return 0; +} diff --git a/urlfilter.sql b/urlfilter.sql new file mode 100644 index 0000000..ee7f0cb --- /dev/null +++ b/urlfilter.sql @@ -0,0 +1,9 @@ +DROP TABLE IF EXISTS urlfilter; + +CREATE TABLE urlfilter ( + id INTEGER PRIMARY KEY, + ip INTEGER, + mask INTEGER, + url VARCHAR(64), + info VARCHAR(64) +);