00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013 #include "config.h"
00014 #include <sys/socket.h>
00015 #include <netinet/in.h>
00016 #include <arpa/inet.h>
00017 #include <errno.h>
00018 #include <string.h>
00019 #include <unistd.h>
00020 #include <fcntl.h>
00021 #include <time.h>
00022
00023 #include "agentapi.h"
00024 #include "debug.h"
00025 #include "dyn_ip.h"
00026 #include "list.h"
00027 #include "util.h"
00028 #ifdef WITH_WIRELESS
00029 #include "monitor.h"
00030 #endif
00031 #include "mn.h"
00032
00033 extern struct mn_data mn;
00034 extern struct mn_config config;
00035 extern struct timeval timers[TIMER_COUNT];
00036
00037
00038 static struct policy_vars monitor_policy[] = {
00039 {EARLY_EXPIRE_STR, EARLY_EXPIRE_BIT},
00040 {NEWEST_FA_STR, NEWEST_FA_BIT},
00041 {EAGER_SWITCH_STR, EAGER_SWITCH_BIT},
00042 {NEWEST_ADV_STR, NEWEST_ADV_BIT},
00043 {"", -1}
00044 };
00045
00046 static dyn_api_sockaddr api_addr;
00047 static socklen_t api_addr_len = 0;
00048
00049
00050 char *state_strings[MN_STATE_COUNT] = {
00051 "Startup", "Disconnected", "Find Agent", "Passive Find",
00052 "Request Tunnel", "Connected",
00053 "Close For Home", "At Home", "Error", "Stop" };
00054
00055
00056
00057 static struct dynamics_mobile_status *
00058 get_mobile_status(void)
00059 {
00060 static struct dynamics_mobile_status status;
00061
00062 status.state = mn.state;
00063
00064 if (mn.state >= 0 && mn.state < MN_STATE_COUNT)
00065 dynamics_strlcpy(status.state_str, state_strings[mn.state],
00066 API_STATE_LEN);
00067 else
00068 memset(status.state_str, 0, sizeof(status.state_str));
00069 status.local_addr = mn.local_addr;
00070 status.co_addr = mn.co_addr;
00071 status.fa_addr = mn.fa_addr;
00072 status.ha_addr = config.ha_ip_addr;
00073 status.home_addr = config.mn_home_ip_addr;
00074 status.tunnel_up = mn.tunnel_up;
00075 status.tunnel_mode = mn.tunnel_mode;
00076 if (mn.tunnel_up) {
00077 status.lifetime = timers[TIMER_LIFETIME].tv_sec - time(NULL);
00078 } else {
00079 status.lifetime = 0;
00080 }
00081 status.last_reply_code = mn.last_reply_code;
00082 status.last_reply_rcvd = mn.last_reply_rcvd;
00083 status.last_request_sent = mn.last_request_sent;
00084 if (mn.info_str == NULL)
00085 memset(status.info_str, 0, API_INFO_LEN + 1);
00086 else
00087 dynamics_strlcpy(status.info_str, mn.info_str,
00088 API_INFO_LEN + 1);
00089 if (mn.warn_str == NULL)
00090 memset(status.warn_str, 0, API_INFO_LEN + 1);
00091 else
00092 dynamics_strlcpy(status.warn_str, mn.warn_str,
00093 API_INFO_LEN + 1);
00094 status.device_count = mn.device_count;
00095 status.discarded_msgs = mn.discarded_msgs;
00096
00097 return &status;
00098 }
00099
00100
00101
00102
00103
00104
00105
00106
00107
00108 static void handle_api_locupd(int s, dyn_api_sockaddr *addr, socklen_t addrlen,
00109 struct api_msg *msg, int block_api)
00110 {
00111 int ok, i;
00112 char device[IFNAMSIZ + 1];
00113 struct in_addr iaddr;
00114
00115
00116
00117
00118 ok = 1;
00119 if (msg->length == 4) {
00120 if (mn.local_addr.s_addr != (__u32) *msg->params) {
00121
00122 memcpy(&mn.local_addr, msg->params, 4);
00123 DEBUG(DEBUG_INFO, "Address changed to %s\n",
00124 inet_ntoa(mn.local_addr));
00125 }
00126 } else if (msg->length > 4 && msg->params[0] == 0 &&
00127 msg->params[1] == 0 && msg->params[2] == 0 &&
00128 msg->params[3] == 0) {
00129 if (msg->length > IFNAMSIZ)
00130 ok = 0;
00131 else {
00132 memcpy(device, msg->params + 4, msg->length - 4);
00133 device[msg->length - 4] = '\0';
00134 ok = 2;
00135 }
00136 } else if (msg->length == 0) {
00137
00138 for (i = 0; i < MAX_INTERFACES; i++) {
00139 if (mn.iface[i].s > -1) {
00140 memcpy(device, mn.iface[i].device, IFNAMSIZ);
00141 device[sizeof(device) - 1] = '\0';
00142 ok = 2;
00143 break;
00144 }
00145 }
00146 if (ok != 2) ok = 0;
00147 } else ok = 0;
00148
00149 if (ok == 2) {
00150 DEBUG(DEBUG_INFO, "\tinterface[%s]\n", device);
00151 if (dyn_ip_get_ifaddr(device, &iaddr) < 0)
00152 ok = 0;
00153 else if (mn.local_addr.s_addr != iaddr.s_addr) {
00154 DEBUG(DEBUG_INFO,
00155 "Address changed to %s (%s)\n",
00156 inet_ntoa(iaddr), device);
00157 mn.local_addr.s_addr = iaddr.s_addr;
00158 }
00159 }
00160
00161 if (!ok) {
00162 DEBUG(DEBUG_INFO, "API: locupd failed - illegal parameter\n");
00163 api_send_reply(s, addr, addrlen, API_ILLEGAL_PARAMETERS, NULL,
00164 0);
00165 return;
00166 }
00167
00168
00169 if (mn.local_addr.s_addr == config.mn_home_ip_addr.s_addr &&
00170 !config.enable_fa_decapsulation) {
00171 close_for_home(STATE_INIT);
00172 } else {
00173 switch (mn.state) {
00174 case MN_DISCONNECTED:
00175 break;
00176 default:
00177
00178 timerclear(&mn.last_reg_send_time);
00179 find_agent(STATE_INIT);
00180 break;
00181 }
00182 }
00183
00184 if (!block_api)
00185 api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);
00186 }
00187
00188
00189 static void handle_api_force_fa(int s, dyn_api_sockaddr *addr,
00190 socklen_t addrlen,
00191 struct api_msg *msg)
00192 {
00193
00194 if (msg->length != 4) {
00195 api_send_reply(s, addr, addrlen, API_ILLEGAL_PARAMETERS, NULL,
00196 0);
00197 return;
00198 }
00199
00200
00201 memcpy(&mn.force_fa_addr, msg->params, 4);
00202 DEBUG(DEBUG_INFO, "Force FA address set to %s\n",
00203 inet_ntoa(mn.force_fa_addr));
00204
00205 api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);
00206 }
00207
00208
00209 static int adv_iter(struct node *node, void *data)
00210 {
00211 struct agentadv_data *adv;
00212 struct api_msg *api_msg;
00213 struct dynamics_mobile_fa_list *list;
00214 int size, tmp;
00215 unsigned int flags;
00216
00217 adv = (struct agentadv_data *) node;
00218 api_msg = (struct api_msg *) data;
00219
00220 list = (struct dynamics_mobile_fa_list *)
00221 ((char *) api_msg->params + api_msg->length);
00222
00223 size = sizeof(struct dynamics_mobile_fa_list);
00224 if ((api_msg->length + size) > API_DATA_SIZE) {
00225 DEBUG(DEBUG_INFO, "adv_iter: Not enough room in msg "
00226 " (itemsize %d, length %d)\n",
00227 size, api_msg->length);
00228 return 0;
00229 }
00230 api_msg->length += size;
00231
00232
00233 UNALIGNED_(&list->addr, &adv->addr);
00234 MOVE_UNALIGNED(list->interface, adv->ifname, IFNAMSIZ);
00235 UNALIGNED_(&list->in_use, &adv->in_use);
00236
00237 if (mn.current_adv != NULL &&
00238 adv->addr.s_addr == mn.current_adv->addr.s_addr) {
00239 tmp = 1;
00240 } else {
00241 tmp = 0;
00242 }
00243 UNALIGNED_(&list->current_adv, &tmp);
00244 flags = 0;
00245 if (adv->adv.ext) {
00246 int opts = ntohs(adv->adv.ext->opts);
00247 if (opts & AGENT_ADV_FOREIGN_AGENT)
00248 flags |= API_MA_FLAGS_FA;
00249 if (opts & AGENT_ADV_HOME_AGENT)
00250 flags |= API_MA_FLAGS_HA;
00251 if (opts & AGENT_ADV_BUSY)
00252 flags |= API_MA_FLAGS_BUSY;
00253 }
00254 if (adv->adv.own_ext)
00255 flags |= API_MA_FLAGS_DYNAMICS;
00256 UNALIGNED_(&list->flags, &flags);
00257
00258 #ifdef WITH_WIRELESS
00259 if (adv->mon != NULL) {
00260 tmp = adv->mon->avg;
00261 } else {
00262 tmp = -1;
00263 }
00264 #else
00265 tmp = -1;
00266 #endif
00267 UNALIGNED_(&list->quality_avg, &tmp);
00268
00269
00270
00271
00272
00273 if (mn.state == MN_DISCONNECTED) {
00274 tmp = -2;
00275 UNALIGNED_(&list->priority, &tmp);
00276 } else
00277 UNALIGNED_(&list->priority, &adv->priority);
00278 UNALIGNED_(&list->last, &adv->last.tv_sec);
00279 UNALIGNED_(&list->reduce, &adv->prio_degrade_percent);
00280
00281 return 1;
00282 }
00283
00284
00285 static void handle_api_get_fa_list(int s, dyn_api_sockaddr *addr,
00286 socklen_t addrlen,
00287 struct api_msg *msg)
00288 {
00289 msg->length = 0;
00290 hashtable_iterator(mn.agentadv, adv_iter, msg);
00291 api_send_reply(s, addr, addrlen, API_SUCCESS,
00292 (unsigned char *) &msg->params, msg->length);
00293 }
00294
00295
00296 static void handle_api_get_fa_info(int s, dyn_api_sockaddr *addr,
00297 socklen_t addrlen,
00298 struct api_msg *msg)
00299 {
00300 struct dynamics_mobile_fa_info *info;
00301 struct agentadv_data *adv;
00302 struct in_addr fa_addr;
00303 int ifindex, tmp;
00304 char interface[IFNAMSIZ + 1];
00305 char nai[API_MAX_NAI_LEN + 1];
00306
00307
00308 if (msg->length != sizeof(struct dynamics_mobile_fa_info)) {
00309 api_send_reply(s, addr, addrlen, API_ILLEGAL_PARAMETERS, NULL,
00310 0);
00311 return;
00312 }
00313 info = (struct dynamics_mobile_fa_info *)&msg->params;
00314 MOVE_UNALIGNED(&fa_addr, &info->list.addr, sizeof(struct in_addr));
00315 DEBUG(DEBUG_API, "handle_api_get_fa_info: %s\n",
00316 inet_ntoa(fa_addr));
00317
00318 ifindex = 0;
00319 MOVE_UNALIGNED(interface, &info->list.interface, IFNAMSIZ);
00320 interface[IFNAMSIZ] = '\0';
00321 if (strlen(interface) > 0) {
00322 ifindex = dyn_ip_get_ifindex(interface);
00323 DEBUG(DEBUG_API, "handle_api_get_fa_info: interface \"%s\""
00324 " ifindex %d\n", interface, ifindex);
00325 }
00326 adv = adv_fetch(mn.agentadv, &fa_addr, ifindex);
00327 if (adv == NULL) {
00328 DEBUG(DEBUG_API, "handle_api_get_fa_info: %s not found\n",
00329 inet_ntoa(fa_addr));
00330 api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0);
00331 return;
00332 }
00333
00334 msg->length = sizeof(struct dynamics_mobile_fa_info);
00335 UNALIGNED_(&info->list.addr, &adv->addr);
00336 UNALIGNED_(&info->list.in_use, &adv->in_use);
00337 UNALIGNED_(&info->ifindex, &ifindex);
00338 #ifdef WITH_WIRELESS
00339 if (adv->mon != NULL)
00340 UNALIGNED_(&info->list.quality_avg, &adv->mon->avg);
00341 else {
00342 tmp = -1;
00343 UNALIGNED_(&info->list.quality_avg, &tmp);
00344 }
00345 #else
00346 tmp = -1;
00347 UNALIGNED_(&info->list.quality_avg, &tmp);
00348 #endif
00349 UNALIGNED_(&tmp, &info->list.quality_avg);
00350 DEBUG(DEBUG_INFO, "quality: %d\n", tmp);
00351 UNALIGNED_(&info->list.priority, &adv->priority);
00352 UNALIGNED_(&info->ifindex, &adv->ifindex);
00353 MOVE_UNALIGNED(info->list.interface, adv->ifname, sizeof(adv->ifname));
00354 UNALIGNED_(&info->list.last, &adv->last.tv_sec);
00355 UNALIGNED_(&info->expire, &adv->expire.tv_sec);
00356 UNALIGNED_(&info->arpentry, &adv->arpentry);
00357 nai[0] = '\0';
00358 if (adv->adv.fa_nai != NULL &&
00359 API_MAX_NAI_LEN >= GET_NAI_LEN(adv->adv.fa_nai)) {
00360 memcpy(nai, MSG_NAI_DATA(adv->adv.fa_nai), API_MAX_NAI_LEN);
00361 nai[GET_NAI_LEN(adv->adv.fa_nai)] = '\0';
00362 }
00363 DEBUG(DEBUG_INFO, "\tNAI[%s]\n", nai);
00364 MOVE_UNALIGNED(&info->nai, &nai, API_MAX_NAI_LEN + 1);
00365
00366 api_send_reply(s, addr, addrlen, API_SUCCESS,
00367 (unsigned char *) &msg->params, msg->length);
00368 }
00369
00370
00371 #ifdef WITH_WIRELESS
00372 static void handle_api_get_iw_ch(int s, dyn_api_sockaddr *addr,
00373 socklen_t addrlen,
00374 struct api_msg *msg)
00375 {
00376 int r;
00377 struct dynamics_mn_iw_ch_info *info;
00378
00379 msg->length = 0;
00380 r = monitor_api_get_ch((unsigned char *)msg->params, &msg->length);
00381
00382 info = (struct dynamics_mn_iw_ch_info *)msg->params;
00383 DEBUG(DEBUG_API, "handle_api_get_iw_ch: %s: %d "
00384 "(msg->length: %d(%d) num: %d)\n",
00385 info->ifname, info->channel,
00386 msg->length, sizeof(struct dynamics_mn_iw_ch_info),
00387 msg->length/sizeof(struct dynamics_mn_iw_ch_info));
00388
00389 if (r)
00390 api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0);
00391 else
00392 api_send_reply(s, addr, addrlen, API_SUCCESS,
00393 (unsigned char *) msg->params, msg->length);
00394 }
00395
00396
00397 static void handle_api_set_iw_ch(int s, dyn_api_sockaddr *addr,
00398 socklen_t addrlen,
00399 struct api_msg *msg)
00400 {
00401 struct dynamics_mn_iw_ch_info info;
00402
00403 memcpy((char *)&info, (char *)msg->params,
00404 sizeof(struct dynamics_mn_iw_ch_info));
00405
00406 if (monitor_api_set_ch(info.ifname, info.channel))
00407 api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0);
00408 else
00409 api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);
00410 }
00411 #endif
00412
00413 static void handle_api_rescan(int s, dyn_api_sockaddr *addr,
00414 socklen_t addrlen,
00415 struct api_msg *msg)
00416 {
00417 int r = check_interfaces(mn.iface, MAX_INTERFACES);
00418 api_send_reply(s, addr, addrlen, r ? API_FAILED : API_SUCCESS, NULL,
00419 0);
00420 }
00421
00422 static void handle_register_dev_info_socket(int s, dyn_api_sockaddr *addr,
00423 socklen_t addrlen,
00424 struct api_msg *msg)
00425 {
00426 char *path = (char *) msg->params;
00427
00428 DEBUG(DEBUG_API, "API register device info socket[%s]\n", path);
00429 if (msg->length < 2) {
00430 DEBUG(DEBUG_API, "\ttoo short message\n");
00431 api_send_reply(s, addr, addrlen, API_FAILED, NULL, 0);
00432 return;
00433 }
00434 path[msg->length - 1] = '\0';
00435 memset(&mn.dev_info_addr, 0, sizeof(mn.dev_info_addr));
00436 mn.dev_info_addr.sun_family = AF_LOCAL;
00437 dynamics_strlcpy(mn.dev_info_addr.sun_path, path, msg->length);
00438 api_send_reply(s, addr, addrlen, API_SUCCESS, NULL, 0);
00439 }
00440
00441
00442 static int monitor_api_set_policy(char *name, int on)
00443 {
00444 struct policy_vars *t = monitor_policy;
00445 int i = 0, len;
00446
00447 if (name == NULL || (on != 0 && on != 1))
00448 return 1;
00449
00450 DEBUG(DEBUG_API, "monitor_set_policy: '%s' %s \n",
00451 name, on == 0 ? "off" : "on");
00452
00453 len = strlen(t[i].name);
00454 len = strlen(name) < len ? strlen(name) : len;
00455 while (t[i].bit != -1 &&
00456 strncasecmp(t[i].name, name, len) != 0)
00457 i++;
00458
00459 if (t[i].bit == -1) {
00460 DEBUG(DEBUG_API, "monitor_set_policy: No policy matched!\n");
00461 return 1;
00462 }
00463
00464 if (on)
00465 POLICY_SET(t[i].bit);
00466 else
00467 POLICY_CLR(t[i].bit);
00468
00469 return 0;
00470 }
00471
00472
00473 static int monitor_api_get_policy(char *buffer, int len)
00474 {
00475 int curr = 0, r, i;
00476 struct policy_vars *t = monitor_policy;
00477
00478 for (i = 0, r = 0; t[i].bit != -1 && r == 0; i++)
00479 r = copy_str(buffer, len, &curr, t[i].name,
00480 POLICY(t[i].bit) ? "ON " : "OFF");
00481 if (r) {
00482 DEBUG(DEBUG_API, "monitor_api_get_policy: insufficient "
00483 "space\n");
00484 return API_INSUFFICIENT_SPACE;
00485 }
00486
00487 DEBUG(DEBUG_API, buffer);
00488 return API_SUCCESS;
00489 }
00490
00491
00492 static void handle_policy(int s, dyn_api_sockaddr *addr,
00493 socklen_t addrlen,
00494 struct api_msg *msg, int on)
00495 {
00496 int r = monitor_api_set_policy((char *)msg->params, on);
00497 api_send_reply(s, addr, addrlen, r, msg->params, msg->length);
00498 }
00499
00500 static void handle_get_policy(int s, dyn_api_sockaddr *addr,
00501 socklen_t addrlen,
00502 struct api_msg *msg)
00503 {
00504 int r = monitor_api_get_policy((char *)msg->params, msg->length);
00505 api_send_reply(s, addr, addrlen, r, msg->params, msg->length);
00506 }
00507
00508 #ifdef WITH_WIRELESS
00509
00510 static void handle_mon_conf(int s, dyn_api_sockaddr *addr,
00511 socklen_t addrlen,
00512 struct api_msg *msg, int type)
00513 {
00514 int r = monitor_api_mon_conf((char *)msg->params, msg->length, type);
00515 api_send_reply(s, addr, addrlen, r, msg->params, msg->length);
00516 }
00517
00518 #endif
00519
00520
00521
00522
00523 void handle_api(int sock, int admin)
00524 {
00525 dyn_api_sockaddr addr;
00526 unsigned int addrlen;
00527 struct api_msg msg;
00528 #ifdef MN_LOCUPD_PROFILER
00529 char *name;
00530 char tmp[30];
00531 struct in_addr faaddr;
00532 #endif
00533
00534 DEBUG(DEBUG_API, "receive from api\n");
00535 addrlen = sizeof(addr);
00536 memset(&addr, 0, addrlen);
00537 if (api_receive(sock, &addr, &addrlen, &msg) < 0) {
00538 LOG2(LOG_ERR, "api receive: %s\n", strerror(errno));
00539 return;
00540 }
00541 if (msg.type != API_CALL_MSG) return;
00542 #ifdef MN_LOCUPD_PROFILER
00543 switch (msg.code) {
00544 case API_FORCE_FA:
00545 memcpy(&faaddr, msg.params, 4);
00546 snprintf(tmp, sizeof(tmp), "FORCE %s", inet_ntoa(faaddr));
00547 name = tmp;
00548 break;
00549 case API_UPDATE_LOCATION: name = "UPDATE"; break;
00550 case API_UPDATE_LOCATION_BLOCK: name = "UPDATEB"; break;
00551 case API_DISCONNECT: name = "DISCONNECT"; break;
00552 case API_CONNECT: name = "CONNECT"; break;
00553 default:
00554 snprintf(tmp, sizeof(tmp), "%i", msg.code);
00555 name = tmp;
00556 break;
00557 }
00558 gettimeofday(&mn.last_api, NULL);
00559 fprintf(mn.profile, "API %s %u.%06u\n", name,
00560 (unsigned int) mn.last_api.tv_sec,
00561 (unsigned int) mn.last_api.tv_usec);
00562 #endif
00563 switch (msg.code) {
00564 case API_CONNECT:
00565 DEBUG(DEBUG_API, "api connect\n");
00566 if (!admin) break;
00567 mn.ha_error_count = 0;
00568 if (mn.state == MN_DISCONNECTED) {
00569
00570 timerclear(&mn.last_reg_send_time);
00571 check_interfaces(mn.iface, MAX_INTERFACES);
00572 memcpy(&mn.tunnel_mode, msg.params,
00573 sizeof(mn.tunnel_mode));
00574 DEBUG(DEBUG_API, "tunnel_mode=%i\n", mn.tunnel_mode);
00575 if (mn.tunnel_mode == API_TUNNEL_FULL_HA &&
00576 mn.local_addr.s_addr ==
00577 config.mn_home_ip_addr.s_addr) {
00578 struct in_addr iaddr;
00579 char device[IFNAMSIZ + 1];
00580 if (dyn_ip_route_get(config.ha_ip_addr, device,
00581 IFNAMSIZ) == 0 &&
00582 dyn_ip_get_ifaddr(device, &iaddr) == 0 &&
00583 mn.local_addr.s_addr != iaddr.s_addr) {
00584 DEBUG(DEBUG_INFO,
00585 "Address changed to %s\n",
00586 inet_ntoa(iaddr));
00587 mn.local_addr.s_addr = iaddr.s_addr;
00588 }
00589 }
00590 find_agent(STATE_INIT);
00591 memcpy(&api_addr, &addr, sizeof(addr));
00592 api_addr_len = addrlen;
00593
00594
00595
00596 } else {
00597 api_send_reply(sock, &addr, addrlen, API_NOT_PERMITTED,
00598 NULL, 0);
00599 }
00600 break;
00601 case API_UPDATE_LOCATION:
00602 DEBUG(DEBUG_API, "api update location\n");
00603 if (!admin) break;
00604 check_interfaces(mn.iface, MAX_INTERFACES);
00605 handle_api_locupd(sock, &addr, addrlen, &msg, 0);
00606 break;
00607 case API_UPDATE_LOCATION_BLOCK:
00608 DEBUG(DEBUG_API, "api update location (block)\n");
00609 if (!admin) break;
00610 check_interfaces(mn.iface, MAX_INTERFACES);
00611 handle_api_locupd(sock, &addr, addrlen, &msg, 1);
00612 memcpy(&api_addr, &addr, sizeof(addr));
00613 api_addr_len = addrlen;
00614
00615
00616 break;
00617 case API_CANCEL:
00618 DEBUG(DEBUG_API, "Cancel received.\n");
00619 if (!admin) break;
00620
00621 api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0);
00622 break;
00623 case API_DISCONNECT:
00624 DEBUG(DEBUG_API, "api disconnect\n");
00625 if (!admin) break;
00626 check_interfaces(mn.iface, MAX_INTERFACES);
00627 disconnect();
00628 api_send_reply(sock, &addr, addrlen, API_SUCCESS, NULL, 0);
00629 break;
00630 case API_GET_CAREOF_ADDR:
00631 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00632 (unsigned char *) &mn.co_addr,
00633 sizeof(mn.co_addr));
00634 break;
00635 case API_GET_TUNNELING_MODE:
00636 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00637 (unsigned char *) &mn.tunnel_mode, sizeof(int));
00638 break;
00639 case API_GET_STATUS:
00640 api_send_reply(sock, &addr, addrlen, API_SUCCESS,
00641 (unsigned char *) get_mobile_status(),
00642 sizeof(struct dynamics_mobile_status));
00643 break;
00644 case API_CONFIRM:
00645 DEBUG(DEBUG_API, "api confirm\n");
00646 if (!admin) break;
00647 if (mn.state != MN_CONNECTED &&
00648 mn.state != MN_REQUEST_TUNNEL) {
00649 api_send_reply(sock, &addr, addrlen,
00650 API_NOT_PERMITTED, NULL, 0);
00651 break;
00652
00653 }
00654 memcpy(&api_addr, &addr, sizeof(addr));
00655 api_addr_len = addrlen;
00656 request_tunnel(STATE_INIT, 1, 0);
00657 break;
00658 case API_FORCE_FA:
00659 DEBUG(DEBUG_API, "api force fa\n");
00660 if (!admin) break;
00661 handle_api_force_fa(sock, &addr, addrlen, &msg);
00662 break;
00663 case API_GET_FA_LIST:
00664 DEBUG(DEBUG_API, "api get fa list\n");
00665 handle_api_get_fa_list(sock, &addr, addrlen, &msg);
00666 break;
00667 case API_GET_FA_INFO:
00668 DEBUG(DEBUG_API, "api get fa info\n");
00669 handle_api_get_fa_info(sock, &addr, addrlen, &msg);
00670 break;
00671 #ifdef WITH_WIRELESS
00672 case API_IW_GET_CH:
00673 DEBUG(DEBUG_API, "api get wireless channel info\n");
00674 handle_api_get_iw_ch(sock, &addr, addrlen, &msg);
00675 break;
00676 case API_IW_SET_CH:
00677 DEBUG(DEBUG_API, "api set wireless channel info\n");
00678 if (!admin) break;
00679 handle_api_set_iw_ch(sock, &addr, addrlen, &msg);
00680 break;
00681 #endif
00682 case API_RESCAN:
00683 DEBUG(DEBUG_API, "api rescan interfaces\n");
00684 handle_api_rescan(sock, &addr, addrlen, &msg);
00685 break;
00686 case API_REGISTER_DEV_INFO_SOCKET:
00687 DEBUG(DEBUG_API, "api register dev info socket\n");
00688 if (!admin) break;
00689 handle_register_dev_info_socket(sock, &addr, addrlen, &msg);
00690 break;
00691 case API_POLICY_OFF:
00692 DEBUG(DEBUG_API, "api policy off\n");
00693 if (!admin) break;
00694 handle_policy(sock, &addr, addrlen, &msg, 0);
00695 break;
00696 case API_POLICY_ON:
00697 DEBUG(DEBUG_API, "api policy on\n");
00698 if (!admin) break;
00699 handle_policy(sock, &addr, addrlen, &msg, 1);
00700 break;
00701 case API_GET_POLICY:
00702 DEBUG(DEBUG_API, "api get policy\n");
00703 handle_get_policy(sock, &addr, addrlen, &msg);
00704 break;
00705 #ifdef WITH_WIRELESS
00706 case API_GET_MON_CONF:
00707 DEBUG(DEBUG_API, "api get mon conf\n");
00708 handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF);
00709 break;
00710 case API_GET_MON_CONF_VAR:
00711 DEBUG(DEBUG_API, "api get mon conf var\n");
00712 handle_mon_conf(sock, &addr, addrlen, &msg, GET_MONCONF_VAR);
00713 break;
00714 case API_SET_MON_CONF_VAR:
00715 DEBUG(DEBUG_API, "api set mon conf\n");
00716 if (!admin) break;
00717 handle_mon_conf(sock, &addr, addrlen, &msg, SET_MONCONF_VAR);
00718 break;
00719 #endif
00720 default:
00721
00722
00723 DEBUG(DEBUG_API, "api call not supported\n");
00724 api_send_reply(sock, &addr, addrlen, API_NOT_SUPPORTED, NULL,
00725 0);
00726 break;
00727 }
00728 }
00729
00730
00731
00732
00733
00734
00735
00736 void reply_waiting_api(int code, unsigned char *data, int datalen)
00737 {
00738 #ifdef DYN_TARGET_LINUX
00739 if (api_addr_len > 0) {
00740 #endif
00741 #ifdef DYN_TARGET_WINDOWS
00742 if (api_addr.sin_port != 0) {
00743 #endif
00744 DEBUG(DEBUG_API, "Replying to waiting API call\n");
00745 api_send_reply(mn.api_rw_socket, &api_addr, api_addr_len, code,
00746 data, datalen);
00747 memset(&api_addr, 0, sizeof(api_addr));
00748 api_addr_len = 0;
00749 } else DEBUG(DEBUG_API, "reply_waiting_api: no waiting call\n");
00750 }