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_msg_event_process(tc_event_t *rev) { msg_client_t msg; if (tc_socket_recv(rev->fd, (char *) &msg, MSG_CLIENT_SIZE) == TC_ERROR) { tc_socket_close(rev->fd); tc_log_info(LOG_NOTICE, 0, "close sock:%d", rev->fd); tc_event_del(rev->loop, rev, TC_EVENT_READ); return TC_ERROR; } switch (msg.type) { case CLIENT_ADD: tc_log_debug1(LOG_DEBUG, 0, "add client router:%u", ntohs(msg.client_port)); router_add(msg.client_ip, msg.client_port, rev->fd); break; case CLIENT_DEL: tc_log_debug1(LOG_DEBUG, 0, "del client router:%u", ntohs(msg.client_port)); router_del(msg.client_ip, msg.client_port); break; } return TC_OK; }
void router_test(void) { int i; uint8_t id[N_NODEID] = {0x56, 0x31,}; struct node_t* nodes2[10]; struct node_t nodes[] = { { 1,{ 0x56, 0x25, } }, { 1,{ 0x56, 0x80, } }, { 1,{ 0x56, 0xFF, } }, { 1,{ 0x56, 0x00, } }, { 1,{ 0x56, 0x71, } }, { 1,{ 0x56, 0x10, } }, { 1,{ 0x56, 0x0E, } }, { 1,{ 0x56, 0xCE, } }, { 1,{ 0x7E, 0x31, } }, { 1,{ 0x29, 0x31, } }, { 1,{ 0x80, 0x31, } }, { 1,{ 0x69, 0x31, } }, { 1,{ 0x59, 0x31, } }, { 1,{ 0x40, 0x31, } }, }; struct router_t* router; router = router_create(id); for (i = 0; i < sizeof(nodes) / sizeof(nodes[0]); i++) { router_add(router, nodes[i].id, &nodes[i].addr, NULL); } router_nearest(router, id, nodes2, 6); router_destroy(router); while(1) router_test2(); }
static void router_test2(void) { int i; struct node_t* node; struct node_t* result[8]; static struct node_t s_nodes[100000]; uint8_t id[N_NODEID] = { 0xAB, 0xCD, 0xEF, 0x89, }; heap_t* heap, *heap2; struct router_t* router; router = router_create(id); heap = heap_create(node_compare_less, (void*)id); heap_reserve(heap, 8 + 1); for (i = 0; i < sizeof(s_nodes) / sizeof(s_nodes[0]); i++) { int v = rand(); memset(&s_nodes[i], 0, sizeof(s_nodes[i])); memcpy(s_nodes[i].id, &v, sizeof(v)); s_nodes[i].ref = 1; if (0 == router_add(router, s_nodes[i].id, &s_nodes[i].addr, &node)) { heap_push(heap, node); if (heap_size(heap) > 8) { node_release((struct node_t*)heap_top(heap)); heap_pop(heap); } } } assert(8 == heap_size(heap)); assert(8 == router_nearest(router, id, result, 8)); heap2 = heap_create(node_compare_less, (void*)id); heap_reserve(heap2, 8); for (i = 0; i < 8; i++) { heap_push(heap2, result[i]); } assert(heap_size(heap) == heap_size(heap2)); for (i = 0; i < 8; i++) { assert(heap_top(heap2) == heap_top(heap)); heap_pop(heap); heap_pop(heap2); } router_destroy(router); heap_destroy(heap); heap_destroy(heap2); printf("router test ok!\n"); }
/* * Routers * */ void parse_routers() { xmlXPathObjectPtr xmlobject; xmlNode *router; char *text, *request="/config_ndpmon/routers"; xmlobject = xmlXPathEval ((xmlChar*)request, xpctxt); if (xmlobject->nodesetval==NULL) { xmlXPathFreeObject (xmlobject); return; } router = xmlobject->nodesetval->nodeTab[0]->children; while(router != NULL) { if (router->type == XML_ELEMENT_NODE && STRCMP(router->name,"router")==0) { struct ether_addr mac; struct in6_addr lla; uint8_t param_curhoplimit=0; uint8_t param_flags_reserved=0; uint16_t param_router_lifetime=0; uint32_t param_reachable_timer=0; uint32_t param_retrans_timer=0; uint32_t param_mtu=0; int params_volatile=1; prefix_t* tmp_prefix = NULL; address_t* tmp_address = NULL; xmlNode *param = router->children; int vlan_id = 4095; while(param != NULL) { if (param->type != XML_ELEMENT_NODE) { param = param->next; continue; } /* We have an XML Element: */ if( !STRCMP(param->name,"mac") ) { memcpy(&mac,ether_aton((char *)XML_GET_CONTENT(param->children)),sizeof(struct ether_addr)); } else if( !STRCMP(param->name,"vlan_id") ) { text = (char*)XML_GET_CONTENT(param->children); vlan_id = atoi(text!=NULL?text:"4095"); } else if( !STRCMP(param->name,"lla") ) { inet_pton(AF_INET6,(char *)XML_GET_CONTENT(param->children), &lla); } else if( !STRCMP(param->name,"param_curhoplimit") ) { text = (char*)XML_GET_CONTENT(param->children); param_curhoplimit = atoi(text!=NULL?text:"0"); } else if( !STRCMP(param->name,"param_flags_reserved") ) { text = (char*)XML_GET_CONTENT(param->children); param_flags_reserved = atoi(text!=NULL?text:"0"); } else if( !STRCMP(param->name,"param_router_lifetime") ) { text = (char*)XML_GET_CONTENT(param->children); param_router_lifetime = atoi(text!=NULL?text:"0"); } else if( !STRCMP(param->name,"param_reachable_timer") ) { text = (char*)XML_GET_CONTENT(param->children); param_reachable_timer = strtoul(text!=NULL?text:"0", NULL, 10); } else if( !STRCMP(param->name,"param_retrans_timer") ) { text = (char*)XML_GET_CONTENT(param->children); param_retrans_timer = strtoul(text!=NULL?text:"0", NULL, 10); } else if( !STRCMP(param->name,"param_mtu") ) { text = (char*)XML_GET_CONTENT(param->children); param_mtu = strtoul(text!=NULL?text:"0", NULL, 10); } else if( !STRCMP(param->name,"params_volatile") ) { text = (char*)XML_GET_CONTENT(param->children); params_volatile = atoi(text!=NULL?text:"1"); } else if( !STRCMP(param->name,"addresses") ) { xmlNode *address = param->children; while(address != NULL) { if (address->type == XML_ELEMENT_NODE && STRCMP(address->name,"address")==0 ) { /* Read address: */ address_t* new_address = malloc(sizeof(address_t)); if (new_address==NULL) { fprintf(stderr, "malloc failed."); } inet_pton(AF_INET6,(char *)XML_GET_CONTENT(address->children), &new_address->address); /* Add address to tmp address list: */ new_address->next = tmp_address; tmp_address = new_address; } /* Fetch next address node: */ address = address->next; } } /* end addresses */ else if( !STRCMP(param->name,"prefixes") ) { xmlNode *prefix = param->children; while(prefix != NULL) { if (prefix->type == XML_ELEMENT_NODE && STRCMP(prefix->name,"prefix")==0) { /* Read prefix params: */ xmlNode *prefix_param = prefix->children; prefix_t* new_prefix = malloc(sizeof(prefix_t)); char buffer[INET6_ADDRSTRLEN]; if (new_prefix==NULL) { fprintf(stderr, "malloc failed."); } memset(&new_prefix->prefix, 0, sizeof(struct in6_addr)); new_prefix->mask = 0; new_prefix->param_valid_time = 0; new_prefix->param_preferred_time = 0; while(prefix_param != NULL) { if (prefix_param->type != XML_ELEMENT_NODE) { prefix_param = prefix_param->next; continue; } /* We have an XML Element: */ if (STRCMP(prefix_param->name,"address")==0) { text=(char *)XML_GET_CONTENT(prefix_param->children); strncpy(buffer,text, INET6_ADDRSTRLEN); inet_pton(AF_INET6,buffer, &new_prefix->prefix); } else if (STRCMP(prefix_param->name,"mask")==0) { text=(char *)XML_GET_CONTENT(prefix_param->children); new_prefix->mask = atoi(text!=NULL?text:0); } else if (STRCMP(prefix_param->name,"param_flags_reserved")==0) { text=(char *)XML_GET_CONTENT(prefix_param->children); new_prefix->param_flags_reserved = atoi(text!=NULL?text:0); } else if (STRCMP(prefix_param->name,"param_valid_time")==0) { text=(char *)XML_GET_CONTENT(prefix_param->children); new_prefix->param_valid_time = strtoul(text!=NULL?text:"0", NULL, 10); } else if (STRCMP(prefix_param->name,"param_preferred_time")==0) { text=(char *)XML_GET_CONTENT(prefix_param->children); new_prefix->param_preferred_time = strtoul(text!=NULL?text:"0", NULL, 10); } prefix_param = prefix_param->next; } /* Add prefix to tmp list:*/ new_prefix->next = tmp_prefix; tmp_prefix = new_prefix; } /* Fetch next prefix node: */ prefix = prefix->next; } } /* end prefixes */ /* Fetch next router param: */ param = param->next; } /* end router params */ /* Add router to the router list: */ router_add( &routers, vlan_id, &mac, &lla, param_curhoplimit, param_flags_reserved, param_router_lifetime, param_reachable_timer, param_retrans_timer, param_mtu, params_volatile ); while (tmp_prefix!=NULL) { prefix_t* current=tmp_prefix; router_add_prefix( routers, vlan_id, lla, mac, current->prefix, current->mask, current->param_flags_reserved, current->param_valid_time, current->param_preferred_time ); tmp_prefix = current->next; free(current); } while (tmp_address!=NULL) { address_t* current=tmp_address; router_add_address(routers, vlan_id, mac, current->address); tmp_address = current->next; free(current); } } /* end is XML element and router */ /* Fetch next router node: */ router = router->next; } xmlXPathFreeObject (xmlobject); }
static int tc_msg_event_process(tc_event_t *rev) { int fd, version; msg_client_t msg; fd = rev->fd; memset(&msg, 0, sizeof(msg_client_t)); if (tunnel[fd].first_in) { if (tc_socket_recv(fd, (char *) &msg, MSG_CLIENT_MIN_SIZE) == TC_ERROR) { tc_intercept_close_fd(fd, rev); return TC_ERROR; } version = ntohs(msg.type); tunnel[fd].first_in = 0; if (msg.client_ip != 0 || msg.client_port != 0) { tunnel[fd].clt_msg_size = MSG_CLIENT_MIN_SIZE; tc_log_info(LOG_WARN, 0, "too old tcpcopy for intercept"); srv_settings.old = 1; } else { if (version != INTERNAL_VERSION) { tc_log_info(LOG_WARN, 0, "not compatible,tcpcopy:%d,intercept:%d", msg.type, INTERNAL_VERSION); } tunnel[fd].clt_msg_size = MSG_CLIENT_SIZE; if (tc_socket_recv(fd, ((char *) &msg + MSG_CLIENT_MIN_SIZE), MSG_CLIENT_SIZE - MSG_CLIENT_MIN_SIZE) == TC_ERROR) { tc_intercept_close_fd(fd, rev); return TC_ERROR; } return TC_OK; } } else { if (tc_socket_recv(fd, (char *) &msg, tunnel[fd].clt_msg_size) == TC_ERROR) { tc_intercept_close_fd(fd, rev); return TC_ERROR; } } msg.client_ip = msg.client_ip; msg.client_port = msg.client_port; msg.type = ntohs(msg.type); msg.target_ip = msg.target_ip; msg.target_port = msg.target_port; switch (msg.type) { case CLIENT_ADD: #if (!TCPCOPY_SINGLE) tot_router_items++; tc_log_debug1(LOG_DEBUG, 0, "add client router:%u", ntohs(msg.client_port)); router_add(srv_settings.old, msg.client_ip, msg.client_port, msg.target_ip, msg.target_port, fd); #endif break; case CLIENT_DEL: tc_log_debug1(LOG_DEBUG, 0, "del client router:%u", ntohs(msg.client_port)); break; default: tc_log_info(LOG_WARN, 0, "unknown msg type:%u", msg.type); } return TC_OK; }
static int tc_msg_event_proc(tc_event_t *rev) { msg_clt_t msg; register int fd, version; tunnel_basic_t *tunnel; fd = rev->fd; tunnel = srv_settings.tunnel; if (!tunnel[fd].first_in) { if (tc_socket_rcv(fd, (char *) &msg, tunnel[fd].clt_msg_size) == TC_ERR) { tc_intercept_release_tunnel(fd, rev); return TC_ERR; } } else { if (tc_socket_rcv(fd, (char *) &msg, MSG_CLT_MIN_SIZE) != TC_ERR) { tunnel[fd].first_in = 0; version = ntohs(msg.type); if (msg.clt_ip != 0 || msg.clt_port != 0) { tc_log_info(LOG_ERR, 0, "client too old for intercept"); return TC_ERR; } else { if (version != INTERNAL_VERSION) { tc_log_info(LOG_WARN, 0, "not compatible,client:%d,intercept:%d", msg.type, INTERNAL_VERSION); } tunnel[fd].clt_msg_size = MSG_CLT_SIZE; if (tc_socket_rcv(fd, ((char *) &msg + MSG_CLT_MIN_SIZE), MSG_CLT_SIZE - MSG_CLT_MIN_SIZE) == TC_ERR) { tc_intercept_release_tunnel(fd, rev); return TC_ERR; } return TC_OK; } } else { tc_intercept_release_tunnel(fd, rev); return TC_ERR; } } msg.clt_ip = msg.clt_ip; msg.clt_port = msg.clt_port; msg.type = ntohs(msg.type); msg.target_ip = msg.target_ip; msg.target_port = msg.target_port; switch (msg.type) { case CLIENT_ADD: #if (!TC_SINGLE) tot_router_items++; tc_log_debug1(LOG_DEBUG, 0, "add client router:%u", ntohs(msg.clt_port)); router_add(msg.clt_ip, msg.clt_port, msg.target_ip, msg.target_port, rev->fd); #endif break; case CLIENT_DEL: tc_log_debug1(LOG_DEBUG, 0, "del client router:%u", ntohs(msg.clt_port)); break; default: tc_log_info(LOG_WARN, 0, "unknown msg type:%u", msg.type); } return TC_OK; }