"Fossies" - the Fresh Open Source Software Archive  

Source code changes of the file "src/ec_redirect.c" between
ettercap-0.8.3.tar.gz and ettercap-0.8.3.1.tar.gz

About: ettercap is a multipurpose sniffer/interceptor/logger for switched LAN.

ec_redirect.c  (ettercap-0.8.3):ec_redirect.c  (ettercap-0.8.3.1)
skipping to change at line 56 skipping to change at line 56
enum { enum {
EC_REDIR_COMMAND_INSERT, EC_REDIR_COMMAND_INSERT,
EC_REDIR_COMMAND_REMOVE EC_REDIR_COMMAND_REMOVE
}; };
/* /*
* execute the script to add or remove the redirection * execute the script to add or remove the redirection
*/ */
int ec_redirect(ec_redir_act_t action, char *name, ec_redir_proto_t proto, int ec_redirect(ec_redir_act_t action, char *name, ec_redir_proto_t proto,
const char *source, const char *destination, const char *destination, u_int16 sport, u_int16 dport)
u_int16 sport, u_int16 dport)
{ {
char asc_sport[16]; char asc_sport[16];
char asc_dport[16]; char asc_dport[16];
char asc_source[MAX_ASCII_ADDR_LEN];
char asc_destination[MAX_ASCII_ADDR_LEN]; char asc_destination[MAX_ASCII_ADDR_LEN];
int ret_val = 0; int ret_val = 0;
char *param[4]; char *param[4];
char *commands[2] = {NULL, NULL}; char *commands[2] = {NULL, NULL};
char *command = NULL; char *command = NULL;
struct redir_entry *re, *tmp; struct redir_entry *re, *tmp;
char *str_dstnet = NULL;
char *str_dstmask = NULL;
char *str_tmp = NULL;
u_char *binmask = NULL;
/* undefined defaults to any */ /* undefined defaults to any */
switch (proto) { switch (proto) {
case EC_REDIR_PROTO_IPV4: case EC_REDIR_PROTO_IPV4:
if (source == NULL || !strcmp(source, "0.0.0.0/0")) if (destination == NULL)
source = IPV4_ANY; destination = "0.0.0.0/0";
if (destination == NULL || !strcmp(destination, "0.0.0.0/0"))
destination = IPV4_ANY;
break; break;
case EC_REDIR_PROTO_IPV6: case EC_REDIR_PROTO_IPV6:
if (source == NULL || !strcmp(source, "::/0")) if (destination == NULL)
source = IPV6_ANY; destination = "::/0";
if (destination == NULL || !strcmp(destination, "::/0"))
destination = IPV6_ANY;
break; break;
default: default:
DEBUG_MSG("ec_redirect(): invalid address family given"); DEBUG_MSG("ec_redirect(): invalid address family given");
return -E_INVALID; return -E_INVALID;
} }
DEBUG_MSG("ec_redirect(\"%s\", \"%s\", %s, %s, %s, %d, %d)", DEBUG_MSG("ec_redirect(\"%s\", \"%s\", %s, %s, %d, %d)",
(action == EC_REDIR_ACTION_INSERT ? "insert" : "remove"), (action == EC_REDIR_ACTION_INSERT ? "insert" : "remove"),
name, name,
(proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"), (proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6"),
source,
destination, destination,
sport, sport,
dport); dport);
/* check and set redirects commands from etter.conf */ /* check and set redirects commands from etter.conf */
set_redir_command(proto, commands); set_redir_command(proto, commands);
/* insert or remove commands */ /* insert or remove commands */
switch (action) { switch (action) {
case EC_REDIR_ACTION_INSERT: case EC_REDIR_ACTION_INSERT:
/* check if entry is already present */ /* check if entry is already present */
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) {
if (proto == re->proto && if (proto == re->proto &&
!strcmp(source, re->source) &&
!strcmp(destination, re->destination) && !strcmp(destination, re->destination) &&
sport == re->from_port && dport == re->to_port) { sport == re->from_port && dport == re->to_port) {
DEBUG_MSG("ec_redirect(): redirect entry already present"); DEBUG_MSG("ec_redirect(): redirect entry already present");
return -E_INVALID; return -E_INVALID;
} }
} }
/* get command and check if it's defined */
command = commands[EC_REDIR_COMMAND_INSERT]; command = commands[EC_REDIR_COMMAND_INSERT];
if (command == NULL) {
DEBUG_MSG("ec_redirect(): redirect insert command for %s desired "
"but not set in etter.conf - skipping...",
proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6");
return -E_NOTHANDLED;
}
/* allocate memory for redirect entry and parse input and set values */
SAFE_CALLOC(re, 1, sizeof(struct redir_entry));
re->name = strdup(name);
re->proto = proto;
re->destination = strdup(destination);
re->from_port = sport;
re->to_port = dport;
re->orig_nport = htons(sport);
/* parse destination specification */
str_tmp = strdup(destination);
str_dstnet = ec_strtok(str_tmp, "/", &str_dstmask);
if (str_dstnet != NULL) {
/* convert network */
if (ip_addr_pton(str_dstnet, &re->dst_network) != E_SUCCESS)
goto clean_abort;
/* convert prefix length to netmask */
if (str_dstmask != NULL && strlen(str_dstmask)) {
/* prefix length specified */
u_int32 dstmask;
if ((dstmask = strtoul(str_dstmask, NULL, 10)) <= 128) {
binmask = ec_plen_to_binary(ntohs(re->dst_network.addr_len), d
stmask);
ip_addr_init(&re->dst_netmask, ntohs(re->dst_network.addr_type
), binmask);
SAFE_FREE(binmask);
SAFE_FREE(str_tmp);
}
else
goto clean_abort;
}
else {
/* no prefix length specified */
u_int32 dstmask;
/* assume full (host) prefix length */
dstmask = ntohs(re->dst_network.addr_len) * 8;
binmask = ec_plen_to_binary(ntohs(re->dst_network.addr_len), dstm
ask);
ip_addr_init(&re->dst_netmask, ntohs(re->dst_network.addr_type),
binmask);
SAFE_FREE(binmask);
SAFE_FREE(str_tmp);
}
}
else /* destination specification invalid */
goto clean_abort;
/* sanity check */
switch (proto) {
case EC_REDIR_PROTO_IPV4:
if (ntohs(re->dst_network.addr_type) != AF_INET) {
DEBUG_MSG("ec_redirect(): address family mixup! - aborting");
goto clean_abort;
}
break;
case EC_REDIR_PROTO_IPV6:
if (ntohs(re->dst_network.addr_type) != AF_INET6) {
DEBUG_MSG("ec_redirect(): address family mixup! - aborting");
goto clean_abort;
}
break;
default:
clean_abort:
SAFE_FREE(re->name);
SAFE_FREE(re->destination);
SAFE_FREE(re);
SAFE_FREE(str_tmp);
return -E_INVALID;
break;
}
break; break;
case EC_REDIR_ACTION_REMOVE: case EC_REDIR_ACTION_REMOVE:
/* check if entry is still present */ /* check if entry is still present */
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) {
if (proto == re->proto && if (proto == re->proto &&
!strcmp(source, re->source) &&
!strcmp(destination, re->destination) && !strcmp(destination, re->destination) &&
sport == re->from_port && dport == re->to_port) { sport == re->from_port && dport == re->to_port) {
/* entry present - ready to be removed */ /* entry present - ready to be removed */
command = commands[EC_REDIR_COMMAND_REMOVE]; command = commands[EC_REDIR_COMMAND_REMOVE];
if (command == NULL) {
DEBUG_MSG("ec_redirect(): redirect insert command for %s "
"desired but not set in etter.conf - skipping...",
proto == EC_REDIR_PROTO_IPV4 ? "IPv4" : "IPv6");
return -E_NOTHANDLED;
}
break; break;
} }
} }
if (command == NULL) { if (command == NULL) {
DEBUG_MSG("ec_redirect(): redirect entry not present anymore"); DEBUG_MSG("ec_redirect(): redirect entry not present anymore");
return -E_INVALID; return -E_INVALID;
} }
break; break;
default: default:
DEBUG_MSG("ec_redirect(): no valid action defined - aborting!"); DEBUG_MSG("ec_redirect(): no valid action defined - aborting!");
return -E_FATAL; return -E_FATAL;
} }
/* ready to complete redirect commands */ /* ready to complete redirect commands */
snprintf(asc_source, MAX_ASCII_ADDR_LEN, "%s", source); if (!strcmp(destination, "0.0.0.0/0")) {
snprintf(asc_destination, MAX_ASCII_ADDR_LEN, "%s", destination); snprintf(asc_destination, MAX_ASCII_ADDR_LEN, "%s", IPV4_ANY);
}
else if (!strcmp(destination, "::/0")) {
snprintf(asc_destination, MAX_ASCII_ADDR_LEN, "%s", IPV6_ANY);
}
else {
snprintf(asc_destination, MAX_ASCII_ADDR_LEN, "%s", destination);
}
snprintf(asc_sport, 16, "%u", sport); snprintf(asc_sport, 16, "%u", sport);
snprintf(asc_dport, 16, "%u", dport); snprintf(asc_dport, 16, "%u", dport);
/* make the substitutions in the script */ /* make the substitutions in the script */
str_replace(&command, "%iface", EC_GBL_OPTIONS->iface); str_replace(&command, "%iface", EC_GBL_OPTIONS->iface);
str_replace(&command, "%source", asc_source);
str_replace(&command, "%destination", asc_destination); str_replace(&command, "%destination", asc_destination);
str_replace(&command, "%port", asc_sport); str_replace(&command, "%port", asc_sport);
str_replace(&command, "%rport", asc_dport); str_replace(&command, "%rport", asc_dport);
#if defined(OS_DARWIN) || defined(OS_BSD) #if defined(OS_DARWIN) || defined(OS_BSD)
str_replace(&command, "%set", IPFW_SET); str_replace(&command, "%set", IPFW_SET);
#endif #endif
DEBUG_MSG("ec_redirect(): execute [%s]", command); DEBUG_MSG("ec_redirect(): execute [%s]", command);
skipping to change at line 171 skipping to change at line 256
/* execute the script */ /* execute the script */
switch (fork()) { switch (fork()) {
case 0: case 0:
regain_privs(); regain_privs();
execvp(param[0], param); execvp(param[0], param);
drop_privs(); drop_privs();
WARN_MSG("Cannot setup redirect (command: %s), please edit your " WARN_MSG("Cannot setup redirect (command: %s), please edit your "
"etter.conf file and put a valid value in redir_command_on" "etter.conf file and put a valid value in redir_command_on"
"|redir_command_off field\n", param[0]); "|redir_command_off field\n", param[0]);
SAFE_FREE(command); SAFE_FREE(command);
SAFE_FREE(re->name);
SAFE_FREE(re->destination);
SAFE_FREE(re);
_exit(-E_INVALID); _exit(-E_INVALID);
case -1: case -1:
SAFE_FREE(command); SAFE_FREE(command);
return -E_INVALID; return -E_INVALID;
default: default:
wait(&ret_val); wait(&ret_val);
if (WIFEXITED(ret_val) && WEXITSTATUS(ret_val)) { if (WIFEXITED(ret_val) && WEXITSTATUS(ret_val)) {
DEBUG_MSG("ec_redirect(): child exited with non-zero return " DEBUG_MSG("ec_redirect(): child exited with non-zero return "
"code: %d", WEXITSTATUS(ret_val)); "code: %d", WEXITSTATUS(ret_val));
USER_MSG("ec_redirect(): redir_command_on had non-zero exit " USER_MSG("ec_redirect(): redir_command_on had non-zero exit "
"status (%d): [%s]\n", WEXITSTATUS(ret_val), command); "status (%d): [%s]\n", WEXITSTATUS(ret_val), command);
SAFE_FREE(command); SAFE_FREE(command);
SAFE_FREE(re->name);
SAFE_FREE(re->destination);
SAFE_FREE(re);
return -E_INVALID; return -E_INVALID;
} }
else { /* redirect command exited normally */ else { /* redirect command exited normally */
/* register entry */
switch (action) { switch (action) {
case EC_REDIR_ACTION_INSERT: case EC_REDIR_ACTION_INSERT:
SAFE_CALLOC(re, 1, sizeof(struct redir_entry)); /* register entry */
re->name = strdup(name);
re->proto = proto;
re->source = strdup(source);
re->destination = strdup(destination);
re->from_port = sport;
re->to_port = dport;
LIST_INSERT_HEAD(&redirect_entries, re, next); LIST_INSERT_HEAD(&redirect_entries, re, next);
register_redir_service(name, sport, dport); register_redir_service(name, sport, dport);
break; break;
case EC_REDIR_ACTION_REMOVE: case EC_REDIR_ACTION_REMOVE:
/* remove entry from list */ /* remove entry from list */
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) {
if (re->proto == proto && if (re->proto == proto &&
!strcmp(re->source, source) &&
!strcmp(re->destination, destination) && !strcmp(re->destination, destination) &&
sport == re->from_port && sport == re->from_port &&
dport == re->to_port) { dport == re->to_port) {
LIST_REMOVE(re, next); LIST_REMOVE(re, next);
SAFE_FREE(re->name); SAFE_FREE(re->name);
SAFE_FREE(re->source);
SAFE_FREE(re->destination); SAFE_FREE(re->destination);
SAFE_FREE(re); SAFE_FREE(re);
} }
} }
break; break;
default: default:
break; break;
} }
} }
skipping to change at line 315 skipping to change at line 394
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) { LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) {
func(re); func(re);
i++; i++;
} }
return i ? i : -E_NOTFOUND; return i ? i : -E_NOTFOUND;
} }
/* /*
* check if a packet matches a installed redirect
*/
int ec_redirect_lookup(struct packet_object *po)
{
struct redir_entry *re, *tmp;
struct ip_addr srv_network;
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) {
if (po->L4.dst == re->orig_nport) {
/* port matched - now check on the IPs */
ip_addr_get_network(&po->L3.dst, &re->dst_netmask, &srv_network);
if (!ip_addr_cmp(&re->dst_network, &srv_network))
return E_SUCCESS;
}
else if (po->L4.src == re->orig_nport) {
/* port matched - now check on the IPs */
ip_addr_get_network(&po->L3.src, &re->dst_netmask, &srv_network);
if (!ip_addr_cmp(&re->dst_network, &srv_network))
return E_SUCCESS;
}
}
return -E_NOMATCH;
}
/*
* remove all registered redirects * remove all registered redirects
*/ */
void ec_redirect_cleanup(void) void ec_redirect_cleanup(void)
{ {
struct redir_entry *re, *tmp; struct redir_entry *re, *tmp;
struct serv_entry *se, *stmp; struct serv_entry *se, *stmp;
DEBUG_MSG("ec_redirect_cleanup()"); DEBUG_MSG("ec_redirect_cleanup()");
LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp) LIST_FOREACH_SAFE(re, &redirect_entries, next, tmp)
ec_redirect(EC_REDIR_ACTION_REMOVE, re->name, re->proto, ec_redirect(EC_REDIR_ACTION_REMOVE, re->name, re->proto,
re->source, re->destination, re->from_port, re->to_port); re->destination, re->from_port, re->to_port);
SLIST_FOREACH_SAFE(se, &redirect_services, next, stmp) { SLIST_FOREACH_SAFE(se, &redirect_services, next, stmp) {
SAFE_FREE(se->name); SAFE_FREE(se->name);
SAFE_FREE(se); SAFE_FREE(se);
} }
} }
/* /*
* store redirect services in a unique list * store redirect services in a unique list
*/ */
 End of changes. 23 change blocks. 
32 lines changed or deleted 140 lines changed or added

Home  |  About  |  Features  |  All  |  Newest  |  Dox  |  Diffs  |  RSS Feeds  |  Screenshots  |  Comments  |  Imprint  |  Privacy  |  HTTP(S)