updated on Mon Jan 23 12:00:23 UTC 2012
[aur-mirror.git] / moblock / moblock_0.9_rc2.patch
blob69994ffe83b3f7b92664c19f2abdbc932938211f
1 diff -Naur MoBlock-0.8_orig/Changelog MoBlock-0.8/Changelog
2 --- MoBlock-0.8_orig/Changelog 2006-03-22 12:44:31.000000000 -0500
3 +++ MoBlock-0.8/Changelog 2008-02-10 11:56:08.000000000 -0500
4 @@ -4,6 +4,23 @@
6 ---
8 +0.9: - fix for kernel 2.6.23
9 + - support for MARKing packets instead of DROPping or
10 + ACCEPTing
11 + - example start script that REJECTs packets instead of
12 + DROPping.
13 + - Integrated a patch from David Walluck for proper loading
14 + of p2b files (version 2)
15 + - command line options for logging to syslog, stdout
16 + and log timestamping
17 + - fixed loading pg1 lists with comments (lines starting
18 + with '#')
19 + - fixed a bug in ranges merge
20 + - applied patch 2223 by badfish99: "IPs logged with bytes
21 + reversed on big-endian m/c"
23 +---
25 0.8: - support for NFQUEUE-ing from iptables FORWARD chain (thx to
26 hyakki for suggestions and testing!)
27 - included patches from Maximilian Mehnert to support log file
28 diff -Naur MoBlock-0.8_orig/Makefile MoBlock-0.8/Makefile
29 --- MoBlock-0.8_orig/Makefile 2006-03-22 12:44:31.000000000 -0500
30 +++ MoBlock-0.8/Makefile 2007-11-22 08:10:44.000000000 -0500
31 @@ -1,4 +1,3 @@
33 # To use the old-soon-to-be-deprecated libipq interface
34 # uncomment the following line and comment the NFQUEUE one,
35 # then comment the gcc line with netfilter_queue and
36 @@ -7,7 +6,7 @@
37 #QUEUE_LIB=LIBIPQ
38 QUEUE_LIB=NFQUEUE
40 -CFLAGS=-Wall -O2 -march=i586 -mtune=i686 -fomit-frame-pointer -ffast-math \
41 +CFLAGS=-Wall -O3 -march=i586 -mtune=i686 -fomit-frame-pointer -ffast-math \
42 -D_GNU_SOURCE -D$(QUEUE_LIB) -L/usr/include/libipq
43 CC=gcc
45 diff -Naur MoBlock-0.8_orig/MoBlock-nfq-reject.sh MoBlock-0.8/MoBlock-nfq-reject.sh
46 --- MoBlock-0.8_orig/MoBlock-nfq-reject.sh 1969-12-31 19:00:00.000000000 -0500
47 +++ MoBlock-0.8/MoBlock-nfq-reject.sh 2007-11-22 08:10:44.000000000 -0500
48 @@ -0,0 +1,104 @@
49 +#!/bin/sh
51 +# MoBlock.sh - MoBlock start script
52 +# ---------------------------------
54 +ACTIVATE_CHAINS=1
55 +WHITE_TCP_IN=""
56 +WHITE_UDP_IN=""
57 +WHITE_TCP_OUT=""
58 +WHITE_UDP_OUT=""
59 +WHITE_TCP_FORWARD=""
60 +WHITE_UDP_FORWARD=""
61 +REJECT_MARK="10"
63 +PIDF=/var/run/moblock.pid
65 +FNAME=`basename $0 .sh`
66 +MODE=`echo $FNAME|awk -F- '{print $2}'`
68 +if [ -f $PIDF ]; then
69 + PID=`cat $PIDF`
70 + if [ `ps -p $PID|wc -l` -gt 1 ]; then
71 + echo "$0: $PIDF exists and processs seems to be running. Exiting."
72 + exit 1;
73 + fi;
74 +fi;
76 +if [ $MODE == "ipq" ]; then
77 + modprobe ip_queue
78 + TARGET="QUEUE"
79 +elif [ $MODE == "nfq" ]; then
80 + modprobe ipt_NFQUEUE
81 + TARGET="NFQUEUE"
82 +fi;
84 +modprobe ipt_state
86 +# Filter all traffic, edit for your needs
88 +iptables -N MOBLOCK_IN
89 +iptables -N MOBLOCK_OUT
90 +iptables -N MOBLOCK_FW
92 +if [ $ACTIVATE_CHAINS -eq 1 ]; then
93 + iptables -I INPUT -p all -m state --state NEW -j MOBLOCK_IN
94 + iptables -I OUTPUT -p all -m state --state NEW -j MOBLOCK_OUT
95 + iptables -I FORWARD -p all -m state --state NEW -j MOBLOCK_FW
96 +fi;
99 +iptables -I MOBLOCK_IN -p all -j $TARGET
101 +iptables -I MOBLOCK_OUT -p all -j $TARGET
103 +iptables -I MOBLOCK_FW -p all -j $TARGET
105 +for PORT in $WHITE_TCP_OUT; do
106 + iptables -I MOBLOCK_OUT -p tcp --dport $PORT -j ACCEPT
107 +done
108 +for PORT in $WHITE_UDP_OUT; do
109 + iptables -I MOBLOCK_OUT -p udp --dport $PORT -j ACCEPT
110 +done
112 +for PORT in $WHITE_TCP_IN; do
113 + iptables -I MOBLOCK_IN -p tcp --dport $PORT -j ACCEPT
114 +done
115 +for PORT in $WHITE_UDP_IN; do
116 + iptables -I MOBLOCK_IN -p udp --dport $PORT -j ACCEPT
117 +done
119 +for PORT in $WHITE_TCP_FORWARD; do
120 + iptables -I MOBLOCK_FW -p tcp --dport $PORT -j ACCEPT
121 +done
122 +for PORT in $WHITE_UDP_FORWARD; do
123 + iptables -I MOBLOCK_FW -p udp --dport $PORT -j ACCEPT
124 +done
126 +iptables -I OUTPUT -p all -m state --state NEW -m mark --mark $REJECT_MARK -j REJECT
127 +iptables -I FORWARD -p all -m state --state NEW -m mark --mark $REJECT_MARK -j REJECT
129 +# Here you can change block list and log files
130 +./moblock -d /etc/ipfilter.dat -t -s -r $REJECT_MARK ./moblock.log
132 +# On exit delete the rules we added
134 +if [ $ACTIVATE_CHAINS -eq 1 ]; then
135 + iptables -D INPUT -p all -m state --state NEW -j MOBLOCK_IN
136 + iptables -D OUTPUT -p all -m state --state NEW -j MOBLOCK_OUT
137 + iptables -D FORWARD -p all -m state --state NEW -j MOBLOCK_FW
138 +fi;
140 +iptables -D OUTPUT -p all -m state --state NEW -m mark --mark $REJECT_MARK -j REJECT
141 +iptables -D FORWARD -p all -m state --state NEW -m mark --mark $REJECT_MARK -j REJECT
143 +iptables -F MOBLOCK_IN
144 +iptables -X MOBLOCK_IN
145 +iptables -F MOBLOCK_OUT
146 +iptables -X MOBLOCK_OUT
147 +iptables -F MOBLOCK_FW
148 +iptables -X MOBLOCK_FW
150 +if [ -f $PIDF ]; then
151 + rm $PIDF;
153 diff -Naur MoBlock-0.8_orig/MoBlock.c MoBlock-0.8/MoBlock.c
154 --- MoBlock-0.8_orig/MoBlock.c 2006-03-22 12:44:31.000000000 -0500
155 +++ MoBlock-0.8/MoBlock.c 2008-02-10 11:56:08.000000000 -0500
156 @@ -35,6 +35,8 @@
157 #include <linux/netfilter_ipv4.h>
158 #include <signal.h>
159 #include <regex.h>
160 +#include <time.h>
161 +#include <syslog.h>
163 // in Makefile define LIBIPQ to use soon-to-be-deprecated ip_queue,
164 // NFQUEUE for ipt_NFQUEUE (from kernel 2.6.14)
165 @@ -46,7 +48,7 @@
166 #include <libnetfilter_queue/libnetfilter_queue.h>
167 #endif
169 -#define MB_VERSION "0.8"
170 +#define MB_VERSION "0.9rc2"
172 #define BUFSIZE 2048
173 #define PAYLOADSIZE 21
174 @@ -58,6 +60,9 @@
175 #define SRC_ADDR(payload) (*(in_addr_t *)((payload)+12))
176 #define DST_ADDR(payload) (*(in_addr_t *)((payload)+16))
178 +#define likely(x) __builtin_expect((x),1)
179 +#define unlikely(x) __builtin_expect((x),0)
181 // rbt datatypes/functions
183 typedef enum {
184 @@ -96,7 +101,8 @@
185 char filename[100];
186 } blocklist_info;
188 -int merged_ranges=0, skipped_ranges=0;
189 +u_int32_t merged_ranges=0, skipped_ranges=0, accept_mark=0, reject_mark=0;
190 +u_int8_t log2syslog=0, log2file=0, log2stdout=0, timestamp=0;
192 #ifdef LIBIPQ
193 static void die(struct ipq_handle *h)
194 @@ -112,11 +118,13 @@
195 static char buf[2][ sizeof("aaa.bbb.ccc.ddd") ];
196 static short int index=0;
198 + ip = ntohl(ip);
200 sprintf(buf[index],"%d.%d.%d.%d",
201 - (ip) & 0xff,
202 - (ip >> 8) & 0xff,
203 + (ip >> 24) & 0xff,
204 (ip >> 16) & 0xff,
205 - (ip >> 24) & 0xff);
206 + (ip >> 8) & 0xff,
207 + (ip) & 0xff);
209 if (index) {
210 index=0;
211 @@ -134,10 +142,38 @@
212 fflush(stdout);
215 +void log_action(char *msg)
217 + char timestr[30];
218 + time_t tv;
220 + if (timestamp) {
221 + tv = time(NULL);
222 + strncpy(timestr, ctime(&tv), 19);
223 + timestr[19] = '\0';
224 + strcat(timestr, "| ");
226 + else strcpy(timestr, "");
228 + if (log2syslog) {
229 + syslog(LOG_INFO, msg);
232 + if (log2file) {
233 + fprintf(logfile,"%s%s",timestr,msg);
234 + fflush(logfile);
237 + if (log2stdout) {
238 + fprintf(stdout,"%s%s",timestr,msg);
242 inline void ranged_insert(char *name,char *ipmin,char *ipmax)
244 recType tmprec;
245 int ret;
246 + char msgbuf[255];
248 if ( strlen(name) > (BNAME_LEN-1) ) {
249 strncpy(tmprec.blockname, name, BNAME_LEN);
250 @@ -149,10 +185,11 @@
251 if ( (ret=insert(ntohl(inet_addr(ipmin)),&tmprec)) != STATUS_OK )
252 switch(ret) {
253 case STATUS_MEM_EXHAUSTED:
254 - fprintf(logfile,"Error inserting range, MEM_EXHAUSTED.\n");
255 + log_action("Error inserting range, MEM_EXHAUSTED.\n");
256 break;
257 case STATUS_DUPLICATE_KEY:
258 - fprintf(logfile,"Duplicated range ( %s )\n",name);
259 + sprintf(msgbuf,"Duplicated range ( %s )\n",name);
260 + log_action(msgbuf);
261 break;
262 case STATUS_MERGED:
263 merged_ranges++;
264 @@ -161,8 +198,9 @@
265 skipped_ranges++;
266 break;
267 default:
268 - fprintf(logfile,"Unexpected return value from ranged_insert()!\n");
269 - fprintf(logfile,"Return value was: %d\n",ret);
270 + log_action("Unexpected return value from ranged_insert()!\n");
271 + sprintf(msgbuf,"Return value was: %d\n",ret);
272 + log_action(msgbuf);
273 break;
276 @@ -177,15 +215,19 @@
277 regex_t regmain;
278 regmatch_t matches[4];
279 int i;
280 + char msgbuf[255];
282 regcomp(&regmain, "^(.*)[:]([0-9.]*)[-]([0-9.]*)$", REG_EXTENDED);
284 fp=fopen(filename,"r");
285 if ( fp == NULL ) {
286 - fprintf(logfile,"Error opening %s, aborting...\n", filename);
287 + sprintf(msgbuf,"Error opening %s, aborting...\n", filename);
288 + log_action(msgbuf);
289 exit(-1);
291 while ( (count=getline(&line,&len,fp)) != -1 ) {
292 + if ( line[0] == '#' ) //comment line, skip
293 + continue;
294 for(i=count-1; i>=0; i--) {
295 if ((line[i] == '\r') || (line[i] == '\n') || (line[i] == ' ')) {
296 line[i] = 0;
297 @@ -207,36 +249,78 @@
298 line+matches[3].rm_so);
299 ntot++;
300 } else {
301 - fprintf(logfile,"Short guarding.p2p line %s, skipping it...\n", line);
302 + sprintf(msgbuf,"Short guarding.p2p line %s, skipping it...\n", line);
303 + log_action(msgbuf);
306 if (line)
307 free(line);
308 fclose(fp);
309 - fprintf(logfile,"Ranges loaded: %d\n",ntot);
310 - printf("* Ranges loaded: %d\n",ntot);
311 + sprintf(msgbuf, "* Ranges loaded: %d\n", ntot);
312 + log_action(msgbuf);
313 + if ( !log2stdout )
314 + printf(msgbuf);
317 -void loadlist_pg2(char *filename) // experimental, no check for list sanity
318 +void loadlist_pg2(char *filename) // supports only v2 files
320 FILE *fp;
321 - int i,retval,ntot=0;
322 - char name[100],ipmin[16]; // hope we don't have a list with longer names...
323 + int i, j, c, retval=0, ntot=0;
324 + char name[100],ipmin[16], msgbuf[255]; // hope we don't have a list with longer names...
325 uint32_t start_ip, end_ip;
326 struct in_addr startaddr,endaddr;
327 + size_t s;
329 fp=fopen(filename,"r");
330 if ( fp == NULL ) {
331 - fprintf(logfile,"Error opening %s, aborting...\n", filename);
332 + sprintf(msgbuf, "Error opening %s, aborting...\n", filename);
333 + log_action(msgbuf);
334 exit(-1);
337 - fgetc(fp); // skip first 4 bytes, don't know what they are
338 - fgetc(fp);
339 - fgetc(fp);
340 - retval=fgetc(fp);
341 + for (j=0; j<4; j++) {
342 + c=fgetc(fp);
343 + if ( c != 0xff ) {
344 + sprintf(msgbuf,"Byte %d: 0x%x != 0xff, aborting...\n", j+1, c);
345 + log_action(msgbuf);
346 + fclose(fp);
347 + exit(-1);
351 + c=fgetc(fp);
352 + if ( c != 'P' ) {
353 + sprintf(msgbuf,"Byte 5: %c != P, aborting...\n", c);
354 + log_action(msgbuf);
355 + fclose(fp);
356 + exit(-1);
359 + c=fgetc(fp);
360 + if ( c != '2' ) {
361 + sprintf(msgbuf,"Byte 6: %c != 2, aborting...\n", c);
362 + log_action(msgbuf);
363 + fclose(fp);
364 + exit(-1);
367 - while ( retval != EOF ) {
368 + c=fgetc(fp);
369 + if ( c != 'B' ) {
370 + sprintf(msgbuf,"Byte 7: %c != B, aborting...\n", c);
371 + log_action(msgbuf);
372 + fclose(fp);
373 + exit(-1);
376 + c=fgetc(fp);
377 + if ( c != 0x02 ) {
378 + sprintf(msgbuf,"Byte 8: version: %d != 2, aborting...\n", c);
379 + log_action(msgbuf);
380 + fclose(fp);
381 + exit(-1);
384 + do {
385 i=0;
386 do {
387 name[i]=fgetc(fp);
388 @@ -244,9 +328,22 @@
389 } while ( name[i-1] != 0x00 && name[i-1] != EOF);
390 if ( name[i-1] != EOF ) {
391 name[i-1]='\0';
392 - fread(&start_ip,4,1,fp);
393 - fread(&end_ip,4,1,fp);
394 - startaddr.s_addr=start_ip;
395 + s=fread(&start_ip,4,1,fp);
396 + if ( s != 1 ) {
397 + sprintf(msgbuf,"Failed to read start IP: %d != 1, aborting...\n", (int)s);
398 + log_action(msgbuf);
399 + fclose(fp);
400 + exit(-1);
402 + s=fread(&end_ip,4,1,fp);
403 + if ( s != 1 ) {
404 + sprintf(msgbuf,"Failed to read end IP: %d != 1, aborting...\n", (int)s);
405 + log_action(msgbuf);
406 + fclose(fp);
407 + exit(-1);
410 + startaddr.s_addr=start_ip;
411 endaddr.s_addr=end_ip;
412 strcpy(ipmin,inet_ntoa(startaddr));
413 ranged_insert(name,ipmin,inet_ntoa(endaddr));
414 @@ -255,22 +352,25 @@
415 else {
416 retval=EOF;
419 + } while ( retval != EOF );
420 fclose(fp);
421 - fprintf(logfile,"Ranges loaded: %d\n",ntot);
422 - printf("* Ranges loaded: %d\n",ntot);
423 + sprintf(msgbuf, "* Ranges loaded: %d\n",ntot);
424 + log_action(msgbuf);
425 + if ( !log2stdout )
426 + printf(msgbuf);
429 void loadlist_dat(char *filename)
431 FILE *fp;
432 int ntot=0;
433 - char readbuf[200], *name, start_ip[16], end_ip[16];
434 + char readbuf[200], *name, start_ip[16], end_ip[16], msgbuf[255];
435 unsigned short ip1_0, ip1_1, ip1_2, ip1_3, ip2_0, ip2_1, ip2_2, ip2_3;
437 fp=fopen(filename,"r");
438 if ( fp == NULL ) {
439 - fprintf(logfile,"Error opening %s, aborting...\n", filename);
440 + sprintf(msgbuf,"Error opening %s, aborting...\n", filename);
441 + log_action(msgbuf);
442 exit(-1);
445 @@ -286,38 +386,45 @@
446 ntot++;
448 fclose(fp);
449 - fprintf(logfile,"Ranges loaded: %d\n",ntot);
450 - printf("* Ranges loaded: %d\n",ntot);
451 + sprintf(msgbuf, "* Ranges loaded: %d\n", ntot);
452 + log_action(msgbuf);
453 + if ( !log2stdout )
454 + printf(msgbuf);
457 void reopen_logfile(void)
459 + char msgbuf[255];
461 if (logfile != NULL) {
462 fclose(logfile);
463 logfile=NULL;
465 logfile=fopen(logfile_name,"a");
466 if (logfile == NULL) {
467 - fprintf(stderr, "Unable to open logfile %s\n", logfile_name);
468 + sprintf(msgbuf, "Unable to open logfile %s\n", logfile_name);
469 + log_action(msgbuf);
470 exit(-1);
472 - fprintf(logfile, "Reopening logfile.\n");
473 + log_action("Reopening logfile.\n");
476 void my_sahandler(int sig)
478 + char msgbuf[255];
480 switch( sig ) {
481 case SIGUSR1:
482 - fprintf(logfile,"Got SIGUSR1! Dumping stats...\n");
483 + log_action("Got SIGUSR1! Dumping stats...\n");
484 ll_show(logfile);
485 reopen_logfile();
486 break;
487 case SIGUSR2:
488 - fprintf(logfile,"Got SIGUSR2! Dumping stats to /var/log/MoBlock.stats\n");
489 + log_action("Got SIGUSR2! Dumping stats to /var/log/MoBlock.stats\n");
490 ll_log();
491 break;
492 case SIGHUP:
493 - fprintf(logfile,"\nGot SIGHUP! Dumping and resetting stats, reloading blocklist\n\n");
494 + log_action("Got SIGHUP! Dumping and resetting stats, reloading blocklist\n");
495 ll_log();
496 ll_clear(); // clear stats list
497 destroy_tree(); // clear loaded ranges
498 @@ -332,17 +439,18 @@
499 loadlist_pg2(blocklist_info.filename);
500 break;
501 default:
502 - fprintf(logfile,"Unknown blocklist type while reloading list, contact the developer!\n");
503 + log_action("Unknown blocklist type while reloading list, contact the developer!\n");
504 break;
506 reopen_logfile();
507 break;
508 case SIGTERM:
509 - fprintf(logfile,"Got SIGTERM! Dumping stats and exiting.\n");
510 + log_action("Got SIGTERM! Dumping stats and exiting.\n");
511 ll_log();
512 exit(0);
513 default:
514 - fprintf(logfile,"Received signal = %d but not handled\n",sig);
515 + sprintf(msgbuf,"Received signal = %d but not handled\n",sig);
516 + log_action(msgbuf);
517 break;
520 @@ -378,7 +486,7 @@
522 int id=0, status=0;
523 struct nfqnl_msg_packet_hdr *ph;
524 - char *payload;
525 + char *payload, msgbuf[255];
526 recType tmprec;
528 ph = nfq_get_msg_packet_hdr(nfa);
529 @@ -389,34 +497,78 @@
530 switch (ph->hook) {
531 case NF_IP_LOCAL_IN:
532 if ( find(ntohl(SRC_ADDR(payload)),&tmprec) == STATUS_OK ) {
533 + // we drop the packet instead of rejecting
534 + // we don't want the other host to know we are alive
535 status=nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
536 - fprintf(logfile,"Blocked IN: %s,hits: %d,SRC: %s\n",tmprec.blockname,tmprec.hits,ip2str(SRC_ADDR(payload)));
537 - } else status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
538 + sprintf(msgbuf,"Blocked IN: %s,hits: %d,SRC: %s\n",tmprec.blockname,tmprec.hits,ip2str(SRC_ADDR(payload)));
539 + log_action(msgbuf);
541 + else if ( unlikely(accept_mark) ) {
542 + // we set the user-defined accept_mark and set NF_REPEAT verdict
543 + // it's up to other iptables rules to decide what to do with this marked packet
544 + status = nfq_set_verdict_mark(qh, id, NF_REPEAT, accept_mark, 0, NULL);
546 + else {
547 + // no accept_mark, just NF_ACCEPT the packet
548 + status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
550 break;
551 case NF_IP_LOCAL_OUT:
552 if ( find(ntohl(DST_ADDR(payload)),&tmprec) == STATUS_OK ) {
553 - status=nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
554 - fprintf(logfile,"Blocked OUT: %s,hits: %d,DST: %s\n",tmprec.blockname,tmprec.hits,ip2str(DST_ADDR(payload)));
555 - } else status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
556 + if ( likely(reject_mark) ) {
557 + // we set the user-defined reject_mark and set NF_REPEAT verdict
558 + // it's up to other iptables rules to decide what to do with this marked packet
559 + status = nfq_set_verdict_mark(qh, id, NF_REPEAT, reject_mark, 0, NULL);
561 + else {
562 + status = nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
564 + sprintf(msgbuf,"Blocked OUT: %s,hits: %d,DST: %s\n",tmprec.blockname,tmprec.hits,ip2str(DST_ADDR(payload)));
565 + log_action(msgbuf);
567 + else if ( unlikely(accept_mark) ) {
568 + // we set the user-defined accept_mark and set NF_REPEAT verdict
569 + // it's up to other iptables rules to decide what to do with this marked packet
570 + status = nfq_set_verdict_mark(qh, id, NF_REPEAT, accept_mark, 0, NULL);
572 + else {
573 + // no accept_mark, just NF_ACCEPT the packet
574 + status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
576 break;
577 case NF_IP_FORWARD:
578 if ( find2(ntohl(SRC_ADDR(payload)), ntohl(DST_ADDR(payload)), &tmprec) == STATUS_OK ) {
579 - status=nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
580 - fprintf(logfile,"Blocked FWD: %s,hits: %d,SRC: %s, DST: %s\n",
581 + if ( likely(reject_mark) ) {
582 + // we set the user-defined reject_mark and set NF_REPEAT verdict
583 + // it's up to other iptables rules to decide what to do with this marked packet
584 + status = nfq_set_verdict_mark(qh, id, NF_REPEAT, reject_mark, 0, NULL);
586 + else {
587 + status = nfq_set_verdict(qh, id, NF_DROP, 0, NULL);
589 + sprintf(msgbuf,"Blocked FWD: %s,hits: %d,SRC: %s, DST: %s\n",
590 tmprec.blockname, tmprec.hits, ip2str(SRC_ADDR(payload)), ip2str(DST_ADDR(payload)));
591 - fflush(logfile);
592 - } else status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
593 + log_action(msgbuf);
595 + else if ( unlikely(accept_mark) ) {
596 + // we set the user-defined accept_mark and set NF_REPEAT verdict
597 + // it's up to other iptables rules to decide what to do with this marked packet
598 + status = nfq_set_verdict_mark(qh, id, NF_REPEAT, accept_mark, 0, NULL);
600 + else {
601 + // no accept_mark, just NF_ACCEPT the packet
602 + status = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL);
604 break;
605 default:
606 - fprintf(logfile,"Not NF_LOCAL_IN/OUT/FORWARD packet!\n");
607 + log_action("Not NF_LOCAL_IN/OUT/FORWARD packet!\n");
608 break;
611 else {
612 - fprintf(logfile,"NFQUEUE: can't get msg packet header.\n");
613 + log_action("NFQUEUE: can't get msg packet header.\n");
614 return(1); // from nfqueue source: 0 = ok, >0 = soft error, <0 hard error
616 - fflush(logfile);
617 return(0);
619 #endif
620 @@ -492,46 +644,48 @@
621 struct nfq_q_handle *qh;
622 struct nfnl_handle *nh;
623 int fd,rv;
624 - char buf[BUFSIZE];
625 + char buf[BUFSIZE], msgbuf[255];
627 h = nfq_open();
628 if (!h) {
629 - fprintf(logfile, "Error during nfq_open()\n");
630 + log_action("Error during nfq_open()\n");
631 exit(-1);
634 if (nfq_unbind_pf(h, AF_INET) < 0) {
635 - fprintf(logfile, "error during nfq_unbind_pf()\n");
636 - exit(-1);
637 + log_action("error during nfq_unbind_pf()\n");
638 + //exit(-1);
641 if (nfq_bind_pf(h, AF_INET) < 0) {
642 - fprintf(logfile, "Error during nfq_bind_pf()\n");
643 + log_action("Error during nfq_bind_pf()\n");
644 exit(-1);
647 - fprintf(logfile,"NFQUEUE: binding to queue '%hd'\n", queuenum);
648 + sprintf(msgbuf,"NFQUEUE: binding to queue '%hd'\n", queuenum);
649 + log_action(msgbuf);
650 qh = nfq_create_queue(h, queuenum, &nfqueue_cb, NULL);
651 if (!qh) {
652 - fprintf(logfile, "error during nfq_create_queue()\n");
653 + log_action("error during nfq_create_queue()\n");
654 exit(-1);
657 if (nfq_set_mode(qh, NFQNL_COPY_PACKET, PAYLOADSIZE) < 0) {
658 - fprintf(logfile, "can't set packet_copy mode\n");
659 + log_action("can't set packet_copy mode\n");
660 exit(-1);
663 nh = nfq_nfnlh(h);
664 fd = nfnl_fd(nh);
666 - while ((rv = recv(fd, buf, sizeof(buf), 0)) && rv >= 0) {
667 + while ((rv = recv(fd, buf, sizeof(buf), 0)) >= 0) {
668 nfq_handle_packet(h, buf, rv);
671 - printf("NFQUEUE: unbinding from queue 0\n");
672 + log_action("NFQUEUE: unbinding from queue 0\n");
673 nfq_destroy_queue(qh);
674 nfq_close(h);
675 + nfq_unbind_pf(h, AF_INET);
676 return(0);
677 #endif
679 @@ -540,11 +694,16 @@
680 void print_options(void)
682 printf("\nMoBlock %s by Morpheus",MB_VERSION);
683 - printf("\nSyntax: MoBlock -dnp <blocklist> [-b] [-q 0-65535] <logfile>\n\n");
684 + printf("\nSyntax: MoBlock -dnp <blocklist> [-q 0-65535] <logfile>\n\n");
685 printf("\t-d\tblocklist is an ipfilter.dat file\n");
686 printf("\t-n\tblocklist is a peerguardian 2.x file (.p2b)\n");
687 printf("\t-p\tblocklist is a peerguardian file (.p2p)\n");
688 printf("\t-q\t0-65535 NFQUEUE number (as specified in --queue-num with iptables)\n");
689 + printf("\t-r MARK\tmark packet with MARK instead of DROP\n");
690 + printf("\t-a MARK\tmark packet with MARK instead of ACCEPT\n");
691 + printf("\t-l\tlog to stdout\n");
692 + printf("\t-s\tlog to syslog\n");
693 + printf("\t-t\tlog timestamping\n\n");
696 void on_quit()
697 @@ -556,6 +715,7 @@
699 int ret=0;
700 unsigned short int queuenum=0;
701 + char msgbuf[255];
703 if (argc < 3) {
704 print_options();
705 @@ -591,10 +751,11 @@
707 logfile_name=malloc(strlen(argv[argc-1])+1);
708 strcpy(logfile_name,argv[argc-1]);
709 + log2file = 1;
710 printf("* Logging to %s\n",logfile_name);
712 while (1) { //scan command line options
713 - ret=getopt(argc, argv, "d:n:p:q:");
714 + ret=getopt(argc, argv, "d:n:p:q:a:r:stl");
715 if ( ret == -1 ) break;
717 switch (ret) {
718 @@ -619,6 +780,28 @@
719 case 'q':
720 queuenum=(unsigned short int)atoi(optarg);
721 break;
722 + case 'r':
723 + reject_mark=(u_int32_t)atoi(optarg);
724 + printf("* DROP MARK: %d\n", reject_mark);
725 + reject_mark=htonl(reject_mark);
726 + break;
727 + case 'a':
728 + accept_mark=(u_int32_t)atoi(optarg);
729 + printf("* ACCEPT MARK: %d\n", accept_mark);
730 + accept_mark=htonl(accept_mark);
731 + break;
732 + case 's':
733 + log2syslog = 1;
734 + printf("* Logging to syslog\n");
735 + break;
736 + case 't':
737 + timestamp = 1;
738 + printf("* Log timestamp enabled\n");
739 + break;
740 + case 'l':
741 + log2stdout = 1;
742 + printf("* Log to stdout enabled\n");
743 + break;
744 case '?': // unknown option
745 print_options();
746 exit(-1);
747 @@ -626,10 +809,14 @@
751 - printf("* Merged ranges: %d\n", merged_ranges);
752 - fprintf(logfile, "Merged ranges: %d\n", merged_ranges);
753 - printf("* Skipped useless ranges: %d\n", skipped_ranges);
754 - fprintf(logfile,"Skipped useless ranges: %d\n", skipped_ranges);
755 + sprintf(msgbuf, "* Merged ranges: %d\n", merged_ranges);
756 + log_action(msgbuf);
757 + if ( !log2stdout )
758 + printf(msgbuf);
759 + sprintf(msgbuf,"* Skipped useless ranges: %d\n", skipped_ranges);
760 + log_action(msgbuf);
761 + if ( !log2stdout )
762 + printf(msgbuf);
763 fflush(NULL);
765 netlink_loop(queuenum);
766 diff -Naur MoBlock-0.8_orig/README MoBlock-0.8/README
767 --- MoBlock-0.8_orig/README 2006-03-22 12:44:31.000000000 -0500
768 +++ MoBlock-0.8/README 2007-11-22 08:10:44.000000000 -0500
769 @@ -1,5 +1,5 @@
771 -MoBlock README v0.8
772 +MoBlock README v0.9
773 http://moblock.berlios.de
775 .Introduction.
776 @@ -47,6 +47,22 @@
777 ip_conntrack 40044 1 ipt_state
778 iptable_filter 2176 1
779 ip_tables 17600 3 ipt_NFQUEUE,ipt_state,iptable_filter
781 + ...and these with kernel 2.6.23 using NFQUEUE interface:
783 + nfnetlink_queue 9344 1
784 + nfnetlink 4568 2 nfnetlink_queue
785 + ipt_REJECT 3520 2
786 + xt_mark 1600 2
787 + nf_conntrack_ipv4 12424 5
788 + iptable_filter 2308 1
789 + ip_tables 10328 1 iptable_filter
790 + xt_state 1984 5
791 + nf_conntrack 48356 2 nf_conntrack_ipv4,xt_state
792 + xt_NFQUEUE 1664 3
793 + x_tables 11396 5 ipt_REJECT,xt_mark,ip_tables,xt_state,xt_NFQUEUE
795 + (notice that ipt_NFQUEUE has changed to xt_NFQUEUE, same thing for other modules too)
797 2) A valid guarding.p2p/ipfilter.dat/p2p.p2b host file in /etc ( /etc/guarding.p2p ).
798 MoBlock tries to skip malformed or duplicate ranges but
799 @@ -140,8 +156,18 @@
800 To specify a NFQUEUE queue number:
802 ./moblock -p /etc/guarding.p2p -q 5 MoBlock.log
804 + From version 0.9 MoBlock supports MARKing packets and RETURN them to
805 + iptables, there's an example start script (MoBlock-nfq-reject.sh) that
806 + uses this feature to REJECT packet instead of dropping them. It can help
807 + in complex firewall configuration where you need more control of packets
808 + flow after MoBlock inspection.
809 + See the mentioned start script for reference, you can set the MARK value
810 + for packets that MoBlock would drop (ip in list) with the "-r" command line
811 + option and for packets that MoBlock would accept (ip not in list) with
812 + the "-a" command line option.
814 - To stop it:
815 + To stop MoBlock:
817 kill -TERM <MoBlockPid>
819 @@ -149,7 +175,7 @@
820 To obtain stats about blocked ranges while it's running:
822 kill -USR1 <MoBlockPid> # write stats to logfile
823 - kill -USR2 <MoBlockPid> # write stats to /var/log/MoBlock.stats
824 + kill -USR2 <MoBlockPid> # write stats to /var/log/MoBlock.stats
826 ** NEW: to reload the blocklist while MoBlock is running send to it the
827 HUP signal:
828 @@ -168,7 +194,10 @@
829 took some code and ideas from his FTwall
830 - Andrew de Quincey (adq at lidskialf dot net) for regular expressions
831 and command line args patch
832 -- Maximilian Mehnert (clessing at freenet dot de) for logfile rotation
833 +- clessing at freenet dot de for logfile rotation
834 patches, pid file creation, start script, fixes/files for debian packaging
835 +- David Walluck, patch for proper loading of p2b files
836 +- jre, for continuing clessing work on debian packaging and many other
837 + contributions
839 -Last Updated: 20/Mar/2006
840 +Last Updated: 15/Oct/2007
841 diff -Naur MoBlock-0.8_orig/rbt.c MoBlock-0.8/rbt.c
842 --- MoBlock-0.8_orig/rbt.c 2006-03-22 12:44:31.000000000 -0500
843 +++ MoBlock-0.8/rbt.c 2008-02-10 11:56:08.000000000 -0500
844 @@ -19,7 +19,7 @@
845 #include <stdarg.h>
846 #include <time.h>
848 -#define RBT_VERSION 0.8
849 +#define RBT_VERSION 0.9
850 #define BNAME_LEN 80
852 /* implementation dependend declarations */
853 @@ -421,7 +421,7 @@
855 statusEnum insert(keyType key, recType *rec) {
856 nodeType *current, *parent, *x;
857 - keyType tmpkey;
858 + //keyType tmpkey;
859 recType tmprec;
860 int ret;
862 @@ -433,6 +433,23 @@
863 current = root;
864 parent = 0;
865 while (current != NIL) {
866 + if (compEQ2(current->key, key, rec->ipmax)) { // current node key is inside new range to be inserted
867 + strcpy(tmprec.blockname, rec->blockname); // block name from new range
868 + if (compLT(current->rec.ipmax, rec->ipmax))
869 + tmprec.ipmax = rec->ipmax;
870 + else tmprec.ipmax = current->rec.ipmax;
871 + tmprec.hits = 0;
872 + //printf("deleting node :%lu\n", current->key);
873 + ret=delete(current->key);
874 + if ( ret != STATUS_OK )
875 + return(ret);
876 + ret=insert(key, &tmprec);
877 + if ( ret == STATUS_OK ) {
878 + printf("new merge\n");
879 + return(STATUS_MERGED);
881 + else return(ret);
883 if (compEQ(key, current->key)) {
884 if ( rec->ipmax > current->rec.ipmax ) {
885 current->rec.ipmax=rec->ipmax;
886 @@ -458,7 +475,7 @@
889 //check if higher ip (ipmax) is already in a range
890 - if (compEQ2(rec->ipmax,current->key,current->rec.ipmax)) {
891 + /*if (compEQ2(rec->ipmax,current->key,current->rec.ipmax)) {
892 fprintf(logfile,"higher ip in range\n");
893 tmpkey=key;
894 strcpy(tmprec.blockname,current->rec.blockname);
895 @@ -470,7 +487,7 @@
896 if ( ret == STATUS_OK )
897 return(STATUS_MERGED);
898 else return(ret);
900 + }*/
901 parent = current;
902 current = compLT(key, current->key) ?
903 current->left : current->right;
904 @@ -495,7 +512,7 @@
905 } else {
906 root = x;
909 + //printf("new node, key: %lu, parent: %lu\n", x->key, parent ? parent->key : 0);
910 insertFixup(x);
911 lastFind = NULL;