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 }