Diff

Differences From Artifact [c4e4dc8395]:

To Artifact [ac69747424]:


1
2
3
4
5
6
7
8
9
..
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
...
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
...
741
742
743
744
745
746
747

748
749
750
751
752
753
754
....
1070
1071
1072
1073
1074
1075
1076
1077
1078
1079
1080
1081
1082
1083
1084
1085
....
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

/* Copyright 2004 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
................................................................................

	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));
		} else {
			fprintf(stderr, "Fork failed while daemonizing: %s",
				strerror(errno));
		}
		exit(EXIT_FAILURE);
	}

}

#ifdef USE_CACHE
/*
................................................................................
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;

	currtime = time(NULL);

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

	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);
				} else {
					fprintf(stderr, "[Found in cache (%s)] [%s]",
						actionstr, msgbuf);
				}
			}

			return retval;
		}
	}





#endif

	/* 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) {
				syslog(LOG_INFO,
					"[accept whitelist] [%s]",
						msgbuf);
			} else {
				fprintf(stderr,
					"[accept whitelist] [%s]",
						msgbuf);
			}
		}
		statistics.whitelisthits++;
		retval=NF_ACCEPT;
	} else
	if (check_packet_list(&ip, conf.blacklist) == 1) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[reject blacklist] [%s]\n",
						msgbuf);
			} else {
				fprintf(stderr,
					"[reject blacklist] [%s]\n",
						msgbuf);
			}
				
		}
		statistics.blacklisthits++;
		retval=NF_DROP;
	} else
	if (check_packet_dnsbl(&ip, conf.whitelistbl) == 1) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[accept dnsbl] [%s]",
						msgbuf);
			} else {
				fprintf(stderr,
					"[accept dnsbl] [%s]",
						msgbuf);
			}
		}
		statistics.whitelistblhits++;
		retval=NF_ACCEPT;
	} else
	if (check_packet_dnsbl(&ip, conf.blacklistbl) == 1) {
		get_ip_string(&ip);
		if (!conf.quiet) {
			if (conf.debug == 0) {
				syslog(LOG_INFO,
					"[reject dnsbl] [%s]",
						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]",
							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]",
							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


	return retval;
}

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

	int ret;
................................................................................
		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->string = (char *)strdup(setting);
		ce->next = NULL;
#ifdef HAVE_FIREDNS
		blacklistlen = strlen(ce->string);
		if (ce->string[blacklistlen - 1] == '.') {
			ce->string[blacklistlen - 1] = '\0';
		}
................................................................................
 *
 * 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.
 *
 * 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.
................................................................................
	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);
			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(
 *                             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."
 *   It must be able to cope with "ip" being NULL.
 *
 */
static void get_ip_string(const struct packet_info *ip) {

	int rv;

	







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

	rv = snprintf(msgbuf, sizeof(msgbuf), "%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;
}

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

|







 







<
<
|
<
<
<
<







 







|







|



<







 







<
<
|
|
<
<
<
<
<
>



>
>
>
>
>


<
<
<
<
|
<
<
<
<
|
<
<
<
<
<
<
<


<
|
<
<
<
<
|
<
<
<
<
<
<
<
<


<
|
<
<
<
<
|
<
<
<
<
<
<
<


<
|
<
<
<
<
|
<
<
<
<
<
<
<



<

<
<
<
|
<
<
<
<
<
<
<


<
<
<
|
<
<
<
<
<
<
<
<







 







>







 







>







 







|
|







 







|
<
<
<
<
<
<
<
<







 







|











|
|



|


>
|
>
>
>
>
>
>
>

|



|

|


|







|







1
2
3
4
5
6
7
8
9
..
41
42
43
44
45
46
47


48




49
50
51
52
53
54
55
...
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
...
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
...
990
991
992
993
994
995
996
997
998
999
1000
1001
1002
1003
1004
1005
....
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

/* 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
................................................................................

	pid = fork();

	if (pid > 0) {
		exit(EXIT_SUCCESS);
	}
	if (pid < 0) {


		DPRINT("Fork failed while damonizing: %s", strerror(errno));




		exit(EXIT_FAILURE);
	}

}

#ifdef USE_CACHE
/*
................................................................................
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 = 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) {

			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;
			}


			DPRINTQ("[Found in cache (%s)] [%s]",
					actionstr, buf);





			free(buf);
			return retval;
		}
	}
#else
	int rv;
	char *buf;

	buf = get_ip_string(&ip);
#endif





	if (retval = check_packet_list(&ip, conf.whitelist) > 0) {




		DPRINTQ("[accept whitelist] [%s] [%d]\n", buf, retval);







		statistics.whitelisthits++;
		retval=NF_ACCEPT;

	} else if (retval = check_packet_list(&ip, conf.blacklist) > 0) {




		DPRINTQ("[reject blacklist] [%s] [%d]\n", buf, retval);








		statistics.blacklisthits++;
		retval=NF_DROP;

	} else if (retval = check_packet_dnsbl(&ip, conf.whitelistbl) > 0) {




		DPRINTQ("[accept dnsbl] [%s] [%d]", buf, retval);







		statistics.whitelistblhits++;
		retval=NF_ACCEPT;

	} else if (retval = check_packet_dnsbl(&ip, conf.blacklistbl) > 0) {




		DPRINTQ("[reject dnsbl] [%s] [%d]", buf, retval);







		statistics.blacklistblhits++;
		retval=NF_DROP;
	} else {

		if (conf.default_accept == 1) {



			DPRINTQ("[accept fallthrough] [%s]", buf);







			retval=NF_ACCEPT;
		} else {



			DPRINTQ("[reject fallthrough] [%s]", buf);








			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;
................................................................................
		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';
		}
................................................................................
 *
 * 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". 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.
................................................................................
	while (1) {
		uint32_t p = 0;

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

		if (p == wltmp->cidr.ip) {
			return wltmp->index;








			return 1;
		}

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

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

/*
 * SYNOPSIS:
 *   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 returns a buffer
 *   containing a string representation.  This buffer must be freed.
 *   It must be able to cope with "ip" being NULL.
 *
 */
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(buf, "-");
		if (rv < 0) {	
			syslog(LOG_ERR, "sprintf failed in line %d: %s",
				__LINE__, strerror(errno));
			exit(EXIT_FAILURE);
		}
		return buf;
	}

	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 buf;
}

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