Check-in [371d474ebc]
Overview
Comment:some bugs related to use_cache, etc. also a lot of cleanup.
Downloads: Tarball | ZIP archive | SQL archive
Timelines: family | ancestors | descendants | both | trunk
Files: files | file ages | folders
SHA1: 371d474ebc7f4ae2e14f7b6ee92151dde19a4aee
User & Date: rmiller on 2011-03-06 23:20:20
Other Links: manifest | tags
Context
2011-03-06
23:30
remove pbl_set_verdict. It was a waste of code lines. check-in: 49947c3157 user: rmiller tags: trunk
23:20
some bugs related to use_cache, etc. also a lot of cleanup. check-in: 371d474ebc user: rmiller tags: trunk
17:47
update readme check-in: d59c5b24a3 user: rmiller tags: trunk
Changes

Modified packetbl.c from [c4e4dc8395] to [ac69747424].

1
2

3
4
5
6
7
8
9
1

2
3
4
5
6
7
8
9

-
+








/* Copyright 2004 Russell Miller
/* Copyright 2004-2011 Russell Miller
    This program is free software; you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation; either version 2 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
41
42
43
44
45
46
47
48
49
50

51
52
53
54
55
56
57
58
59
60
61
41
42
43
44
45
46
47



48




49
50
51
52
53
54
55







-
-
-
+
-
-
-
-








	pid = fork();

	if (pid > 0) {
		exit(EXIT_SUCCESS);
	}
	if (pid < 0) {
		if (conf.debug == 0) {
			syslog(LOG_ERR, "Fork failed while daemonizing: %s",
				strerror(errno));
		DPRINT("Fork failed while damonizing: %s", strerror(errno));
		} else {
			fprintf(stderr, "Fork failed while daemonizing: %s",
				strerror(errno));
		}
		exit(EXIT_FAILURE);
	}

}

#ifdef USE_CACHE
/*
174
175
176
177
178
179
180
181

182
183
184
185
186
187
188
189

190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211


212
213
214

215
216
217
218
219
220



221
222
223
224
225
226
227
228
229



230
231

232
233
234
235

236
237
238
239
240
241
242

243
244
245
246
247

248
249
250
251
252
253
254
255
256
257
258
259

260
261
262
263
264

265
266
267
268
269
270
271
272
273
274
275

276
277
278
279
280

281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296

297
298
299
300
301
302
303
304
305
306
307
308
309

310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331

332
333
334
335
336
337
338
168
169
170
171
172
173
174

175
176
177
178
179
180
181
182

183
184
185
186

187
188
189
190
191
192
193
194
195
196
197
198
199
200




201
202



203


204
205
206

207
208
209
210








211
212
213


214




215



216
217


218





219








220
221


222





223







224
225


226





227







228
229
230

231




232







233
234




235








236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257







-
+







-
+



-














-
-
-
-
+
+
-
-
-
+
-
-



-
+
+
+

-
-
-
-
-
-
-
-
+
+
+
-
-
+
-
-
-
-
+
-
-
-


-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-
-


-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-


-
-
+
-
-
-
-
-
+
-
-
-
-
-
-
-



-

-
-
-
-
+
-
-
-
-
-
-
-


-
-
-
-
+
-
-
-
-
-
-
-
-














+







int packet_check_ip(const struct packet_info ip) {
	int retval;

#ifdef USE_CACHE
	uint32_t ipaddr_check;
	uint32_t cache_hash = 0;
	time_t currtime;
	char *actionstr;
	char *actionstr = NULL, *buf = NULL;

	currtime = time(NULL);

	ipaddr_check = packet_info_to_ip(ip);
	if (packet_cache_len > 0) {
		cache_hash = packet_cache_hash(ip) % packet_cache_len;
	}

	buf = get_ip_string(&ip);
	if (cache_hash>0 && cache_hash<packet_cache_len && packet_cache != NULL) {
		if (packet_cache[cache_hash].ipaddr==ipaddr_check 
				&& packet_cache[cache_hash].expires>currtime) {
			get_ip_string(&ip);
			retval = packet_cache[cache_hash].action;
			switch (retval) {
				case NF_DROP:
					actionstr="reject";
					statistics.cachereject++;
					break;
				case NF_ACCEPT:
					actionstr="accept";
					statistics.cacheaccept++;
					break;
				default:
					actionstr="???";
					break;
			}
			if (!conf.quiet) {
				if (conf.debug == 0) {
					syslog(LOG_INFO, "[Found in cache (%s)] [%s]",
						actionstr, msgbuf);
			DPRINTQ("[Found in cache (%s)] [%s]",
					actionstr, buf);
				} else {
					fprintf(stderr, "[Found in cache (%s)] [%s]",
						actionstr, msgbuf);
			free(buf);
				}
			}
			return retval;
		}
	}
#endif
#else
	int rv;
	char *buf;

	/* the get_ip_string is set AFTER the check_packet_*
	 * calls because of the possibility they could screw with
	 * msgbuf.  They shouldn't, really, but better safe than
	 * sorry, at least for now. */
	if (check_packet_list(&ip, conf.whitelist) == 1) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
	buf = get_ip_string(&ip);
