diff --git a/src/api/docs/content/specs/config.yaml b/src/api/docs/content/specs/config.yaml index d979ee3a3..5c7ee3ed9 100644 --- a/src/api/docs/content/specs/config.yaml +++ b/src/api/docs/content/specs/config.yaml @@ -421,6 +421,8 @@ components: type: string setupVars: type: string + pcap: + type: string log: type: object properties: @@ -667,6 +669,7 @@ components: gravity: "/etc/pihole/gravity.db" macvendor: "/etc/pihole/macvendor.db" setupVars: "/etc/pihole/setupVars.conf" + pcap: "" log: ftl: "/var/log/pihole/FTL.log" dnsmasq: "/var/log/pihole/pihole.log" diff --git a/src/config/config.c b/src/config/config.c index b2e8e6890..408d278e3 100644 --- a/src/config/config.c +++ b/src/config/config.c @@ -999,6 +999,13 @@ void initConfig(struct config *conf) conf->files.setupVars.f = FLAG_ADVANCED_SETTING; conf->files.setupVars.d.s = (char*)"/etc/pihole/setupVars.conf"; + conf->files.pcap.k = "files.pcap"; + conf->files.pcap.h = "An optional file containing a pcap capture of the network traffic. This file is used for debugging purposes only. If you don't know what this is, you don't need it.\n Setting this to an empty string disables pcap recording. The file must be writable by the user running FTL (typically pihole). Failure to write to this file will prevent the DNS resolver from starting. The file is appended to if it already exists."; + conf->files.pcap.a = cJSON_CreateStringReference(""); + conf->files.pcap.t = CONF_STRING; + conf->files.pcap.f = FLAG_ADVANCED_SETTING; + conf->files.pcap.d.s = (char*)""; + conf->files.log.webserver.k = "files.log.webserver"; conf->files.log.webserver.h = "The log file used by the webserver"; conf->files.log.webserver.a = cJSON_CreateStringReference(""); diff --git a/src/config/config.h b/src/config/config.h index e20f7276d..f9d765b89 100644 --- a/src/config/config.h +++ b/src/config/config.h @@ -239,6 +239,7 @@ struct config { struct conf_item gravity; struct conf_item macvendor; struct conf_item setupVars; + struct conf_item pcap; struct { struct conf_item ftl; struct conf_item dnsmasq; diff --git a/src/config/dnsmasq_config.c b/src/config/dnsmasq_config.c index bd3423c1c..f07ebe487 100644 --- a/src/config/dnsmasq_config.c +++ b/src/config/dnsmasq_config.c @@ -511,6 +511,22 @@ bool __attribute__((const)) write_dnsmasq_config(struct config *conf, bool test_ fputs("# Cache all DNS records\n", pihole_conf); fputs("cache-rr=ANY\n\n", pihole_conf); + // Add option for PCAP file recording + if(strlen(conf->files.pcap.v.s) > 0) + { + if(file_writeable(conf->files.pcap.v.s)) + { + fputs("# PCAP network traffic recording\n", pihole_conf); + fprintf(pihole_conf, "dumpmask=0xFFFF\n"); + fprintf(pihole_conf, "dumpfile=%s\n", conf->files.pcap.v.s); + fputs("\n", pihole_conf); + } + else + { + log_err("Cannot write to %s, disabling PCAP recording", conf->files.pcap.v.s); + } + } + // Add additional config lines to disk (if present) if(conf->misc.dnsmasq_lines.v.json != NULL && cJSON_GetArraySize(conf->misc.dnsmasq_lines.v.json) > 0) diff --git a/src/files.c b/src/files.c index 63b9c92af..18c4d7718 100644 --- a/src/files.c +++ b/src/files.c @@ -93,6 +93,28 @@ bool file_readable(const char *filename) return access(filename, R_OK) == 0; } +/** + * Function to check whether a file is writable or not. + * This function also returns success when a file does not exist yet but could + * be created and written to. + */ +bool file_writeable(const char *filename) +{ + // Check if file is writable + FILE *fp = fopen(filename, "ab"); + if(fp == NULL) + { + // File is not writable + return false; + } + + // Close file + fclose(fp); + + // File is writable + return true; +} + /** * Function to check whether a directory exists or not. * It returns true if given path is a directory and exists diff --git a/src/files.h b/src/files.h index 334bf0fce..007df716a 100644 --- a/src/files.h +++ b/src/files.h @@ -21,6 +21,7 @@ bool chmod_file(const char *filename, const mode_t mode); bool file_exists(const char *filename); bool file_readable(const char *filename); +bool file_writeable(const char *filename); bool get_database_stat(struct stat *st); unsigned long long get_FTL_db_filesize(void); void get_permission_string(char permissions[10], struct stat *st); diff --git a/test/hostnames.sh b/test/hostnames.sh index a988269d1..7f49ac44e 100644 --- a/test/hostnames.sh +++ b/test/hostnames.sh @@ -13,8 +13,8 @@ getIPs() { if [ -n "${addresses}" ]; then while IFS= read -r addr ; do # Check if Pi-hole can use itself to block a domain - dig_result=$(dig +tries=1 +time=2 -"${protocol}" -x "${addr}" @127.0.0.1 +short) - if [[ $addr == "127.0.0.1" && $dig_result == "localhost." ]] || [[ $addr == "::1" && $dig_result == "ip6-localhost." ]] || [[ $dig_result == "pi.hole." ]]; then + dig_result=$(dig +tries=1 +time=2 -x "${addr}" @127.0.0.1 +short) + if [[ $addr == "127.0.0.1" && $dig_result == "localhost." ]] || [[ $addr == "::1" && [[ $dig_result == "localhost." || $dig_result == "ip6-localhost." ]] ]] || [[ $dig_result == "pi.hole." ]]; then echo "${addr} is \"${dig_result}\": OK" else # Otherwise, show a failure diff --git a/test/pihole.toml b/test/pihole.toml index cf6ebd19d..878750f07 100644 --- a/test/pihole.toml +++ b/test/pihole.toml @@ -676,6 +676,17 @@ # setupVars = "/etc/pihole/setupVars.conf" + # An optional file containing a pcap capture of the network traffic. This file is used + # for debugging purposes only. If you don't know what this is, you don't need it. + # Setting this to an empty string disables pcap recording. The file must be writable + # by the user running FTL (typically pihole). Failure to write to this file will + # prevent the DNS resolver from starting. The file is appended to if it already + # exists. + # + # Possible values are: + # + pcap = "" + [files.log] # The location of FTL's log file #