initial commit
This commit is contained in:
commit
7b7b87db59
|
@ -0,0 +1,3 @@
|
|||
*.o
|
||||
urlfilter
|
||||
urlfilter.db
|
|
@ -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
|
|
@ -0,0 +1,191 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <sqlite3.h>
|
||||
|
||||
#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 <ip> <netmask> <url> <info>\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;
|
||||
}
|
|
@ -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)
|
||||
);
|
Loading…
Reference in New Issue