📄 mn_api.c
字号:
struct dynamics_mn_iw_ch_info *info; msg->length = 0; r = monitor_api_get_ch((unsigned char *)msg->params, &msg->length); info = (struct dynamics_mn_iw_ch_info *)msg->params; DEBUG(DEBUG_API, "handle_api_get_iw_ch: %s: %d " "(msg->length: %d(%d) num: %d)\n", info->ifname, info->channel, msg->length, sizeof(struct dynamics_mn_iw_ch_info), msg->length/sizeof(struct dynamics_mn_iw_ch_info)); if (r) api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0); else api_send_reply(s, addr, addrlen, API_SUCCESS, (unsigned char *) msg->params, msg->length);}static void handle_api_set_iw_ch(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg){ struct dynamics_mn_iw_ch_info info; memcpy((char *)&info, (char *)msg->params, sizeof(struct dynamics_mn_iw_ch_info)); if (monitor_api_set_ch(info.ifname, info.channel)) api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0); else api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);}#endif /* WITH_WIRELESS */static void handle_api_rescan(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg){ int r = check_interfaces(mn.iface, MAX_INTERFACES); api_send_reply(s, addr, addrlen, r ? API_FAILED : API_SUCCESS, NULL, 0);}static void handle_register_dev_info_socket(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg){ char *path = (char *) msg->params; DEBUG(DEBUG_API, "API register device info socket[%s]\n", path); if (msg->length < 2) { DEBUG(DEBUG_API, "\ttoo short message\n"); api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0); return; } path[msg->length - 1] = '\0'; memset(&mn.dev_info_addr, 0, sizeof(mn.dev_info_addr)); mn.dev_info_addr.sun_family = AF_LOCAL; dynamics_strlcpy(mn.dev_info_addr.sun_path, path, msg->length); api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);}static int monitor_api_set_policy(char *name, int on){ struct policy_vars *t = monitor_policy; int i = 0, len; if (name == NULL || (on != 0 && on != 1)) return 1; DEBUG(DEBUG_API, "monitor_set_policy: '%s' %s \n", name, on == 0 ? "off" : "on"); len = strlen(t[i].name); len = strlen(name) < len ? strlen(name) : len; while (t[i].bit != -1 && strncasecmp(t[i].name, name, len) != 0) i++; if (t[i].bit == -1) { DEBUG(DEBUG_API, "monitor_set_policy: No policy matched!\n"); return 1; } if (on) POLICY_SET(t[i].bit); else POLICY_CLR(t[i].bit); return 0;}static int monitor_api_get_policy(char *buffer, int len){ int curr = 0, r, i; struct policy_vars *t = monitor_policy; for (i = 0, r = 0; t[i].bit != -1 && r == 0; i++) r = copy_str(buffer, len, &curr, t[i].name, POLICY(t[i].bit) ? "ON " : "OFF"); if (r) { DEBUG(DEBUG_API, "monitor_api_get_policy: insufficient " "space\n"); return API_INSUFFICIENT_SPACE; } DEBUG(DEBUG_API, buffer); return API_SUCCESS;}static void handle_policy(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg, int on){ int r = monitor_api_set_policy((char *)msg->params, on); api_send_reply(s, addr, addrlen, r, msg->params, msg->length);}static void handle_get_policy(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg){ int r = monitor_api_get_policy((char *)msg->params, msg->length); api_send_reply(s, addr, addrlen, r, msg->params, msg->length);}#ifdef WITH_WIRELESSstatic void handle_mon_conf(int s, dyn_api_sockaddr *addr, socklen_t addrlen, struct api_msg *msg, int type){ int r = monitor_api_mon_conf((char *)msg->params, msg->length, type); api_send_reply(s, addr, addrlen, r, msg->params, msg->length);}#endif /* WITH_WIRELESS *//* Handle API call from socket sock. If it is privileged, the admin * is nonzero. */void handle_api(int sock, int admin){ dyn_api_sockaddr addr; unsigned int addrlen; struct api_msg msg;#ifdef MN_LOCUPD_PROFILER char *name; char tmp[30]; struct in_addr faaddr;#endif DEBUG(DEBUG_API, "receive from api\n"); addrlen = sizeof(addr); memset(&addr, 0, addrlen); if (api_receive(sock, &addr, &addrlen, &msg) < 0) { LOG2(LOG_ERR, "api receive: %s\n", strerror(errno)); return; } if (msg.type != API_CALL_MSG) return;#ifdef MN_LOCUPD_PROFILER switch (msg.code) { case API_FORCE_FA: memcpy(&faaddr, msg.params, 4); snprintf(tmp, sizeof(tmp), "FORCE %s", inet_ntoa(faaddr)); name = tmp; break; case API_UPDATE_LOCATION: name = "UPDATE"; break; case API_UPDATE_LOCATION_BLOCK: name = "UPDATEB"; break; case API_DISCONNECT: name = "DISCONNECT"; break; case API_CONNECT: name = "CONNECT"; break; default: snprintf(tmp, sizeof(tmp), "%i", msg.code); name = tmp; break; } gettimeofday(&mn.last_api, NULL); fprintf(mn.profile, "API %s %u.%06u\n", name, (unsigned int) mn.last_api.tv_sec, (unsigned int) mn.last_api.tv_usec);#endif switch (msg.code) { case API_CONNECT: DEBUG(DEBUG_API, "api connect\n"); if (!admin) break; mn.ha_error_count = 0; if (mn.state == MN_DISCONNECTED) { /* allow quick locupd */ timerclear(&mn.last_reg_send_time); check_interfaces(mn.iface, MAX_INTERFACES); memcpy(&mn.tunnel_mode, msg.params, sizeof(mn.tunnel_mode)); DEBUG(DEBUG_API, "tunnel_mode=%i\n", mn.tunnel_mode); if (mn.tunnel_mode == API_TUNNEL_FULL_HA && mn.local_addr.s_addr == config.mn_home_ip_addr.s_addr) { struct in_addr iaddr; char device[IFNAMSIZ + 1]; if (dyn_ip_route_get(config.ha_ip_addr, device, IFNAMSIZ) == 0 && dyn_ip_get_ifaddr(device, &iaddr) == 0 && mn.local_addr.s_addr != iaddr.s_addr) { DEBUG(DEBUG_INFO, "Address changed to %s\n", inet_ntoa(iaddr)); mn.local_addr.s_addr = iaddr.s_addr; } } find_agent(STATE_INIT); memcpy(&api_addr, &addr, sizeof(addr)); api_addr_len = addrlen; /* this API call is replied with reply_waiting_api * after the status of the connection attempt is known */ } else { api_send_reply(sock, &addr, addrlen, API_NOT_PERMITTED, NULL, 0); } break; case API_UPDATE_LOCATION: DEBUG(DEBUG_API, "api update location\n"); if (!admin) break; check_interfaces(mn.iface, MAX_INTERFACES); handle_api_locupd(sock, &addr, addrlen, &msg, 0); break; case API_UPDATE_LOCATION_BLOCK: DEBUG(DEBUG_API, "api update location (block)\n"); if (!admin) break; check_interfaces(mn.iface, MAX_INTERFACES); handle_api_locupd(sock, &addr, addrlen, &msg, 1); memcpy(&api_addr, &addr, sizeof(addr)); api_addr_len = addrlen; /* this API call is replied with reply_waiting_api * after the status of the connection attempt is known */ break; case API_CANCEL: DEBUG(DEBUG_API, "Cancel received.\n"); if (!admin) break; api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0); break; case API_DISCONNECT: DEBUG(DEBUG_API, "api disconnect\n"); if (!admin) break; check_interfaces(mn.iface, MAX_INTERFACES); disconnect(); api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0); break; case API_GET_CAREOF_ADDR: api_send_reply(sock, &addr, addrlen, API_SUCCESS, (unsigned char *) &mn.co_addr, sizeof(mn.co_addr)); break; case API_GET_TUNNELING_MODE: api_send_reply(sock, &addr, addrlen, API_SUCCESS, (unsigned char *) &mn.tunnel_mode, sizeof(int)); break; case API_GET_STATUS: api_send_reply(sock, &addr, addrlen, API_SUCCESS, (unsigned char *) get_mobile_status(), sizeof(struct dynamics_mobile_status)); break; case API_CONFIRM: DEBUG(DEBUG_API, "api confirm\n"); if (!admin) break; if (mn.state != MN_CONNECTED && mn.state != MN_REQUEST_TUNNEL) { api_send_reply(sock, &addr, addrlen, API_NOT_PERMITTED, NULL, 0); break; } memcpy(&api_addr, &addr, sizeof(addr)); api_addr_len = addrlen; request_tunnel(STATE_INIT, 1, 0); break; case API_FORCE_FA: DEBUG(DEBUG_API, "api force fa\n"); if (!admin) break; handle_api_force_fa(sock, &addr, addrlen, &msg); break; case API_GET_FA_LIST: DEBUG(DEBUG_API, "api get fa list\n"); handle_api_get_fa_list(sock, &addr, addrlen, &msg); break; case API_GET_FA_INFO: DEBUG(DEBUG_API, "api get fa info\n"); handle_api_get_fa_info(sock, &addr, addrlen, &msg); break;#ifdef WITH_WIRELESS case API_IW_GET_CH: DEBUG(DEBUG_API, "api get wireless channel info\n"); handle_api_get_iw_ch(sock, &addr, addrlen, &msg); break; case API_IW_SET_CH: DEBUG(DEBUG_API, "api set wireless channel info\n"); if (!admin) break; handle_api_set_iw_ch(sock, &addr, addrlen, &msg); break;#endif case API_RESCAN: DEBUG(DEBUG_API, "api rescan interfaces\n"); handle_api_rescan(sock, &addr, addrlen, &msg); break; case API_REGISTER_DEV_INFO_SOCKET: DEBUG(DEBUG_API, "api register dev info socket\n"); if (!admin) break; handle_register_dev_info_socket(sock, &addr, addrlen, &msg); break; case API_POLICY_OFF: DEBUG(DEBUG_API, "api policy off\n"); if (!admin) break; handle_policy(sock, &addr, addrlen, &msg, 0); break; case API_POLICY_ON: DEBUG(DEBUG_API, "api policy on\n"); if (!admin) break; handle_policy(sock, &addr, addrlen, &msg, 1); break; case API_GET_POLICY: DEBUG(DEBUG_API, "api get policy\n"); handle_get_policy(sock, &addr, addrlen, &msg); break;#ifdef WITH_WIRELESS case API_GET_MON_CONF: DEBUG(DEBUG_API, "api get mon conf\n"); handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF); break; case API_GET_MON_CONF_VAR: DEBUG(DEBUG_API, "api get mon conf var\n"); handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF_VAR); break; case API_SET_MON_CONF_VAR: DEBUG(DEBUG_API, "api set mon conf\n"); if (!admin) break; handle_mon_conf(sock, &addr, addrlen, &msg, SET_MONCONF_VAR); break;#endif default: /* Just send a message indicating that the function is not * supported. No need to confirm that message gets through. */ DEBUG(DEBUG_API, "api call not supported\n"); api_send_reply(sock, &addr, addrlen, API_NOT_SUPPORTED, NULL, 0); break; }}/* * Reply to possibly waiting API call. * Parameters: * code - error code to return */void reply_waiting_api(int code, unsigned char *data, int datalen){#ifdef DYN_TARGET_LINUX if (api_addr_len > 0) {#endif#ifdef DYN_TARGET_WINDOWS if (api_addr.sin_port != 0) {#endif DEBUG(DEBUG_API, "Replying to waiting API call\n"); api_send_reply(mn.api_rw_socket, &api_addr, api_addr_len, code, data, datalen); memset(&api_addr, 0, sizeof(api_addr)); api_addr_len = 0; } else DEBUG(DEBUG_API, "reply_waiting_api: no waiting call\n");}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -