int parse_interfaces( conf_t *conf, char *s ) { char *s2; if_t *iface; iface = conf->interfaces->next; while( iface != conf->interfaces ) { if_t *i; i = iface->next; free( iface ); iface = i; } free( conf->interfaces ); if( !*s ) { conf->interfaces = malloc( sizeof( if_t ) ); memset( conf->interfaces, 0, sizeof( if_t ) ); conf->interfaces->next = conf->interfaces; return( 1 ); } s[strlen(s)+1] = 0; conf->interfaces = iface = malloc( sizeof( if_t ) ); while( 1 ) { while( ( *s == ' ' || *s == '\t' ) && *s ) s ++; for( s2 = s; *s2 != ' ' && *s2 != '\t' && *s2; s2 ++ ); *s2 = 0; if( *s < '0' || *s > '9' ) get_if_ip( s, iface->text ); else strcpy( iface->text, s ); s = s2 + 1; if( *s ) { iface->next = malloc( sizeof( if_t ) ); iface = iface->next; } else { iface->next = conf->interfaces; break; } } return( 1 ); }
/* log filter request from filter driver */ void dispatch_request(struct flt_request *request) { u_long from_ip, to_ip; u_short from_port, to_port; char msg[1024], pname_buf[MAX_PATH], addr_from[100], addr_to[100], *pname, uname[200]; if (request->log_skipped != 0) { if (_snprintf(msg, sizeof(msg), "SKIP\t%u", request->log_skipped) == -1) msg[sizeof(msg) - 1] = '\0'; log_msg(msg, MSGTYPE_ERROR); } if (request->pid != (ULONG)-1) { if (request->pname == NULL) { // try to resolve pid to pname if (get_pname_by_pid(request->pid, pname_buf + sizeof(DWORD), sizeof(pname_buf) - sizeof(DWORD))) { // send message to driver to send process name next time DWORD n; pname = pname_buf + sizeof(DWORD); *(DWORD *)pname_buf = request->pid; if (!DeviceIoControl(g_device, IOCTL_CMD_SETPNAME, pname_buf, sizeof(DWORD) + strlen(pname) + 1, NULL, 0, &n, NULL)) winerr("DeviceIoControl"); } else { error("PROCESS\tCan't resolve pid %u!", request->pid); sprintf(pname_buf, "pid:%u", request->pid); pname = pname_buf; } } else pname = (char *)&request[1]; } else pname = ""; if (request->sid_a != NULL) { SID_AND_ATTRIBUTES *sa; char user[100], domain[100]; DWORD size1, size2; SID_NAME_USE type; if (request->pname != NULL) { char *buf = (char *)&request[1]; buf += strlen(buf) + 1; sa = (SID_AND_ATTRIBUTES *)buf; } else sa = (SID_AND_ATTRIBUTES *)&request[1]; // convert sid from relative pointer to absolute sa->Sid = (PSID)((char *)sa + (ULONG)sa->Sid); size1 = sizeof(user); size2 = sizeof(domain); if (LookupAccountSid(NULL, sa->Sid, user, &size1, domain, &size2, &type)) { if (_snprintf(uname, sizeof(uname), "{%s\\%s}", domain, user) == -1) uname[sizeof(uname) - 1] = '\0'; } else strcpy(uname, "{??\\??}"); // TODO: convert SID to string } else uname[0] = '\0'; // check is it request type "TYPE_RESOLVE_PID" if (request->type == TYPE_RESOLVE_PID) { if (_snprintf(msg, sizeof(msg), "PROCESS\t%u\t%s\t%s", request->pid, pname, uname) == -1) msg[sizeof(msg) - 1] = '\0'; log_msg(msg, MSGTYPE_ALLOW); } else if (request->type == TYPE_LISTEN || request->type == TYPE_NOT_LISTEN) { // using from_ip & from_port as listen_ip & listen_port from_ip = ((struct sockaddr_in *)&request->addr.from)->sin_addr.s_addr; from_port = ntohs(((struct sockaddr_in *)&request->addr.from)->sin_port); prepare_addr(addr_from, sizeof(addr_from), from_ip); sprintf(addr_from + strlen(addr_from), ":%d", from_port); if (_snprintf(msg, sizeof(msg), "%s\tTCP\t%s\t%s\t%s", (request->type == TYPE_LISTEN) ? "LISTEN" : "NOT_LISTEN", addr_from, pname, uname) == -1) msg[sizeof(msg) - 1] = '\0'; log_msg(msg, MSGTYPE_ALLOW); } else { // prepare message from_ip = ((struct sockaddr_in *)&request->addr.from)->sin_addr.s_addr; from_port = ntohs(((struct sockaddr_in *)&request->addr.from)->sin_port); to_ip = ((struct sockaddr_in *)&request->addr.to)->sin_addr.s_addr; to_port = ntohs(((struct sockaddr_in *)&request->addr.to)->sin_port); // prepare address "from" & "to" if (from_ip == 0) { // try to route "to" addr to get "from" from_ip = get_if_ip(to_ip); } prepare_addr(addr_from, sizeof(addr_from), from_ip); if (to_ip == 0) { // some kind of "reverse route" :-) to_ip = get_if_ip(from_ip); } prepare_addr(addr_to, sizeof(addr_to), to_ip); // add ports if nonzero if (from_port != 0) sprintf(addr_from + strlen(addr_from), ":%d", from_port); if (to_port != 0) sprintf(addr_to + strlen(addr_to), ":%d", to_port); if (request->result == FILTER_ALLOW || request->result == FILTER_DENY || request->result == FILTER_DISCONNECT) { // log it! (TDI message) char tdi_msg[100 + RULE_ID_SIZE], size_str[64], *direction; switch (request->result) { case FILTER_ALLOW: strcpy(tdi_msg, "ALLOW"); break; case FILTER_DENY: strcpy(tdi_msg, "DENY"); break; default: strcpy(tdi_msg, "CLOSED"); } if (request->result != FILTER_DISCONNECT) { int size; size_str[0] = '\0'; switch (request->type) { case TYPE_CONNECT_CANCELED: strcat(tdi_msg, "(CANCELED)"); break; case TYPE_CONNECT_RESET: strcat(tdi_msg, "(RESET)"); break; case TYPE_CONNECT_TIMEOUT: strcat(tdi_msg, "(TIMEOUT)"); break; case TYPE_CONNECT_UNREACH: strcat(tdi_msg, "(UNREACH)"); break; case TYPE_CONNECT_ERROR: sprintf(tdi_msg + strlen(tdi_msg), "(ERR:%x)", request->status); break; case TYPE_DATAGRAM: size = (request->direction == DIRECTION_IN) ? request->log_bytes_in : request->log_bytes_out; if (size != (ULONG)-1) sprintf(size_str, "%u", size); break; } strcat(tdi_msg, "\t["); size = strlen(tdi_msg); memcpy(tdi_msg + size, request->log_rule_id, RULE_ID_SIZE); tdi_msg[size + RULE_ID_SIZE + 1] = '\0'; // string can be not zero-terminated strcat(tdi_msg, "]"); } else sprintf(size_str, "%u/%u", request->log_bytes_out, request->log_bytes_in); switch (request->direction) { case DIRECTION_IN: direction = "IN"; break; case DIRECTION_OUT: direction = "OUT"; break; case DIRECTION_ANY: direction = "*"; break; default: direction = "?"; } if (_snprintf(msg, sizeof(msg), "%s\t%s\t%s\t%s\t%s\t%s\t%s\t%s", tdi_msg, (request->proto == IPPROTO_TCP) ? "TCP" : (request->proto == IPPROTO_UDP ? "UDP" : "RawIP"), direction, addr_from, addr_to, size_str, pname, uname) == -1) msg[sizeof(msg) - 1] = '\0'; // sound it! if (request->result == FILTER_DENY) { // TODO: try to sound it by voice of user! if (request->direction == DIRECTION_IN && wave_deny_in[0] != '\0') PlaySound(wave_deny_in, NULL, SND_FILENAME | SND_ASYNC); if (request->direction == DIRECTION_OUT && wave_deny_out[0] != '\0') PlaySound(wave_deny_out, NULL, SND_FILENAME | SND_ASYNC); } log_msg(msg, request->result == FILTER_ALLOW ? MSGTYPE_ALLOW : MSGTYPE_DENY); } else if (request->result == FILTER_PACKET_LOG || request->result == FILTER_PACKET_BAD) { char flags[50], proto[50]; // prepare TCP flags or ICMP type if (request->result == FILTER_PACKET_LOG) { if (request->proto == IPPROTO_TCP) { UCHAR th_flags = request->packet.tcp_flags; flags[0] = (th_flags & TH_FIN) ? 'F' : '-'; flags[1] = (th_flags & TH_SYN) ? 'S' : '-'; flags[2] = (th_flags & TH_RST) ? 'R' : '-'; flags[3] = (th_flags & TH_PUSH) ? 'P' : '-'; flags[4] = (th_flags & TH_ACK) ? 'A' : '-'; flags[5] = (th_flags & TH_URG) ? 'U' : '-'; flags[6] = '\0'; } else if (request->proto == IPPROTO_ICMP) sprintf(flags, "%d.%d", request->packet.icmp_type, request->packet.icmp_code); else flags[0] = '\0'; } else flags[0] = '\0'; switch (request->proto) { case IPPROTO_TCP: if (request->packet.tcp_state > TCP_STATE_NONE && request->packet.tcp_state < TCP_STATE_MAX) sprintf(proto, "TCP(%s)", g_tcp_states[request->packet.tcp_state]); else strcpy(proto, "TCP"); break; case IPPROTO_UDP: strcpy(proto, "UDP"); break; case IPPROTO_ICMP: strcpy(proto, "ICMP"); break; default: sprintf(proto, "%d", request->proto); } // log it! (packet filter message) if (_snprintf(msg, sizeof(msg), "%s\t%s\t%s\t%s\t%s\t%u\t%s", (request->result == FILTER_PACKET_LOG) ? "PACKET" : "BAD_PACKET", proto, (request->direction == DIRECTION_IN) ? "IN" : "OUT", addr_from, addr_to, (request->direction == DIRECTION_IN) ? request->log_bytes_in : request->log_bytes_out, flags) == -1) msg[sizeof(msg) - 1] = '\0'; log_msg(msg, request->result == FILTER_PACKET_LOG ? MSGTYPE_ALLOW : MSGTYPE_DENY); } } }
static int CheckValid() { char temp_arr[1024]; char *temp_strs[1024]; int i, l, len_strs; char *port_strs[1024]; char port_range[1024]; char mybuf[] = "00:00:00:00:00:00"; if (strlen(sysconfig.if_in) < 1 || strlen(sysconfig.if_out) < 1) { OD("missing ifnames"); return -1; } if (sysconfig.is_test) { if (strlen(sysconfig.src_mac.name) < 1) { /* retrieve source mac address. */ if (source_hwaddr(sysconfig.if_out, mybuf) == -1) { OD("Unable to retrieve source mac"); return -1; // continue, fail later } strcpy(sysconfig.src_mac.name, mybuf); } /* extract address ranges */ extract_ip_range(&sysconfig.src_ip); extract_mac_range(&sysconfig.src_mac); for (i = 0; i < sysconfig.dst_count && i < FIO_MAX_DST_TEST; i++) { extract_ip_range(&sysconfig.dst_ip[i]); extract_mac_range(&sysconfig.dst_mac[i]); } } if (source_hwaddr(sysconfig.if_in, mybuf) == -1) { OD("Unable to retrieve source mac %s", sysconfig.if_in); return -1; } bcopy(ether_aton(mybuf), &sysconfig.if_macs[0], ETH_ALEN); OD("if %s mac %s", sysconfig.if_in, mybuf); if (source_hwaddr(sysconfig.if_out, mybuf) == -1) { OD("Unable to retrieve source mac %s", sysconfig.if_out); return -1; } bcopy(ether_aton(mybuf), &sysconfig.if_macs[1], ETH_ALEN); OD("if %s mac %s", sysconfig.if_out, mybuf); extract_mac_range(&sysconfig.defgw_mac); OD("defgw mac %s", sysconfig.defgw_mac.name); if (get_if_ip(sysconfig.if_in, &sysconfig.if_ips[0])) OD("<error> %s get ip", sysconfig.if_in); if (get_if_ip(sysconfig.if_out, &sysconfig.if_ips[1])) OD("<error> %s get ip", sysconfig.if_out); OD("read %d ipmac", g_mac_num); len_strs = splite_str(sysconfig.str_interested_proto, sizeof(sysconfig.str_interested_proto), temp_arr, 1024, temp_strs, 1024, ' '); translate_proto(temp_strs, len_strs, 1); len_strs = splite_str(sysconfig.str_def_proto, sizeof(sysconfig.str_def_proto), temp_arr, 1024, temp_strs, 1024, ' '); translate_proto(temp_strs, len_strs, 2); len_strs = splite_str(sysconfig.str_interested_port, sizeof(sysconfig.str_interested_port), temp_arr, 1024, temp_strs, 1024, ' '); for (i = 0; i < len_strs; i++) { l = splite_str(temp_strs[i], strlen(temp_strs[i])+1, port_range, 1024, port_strs, 1024, '~'); translate_port(port_strs, l, i); } sysconfig.mac_lifetime *= 1000000; sysconfig.mac_buddy_lifetime *= 1000000; //sysconfig.multip_checktime *= 1000000; if (strlen(sysconfig.if_in)) strncpy(sysconfig.nic_names[sysconfig.num_nic++], sysconfig.if_in, FIO_MAX_NAME_LEN); if (strlen(sysconfig.if_out) && strcmp(sysconfig.if_out, sysconfig.if_in)) strncpy(sysconfig.nic_names[sysconfig.num_nic++], sysconfig.if_out, FIO_MAX_NAME_LEN); return 0; }