#endif

				syslog(LOG_INFO,
					"[accept whitelist] [%s]",
	if (retval = check_packet_list(&ip, conf.whitelist) > 0) {
						msgbuf);
			} else {
				fprintf(stderr,
					"[accept whitelist] [%s]",
		DPRINTQ("[accept whitelist] [%s] [%d]\n", buf, retval);
						msgbuf);
			}
		}
		statistics.whitelisthits++;
		retval=NF_ACCEPT;
	} else
	if (check_packet_list(&ip, conf.blacklist) == 1) {
	} else if (retval = check_packet_list(&ip, conf.blacklist) > 0) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[reject blacklist] [%s]\n",
		DPRINTQ("[reject blacklist] [%s] [%d]\n", buf, retval);
						msgbuf);
			} else {
				fprintf(stderr,
					"[reject blacklist] [%s]\n",
						msgbuf);
			}
				
		}
		statistics.blacklisthits++;
		retval=NF_DROP;
	} else
	if (check_packet_dnsbl(&ip, conf.whitelistbl) == 1) {
	} else if (retval = check_packet_dnsbl(&ip, conf.whitelistbl) > 0) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[accept dnsbl] [%s]",
		DPRINTQ("[accept dnsbl] [%s] [%d]", buf, retval);
						msgbuf);
			} else {
				fprintf(stderr,
					"[accept dnsbl] [%s]",
						msgbuf);
			}
		}
		statistics.whitelistblhits++;
		retval=NF_ACCEPT;
	} else
	if (check_packet_dnsbl(&ip, conf.blacklistbl) == 1) {
	} else if (retval = check_packet_dnsbl(&ip, conf.blacklistbl) > 0) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[reject dnsbl] [%s]",
		DPRINTQ("[reject dnsbl] [%s] [%d]", buf, retval);
						msgbuf);
			} else {
				fprintf(stderr,
					"[reject dnsbl] [%s]",
						msgbuf);
			}
		}
		statistics.blacklistblhits++;
		retval=NF_DROP;
	} else {
		get_ip_string(&ip);
		if (conf.default_accept == 1) {
			if (!conf.quiet) {
				if (conf.debug == 0) {
					syslog(LOG_INFO,
						"[accept fallthrough] [%s]",
			DPRINTQ("[accept fallthrough] [%s]", buf);
							msgbuf);
				} else {
					fprintf(stderr,
						"[accept fallthrough] [%s]",
							msgbuf);
				}
			}
			retval=NF_ACCEPT;
		} else {
			if (!conf.quiet) {
				if (conf.debug == 0) {
					syslog(LOG_INFO,
						"[reject fallthrough] [%s]",
			DPRINTQ("[reject fallthrough] [%s]", buf);
							msgbuf);
				} else {
					fprintf(stderr,
						"[reject fallthrough] [%s]",
							msgbuf);
				}

			}
			retval=NF_DROP;
		}
		statistics.fallthroughhits++;
	}

#ifdef USE_CACHE
	/* Put current action into the cache. */
	if (packet_cache != NULL) {
		packet_cache[cache_hash].ipaddr = ipaddr_check;
		packet_cache[cache_hash].action = retval;
		packet_cache[cache_hash].expires = currtime + packet_cache_ttl;
	}
#endif

	free(buf);
	return retval;
}

