if (line[strlen(line) - 1] == '\n')
line[strlen(line) - 1] = '\0';
+ // Skip all commented lines
+ if (*line == '#')
+ continue;
+
client_curr = (client_t*)malloc(sizeof(client_t));
memset(client_curr, 0, sizeof(client_t));
safe_system(IPTABLES " -t nat -F CAPTIVE_PORTAL");
}
+static int setup_dns_filters() {
+ const char* protos[] = { "udp", "tcp", NULL };
+
+ // Limits the number of DNS requests to 3 kByte/s
+ // A burst of 1MB is permitted at the start
+ const char* limiter = "-m hashlimit --hashlimit-name dns-filter"
+ " --hashlimit-mode srcip --hashlimit-upto 3kb/sec --hashlimit-burst 1024kb";
+
+ char command[STRING_SIZE];
+
+ const char** proto = protos;
+ while (*proto) {
+ snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p %s"
+ " --dport 53 %s -j RETURN", *proto, limiter);
+
+ int r = safe_system(command);
+ if (r)
+ return r;
+
+ proto++;
+ }
+
+ return 0;
+}
+
static int add_client_rules(const client_t* clients) {
char command[STRING_SIZE];
char match[STRING_SIZE];
if (r)
return r;
+ // Allow access to captive portal site
+ snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
+ " -d %s -p tcp --dport %d -j RETURN", intf, REDIRECT_PORT);
+ r = safe_system(command);
+ if (r)
+ return r;
+
return 0;
}
}
// Always pass DNS packets through all firewall rules
- r = safe_system(IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p udp --dport 53 -j RETURN");
- if (r)
- return r;
-
- r = safe_system(IPTABLES " -A CAPTIVE_PORTAL_CLIENTS -p tcp --dport 53 -j RETURN");
- if (r)
- return r;
-
- char command[STRING_SIZE];
- snprintf(command, sizeof(command), IPTABLES " -A CAPTIVE_PORTAL_CLIENTS"
- " -p tcp --dport %d -j RETURN", REDIRECT_PORT);
- r = safe_system(command);
+ r = setup_dns_filters();
if (r)
return r;
char* intf = NULL;
client_t* clients = NULL;
+ struct keyvalue* captive_portal_settings = NULL;
+ struct keyvalue* ethernet_settings = NULL;
+
if (!(initsetuid()))
exit(2);
- struct keyvalue* ethernet_settings = initkeyvalues();
+ ethernet_settings = initkeyvalues();
if (!readkeyvalues(ethernet_settings, ETHERNET_SETTINGS)) {
fprintf(stderr, "Could not read %s\n", ETHERNET_SETTINGS);
r = 1;
goto END;
}
- struct keyvalue* captive_portal_settings = initkeyvalues();
+ captive_portal_settings = initkeyvalues();
if (!readkeyvalues(captive_portal_settings, CAPTIVE_PORTAL_SETTINGS)) {
fprintf(stderr, "Could not read %s\n", CAPTIVE_PORTAL_SETTINGS);
r = 1;