| @@ -1,3 +1,4 @@ | |||
| ############################################################################ | |||
| # Copyright 2019 Pascal Gloor | |||
| # | |||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||
| @@ -11,6 +12,7 @@ | |||
| # 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. | |||
| ############################################################################ | |||
| .PHONY: all clean install uninstall | |||
| @@ -26,3 +26,12 @@ queue=67 | |||
| # actions. | |||
| # Set to 0 for production. | |||
| 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 | |||
| @@ -1,3 +1,4 @@ | |||
| ############################################################################### | |||
| # Copyright 2019 Pascal Gloor | |||
| # | |||
| # Licensed under the Apache License, Version 2.0 (the "License"); | |||
| @@ -11,10 +12,11 @@ | |||
| # 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. | |||
| ############################################################################### | |||
| CC := gcc | |||
| CCFLAGS := -Wall -O2 -I../inc | |||
| LDFLAGS := -lnetfilter_queue | |||
| CCFLAGS := -Wall -Werror -pedantic -O2 -I../inc | |||
| LDFLAGS := -lnetfilter_queue -lpthread | |||
| TARGETS:= dhcp_protect | |||
| MAINS := $(.o, $(TARGETS) ) | |||
| @@ -26,6 +28,7 @@ OBJ := \ | |||
| dp_nfqueue.o \ | |||
| dp_accounting.o \ | |||
| dp_blacklist.o \ | |||
| dp_events.o \ | |||
| $(MAINS) | |||
| DEPS := | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 <time.h> | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_ACCOUNTING 1 | |||
| @@ -5,6 +21,8 @@ | |||
| #include "dp_helpers.h" | |||
| #define DP_AC_CLEAN_INT 5 | |||
| typedef struct dp_accounting { | |||
| unsigned char remoteid[256]; | |||
| int len; | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 <time.h> | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_BLACKLIST 1 | |||
| @@ -5,6 +21,8 @@ | |||
| #include "dp_helpers.h" | |||
| #define DP_BL_CLEAN_INT 5 | |||
| typedef struct dp_blacklist { | |||
| unsigned char remoteid[256]; | |||
| int len; | |||
| @@ -1,9 +1,27 @@ | |||
| /************************************************************************** | |||
| * 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 <stdint.h> | |||
| #include "dp_dhcpv4.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) { | |||
| 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 | |||
| @@ -98,3 +116,12 @@ void dp_dhcpv4_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, | |||
| } | |||
| } | |||
| } | |||
| 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; | |||
| } | |||
| @@ -1,8 +1,53 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_DHCPV4 1 | |||
| #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 ( | |||
| dp_conf*, | |||
| unsigned char*, | |||
| @@ -11,4 +56,6 @@ void dp_dhcpv4_check ( | |||
| unsigned char**, | |||
| int*); | |||
| dp_dhcpv4_stats *dp_dhcpv4_cnt(uint8_t); | |||
| #endif // __DP_MACRO | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 <stdint.h> | |||
| #include <netinet/in.h> | |||
| @@ -5,6 +21,8 @@ | |||
| #include "dp_dhcpv6.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) { | |||
| uint8_t msgtype = (uint8_t)pkt[offset]; | |||
| @@ -47,3 +65,12 @@ void dp_dhcpv6_check(dp_conf *conf, unsigned char *pkt, int pktlen, int offset, | |||
| 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; | |||
| } | |||
| @@ -1,8 +1,70 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_DHCPV6 1 | |||
| #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 ( | |||
| dp_conf*, | |||
| unsigned char*, | |||
| @@ -11,4 +73,6 @@ void dp_dhcpv6_check ( | |||
| unsigned char**, | |||
| int*); | |||
| dp_dhcpv6_stats *dp_dhcpv6_cnt(uint8_t); | |||
| #endif // __DP_MACRO | |||
| @@ -0,0 +1,120 @@ | |||
| /************************************************************************** | |||
| * 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); | |||
| } | |||
| @@ -0,0 +1,28 @@ | |||
| /************************************************************************** | |||
| * 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); | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 <stdarg.h> | |||
| #include <string.h> | |||
| @@ -76,6 +92,10 @@ dp_conf *dp_load_config(dp_conf *conf, char *file) { | |||
| conf->queue = atoi(value); | |||
| else if ( strcmp(name, "dryrun")==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 | |||
| fprintf(stderr,"unknown directive '%s', ignored\n", name); | |||
| @@ -107,6 +127,13 @@ dp_conf *dp_load_config(dp_conf *conf, char *file) { | |||
| fprintf(stderr, "dryrun value invalid (0 or 1)\n"); | |||
| 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 ) | |||
| return NULL; | |||
| @@ -118,6 +145,8 @@ dp_conf *dp_load_config(dp_conf *conf, char *file) { | |||
| printf("\t%-20s = %4i\n", "max_pkt_per_interval", conf->pktint); | |||
| printf("\t%-20s = %4is\n", "blacklist_time", conf->bltime); | |||
| 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; | |||
| @@ -1,6 +1,24 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_HELPERS 1 | |||
| #include <linux/limits.h> | |||
| typedef struct dp_conf { | |||
| int pktint; | |||
| int interval; | |||
| @@ -8,6 +26,8 @@ typedef struct dp_conf { | |||
| int bltime; | |||
| int queue; | |||
| int dryrun; | |||
| char stats_file[PATH_MAX]; | |||
| int stats_interval; | |||
| } dp_conf; | |||
| @@ -1,13 +1,35 @@ | |||
| /************************************************************************** | |||
| * 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 <string.h> | |||
| #include <errno.h> | |||
| #include <pthread.h> | |||
| #include "dp_main.h" | |||
| #include "dp_helpers.h" | |||
| #include "dp_nfqueue.h" | |||
| #include "dp_events.h" | |||
| // main function | |||
| int main(int argc, char **argv) { | |||
| char *configfile; | |||
| dp_conf conf; | |||
| pthread_t pth_nfqueue, pth_events; | |||
| if ( argc == 2 ) { | |||
| configfile = argv[1]; | |||
| @@ -20,7 +42,19 @@ int main(int argc, char **argv) { | |||
| if ( dp_load_config(&conf, configfile) == NULL ) | |||
| 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; | |||
| } | |||
| @@ -1,19 +1,20 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #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 | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 <arpa/inet.h> | |||
| @@ -11,29 +27,30 @@ | |||
| #include "dp_dhcpv6.h" | |||
| // 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_q_handle *qh; | |||
| int fd; | |||
| if ( ( h = nfq_open() ) == NULL ) { | |||
| 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 ) { | |||
| fprintf(stderr, "error during nfq_create_queue() %s\n", strerror(errno)); | |||
| return; | |||
| return NULL; | |||
| } | |||
| if ( nfq_set_mode(qh, NFQNL_COPY_PACKET, 1500) < 0 ) { | |||
| 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 ) { | |||
| fprintf(stderr,"error during nfq_set_queue_flags() %s\n", strerror(errno)); | |||
| return; | |||
| return NULL; | |||
| } | |||
| fd = nfq_fd(h); | |||
| @@ -47,16 +64,17 @@ void dp_nfq_start(dp_conf *conf) { | |||
| switch(rv) { | |||
| case -1: | |||
| fprintf(stderr, "recv() error: %s\n", strerror(errno)); | |||
| return; | |||
| return NULL; | |||
| case 0: | |||
| fprintf(stderr,"socket is closed!?\n"); | |||
| return; | |||
| return NULL; | |||
| default: | |||
| // send packet to callback | |||
| nfq_handle_packet(h, buf, rv); | |||
| break; | |||
| } | |||
| } | |||
| return NULL; | |||
| } | |||
| // decode dhcp packet | |||
| @@ -124,9 +142,6 @@ int dp_dhcp_check(struct nfq_data *nfa, dp_conf *conf) { | |||
| end: | |||
| dp_accounting_cleanup(conf); | |||
| dp_blacklist_cleanup(conf); | |||
| return rv; | |||
| } | |||
| @@ -1,3 +1,19 @@ | |||
| /************************************************************************** | |||
| * 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 | |||
| #define __DP_NFQUEUE 1 | |||
| @@ -7,8 +23,8 @@ | |||
| #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 | |||