static int pbl_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
        struct nfq_data *nfa, void *data) {

	int ret;
741
742
743
744
745
746
747

748
749
750
751
752
753
754
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674







+







		ce = malloc(sizeof(struct config_entry));
		if (ce == NULL) {
			/* shouldn't happen... */
			fprintf(stderr, "Failed to allocate memory for ce struct\n");
			exit(EXIT_FAILURE);
		}

		ce->index = i;
		ce->string = (char *)strdup(setting);
		ce->next = NULL;
#ifdef HAVE_FIREDNS
		blacklistlen = strlen(ce->string);
		if (ce->string[blacklistlen - 1] == '.') {
			ce->string[blacklistlen - 1] = '\0';
		}
1070
1071
1072
1073
1074
1075
1076
1077
1078


1079
1080
1081
1082
1083
1084
1085
990
991
992
993
994
995
996


997
998
999
1000
1001
1002
1003
1004
1005







-
-
+
+







 *
 * ARGUMENTS:
 *   struct packet_info *ip       IP address data to check in supplied list. 
 *   struct config_entry *list    List that contains data to check in against,
 *                                whitelist for example.
 *
 * RETURN VALUE:
 *   0 is returned if the "ip" cannot be found in the given "list".  1 is
 *   returned on a successful match.
 *   0 is returned if the "ip" cannot be found in the given "list". The index
 *   of the matched list is returned on a successful match.
 *
 * NOTES:
 *   "check_packet_list"  searches the given list parameter (which is a list
 *   CIDRs) to determine if the data passed in "ip" matches (whitelist, for
 *   for example).
 *   This function must be able to cope with NULL "ip" and "list" paramters
 *   without aborting.
1105
1106
1107
1108
1109
1110
1111
1112
1113
1114
1115

1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135

1136
1137
1138
1139
1140
1141
1142
1143
1144
1145
1146
1147
1148


1149
1150
1151
1152

1153
1154

1155








1156
1157

1158
1159
1160
1161

1162
1163

1164
1165
1166

1167
1168
1169
1170
1171
1172
1173
1174

1175
1176
1177
1178
1179
1180
1181
1025
1026
1027
1028
1029
1030
1031




1032





1033
1034
1035
1036
1037
1038
1039
1040
1041
1042
1043
1044
1045
1046

1047
1048
1049
1050
1051
1052
1053
1054
1055
1056
1057
1058


1059
1060
1061
1062
1063

1064
1065
1066
1067

1068
1069
1070
1071
1072
1073
1074
1075
1076

1077
1078
1079
1080

1081
1082

1083
1084
1085

1086
1087
1088
1089
1090
1091
1092
1093

1094
1095
1096
1097
1098
1099
1100
1101







-
-
-
-
+
-
-
-
-
-














-
+











-
-
+
+



-
+


+
-
+
+
+
+
+
+
+
+

-
+



-
+

-
+


-
+







-
+







	while (1) {
		uint32_t p = 0;

		p = ip_proc;
		p &= wltmp->cidr.processed;

		if (p == wltmp->cidr.ip) {
			rv = snprintf(msgbuf, sizeof(msgbuf), 
					"%hhu.%hhu.%hhu.%hhu %x/%d",
					ip->b1, ip->b2, ip->b3, ip->b4,
					wltmp->cidr.ip, wltmp->cidr.network);
			return wltmp->index;
			if (rv < 0) {
				syslog(LOG_ERR, "snprintf failed at line %d: %s",
					__LINE__, strerror(errno));
				exit (1);
			}
			return 1;
		}

		if (wltmp->next == NULL) {
			break;
		}

		wltmp = wltmp->next;
	}
	return 0;
}

/*
 * SYNOPSIS:
 *   static void get_ip_string(
 *   char * get_ip_string(
 *                             const struct packet_info *ip
 *                            );
 *
 * ARGUMENTS:
 *   struct packet_info *ip       Structure containing IP parts to construct
 *                                the ASCII representation from.
 *
 * RETURN VALUE:
 *   (none)
 *
 * NOTES:
 *   This function takes the data in the parameter "ip" and stores an ASCII
 *   representation in the global variable "msgbuf."
 *   This function takes the data in the parameter "ip" and returns a buffer
 *   containing a string representation.  This buffer must be freed.
 *   It must be able to cope with "ip" being NULL.
 *
 */
static void get_ip_string(const struct packet_info *ip) {
char *get_ip_string(const struct packet_info *ip) {

	int rv;
	char *buf = NULL;
	

	buf = malloc(BUFFERSIZE); 
	if (buf == NULL) {
		syslog(LOG_ERR, "could not malloc buf in get_ip_string: %s\n",
			strerror(errno));
		exit(EXIT_FAILURE);
	}

	if (ip == NULL) {
		rv = sprintf(msgbuf, "-");
		rv = sprintf(buf, "-");
		if (rv < 0) {	
			syslog(LOG_ERR, "sprintf failed in line %d: %s",
				__LINE__, strerror(errno));
			exit(1);
			exit(EXIT_FAILURE);
		}
		return;
		return buf;
	}

	rv = snprintf(msgbuf, sizeof(msgbuf), "%hhu.%hhu.%hhu.%hhu:%hu.%hu", 
	rv = snprintf(buf, BUFFERSIZE, "%hhu.%hhu.%hhu.%hhu:%hu.%hu", 
			ip->b1, ip->b2, ip->b3, ip->b4,
			ip->s_port,ip->d_port);
		if (rv < 0) {
			syslog(LOG_ERR, "snprintf failed in line %d: %s",
				__LINE__, strerror(errno));
			exit(1);
		}
	return;
	return buf;
}

#ifdef USE_SOCKSTAT
/*
 * SYNOPSIS:
 *   void *pbl_sockstat_thread(
 *                             void *tdata

Modified packetbl.h from [04dd1a732b] to [0899b0d159].

67
68
69
70
71
72
73







74
75
76
77
78
79
80
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87







+
+
+
+
+
+
+







# define PBL_SET_MODE nfq_set_mode
# define PBL_COPY_PACKET NFQNL_COPY_PACKET
# define PBL_ID_T u_int32_t
# define PBL_ERRSTR ""

#define DEBUG(x, y) if (conf.debug >= x) { printf(y "\n"); }
#define INVALID_OCTET(x) x < 0 || x > 255
#define DPRINT(format, args...) if (conf.debug == 0) { \
	syslog(LOG_INFO, format , ## args); \
} else { \
	fprintf(stderr, format , ## args); \
}

#define DPRINTQ(format, args...) if (!conf.quiet) { DPRINT(format, ## args) };

struct packet_info {

	uint8_t b1;
	uint8_t b2;
	uint8_t b3;
	uint8_t b4;
95
96
97
98
99
100
101

102
103
104
105
106
107
108
109
110
111
112
113
102
103
104
105
106
107
108
109
110
111
112


113
114
115
116
117
118
119







+



-
-








struct config_entry {

	char *string;
	struct config_entry *next;
	struct packet_info ip;
	struct cidr	cidr;
	int index;

};

char msgbuf[BUFFERSIZE];

struct config {
	int	allow_non25;
	int	allow_nonsyn;
	int	default_accept;
	int	dryrun;
	int 	log_facility;
	int	queueno;
137
138
139
140
141
142
143
144

145
146
147
148
149
150
151
152
153
154
155
156
157
158

159
160
161
162
163
164
165
143
144
145
146
147
148
149

150
151
152
153
154
155
156
157
158
159
160
161
162
163

164
165
166
167
168
169
170
171







-
+













-
+







struct packet_cache_t {
	uint32_t ipaddr;
	time_t	expires;
	int	action;
};
struct packet_cache_t *packet_cache = NULL;
uint32_t packet_cache_len = USE_CACHE_DEF_LEN;
uint16_t packet_cache_ttl = USE_CACHE_DEF_TTL;
uint32_t packet_cache_ttl = USE_CACHE_DEF_TTL;
#endif

struct config_entry *hostlistcache = NULL;

int get_packet_info(char *payload, struct packet_info *ip);

int check_packet_list(const struct packet_info *ip, struct config_entry *list);
int check_packet_dnsbl(const struct packet_info *ip, struct config_entry *list);
int parse_cidr(struct config_entry *ce);
/* int validate_blacklist(char *); */
void parse_config(void);
void parse_arguments(int argc, char **argv);
void pbl_init_sockstat(void);
static void get_ip_string(const struct packet_info *ip);
char * get_ip_string(const struct packet_info *ip);
static void pbl_set_verdict(struct PBL_HANDLE *h, PBL_ID_T id,
        unsigned int verdict);

static int pbl_callback(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg,
	struct nfq_data *nfa, void *data);
	
typedef struct facility {