static int mpoa_egress_cache_purge_reply( uint8_t * buff ){ int pos = 0; struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h *)buff; struct nhrp_common_h *common; struct nhrp_cie *cie; struct extension_values values; struct k_message msg; memset(&values, 0, sizeof(struct extension_values)); memset(&msg,0,sizeof(struct k_message)); pos += sizeof(struct nhrp_fixed_h); common = (struct nhrp_common_h*)(buff + pos); if(!check_incoming(ntohl(common->request_ID), MPOA_EGRESS_CACHE_PURGE_REQUEST)) return -1; pos += sizeof(struct nhrp_common_h); cie = (struct nhrp_cie *)(buff + pos); msg.ip_mask = calculate_ip_mask(cie->prefix_length); if(fixed->ar_extoff) parse_extensions(buff + ntohs(fixed->ar_extoff),&values); else { printf("mpcd: p_recogn.c: warning: "); printf("no extensions in MPOA Egress Cache Purge Reply\n"); return -1; } if (values.dll_header_present == 0) { printf("mpcd: p_recogn.c: warning: "); printf("DLL Header Extension missing in MPOA Egress Cache Purge Reply\n"); return -1; } msg.content.eg_info.cache_id = values.dll_ext.cache_id; msg.type = EGRESS_PURGE_RCVD; memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN); return send_to_kernel(&msg); }
/* 2010 returns 1 if ok and 0 if node desn't exists */ int send_to_net(MESSAGE *msg) { int k, len; MESSAGE m; struct sockaddr_in svr; char addr[256]; k = msg->int_msg.control.receiver.node; /* 2010 check if node exists */ m.msg_type = MSG_NET; m.param.pword[0] = NET_NODE_EXIST; m.param.pword[1] = k; m.param.pword[2] = my_ctx.program_id; write(network_socket, &m, sizeof(MESSAGE)); bzero(&m, sizeof(MESSAGE)); while ((m.msg_type != MSG_NET) && (m.param.pword[0] != NET_NODE_EXIST)) { read(network_socket, &m, sizeof(MESSAGE)); } DEBUG_PRINT("NET_NODE_EXIST %d: %d\n", k, m.param.pword[1]); if (m.param.pword[1] != 1) return 0; strcpy(addr, m.param.pstr); if (RInstance[k] == -1) { bzero(&m, sizeof(MESSAGE)); m.msg_type = MSG_VLP; m.param.pword[0] = VLP_REMOTE_INSTANCE_PLEASE; m.param.pword[1] = my_ctx.program_id; m.param.pword[2] = k; send_to_kernel(&m); bzero(&m, sizeof(MESSAGE)); DEBUG_PRINT("VLP_REMOTE_INSTANCE_PLEASE of program id: %d on node %d\n", my_ctx.program_id, k); while (1) { read(network_socket, &m, sizeof(MESSAGE)); if ((m.msg_type == MSG_VLP) && (m.param.pword[0] == VLP_REMOTE_INSTANCE_HERE)) break; } DEBUG_PRINT("remote instance made with id: %d addr %s port %d\n",m.param.pword[1],addr, htons(m.param.pword[8])); RInstance[k] = m.param.pword[1]; /* Make direct connection */ DirConn[k] = socket(AF_INET, SOCK_STREAM, 0); svr.sin_family = AF_INET; svr.sin_addr.s_addr = inet_addr(addr); svr.sin_port = htons(m.param.pword[8]); len = connect(DirConn[k], (struct sockaddr *) &svr, sizeof(svr)); if (len != 0) { RInstance[k] = -1; writeln_str("Cannot connect remote instance!"); DEBUG_PRINT("Cannot establish remote connection\n"); } else { DEBUG_PRINT("Remote connection established\n"); //fcntl ( DirConn[k], F_SETFL, O_NONBLOCK | fcntl ( DirConn[k], F_GETFL, 0 ) ); } } if (RInstance[k] != -1) { DEBUG_PRINT("Remote instance already exists\n"); write(DirConn[k], &(msg->int_msg), sizeof(message)); } return 1; }
static int mpoa_trigger( uint8_t * buff ){ int pos = 0; struct k_message msg; struct nhrp_common_h *common; struct extension_values values; struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h*)buff; memset(&values, 0, sizeof(struct extension_values)); pos += sizeof(struct nhrp_fixed_h); common = (struct nhrp_common_h *)(buff + pos); pos += sizeof(struct nhrp_common_h); memset(&msg,0,sizeof(struct k_message)); if(ntohs(fixed->ar_extoff)) { printf("mpcd: p_recogn.c: mpoa_trigger: ar$extoff in Fixed Header != 0\n" ); parse_extensions(buff+ntohs(fixed->ar_extoff),&values); } if(!common->dst_proto_len){ printf("mpcd: p_recogn.c: mpoa_trigger: no destination ip to trigger! \n"); return -1; } if(common->src_proto_len) msg.content.in_info.in_dst_ip = common->dst_protocol_address; /* * If src_proto_len == 0 dst_protocol_address is found in "place" * of dst_ptocol_address. */ else msg.content.in_info.in_dst_ip = common->src_protocol_address; memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN); msg.type = MPOA_TRIGGER_RCVD; send_to_kernel(&msg); return 1; }
static int nhrp_purge_request(uint8_t *buff){ int pos = 0; int cie_limit = 0; uint32_t ip_mask; uint8_t eg_MPC_data_ATM_addr[ATM_ESA_LEN]; uint32_t eg_MPS_ip_addr; uint32_t purge_ip; struct k_message msg; struct extension_values values; struct nhrp_common_h_no_ip *common_no_ip; struct nhrp_cie_no_nbma *cie_no_nbma; struct nhrp_cie *cie; struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h *)buff; memset(&msg,0,sizeof(struct k_message)); if(ntohs(fixed->ar_extoff)){ cie_limit = ntohs(fixed->ar_extoff); } else{ cie_limit = ntohs(fixed->ar_pktsz); } pos += sizeof(struct nhrp_fixed_h); common_no_ip = (struct nhrp_common_h_no_ip *)(buff + pos); memcpy(eg_MPC_data_ATM_addr, common_no_ip->src_nbma_address ,ATM_ESA_LEN); pos += sizeof(struct nhrp_common_h_no_ip); if(common_no_ip->src_proto_len == PROTO_LEN_IP){ eg_MPS_ip_addr = ntohl((uint32_t)*(buff + pos)); pos += sizeof(eg_MPS_ip_addr); } if(common_no_ip->dst_proto_len == PROTO_LEN_IP) pos += sizeof(uint32_t); while(pos < cie_limit){ cie = (struct nhrp_cie *)(buff + pos); if(cie->cli_addr_tl){ purge_ip = cie->cli_protocol_address; ip_mask = calculate_ip_mask(cie->prefix_length); pos += sizeof(struct nhrp_cie); } else{ cie_no_nbma = (struct nhrp_cie_no_nbma *)(buff + pos); purge_ip = cie_no_nbma->cli_protocol_address; ip_mask = calculate_ip_mask(cie_no_nbma->prefix_length); pos += sizeof(struct nhrp_cie_no_nbma); } msg.type = INGRESS_PURGE_RCVD; msg.ip_mask = ip_mask; msg.content.in_info.in_dst_ip = purge_ip; memcpy(msg.MPS_ctrl, mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN); send_to_kernel(&msg); } /* we really do not do anything with the extensions, just parse them */ if(ntohs(fixed->ar_extoff)){ pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values); } if(!(ntohs(common_no_ip->flags) & FLAG_N )) return send_purge_reply(buff); return 1; }
int setProfile(FILE *file,char c) { int ret = 0; int len = 0; if(file == NULL) { printf("open file \"etc\" error!\n"); return ; } memset(file_list,'\0',MSG_LEN*sizeof(char)); while(fgets(file_list,MSG_LEN,file) != NULL) { len = strlen(file_list); if(file_list[0] != '#') //过滤注释 { file_list[len -1] = c;//添加白名单标志 file_list[len] = '\0';//长度 printf("%s\n",file_list); ret = send_to_kernel(skfd,file_list,0); } } fclose(file); return ret; }
static void sig_init(int signol) { send_to_kernel(skfd,"user process exit!",MSG_CLOSE); printf("user process exit!\n"); if(skfd) close(skfd); exit(0); }
static void signal_handler(int sig){ struct k_message msg; memset(&msg,0,sizeof(struct k_message)); if (sig == SIGHUP) msg.type = RELOAD; else msg.type = CLEAN_UP_AND_EXIT; send_to_kernel(&msg); printf("mpcd: main.c: signal_handler() signal %d\n", sig); return; }
/* * Keep alive state machine. Sequence number less than * and keep_alive_lifetime equal to zero is used * when checking wheter the MPS is still alive. * */ void keep_alive_sm(unsigned keep_alive_lifetime, int sequence_number){ struct k_message msg; static unsigned previous_sequence_number = 0; static int start_keep_alive_sm = 0; time_t now = time(NULL); memset(&msg,0,sizeof(struct k_message)); if(!keep_alive_sm_running){ start_keep_alive_sm = 0; return; } if(!start_keep_alive_sm){ dprintf("mpcd: io.c: starting keep_alive_sm.\n"); stay_alive = time(NULL) + MPC_C2; start_keep_alive_sm = 1; return; } if( now > stay_alive ){ dprintf("mpcd: io.c: MPS death!"); msg.type = MPS_DEATH; memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN); send_to_kernel(&msg); previous_sequence_number = 0; stay_alive = now + MPC_C2; return; } if( sequence_number < 0 ) return; if( sequence_number < previous_sequence_number ){ dprintf("mpcd: io.c: MPS death!"); msg.type = MPS_DEATH; memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR,ATM_ESA_LEN); send_to_kernel(&msg); previous_sequence_number = 0; stay_alive = now + MPC_C2; return; } stay_alive = now + keep_alive_lifetime; previous_sequence_number = sequence_number; return; }
static int mpoa_resolution_reply( uint8_t * buff ){ int pos = 0; struct k_message msg; struct extension_values values; struct nhrp_common_h *common; struct nhrp_cie *cie; struct nhrp_fixed_h *fixed = (struct nhrp_fixed_h*)buff; memset(&values, 0, sizeof(struct extension_values)); memset(&msg,0,sizeof(struct k_message)); pos += sizeof(struct nhrp_fixed_h); common = (struct nhrp_common_h*)(buff + pos); if(!check_incoming(ntohl(common->request_ID),MPOA_RESOLUTION_REQUEST)) return -1; pos += sizeof(struct nhrp_common_h); cie = (struct nhrp_cie*)(buff + pos); if(cie->code){ print_cie_code(cie->code); return -1; } msg.content.in_info.holding_time = ntohs(cie->holding_time); if(fixed->ar_extoff) pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values); if (values.egress_cache_tag_ext_present == 0) { printf("mpcd: p_recogn.c: warning: "); printf("received MPOA Resolution Reply "); printf("with no Egress Cache Tag Extension\n"); } if(values.tag_present && values.tag == 0) { printf("mpcd: p_recogn.c: warning: "); printf("received MPOA Resolution Reply "); printf("with Egress Cache Tag Extension where tag == 0\n"); values.tag_present = 0; } if(values.tag_present){ msg.content.in_info.tag = values.tag; } msg.type = MPOA_RES_REPLY_RCVD; msg.content.in_info.in_dst_ip = common->dst_protocol_address; memcpy(msg.content.in_info.eg_MPC_ATM_addr,cie->cli_nbma_address,ATM_ESA_LEN); memcpy(msg.MPS_ctrl,mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN); if(values.service_category_present) msg.qos.txtp.traffic_class = service_category_to_traff_class(values.service_category); else msg.qos.txtp.traffic_class = ATM_UBR; send_to_kernel(&msg); keep_alive_sm_running = 1; return MPOA_RESOLUTION_REPLY; }
static int mpoa_cache_imposition_request( uint8_t * buff ){ int pos = 0; struct k_message msg; struct nhrp_fixed_h * fixed = (struct nhrp_fixed_h *)buff; struct nhrp_common_h * common; struct nhrp_cie_short * cie_short; struct extension_values values; pos += sizeof( struct nhrp_fixed_h ); memset(&values, 0, sizeof(struct extension_values)); memset(&msg,0,sizeof(struct k_message)); common = (struct nhrp_common_h *)(buff + pos); memcpy(msg.content.eg_info.in_MPC_data_ATM_addr, common->src_nbma_address ,ATM_ESA_LEN); pos += sizeof(struct nhrp_common_h); cie_short = (struct nhrp_cie_short *)(buff + pos); msg.content.eg_info.holding_time = ntohs(cie_short->holding_time); msg.ip_mask = calculate_ip_mask(cie_short->prefix_length); if(ntohs(fixed->ar_extoff)){ pos += parse_extensions(buff + ntohs(fixed->ar_extoff), &values); } if(ntohs(cie_short->holding_time)) { if (values.dll_header_present == 0) { printf("mpcd: p_recogn.c: warning: "); printf("holding time non-zero but MPOA DLL Header Extension missing\n"); return 0; } keep_alive_sm_running = 1; } msg.content.eg_info.cache_id = values.dll_ext.cache_id; msg.content.eg_info.DH_length = values.dll_ext.dh_length; memcpy(msg.content.eg_info.DLL_header, values.dll_ext.dll_header, msg.content.eg_info.DH_length); if(common->src_proto_len) msg.content.eg_info.mps_ip = common->src_protocol_address; if(common->dst_proto_len) msg.content.eg_info.eg_dst_ip = common->dst_protocol_address; msg.content.eg_info.tag = new_tag(msg.content.eg_info.cache_id); memcpy(msg.MPS_ctrl, mpc_control.MPS_CTRL_ATM_ADDR, ATM_ESA_LEN); msg.type = CACHE_IMPOS_RCVD; send_to_kernel(&msg); return send_cache_imposition_reply( buff, msg.content.eg_info.tag, 0x00, 0, MTU_DEFAULT, common->src_nbma_address ); }
static int set_mps_mac_addr(){ char *string = mpc_control.MPS_MAC_ADDRESS; struct k_message msg; unsigned char mac_addr[ETH_ALEN]; int tmp; int i = strlen(string); memset(&msg,0,sizeof(struct k_message)); if (i != 12){ printf("mpcd: main.c: incorrect mac address.\n"); exit(1); } for(i=0;i<6;i++) { sscanf(&string[i*2],"%2x",&tmp); mac_addr[i]=(unsigned char)tmp; } msg.type = SET_MPS_MAC_ADDR; memcpy(&msg.MPS_ctrl,&mac_addr,ETH_ALEN); send_to_kernel(&msg); return 0; }
void send_ready() { int sock, len; struct sockaddr_in svr; char name[255]; struct hostent *info; MESSAGE msg; msg.msg_type = MSG_NET; msg.param.pword[0] = NET_PROPAGATE; msg.param.pword[1] = MSG_VLP; msg.param.pword[2] = my_ctx.node; msg.param.pword[4] = parent_ctx.node; msg.param.pword[6] = VLP_REMOTE_INSTANCE_OK; msg.param.pword[7] = my_ctx.program_id; msg.param.pword[9] = parent_ctx.program_id; DEBUG_PRINT("NET_PROPAGATE VLP_REMOTE_INSTANCE_OK to program_id: %d on node_id: %d\n", msg.param.pword[8], msg.param.pword[4]); sock = socket(AF_INET, SOCK_STREAM, 0); bzero(&svr, sizeof(svr)); svr.sin_family = AF_INET; svr.sin_addr.s_addr = INADDR_ANY; svr.sin_port = 0; bind(sock, (struct sockaddr *) &svr, sizeof(svr)); listen(sock, 5); len = sizeof(svr); getsockname(sock, (struct sockaddr *) &svr, &len); msg.param.pword[8] = ntohs(svr.sin_port); gethostname(name, len); info = gethostbyname(name); bcopy((char *) info->h_addr, (char *) &svr.sin_addr, info->h_length); sprintf(msg.param.pstr, "%s", inet_ntoa(svr.sin_addr)); send_to_kernel(&msg); bzero(&svr, sizeof(svr)); DirConn[parent_ctx.node] = accept(sock, (struct sockaddr *) &svr, &len); DEBUG_PRINT("DirConn[parent_ctx.node] = accept(..... finished\n"); //fcntl ( DirConn[parent_ctx.node], F_SETFL, O_NONBLOCK | fcntl ( DirConn[parent_ctx.node], F_GETFL, 0 ) ); }
int main(int argc, char **argv){ int listen_socket; int opt_ret = 0; struct k_message msg; struct sockaddr_atmsvc control_listen_addr; struct sockaddr_atmsvc mps_ctrl_addr; struct sockaddr_atmsvc lec_addr; memset(&control_listen_addr,0,sizeof(struct sockaddr_atmsvc)); memset(&mpc_control.data_listen_addr,0,sizeof(struct sockaddr_atmsvc)); memset(&lec_addr,0,sizeof(struct sockaddr_atmsvc)); memset(&mps_ctrl_addr,0,sizeof(struct sockaddr_atmsvc)); memset(&msg,0,sizeof(struct k_message)); memset(&mpc_control,0,sizeof(mpc_control)); mpc_control.elan_name[32] = '\0'; init_default_addresses(&control_listen_addr, &mpc_control.data_listen_addr); while( opt_ret != -1 ){ opt_ret = getopt(argc, argv, "h:s:l:c:L:n:C:i:m:"); switch(opt_ret) { case 'h': usage(argv[0]); exit(0); break; case 's': if(text2atm(optarg,(struct sockaddr *)&control_listen_addr, sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){ printf("mpcd: main.c: text2atm failed.\n"); usage(argv[0]); exit(1); } memcpy(mpc_control.OWN_ATM_ADDRESS,control_listen_addr.sas_addr.prv, ATM_ESA_LEN); break; case 'l': if(text2atm(optarg,(struct sockaddr *)&mpc_control.data_listen_addr, sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){ printf("mpcd: main.c: text2atm failed.\n"); usage(argv[0]); exit(1); } break; case 'c': if(text2atm(optarg,(struct sockaddr *)&mps_ctrl_addr, sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){ printf("mpcd: main.c: text2atm failed.\n"); usage(argv[0]); exit(1); } memcpy(mpc_control.MPS_CTRL_ATM_ADDR,mps_ctrl_addr.sas_addr.prv,ATM_ESA_LEN); mpc_control.mps_ctrl_addr_set = 1; break; case 'L': if(text2atm(optarg,(struct sockaddr *)&lec_addr, sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){ printf("mpcd: main.c: text2atm failed.\n"); usage(argv[0]); exit(1); } memcpy(mpc_control.LEC_ADDRESS,lec_addr.sas_addr.prv,ATM_ESA_LEN); mpc_control.use_lecs = 1; break; case 'n': strncpy(mpc_control.elan_name,optarg,33); break; case 'C': if(text2atm(optarg,(struct sockaddr *)&mpc_control.lecs_address, sizeof(struct sockaddr_atmsvc),T2A_SVC | T2A_NAME)<0){ printf("mpcd: main.c: text2atm failed.\n"); usage(argv[0]); exit(1); } break; case 'm': strncpy(mpc_control.MPS_MAC_ADDRESS,optarg,13); mpc_control.mps_mac_addr_set = 1; break; case 'i': mpc_control.INTERFACE_NUMBER = atoi(optarg); break; } } if (argc != optind) { usage(argv[0]); exit(1); } while(1){ create_kernel_socket(mpc_control.INTERFACE_NUMBER); if(mpc_control.use_lecs){ get_mpc_config(&mpc_control.lecs_address, mpc_control.LEC_ADDRESS, mpc_control.elan_name); } msg.type = SET_MPC_CTRL_ADDR; memcpy(msg.MPS_ctrl,mpc_control.OWN_ATM_ADDRESS,ATM_ESA_LEN); if (send_to_kernel(&msg) < 0) { printf("mpcd: main.c: send_to_kernel(SET_MPC_CTRL_ADDR) failed\n"); exit(1); } if(mpc_control.mps_mac_addr_set) set_mps_mac_addr(); listen_to_MPS( control_listen_addr ); if ( (listen_socket = get_listen_socket(&mpc_control.data_listen_addr)) < 0) { printf("mpcd: main.c: listen_socket creation failed\n"); exit (1); } signal(SIGHUP, signal_handler); signal(SIGINT, signal_handler); signal(SIGQUIT, signal_handler); signal(SIGABRT, signal_handler); signal(SIGTERM, signal_handler); main_loop(listen_socket); sleep(5); printf("mpcd: main.c: going back to main loop...\n"); } return 0; }