Diff

Differences From Artifact [c4e4dc8395]:

To Artifact [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