static void resp_dispose(tc_iph_t *ip) { uint16_t size_ip, size_tcp, tot_len; tc_tcph_t *tcp; if (ip->protocol == IPPROTO_TCP) { tot_resp_packs++; size_ip = ip->ihl << 2; if (size_ip >= IPH_MIN_LEN) { tot_len = ntohs(ip->tot_len); tcp = (tc_tcph_t *) ((char *) ip + size_ip); size_tcp = tcp->doff << 2; if (size_tcp >= TCPH_MIN_LEN) { if (srv_settings.user_filter != NULL) { tot_copy_resp_packs++; router_update(ip); } } else { tc_log_info(LOG_WARN, 0, "Invalid TCP len: %d,tot_len:%d", size_tcp, tot_len); } } else { tc_log_info(LOG_WARN, 0, "Invalid IP header length: %d", size_ip); } } }
static void interception_process(int fd) { int diff, new_fd, i, pass_through_flag = 0; time_t now; unsigned long packet_id; struct iphdr *ip_header; struct msg_client_s *c_msg; if(fd == msg_listen_sock){ new_fd = accept(msg_listen_sock, NULL, NULL); set_sock_no_delay(new_fd); if(new_fd != -1){ select_server_add(new_fd); } }else if(fd == firewall_sock){ packet_id = 0; ip_header = nl_firewall_recv(firewall_sock, &packet_id); if(ip_header != NULL){ /* Check if it is the valid user to pass through firewall */ for(i = 0; i < srv_settings.passed_ips.num; i++){ if(srv_settings.passed_ips.ips[i] == ip_header->daddr){ pass_through_flag = 1; break; } } if(pass_through_flag){ /* Pass through the firewall */ dispose_netlink_packet(NF_ACCEPT, packet_id); }else{ router_update(ip_header); now = time(0); diff = now - last_clean_time; if(diff > CHECK_INTERVAL){ route_delete_obsolete(now); delay_table_delete_obsolete(now); last_clean_time = now; } /* Drop the packet */ dispose_netlink_packet(NF_DROP, packet_id); } } }else{ c_msg = msg_server_recv(fd); if(c_msg){ if(c_msg->type == CLIENT_ADD){ tc_log_debug1(LOG_NOTICE, "add client router:%u", ntohs(c_msg->client_port)); router_add(c_msg->client_ip, c_msg->client_port, fd); }else if(c_msg->type == CLIENT_DEL){ tc_log_debug1(LOG_NOTICE, "del client router:%u", ntohs(c_msg->client_port)); router_del(c_msg->client_ip, c_msg->client_port); } }else{ close(fd); select_server_del(fd); log_info(LOG_NOTICE, "close sock:%d", fd); } } }
static int tc_nl_event_process(tc_event_t *rev) { int i, pass_through_flag = 0; char buffer[65535]; unsigned long packet_id; tc_ip_header_t *ip_hdr; packet_id = 0; if (tc_nl_socket_recv(rev->fd, buffer, 65535) == TC_ERROR) { return TC_ERROR; } ip_hdr = tc_nl_ip_header(buffer); packet_id = tc_nl_packet_id(buffer); if (ip_hdr != NULL) { /* check if it is the valid user to pass through firewall */ for (i = 0; i < srv_settings.passed_ips.num; i++) { if (srv_settings.passed_ips.ips[i] == ip_hdr->daddr) { pass_through_flag = 1; break; } } tot_resp_packs++; if (pass_through_flag) { #if (INTERCEPT_THREAD) put_nl_verdict_to_pool(rev->fd, NF_ACCEPT, packet_id); #else /* pass through the firewall */ dispose_netlink_packet(rev->fd, NF_ACCEPT, packet_id); #endif } else { tot_copy_resp_packs++; #if (INTERCEPT_THREAD) /* put response packet header to pool */ put_resp_header_to_pool(ip_hdr); /* drop the packet */ put_nl_verdict_to_pool(rev->fd, NF_DROP, packet_id); #else router_update(srv_settings.router_fd, ip_hdr); tc_check_cleaning(); /* drop the packet */ dispose_netlink_packet(rev->fd, NF_DROP, packet_id); #endif } } return TC_OK; }
static int tc_nfq_process_packet(struct nfq_q_handle *qh, struct nfgenmsg *nfmsg, struct nfq_data *nfa, void *data) { int i, id = 0, payload_len = 0, ret, pass_through_flag = 0; unsigned char *payload; tc_ip_header_t *ip_hdr; struct nfqnl_msg_packet_hdr *ph; ph = nfq_get_msg_packet_hdr(nfa); if (ph) { id = ntohl(ph->packet_id); } payload_len = nfq_get_payload(nfa, &payload); if (payload_len < 40) { tc_log_info(LOG_WARN, 0, "payload len wrong:%d", payload_len); return TC_ERROR; } ip_hdr = (tc_ip_header_t *)payload; if (ip_hdr != NULL) { /* check if it is the valid user to pass through firewall */ for (i = 0; i < srv_settings.passed_ips.num; i++) { if (srv_settings.passed_ips.ips[i] == ip_hdr->daddr) { pass_through_flag = 1; break; } } tot_resp_packs++; if (pass_through_flag) { /* pass through the firewall */ ret = nfq_set_verdict(qh, id, NF_ACCEPT, 0, NULL); } else { tot_copy_resp_packs++; router_update(srv_settings.router_fd, ip_hdr); tc_check_cleaning(); /* drop the packet */ ret = nfq_set_verdict(qh, id, NF_DROP, 0, NULL); } } else { ret = TC_ERROR; } return ret; }
static int tc_nl_event_process(tc_event_t *rev) { int i, pass_through_flag = 0; char buffer[65536]; unsigned long packet_id; tc_ip_header_t *ip_hdr; if (tc_nl_socket_recv(rev->fd, buffer, 65536) == TC_ERROR) { return TC_ERROR; } ip_hdr = tc_nl_ip_header(buffer); packet_id = tc_nl_packet_id(buffer); if (ip_hdr != NULL) { /* check if it is the valid user to pass through firewall */ for (i = 0; i < srv_settings.passed_ips.num; i++) { if (srv_settings.passed_ips.ips[i] == ip_hdr->daddr) { pass_through_flag = 1; break; } } tot_resp_packs++; if (pass_through_flag) { /* pass through the firewall */ dispose_netlink_packet(rev->fd, NF_ACCEPT, packet_id); } else { tot_copy_resp_packs++; router_update(srv_settings.old, srv_settings.router_fd, ip_hdr); /* drop the packet */ dispose_netlink_packet(rev->fd, NF_DROP, packet_id); } } return TC_OK; }
static void * interception_process_msg(void *tid) { int len; char resp[65536]; tc_ip_header_t *ip_hdr; for (;;) { ip_hdr = get_resp_ip_hdr_from_pool(resp, &len); if (ip_hdr == NULL) { tc_log_info(LOG_WARN, 0, "ip header is null"); } router_update(ip_hdr, len); tc_nl_check_cleaning(); } return NULL; }
static int resp_dispose(tc_ip_header_t *ip_header) { int i, passed; uint16_t port, size_ip, size_tcp, tot_len; uint32_t ip_addr; ip_port_pair_t *pair; tc_tcp_header_t *tcp_header; if (ip_header->protocol != IPPROTO_TCP) { return TC_OK; } tot_resp_packs++; size_ip = ip_header->ihl << 2; if (size_ip < 20) { tc_log_info(LOG_WARN, 0, "Invalid IP header length: %d", size_ip); return TC_OK; } tot_len = ntohs(ip_header->tot_len); tcp_header = (tc_tcp_header_t *) ((char *) ip_header + size_ip); size_tcp = tcp_header->doff << 2; if (size_tcp < 20) { tc_log_info(LOG_WARN, 0, "Invalid TCP header len: %d bytes,pack len:%d", size_tcp, tot_len); return TC_OK; } #if (TCPCOPY_PCAP) if (srv_settings.user_filter != NULL) { passed = 1; } else { passed = 0; } #else passed = 0; #endif ip_addr = ip_header->saddr; port = tcp_header->source; if (!passed) { /* filter the packets we do care about */ for (i = 0; i < srv_settings.targets.num; i++) { pair = srv_settings.targets.mappings[i]; if (ip_addr == pair->ip && port == pair->port) { passed = 1; break; } else if (0 == pair->ip && port == pair->port) { passed = 1; break; } } if (passed == 0) { return TC_OK; } } tot_copy_resp_packs++; router_update(srv_settings.router_fd, ip_header); return TC_OK; }