⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 mn_util.c

📁 mobile ip 在linux下的一种实现
💻 C
📖 第 1 页 / 共 2 页
字号:
	wireless_extensions = 1;	while ((c = getopt_long(argc, argv, "+hv", long_options, &oindex)) !=	       EOF) {		switch (c) {		case 'n':			wireless_extensions = 0;			break;		case 'p':			mn.policy_bits = atoi(optarg);			/* 0: no timestamps */			/* 1: with timestamps */			DEBUG(DEBUG_INFO, "Option: %s"			      " 0x%02x (wireless policy)\n",			      long_options[oindex].name,			      mn.policy_bits);			break;		case 'h':			/* show MN specific parameters */			show_usage();			exit(1);			break;		case 'd':			mn.opt_connect = 0;			break;		case '?':			printf("Command line parsing failed - aborting\n");			exit(1);		case 'v':		case 'c':		case 0:			break;		default:			printf("getopt returned character code 0%o\n", c);			exit(1);		}	}	return 0;}#ifdef DYN_TARGET_WINDOWS/* FIX: currently using local UDP socket on Windows because there is no support * for UNIX domain socket.. maybe something else would be better for IPC on * Windows platform(?) */static int windows_api_socket(int admin){	int s;	struct sockaddr_in addr;	int flags;	s = socket(AF_INET, SOCK_DGRAM, 0);	if (s < 0) {		DEBUG(DEBUG_INFO, "API socket opening failed: %s\n",		      strerror(errno));		return -1;	}	flags = fcntl(s, F_GETFL, 0);	if (flags == -1 || fcntl(s, F_SETFL, flags | O_NDELAY) == -1) {		DEBUG(DEBUG_INFO, "API rw fcntl F_SETFL failed: %s\n",		      strerror(errno));		close(s);		return -1;	}	memset(&addr, 0, sizeof(addr));	addr.sin_family = AF_INET;	addr.sin_addr.s_addr = htonl((127 << 24) | 1);	addr.sin_port = htons(admin ? API_UDP_PORT_RW : API_UDP_PORT_RO);	if (bind(s, (struct sockaddr *) &addr, sizeof(addr)) < 0) {		LOG2(LOG_ERR, "API socket - bind: %s\n", strerror(errno));		close(s);		return -1;	}	return s;}#endif/* Initialization routines. Setup sockets and variables. * Returns 1 on success else 0. */int mn_init(void){	int i;	/* Load configuration */	DEBUG(DEBUG_INFO, "Load config\n");	if (!load_mn(&config, program_name,		     opt_config == NULL ? MN_GLOBAL_CONF_FILE : opt_config)) {		LOG2(LOG_ERR, "init: unable to load configuration\n");		return 0;	}	mn.use_auth_alg = config.auth_alg;	mn.agentadv = hashtable_init(256);	if (mn.agentadv == NULL) {		LOG2(LOG_ERR, "init: unable to init agentadv hashtable\n");		return 0;	}	mn.last_req_FA_NAI = (struct fa_nai_ext *) malloc(MAX_FA_NAI_LEN);	if (mn.last_req_FA_NAI == NULL) {		LOG2(LOG_ERR, "init: not enough memory\n");		return 0;	}	memset(mn.last_req_FA_NAI, 0, MAX_FA_NAI_LEN);	if (!config.enable_fa_decapsulation)		check_kernel_support(CHECK_KERNEL_IPIP);	check_kernel_support(CHECK_KERNEL_NETLINK);#ifdef DYN_TARGET_LINUX	if (getuid() || geteuid()) {		fprintf(stderr, "This program must be run by root.\n");		return 0;	}#endif#ifdef DYN_TARGET_WINDOWS	/* FIX: on Windows NT and Windows 2000 check for Administrator	 * privileges */#endif	if ((mn.registration_socket = create_registration_socket()) < 0)		return 0;	mn_handlers_init();	mn.dev_info_addr.sun_family = AF_LOCAL;	/* initialize default socket info path */	dynamics_strlcpy(mn.dev_info_addr.sun_path, DEFAULT_DEVICE_INFO_PATH,			 sizeof(mn.dev_info_addr.sun_path));#ifdef WITH_WIRELESS	/* If wireless extensions enabled, monitor will register it's own	   handlers also */	DEBUG(DEBUG_INFO, "REGISTER MODULE(S)\n");	if (wireless_extensions)		MONITOR_register_module();#endif	/* Check interfaces */	for (i = 0; i < MAX_INTERFACES; i++) {		mn.iface[i].s = -1;		mn.iface[i].s_adv = -1;		mn.iface[i].handlers_off = 1;	}#ifdef INCLUDE_IPAY	/* register Ipay handlers after monitor */	ipay_init();#endif	if (config.home_net_addr_plen < 0 ||	    dyn_ip_route_get(config.home_net_addr, mn.start_default_device,			     IFNAMSIZ) != 0)		mn.start_default_device[0] = '\0';	else		DEBUG(DEBUG_INFO, "Initial default device: %s\n",		      mn.start_default_device);#ifdef DYN_TARGET_LINUX	if ((mn.api_ro_socket =	     api_open_socket(config.mn_api_read_socket_path,			     config.mn_api_read_socket_group,			     config.mn_api_read_socket_owner,			     config.mn_api_read_socket_permissions)) < 0) {		LOG2(LOG_ERR, "init - open_api_ro_socket: %s\n",		     strerror(errno));		return 0;	}	if ((mn.api_rw_socket =	     api_open_socket(config.mn_api_admin_socket_path,			     config.mn_api_admin_socket_group,			     config.mn_api_admin_socket_owner,			     config.mn_api_admin_socket_permissions)) < 0) {		LOG2(LOG_ERR, "init - open api_rw_socket: %s\n",		     strerror(errno));		return 0;	}#endif#ifdef DYN_TARGET_WINDOWS	mn.api_ro_socket = windows_api_socket(0);	mn.api_rw_socket = windows_api_socket(1);#endif#ifdef INCLUDE_IPAY	mn.ipay_sock = socket(AF_INET, SOCK_DGRAM, 0);	if (mn.ipay_sock < 0) {		LOG2(LOG_ERR, "init - open ipay_sock: %s\n", strerror(errno));		return 0;	}	if (config.ipay_mn_port > 0) {		struct sockaddr_in addr;		memset(&addr, 0, sizeof(addr));		addr.sin_family = AF_INET;		addr.sin_addr = config.ipay_mn_addr;		addr.sin_port = htons(config.ipay_mn_port);		if (bind(mn.ipay_sock, (struct sockaddr *) &addr,		    sizeof(addr)) < 0) {			LOG2(LOG_ERR, "init - bind ipay_sock: %s\n",			     strerror(errno));			return 0;		}	}	mn.ipay_sock_fa = socket(AF_INET, SOCK_DGRAM, 0);	if (mn.ipay_sock_fa < 0) {		LOG2(LOG_ERR, "init - open ipay_sock_fa: %s\n",		     strerror(errno));		return 0;	}	if (config.ipay_fa_port > 0) {		struct sockaddr_in addr;		memset(&addr, 0, sizeof(addr));		addr.sin_family = AF_INET;		addr.sin_addr.s_addr = INADDR_ANY;		addr.sin_port = htons(config.ipay_fa_port);		if (bind(mn.ipay_sock_fa, (struct sockaddr *) &addr,		    sizeof(addr)) < 0) {			LOG2(LOG_ERR, "init - bind ipay_sock_fa: %s\n",			     strerror(errno));			return 0;		}	}#endif	mn.rtnetlink_socket = dyn_ip_monitor_open();	if (mn.rtnetlink_socket < 0)		DEBUG(DEBUG_INFO, "init - rtnetlink socket opening failed\n");	/* set own ip-addr */	mn.local_addr = config.mn_home_ip_addr;	init_tunneling();	/* init variables */	mn.registration_id[0] = 0;	mn.registration_id[1] = 0;	mn.last_nonce = 0;        mn.clock_correction = 0;        mn.state = MN_DISCONNECTED;        mn.fa_addr.s_addr = 0;	mn.current_adv = NULL;	mn.force_fa_addr.s_addr = 0;        mn.session_key = NULL;        mn.session_key_len = 0;	mn.tunnel_up = 0;	mn.tunnel_mode = API_TUNNEL_NONE;	mn.ha_error_count = 0;	memset(&mn.cur_route_info, 0, sizeof(mn.cur_route_info));	mn.cur_route_info.net.s_addr = config.home_net_addr.s_addr;	mn.cur_route_info.prefix_len = config.home_net_addr_plen;        timerclear(&mn.last_reg_send_time);	for (i = 0; i < TIMER_COUNT; i++) timerclear(&timers[i]);	if (config.wlan_ap_poll_interval > -1)		gettimeofday(&timers[TIMER_WLAN_AP_POLL], NULL);	if (config.solicitation_interval > -1)		gettimeofday(&timers[TIMER_SOLICITATION], NULL);        openlog(SYSLOG_IDENT, SYSLOG_OPTIONS, config.syslog_facility);	dyn_ip_route_save_default(config.home_net_gateway.s_addr != 0 ?		&config.home_net_gateway : NULL);#ifdef MN_LOCUPD_PROFILER	mn.profile = fopen("mn.prof.log", "a");	if (mn.profile == NULL) {		fprintf(stderr, "Cannot open mn.prof.log\n");		return 0;	}	gettimeofday(&mn.last_api, NULL);	fprintf(mn.profile, "START %u.%06u\n",		(unsigned int) mn.last_api.tv_sec,		(unsigned int) mn.last_api.tv_usec);#endif        /* Setup signals */        signal(SIGTERM, clean_up);        signal(SIGINT, clean_up);        signal(SIGHUP, SIG_IGN);        signal(SIGPIPE, SIG_IGN);	if (!opt_foreground && dynamics_fork_daemon() == -1)		clean_up(0);	dynamics_write_pid_file(MN_PID_FILE);        DEBUG(DEBUG_INFO, " MN initialized to %sconnected state,\n"	      "  SPI: %d, HA: %s,\n", (mn.opt_connect ? "" : "dis"),	      config.spi, inet_ntoa(config.ha_ip_addr));	DEBUG(DEBUG_INFO, "  HomeAddr: %s",	      inet_ntoa(config.mn_home_ip_addr));	DEBUG(DEBUG_INFO, ", CurrentAddr: %s\n", inet_ntoa(mn.local_addr));	syslog(LOG_INFO, "Started.");	check_interfaces(mn.iface, MAX_INTERFACES);#ifdef DYN_TARGET_WINDOWS	mn.pcap_capturer = init_pcap_for_advs();#else	mn.pcap_capturer = -1;#endif /* DYN_TARGET_WINDOWS */	return 1;}/* Perform clean up: close sockets and log. */void clean_up(int sig){	int i;        DEBUG(DEBUG_INFO, "cleaning up..\n");	/* try to disconnect if connected */	if (mn.state == MN_CONNECTED) {		send_registration(REG_DISC);		DEBUG(DEBUG_MESSAGES, "Deregistration message sent\n");	}	if (mn.pcap_capturer > -1) {		DEBUG(DEBUG_INFO, "Terminating pcap capturer\n");		kill(mn.pcap_capturer, SIGTERM);		usleep(100000);		kill(mn.pcap_capturer, SIGKILL);	}	if (mn.agentadv != NULL) {		hashtable_iterator(mn.agentadv, clean_agentadv, NULL);		hashtable_destroy(mn.agentadv);	}        /* close sockets */        close(mn.registration_socket);	for (i = 0; i < MAX_INTERFACES; i++) {		if (mn.iface[i].s > -1)			close(mn.iface[i].s);		if (mn.iface[i].s_adv > -1)			close(mn.iface[i].s_adv);	}	if (mn.api_ro_socket > -1)		close(mn.api_ro_socket);	if (mn.api_rw_socket > -1)		close(mn.api_rw_socket);#ifdef INCLUDE_IPAY	close(mn.ipay_sock);	ipay_cleanup();#endif	if (mn.rtnetlink_socket > -1)		close(mn.rtnetlink_socket);#ifdef WITH_WIRELESS	/* Remove iwspy entries */	MONITOR_unregister_module();#endif	/* stop to any waiting api call */	reply_waiting_api(API_FAILED, NULL, 0);        /* close tunneling device */	close_tunneling();	mn_remove_dynamic_home_addr();	/* free session key */	if (mn.session_key != NULL)		free(mn.session_key);	if (mn.last_req_FA_NAI != NULL)		free(mn.last_req_FA_NAI);        /* unlink api domain sockets */        unlink(config.mn_api_read_socket_path);        unlink(config.mn_api_admin_socket_path);	unlink(MN_PID_FILE);	/* unregister all handlers */	/* FA_ADV_RECEIVE */	i = handler_unregister_all(FA_ADV_RECEIVE);	DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) "	      "removed\n", i, event_type_str(FA_ADV_RECEIVE));	/* FA_ADV_EXPIRE  */	i = handler_unregister_all(FA_ADV_EXPIRE);	DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) "	      "removed\n", i, event_type_str(FA_ADV_EXPIRE));	/* FA_GET */	i = handler_unregister_all(FA_GET);	DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) "	      "removed\n", i, event_type_str(FA_GET));	/* INTERFACE_INIT */	i = handler_unregister_all(INTERFACE_INIT);	DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) "	      "removed\n", i, event_type_str(INTERFACE_INIT));	/* INTERFACE_DOWN */	i = handler_unregister_all(INTERFACE_DOWN);	DEBUG(DEBUG_HANDLERS, "clean_up: %d \"%s\" handler(s) "	      "removed\n", i, event_type_str(INTERFACE_DOWN));        syslog(LOG_INFO, "stopped");        closelog();#ifdef MN_LOCUPD_PROFILER	fclose(mn.profile);#endif        DEBUG(DEBUG_INFO, "cleaned up\n");        exit(0);}void add_fa_host_route(char *dev, struct hashtable *adv_hash, 		       int ifindex, struct in_addr addr){	struct agentadv_data *adv;	adv = adv_fetch(adv_hash, &addr, ifindex);	if (dyn_ip_route_replace(addr, dev) != 0) {		if (adv != NULL && adv->routeentry)			DEBUG(DEBUG_INFO, "Route entry already added for the "			      "FA (%s=>%s)\n", inet_ntoa(addr), dev);		else			DEBUG(DEBUG_INFO, "Could not add a route to the FA "			      "(%s=>%s), but trying to register anyway\n",			      inet_ntoa(addr), dev);	} else {		if (adv != NULL)			adv->routeentry = 1;		else			DEBUG(DEBUG_INFO, "No agentadv for FA %s\n",			      inet_ntoa(addr));	}}static int clean_routes(struct node *node, void *data){	struct agentadv_data *adv, *current;	adv = (struct agentadv_data *) node;	current = (struct agentadv_data *) data;	if (current == adv) return TRUE; /* do not remove current FA's entry */	if (!adv->routeentry) return TRUE;	DEBUG(DEBUG_INFO, "Removing FA route (%s,%s)\n",	      inet_ntoa(adv->addr), adv->ifname);	if (dyn_ip_route_del(adv->addr, adv->ifname) != 0)		LOG2(LOG_ERR, "FA route removing failed (addr=%s, dev=%s)\n",		     inet_ntoa(adv->addr), adv->ifname);	adv->routeentry = 0;	return TRUE;}void remove_fa_host_routes(int all){	DEBUG(DEBUG_INFO, "remove_fa_host_routes(%i)\n", all);	hashtable_iterator(mn.agentadv, clean_routes,			   all ? NULL: mn.current_adv);}int is_coloc_addr_foreign(void){	char dev[IFNAMSIZ];	if (dyn_ip_route_get(config.mn_home_ip_addr, dev, IFNAMSIZ) != 0 ||	    strcmp(dev, "lo") != 0)		return 1;	return 0;}int device_up(int ifindex){	int i;	for (i = 0; i < MAX_INTERFACES; i++) {		if (mn.iface[i].s > -1 &&		    mn.iface[i].index == ifindex)			return 1;	}	return 0;}char *event_type_str(int event_type){	switch (event_type) {	case FA_ADV_RECEIVE:		return "FA Advertisement receive";	case FA_ADV_EXPIRE:		return "FA Advertisement expire";	case FA_GET:		return "Get best FA";	case INTERFACE_INIT:		return "Initialize interface";	case INTERFACE_DOWN:		return "Interface down";	default:		return "Unknown event type!";	}}/** * mn_remove_dynamic_home_addr: * * Remove dynamic home address from interface if it is maintained by * Dynamics MN. * * Returns: 1 on success (address removed), 0 if no dynamic home address, or * -1 on failure */int mn_remove_dynamic_home_addr(void){	if (mn.dynamic_home_addr.s_addr == 0)		return 0;	if (dyn_ip_addr_del(mn.dynamic_home_addr_dev, mn.dynamic_home_addr) ==	    0) {		DEBUG(DEBUG_INFO, "Dynamic home address '%s' removed from "		      "interface '%s'\n", inet_ntoa(mn.dynamic_home_addr),		      mn.dynamic_home_addr_dev);		if (config.mn_home_ip_addr.s_addr ==		    mn.dynamic_home_addr.s_addr) {			DEBUG(DEBUG_INFO, "\treset home address to 0 (use "			      "discovery)\n");			config.mn_home_ip_addr.s_addr =				mn.local_addr.s_addr = 0;			if (config.ha_ip_addr_orig.s_addr == 0) {				DEBUG(DEBUG_INFO, "\treset home agent address "				      "to 0 (use discovery)\n");				config.ha_ip_addr.s_addr = 0;			}		} else {			DEBUG(DEBUG_INFO, "\tDEBUG: config: %s, ",			      inet_ntoa(config.mn_home_ip_addr));			DEBUG(DEBUG_INFO, "obtained: %s\n",			      inet_ntoa(mn.dynamic_home_addr));		}		mn.dynamic_home_addr.s_addr = 0;		return 1;	}	DEBUG(DEBUG_INFO, "Could not remove dynamic home address '%s' "	      "from interface '%s'\n", inet_ntoa(mn.dynamic_home_addr),	      mn.dynamic_home_addr_dev);	return -1;}int monitor_check_policy(int bit){	return POLICY(bit);}int copy_str(char *buffer, int len, int *curr, char *str, char *attr){	int l;	l = strlen(str) + strlen(attr) + 1;	if (*curr+l > len) {		DEBUG(DEBUG_INFO, "copy_str: Not enough room (%d/%d)\n", 		      l, len);		return 1;	}	sprintf(buffer+*curr, "%s%s\n", str, attr);	*curr += l;	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -