1
/*************************************************************************
2
*** Authentication, authorization, accounting + firewalling package
3
*** Copyright 1998-2002 Anton Vinokurov <anton@netams.com>
4
*** Copyright 2002-2008 NeTAMS Development Team
5
*** This code is GPL v3
6
*** For latest version and more info, visit this project web page
7
*** located at http://www.netams.com
9
*************************************************************************/
10
/* $Id: ds_ipfw.c,v 1.44 2009-12-19 17:25:50 anton Exp $ */
16
/////////////////////////////////////////////////////////////////////////////////////
17
void ds_ipfw_cancel(void *ptr);
18
/////////////////////////////////////////////////////////////////////////////////////
19
void ds_ipfw(Service_DS *ds) {
20
socklen_t size_ds = sizeof(struct sockaddr_in);
22
FlowEngine *FE=ds->FE;
25
unsigned char *packet=ds->packet;
27
struct sockaddr_in sin;
28
sin.sin_family = AF_INET;
29
sin.sin_addr.s_addr = INADDR_ANY;
30
sin.sin_port = htons(ds->port);
33
if ((socketid = socket(PF_INET, SOCK_RAW, IPPROTO_DIVERT)) < 0)
34
aLog(D_ERR, "divert socket\n");
38
if (bind(socketid, (struct sockaddr *)&(sin), sizeof(sin)))
39
aLog(D_ERR, "bind divert socket: %u\n", socketid);
44
pthread_cleanup_push(ds_ipfw_cancel, (void*) &socketid);
45
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, NULL);
47
aLog(D_INFO,"IPFW packet processing for data-source:%u initialized\n",ds->instance);
52
bzero(&key, sizeof(struct ipv4_key));
56
CHECK_POLL(ds,status);
58
netams_gettimeofday(&start, NULL);
59
FE->Expiresearch(&start);
62
len=recvfrom(socketid, packet, MAX_PKT_SIZE, 0, (struct sockaddr *)&sin, &size_ds);
63
IPv4GetKey((struct ip*) packet, &key);
65
process_result = FE->Process((u_char *)&key, 1, ntohs(((struct ip*) packet)->ip_len), &flow_entry);
66
if(process_result == -1) {
67
IPv4FillFlow(&key, flow_entry);
70
if (ds->layer7_detect!=LAYER7_DETECT_NONE) layer7_addinfo(key.tcp_info.dst_port, flow_entry);
73
if(ds->ds_flags==DS_DIVERT) process_result = FE->FW(flow_entry);
76
if (process_result && (ds->ds_flags==DS_DIVERT))
77
sendto(socketid, packet, len, 0, (struct sockaddr *)&sin, size_ds);
80
if (ds->layer7_detect!=LAYER7_DETECT_NONE) layer7_checkinfo(key.tcp_info.dst_port, flow_entry, (struct ip*) packet);
82
ds->Measure(&start, len);
87
pthread_cleanup_pop(1);
90
/////////////////////////////////////////////////////////////////////////////////////
91
void ds_ipfw_cancel(void *ptr) {
92
int socketid=*(int*)ptr;
93
shutdown(socketid, SHUT_RDWR);
96
/////////////////////////////////////////////////////////////////////////////////////
98
/////////////////////////////////////////////////////////////////////////////////////