| ############################################################################ | |||||
| # Copyright 2019 Pascal Gloor | # Copyright 2019 Pascal Gloor | ||||
| # | # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | # limitations under the License. | ||||
| ############################################################################ | |||||
| .PHONY: all clean install uninstall | .PHONY: all clean install uninstall | ||||
| # actions. | # actions. | ||||
| # Set to 0 for production. | # Set to 0 for production. | ||||
| dryrun=0 | dryrun=0 | ||||
| # stats file and interval (seconds) | |||||
| # the stats file will be overwritten every n seconds | |||||
| # as defined below. The counters are absolute AND | |||||
| # relative (both included). | |||||
| stats_file=/var/run/dhcp_protect_status.json | |||||
| stats_interval=10 | |||||
| ############################################################################### | |||||
| # Copyright 2019 Pascal Gloor | # Copyright 2019 Pascal Gloor | ||||
| # | # | ||||
| # Licensed under the Apache License, Version 2.0 (the "License"); | # Licensed under the Apache License, Version 2.0 (the "License"); | ||||
| # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | ||||
| # See the License for the specific language governing permissions and | # See the License for the specific language governing permissions and | ||||
| # limitations under the License. | # limitations under the License. | ||||
| ############################################################################### | |||||
| CC := gcc | CC := gcc | ||||
| CCFLAGS := -Wall -O2 -I../inc | |||||
| LDFLAGS := -lnetfilter_queue | |||||
| CCFLAGS := -Wall -Werror -pedantic -O2 -I../inc | |||||
| LDFLAGS := -lnetfilter_queue -lpthread | |||||
| TARGETS:= dhcp_protect | TARGETS:= dhcp_protect | ||||
| MAINS := $(.o, $(TARGETS) ) | MAINS := $(.o, $(TARGETS) ) | ||||
| dp_nfqueue.o \ | dp_nfqueue.o \ | ||||
| dp_accounting.o \ | dp_accounting.o \ | ||||
| dp_blacklist.o \ | dp_blacklist.o \ | ||||
| dp_events.o \ | |||||
| $(MAINS) | $(MAINS) | ||||
| DEPS := | DEPS := | ||||
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <time.h> | #include <time.h> | ||||
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_ACCOUNTING | #ifndef __DP_ACCOUNTING | ||||
| #define __DP_ACCOUNTING 1 | #define __DP_ACCOUNTING 1 | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| #define DP_AC_CLEAN_INT 5 | |||||
| typedef struct dp_accounting { | typedef struct dp_accounting { | ||||
| unsigned char remoteid[256]; | unsigned char remoteid[256]; | ||||
| int len; | int len; |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <time.h> | #include <time.h> | ||||
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_BLACKLIST | #ifndef __DP_BLACKLIST | ||||
| #define __DP_BLACKLIST 1 | #define __DP_BLACKLIST 1 | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| #define DP_BL_CLEAN_INT 5 | |||||
| typedef struct dp_blacklist { | typedef struct dp_blacklist { | ||||
| unsigned char remoteid[256]; | unsigned char remoteid[256]; | ||||
| int len; | int len; |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include "dp_dhcpv4.h" | #include "dp_dhcpv4.h" | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| static dp_dhcpv4_stats dp_v4_stats; | |||||
| void dp_dhcpv4_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, unsigned char **remoteid, int *remoteidlen) { | void dp_dhcpv4_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, unsigned char **remoteid, int *remoteidlen) { | ||||
| int hwaddrpos = offset + 28; // remember where the hw addr is if we need to fallback to it | int hwaddrpos = offset + 28; // remember where the hw addr is if we need to fallback to it | ||||
| int hwlenpos = offset + 2; // remember where the hw addr len is if we need to fallback to it | int hwlenpos = offset + 2; // remember where the hw addr len is if we need to fallback to it | ||||
| } | } | ||||
| } | } | ||||
| } | } | ||||
| dp_dhcpv4_stats *dp_dhcpv4_cnt(uint8_t msgcode) { | |||||
| if ( msgcode > 0 && msgcode < DP_DHCPV4_CODE_LEN ) { | |||||
| dp_v4_stats.relcnt[msgcode]++; | |||||
| dp_v4_stats.abscnt[msgcode]++; | |||||
| } | |||||
| return &dp_v4_stats; | |||||
| } |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_DHCPV4 | #ifndef __DP_DHCPV4 | ||||
| #define __DP_DHCPV4 1 | #define __DP_DHCPV4 1 | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| static char *dp_dhcpv4_code[] = { | |||||
| NULL, | |||||
| "DISCOVER", | |||||
| "OFFER", | |||||
| "REQUEST", | |||||
| "DECLINE", | |||||
| "ACK", | |||||
| "NAK", | |||||
| "RELEASE", | |||||
| "INFORM", | |||||
| "FORCERENEW", | |||||
| "LEASEQUERY", | |||||
| "LEASEUNASSIGNED", | |||||
| "LEASEUNKNOWN", | |||||
| "LEASEACTIVE", | |||||
| "BULKLEASEQUERY", | |||||
| "LEASEQUERYDONE", | |||||
| "ACTIVELEASEQUERY" | |||||
| "LEASEQUERYSTATUS", | |||||
| "TLS" | |||||
| }; | |||||
| #define DP_DHCPV4_CODE_LEN (sizeof(dp_dhcpv4_code)/sizeof(dp_dhcpv4_code[0])) | |||||
| typedef struct dp_dhcpv4_stats { | |||||
| long long unsigned int relcnt[DP_DHCPV4_CODE_LEN]; | |||||
| long long unsigned int abscnt[DP_DHCPV4_CODE_LEN]; | |||||
| } dp_dhcpv4_stats; | |||||
| void dp_dhcpv4_check ( | void dp_dhcpv4_check ( | ||||
| dp_conf*, | dp_conf*, | ||||
| unsigned char*, | unsigned char*, | ||||
| unsigned char**, | unsigned char**, | ||||
| int*); | int*); | ||||
| dp_dhcpv4_stats *dp_dhcpv4_cnt(uint8_t); | |||||
| #endif // __DP_MACRO | #endif // __DP_MACRO |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdint.h> | #include <stdint.h> | ||||
| #include <netinet/in.h> | #include <netinet/in.h> | ||||
| #include "dp_dhcpv6.h" | #include "dp_dhcpv6.h" | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| static dp_dhcpv6_stats dp_v6_stats; | |||||
| void dp_dhcpv6_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, unsigned char **remoteid, int *remoteidlen) { | void dp_dhcpv6_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, unsigned char **remoteid, int *remoteidlen) { | ||||
| uint8_t msgtype = (uint8_t)pkt[offset]; | uint8_t msgtype = (uint8_t)pkt[offset]; | ||||
| offset+=len; | offset+=len; | ||||
| } | } | ||||
| } | } | ||||
| dp_dhcpv6_stats *dp_dhcpv6_cnt(uint8_t msgcode) { | |||||
| if ( msgcode > 0 && msgcode < DP_DHCPV6_CODE_LEN ) { | |||||
| dp_v6_stats.relcnt[msgcode]++; | |||||
| dp_v6_stats.abscnt[msgcode]++; | |||||
| } | |||||
| return &dp_v6_stats; | |||||
| } |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_DHCPV6 | #ifndef __DP_DHCPV6 | ||||
| #define __DP_DHCPV6 1 | #define __DP_DHCPV6 1 | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| static char *dp_dhcpv6_code[] = { | |||||
| NULL, | |||||
| "SOLICIT", | |||||
| "ADVERTISE", | |||||
| "REQUEST", | |||||
| "CONFIRM", | |||||
| "RENEW", | |||||
| "REBIND", | |||||
| "REPLY", | |||||
| "RELEASE", | |||||
| "DECLINE", | |||||
| "RECONFIGURE", | |||||
| "INFORMATION-REQUEST", | |||||
| "RELAY-FORW", | |||||
| "RELAY-REPL", | |||||
| "LEASEQUERY", | |||||
| "LEASEQUERY-REPLY", | |||||
| "LEASEQUERY-DONE", | |||||
| "LEASEQUERY-DATA", | |||||
| "RECONFIGURE-REQUEST", | |||||
| "RECONFIGURE-REPLY", | |||||
| "DHCPV4-QUERY", | |||||
| "DHCPV4-RESPONSE", | |||||
| "ACTIVELEASEQUERY", | |||||
| "STARTTLS", | |||||
| "BNDUPD", | |||||
| "BNDREPLY", | |||||
| "POOLREQ", | |||||
| "POOLRESP", | |||||
| "UPDREQ", | |||||
| "UPDREQALL", | |||||
| "UPDDONE", | |||||
| "CONNECT", | |||||
| "CONNECTREPLY", | |||||
| "DISCONNECT", | |||||
| "STATE", | |||||
| "CONTACT" | |||||
| }; | |||||
| #define DP_DHCPV6_CODE_LEN (sizeof(dp_dhcpv6_code)/sizeof(dp_dhcpv6_code[0])) | |||||
| typedef struct dp_dhcpv6_stats { | |||||
| long long unsigned int relcnt[DP_DHCPV6_CODE_LEN]; | |||||
| long long unsigned int abscnt[DP_DHCPV6_CODE_LEN]; | |||||
| } dp_dhcpv6_stats; | |||||
| void dp_dhcpv6_check ( | void dp_dhcpv6_check ( | ||||
| dp_conf*, | dp_conf*, | ||||
| unsigned char*, | unsigned char*, | ||||
| unsigned char**, | unsigned char**, | ||||
| int*); | int*); | ||||
| dp_dhcpv6_stats *dp_dhcpv6_cnt(uint8_t); | |||||
| #endif // __DP_MACRO | #endif // __DP_MACRO |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | |||||
| #include <string.h> | |||||
| #include <stdint.h> | |||||
| #include <stdlib.h> | |||||
| #include <unistd.h> | |||||
| #include <time.h> | |||||
| #include <linux/limits.h> | |||||
| #include "dp_events.h" | |||||
| #include "dp_helpers.h" | |||||
| #include "dp_accounting.h" | |||||
| #include "dp_blacklist.h" | |||||
| void *dp_events(void *data) { | |||||
| dp_conf *conf = (dp_conf*)data; | |||||
| time_t last_blacklist = time(NULL); | |||||
| time_t last_accounting = time(NULL); | |||||
| time_t last_stats = time(NULL); | |||||
| while(1) { | |||||
| time_t now = time(NULL); | |||||
| if ( last_blacklist + DP_BL_CLEAN_INT >= now ) { | |||||
| dp_blacklist_cleanup(conf); | |||||
| last_blacklist=now; | |||||
| } | |||||
| if ( last_accounting + DP_AC_CLEAN_INT >= now ) { | |||||
| dp_accounting_cleanup(conf); | |||||
| last_accounting=now; | |||||
| } | |||||
| if ( last_stats + conf->stats_interval >= now ) { | |||||
| dp_events_stats(conf); | |||||
| last_stats=now; | |||||
| } | |||||
| usleep(100000); /* 100ms */ | |||||
| } | |||||
| return NULL; | |||||
| } | |||||
| void dp_events_stats(dp_conf *conf) { | |||||
| char tmpfile[PATH_MAX+4]; | |||||
| dp_dhcpv4_stats *stats4; | |||||
| dp_dhcpv6_stats *stats6; | |||||
| FILE *fh; | |||||
| int i; | |||||
| snprintf(tmpfile, sizeof(tmpfile), "%s.tmp", conf->stats_file); | |||||
| if ( ( fh = fopen(tmpfile, "w") ) == NULL ) | |||||
| return; | |||||
| stats4 = dp_dhcpv4_cnt(0); | |||||
| fprintf(fh,"{ \"dhcpv4\": { "); | |||||
| for(i=0; i<DP_DHCPV4_CODE_LEN; i++) { | |||||
| if ( stats4->relcnt[i]>0 ) { | |||||
| fprintf(fh, "\"%s\": { ", dp_dhcpv4_code[i]); | |||||
| fprintf(fh, "\"rel\": %llu, \"abs\": %llu }", stats4->relcnt[i], stats4->abscnt[i]); | |||||
| } | |||||
| else if ( stats4->abscnt[i]>0 ) { | |||||
| fprintf(fh, "\"%s\": { ", dp_dhcpv4_code[i]); | |||||
| fprintf(fh, "\"abs\": %llu }", stats4->abscnt[i]); | |||||
| } | |||||
| if ( ( stats4->relcnt[i]>0 || stats4->abscnt[i]>0 ) && i-1 != DP_DHCPV4_CODE_LEN ) | |||||
| fprintf(fh, ", "); | |||||
| stats4->relcnt[i]=0; | |||||
| } | |||||
| stats6 = dp_dhcpv6_cnt(0); | |||||
| fprintf(fh, "}, \"dhcpv6\" : { "); | |||||
| for(i=0; i<DP_DHCPV6_CODE_LEN; i++) { | |||||
| if ( stats6->relcnt[i]>0 ) { | |||||
| fprintf(fh, "\"%s\": { ", dp_dhcpv6_code[i]); | |||||
| fprintf(fh, "\"rel\": %llu, \"abs\": %llu }", stats6->relcnt[i], stats6->abscnt[i]); | |||||
| } | |||||
| else if ( stats6->abscnt[i]>0 ) { | |||||
| fprintf(fh, "\"%s\": { ", dp_dhcpv6_code[i]); | |||||
| fprintf(fh, "\"abs\": %llu }", stats6->abscnt[i]); | |||||
| } | |||||
| if ( ( stats6->relcnt[i]>0 || stats6->abscnt[i]>0 ) && i-1 != DP_DHCPV6_CODE_LEN ) | |||||
| fprintf(fh, ", "); | |||||
| stats6->relcnt[i]=0; | |||||
| } | |||||
| fprintf(fh, "}"); | |||||
| fclose(fh); | |||||
| rename(tmpfile, conf->stats_file); | |||||
| } |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include "dp_helpers.h" | |||||
| #include "dp_dhcpv4.h" | |||||
| #include "dp_dhcpv6.h" | |||||
| typedef struct dp_stats { | |||||
| dp_dhcpv4_stats dhcpv4; | |||||
| dp_dhcpv6_stats dhcpv6; | |||||
| } dp_stats; | |||||
| void *dp_events (void*); | |||||
| void dp_events_stats(dp_conf *conf); |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <stdarg.h> | #include <stdarg.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| conf->queue = atoi(value); | conf->queue = atoi(value); | ||||
| else if ( strcmp(name, "dryrun")==0 ) | else if ( strcmp(name, "dryrun")==0 ) | ||||
| conf->dryrun = atoi(value) ? 1 : 0; | conf->dryrun = atoi(value) ? 1 : 0; | ||||
| else if ( strcmp(name, "stats_file")==0 ) | |||||
| strncpy(conf->stats_file, value, sizeof(conf->stats_file)-1); | |||||
| else if ( strcmp(name, "stats_interval")==0 ) | |||||
| conf->stats_interval = atoi(value); | |||||
| else | else | ||||
| fprintf(stderr,"unknown directive '%s', ignored\n", name); | fprintf(stderr,"unknown directive '%s', ignored\n", name); | ||||
| fprintf(stderr, "dryrun value invalid (0 or 1)\n"); | fprintf(stderr, "dryrun value invalid (0 or 1)\n"); | ||||
| error=1; | error=1; | ||||
| } | } | ||||
| if ( conf->stats_interval < 1 ) { | |||||
| fprintf(stderr, "stats_interval invalid (must be >0)\n"); | |||||
| error=1; | |||||
| } | |||||
| if ( strlen(conf->stats_file) == 0 ) { | |||||
| fprintf(stderr, "warning: stats file not set, feature disabled\n"); | |||||
| } | |||||
| if ( error ) | if ( error ) | ||||
| return NULL; | return NULL; | ||||
| printf("\t%-20s = %4i\n", "max_pkt_per_interval", conf->pktint); | printf("\t%-20s = %4i\n", "max_pkt_per_interval", conf->pktint); | ||||
| printf("\t%-20s = %4is\n", "blacklist_time", conf->bltime); | printf("\t%-20s = %4is\n", "blacklist_time", conf->bltime); | ||||
| printf("\t%-20s = %4i\n", "queue", conf->queue); | printf("\t%-20s = %4i\n", "queue", conf->queue); | ||||
| printf("\t%-20s = %s\n", "stats_file", conf->stats_file); | |||||
| printf("\t%-20s = %4i\n", "stats_interval", conf->stats_interval); | |||||
| return conf; | return conf; |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_HELPERS | #ifndef __DP_HELPERS | ||||
| #define __DP_HELPERS 1 | #define __DP_HELPERS 1 | ||||
| #include <linux/limits.h> | |||||
| typedef struct dp_conf { | typedef struct dp_conf { | ||||
| int pktint; | int pktint; | ||||
| int interval; | int interval; | ||||
| int bltime; | int bltime; | ||||
| int queue; | int queue; | ||||
| int dryrun; | int dryrun; | ||||
| char stats_file[PATH_MAX]; | |||||
| int stats_interval; | |||||
| } dp_conf; | } dp_conf; | ||||
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | |||||
| #include <stdlib.h> | #include <stdlib.h> | ||||
| #include <string.h> | |||||
| #include <errno.h> | |||||
| #include <pthread.h> | |||||
| #include "dp_main.h" | #include "dp_main.h" | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| #include "dp_nfqueue.h" | #include "dp_nfqueue.h" | ||||
| #include "dp_events.h" | |||||
| // main function | // main function | ||||
| int main(int argc, char **argv) { | int main(int argc, char **argv) { | ||||
| char *configfile; | char *configfile; | ||||
| dp_conf conf; | dp_conf conf; | ||||
| pthread_t pth_nfqueue, pth_events; | |||||
| if ( argc == 2 ) { | if ( argc == 2 ) { | ||||
| configfile = argv[1]; | configfile = argv[1]; | ||||
| if ( dp_load_config(&conf, configfile) == NULL ) | if ( dp_load_config(&conf, configfile) == NULL ) | ||||
| return EXIT_FAILURE; | return EXIT_FAILURE; | ||||
| dp_nfq_start(&conf); | |||||
| if ( pthread_create(&pth_nfqueue, NULL, &dp_nfq_start, &conf) != 0 ) { | |||||
| fprintf(stderr, "pthread_create error: %s\n", strerror(errno)); | |||||
| return EXIT_FAILURE; | |||||
| } | |||||
| if ( pthread_create(&pth_events, NULL, &dp_events, &conf) != 0 ) { | |||||
| fprintf(stderr, "pthread_create error: %s\n", strerror(errno)); | |||||
| return EXIT_FAILURE; | |||||
| } | |||||
| pthread_join(pth_nfqueue, NULL); | |||||
| pthread_join(pth_events, NULL); | |||||
| return 0; | return 0; | ||||
| } | } |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_MAIN | #ifndef __DP_MAIN | ||||
| #define __DP_MAIN 1 | #define __DP_MAIN 1 | ||||
| // Copyright 2019 Pascal Gloor | |||||
| // | |||||
| // Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| // you may not use this file except in compliance with the License. | |||||
| // You may obtain a copy of the License at | |||||
| // | |||||
| // http://www.apache.org/licenses/LICENSE-2.0 | |||||
| // | |||||
| // Unless required by applicable law or agreed to in writing, software | |||||
| // distributed under the License is distributed on an "AS IS" BASIS, | |||||
| // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| // See the License for the specific language governing permissions and | |||||
| // limitations under the License. | |||||
| #endif // __DP_MACRO | #endif // __DP_MACRO |
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #include <stdio.h> | #include <stdio.h> | ||||
| #include <string.h> | #include <string.h> | ||||
| #include <arpa/inet.h> | #include <arpa/inet.h> | ||||
| #include "dp_dhcpv6.h" | #include "dp_dhcpv6.h" | ||||
| // start netfilter queue | // start netfilter queue | ||||
| void dp_nfq_start(dp_conf *conf) { | |||||
| void *dp_nfq_start(void *data) { | |||||
| dp_conf *conf = (dp_conf*)data; | |||||
| struct nfq_handle *h; | struct nfq_handle *h; | ||||
| struct nfq_q_handle *qh; | struct nfq_q_handle *qh; | ||||
| int fd; | int fd; | ||||
| if ( ( h = nfq_open() ) == NULL ) { | if ( ( h = nfq_open() ) == NULL ) { | ||||
| fprintf(stderr,"error during nfq_open() %s\n", strerror(errno)); | fprintf(stderr,"error during nfq_open() %s\n", strerror(errno)); | ||||
| return; | |||||
| return NULL; | |||||
| } | } | ||||
| if ( ( qh = nfq_create_queue(h, conf->queue, &dp_callback, conf) ) == NULL ) { | if ( ( qh = nfq_create_queue(h, conf->queue, &dp_callback, conf) ) == NULL ) { | ||||
| fprintf(stderr, "error during nfq_create_queue() %s\n", strerror(errno)); | fprintf(stderr, "error during nfq_create_queue() %s\n", strerror(errno)); | ||||
| return; | |||||
| return NULL; | |||||
| } | } | ||||
| if ( nfq_set_mode(qh, NFQNL_COPY_PACKET, 1500) < 0 ) { | if ( nfq_set_mode(qh, NFQNL_COPY_PACKET, 1500) < 0 ) { | ||||
| fprintf(stderr,"error during nfq_set_mode() %s\n", strerror(errno)); | fprintf(stderr,"error during nfq_set_mode() %s\n", strerror(errno)); | ||||
| return; | |||||
| return NULL; | |||||
| } | } | ||||
| if ( nfq_set_queue_flags(qh, NFQA_CFG_F_FAIL_OPEN, NFQA_CFG_F_FAIL_OPEN) < 0 ) { | if ( nfq_set_queue_flags(qh, NFQA_CFG_F_FAIL_OPEN, NFQA_CFG_F_FAIL_OPEN) < 0 ) { | ||||
| fprintf(stderr,"error during nfq_set_queue_flags() %s\n", strerror(errno)); | fprintf(stderr,"error during nfq_set_queue_flags() %s\n", strerror(errno)); | ||||
| return; | |||||
| return NULL; | |||||
| } | } | ||||
| fd = nfq_fd(h); | fd = nfq_fd(h); | ||||
| switch(rv) { | switch(rv) { | ||||
| case -1: | case -1: | ||||
| fprintf(stderr, "recv() error: %s\n", strerror(errno)); | fprintf(stderr, "recv() error: %s\n", strerror(errno)); | ||||
| return; | |||||
| return NULL; | |||||
| case 0: | case 0: | ||||
| fprintf(stderr,"socket is closed!?\n"); | fprintf(stderr,"socket is closed!?\n"); | ||||
| return; | |||||
| return NULL; | |||||
| default: | default: | ||||
| // send packet to callback | // send packet to callback | ||||
| nfq_handle_packet(h, buf, rv); | nfq_handle_packet(h, buf, rv); | ||||
| break; | break; | ||||
| } | } | ||||
| } | } | ||||
| return NULL; | |||||
| } | } | ||||
| // decode dhcp packet | // decode dhcp packet | ||||
| end: | end: | ||||
| dp_accounting_cleanup(conf); | |||||
| dp_blacklist_cleanup(conf); | |||||
| return rv; | return rv; | ||||
| } | } | ||||
| /************************************************************************** | |||||
| * Copyright 2019 Pascal Gloor | |||||
| * | |||||
| * Licensed under the Apache License, Version 2.0 (the "License"); | |||||
| * you may not use this file except in compliance with the License. | |||||
| * You may obtain a copy of the License at | |||||
| * | |||||
| * http://www.apache.org/licenses/LICENSE-2.0 | |||||
| * | |||||
| * Unless required by applicable law or agreed to in writing, software | |||||
| * distributed under the License is distributed on an "AS IS" BASIS, | |||||
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |||||
| * See the License for the specific language governing permissions and | |||||
| * limitations under the License. | |||||
| **************************************************************************/ | |||||
| #ifndef __DP_NFQUEUE | #ifndef __DP_NFQUEUE | ||||
| #define __DP_NFQUEUE 1 | #define __DP_NFQUEUE 1 | ||||
| #include "dp_helpers.h" | #include "dp_helpers.h" | ||||
| void dp_nfq_start (dp_conf*); | |||||
| int dp_dhcp_check (struct nfq_data*, dp_conf*); | |||||
| int dp_callback (struct nfq_q_handle*, struct nfgenmsg*, struct nfq_data*, void*); | |||||
| void *dp_nfq_start (void*); | |||||
| int dp_dhcp_check (struct nfq_data*, dp_conf*); | |||||
| int dp_callback (struct nfq_q_handle*, struct nfgenmsg*, struct nfq_data*, void*); | |||||
| #endif // __DP_MACRO | #endif // __DP_MACRO |