mn_handler.c

Go to the documentation of this file.
00001 /* $id: mn_handler.c,v 1.5 1999/09/21 19:15:08 dforsber Exp $
00002  * Mobile Node handler module
00003  *
00004  * Dynamic hierarchial IP tunnel
00005  * Copyright (C) 1998-2001, Dynamics group
00006  *
00007  * This program is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License version 2 as
00009  * published by the Free Software Foundation. See README and COPYING for
00010  * more details.
00011  */
00012 
00013 #ifdef HAVE_CONFIG_H
00014 #include <config.h>
00015 #endif
00016 
00017 #include <stddef.h>
00018 #include <stdlib.h>
00019 #include <string.h>
00020 #include <unistd.h>
00021 #include <sys/socket.h>
00022 #include <netinet/in.h>
00023 #include <arpa/inet.h>
00024 #include <errno.h>
00025 #ifdef DYN_TARGET_LINUX
00026 #include <linux/if.h>
00027 #endif
00028 
00029 #include "mn_handler.h"
00030 #include "mn.h"
00031 #include "debug.h"
00032 #include "util.h"
00033 #include "device_info.h"
00034 #include "fixed_fd_zero.h"
00035 
00036 extern struct mn_data mn;
00037 extern int real_tunnel_up; /* from mn_tunnel */
00038 
00039 /* Event hooks. Handler lists */
00040 static struct list fa_adv_rec_handlers;
00041 static struct list fa_adv_exp_handlers;
00042 static struct list fa_get_handlers;
00043 static struct list interface_init_handlers;
00044 static struct list interface_down_handlers;
00045 
00046 /* MN default Handlers (called first) */
00047 static int mn_default_FA_GET_handler(void *data);
00048 static int mn_default_INTERFACE_INIT_handler(void *data);
00049 static int mn_default_INTERFACE_DOWN_handler(void *data);
00050 
00051 
00052 static int get_device_priority(char *ifname)
00053 {
00054         int i;
00055 
00056         if (ifname == NULL)
00057                 return -1;
00058 
00059         for (i = 0; i < MAX_INTERFACES; i++) {
00060                 if (mn.iface[i].s > -1 && 
00061                     strncmp(mn.iface[i].device, ifname, IFNAMSIZ) == 0) {
00062                         DEBUG(DEBUG_HANDLERS, "\tdevice %s", 
00063                               mn.iface[i].device);
00064                         return mn.iface[i].priority;
00065                 }
00066         }
00067 
00068         DEBUG(DEBUG_HANDLERS, "get_device_priority: Couldn't find interface "
00069               "from interface list (%s, device count %d)\n", ifname, 
00070               mn.device_count);
00071         return -1;
00072 }
00073 
00074 
00075 /* This function will honor the force FA address. If the force FA flag is
00076  * set only one advertisement entry has priority 1 and that's the force FA's
00077  * advertisement. */
00078 static int set_base_priority(struct node *node, void *data)
00079 {
00080         struct timeval tval = *((struct timeval *)data);
00081         struct agentadv_data *adv = (struct agentadv_data *) node;
00082         int prio, i;
00083 
00084         DEBUG(DEBUG_HANDLERS, "set_base_priority: %-15s ", 
00085               inet_ntoa(adv->addr));
00086 
00087         i = cmp_timeval(&tval, &adv->expire);
00088         if (i >= 0)
00089                 DEBUG(DEBUG_HANDLERS, " EXPIRED");
00090         if ((i < 0 || mn.force_fa_addr.s_addr != 0) && adv_ok_fa(adv)) {
00091                 if (mn.force_fa_addr.s_addr != 0)
00092                         DEBUG(DEBUG_HANDLERS, " FORCED FA");
00093                 prio = get_device_priority(adv->ifname);
00094                 if (prio > 0)
00095                         adv->priority = prio;
00096                 DEBUG(DEBUG_HANDLERS, " prio: %d", adv->priority);
00097         } else
00098                 adv->priority = 0;
00099 
00100         DEBUG(DEBUG_HANDLERS, "\n");
00101         return TRUE;
00102 }
00103 
00104 
00105 static int mn_default_FA_GET_handler(void *data)
00106 {
00107         struct timeval tval;
00108         struct hashtable *hash;
00109 
00110         if (data == NULL)
00111                 return -1;
00112 
00113         hash = ((struct event_FA *)data)->hash;
00114 
00115         if (hash == NULL) {
00116                 DEBUG(DEBUG_HANDLERS, "mn_default_FA_GET_handler: hashtable "
00117                       "pointer was NULL\n");
00118                 return 0;
00119         }
00120 
00121         gettimeofday(&tval, NULL);
00122         hashtable_iterator(hash, set_base_priority, &tval);
00123 
00124         return 0;
00125 }
00126 
00127 
00128 static int open_query_socket(void)
00129 {
00130         int sock, r;
00131         struct sockaddr_un addr;
00132         socklen_t addrlen;
00133         
00134         sock = socket(AF_LOCAL, SOCK_DGRAM, 0);
00135         if (sock < 0)
00136                 return sock;
00137         
00138         memset(&addr, 0, sizeof(struct sockaddr_un));
00139         addr.sun_family = AF_LOCAL;
00140         addr.sun_path[0] = '\0';
00141         snprintf(addr.sun_path + 1, sizeof(addr.sun_path) - 1,
00142                  "dynamics-%i-%i", getpid(), (int) random());
00143         addrlen = sizeof(addr.sun_family) + 1 + strlen(addr.sun_path + 1);
00144         
00145         r = bind(sock, (struct sockaddr *) &addr, addrlen);
00146         if (r < 0) {
00147                 DEBUG(DEBUG_INFO, "open_query_socket: bind failed: %s\n",
00148                       strerror(errno));
00149                 return -1;
00150         }
00151 
00152         return sock;
00153 }
00154 
00155 
00156 static int mn_get_device_priority(int index)
00157 {
00158         struct device_info_query msg;
00159         int s;
00160         fd_set set;
00161         int n;
00162         struct timeval tv;
00163 
00164         msg.device_index = index;
00165         msg.priority = -1;
00166 
00167         /* open socket */
00168         s = open_query_socket();
00169         if (s < 0) {
00170                 DEBUG(DEBUG_HANDLERS, "mn_get_device_priority: socket: %s",
00171                       strerror(errno));
00172                 return s;
00173         }
00174 
00175         /* send query */
00176         n = sendto(s, &msg, sizeof(struct device_info_query), 0, 
00177                    (struct sockaddr *)&mn.dev_info_addr, 
00178                    sizeof(mn.dev_info_addr));
00179         if (n != sizeof(struct device_info_query)) {
00180                 DEBUG(DEBUG_HANDLERS, "\tmn_get_device_priority: sendto "
00181                       "%d/%d bytes: %s\n", n, 
00182                       sizeof(struct device_info_query), strerror(errno));
00183                 close(s);
00184                 return -1;
00185         }
00186 
00187         /* get reply */
00188         FD_ZERO(&set);
00189         FD_SET(s, &set);
00190         tv.tv_usec = MICRO_SECONDS_TO_WAIT_INFO_REPLY;
00191         tv.tv_sec = 0;
00192         n = select(FD_SETSIZE, &set, NULL, NULL, &tv);
00193         if (n != 1 || !FD_ISSET(s, &set)) {
00194                 DEBUG(DEBUG_HANDLERS, "mn_get_device_priority: no device "
00195                       "info daemon present?\n");
00196                 close(s);
00197                 return -1;
00198         }
00199 
00200         n = recvfrom(s, (void *) &msg, sizeof(msg), 0, NULL, 0);
00201         if (n != sizeof(msg)) {
00202                 DEBUG(DEBUG_HANDLERS, "mn_get_device_priority: couldn't "
00203                       "receive the whole message %d/%d\n", 
00204                         n, sizeof(msg));
00205                 close(s);
00206                 return -1;
00207         }
00208         DEBUG(DEBUG_HANDLERS, "mn_get_device_priority: received reply. "
00209               "priority = %d\n", msg.priority);
00210 
00211         close(s);
00212         return msg.priority;
00213 }
00214 
00215 
00216 static int mn_default_INTERFACE_INIT_handler(void *data)
00217 {
00218         struct event_INTERFACE *i = (struct event_INTERFACE *)data;
00219         int prio;
00220         
00221         if (!i)
00222                 return -1;
00223         
00224         DEBUG(DEBUG_HANDLERS, "mn_default_INTERFACE_INIT_handler\n");
00225         DEBUG(DEBUG_HANDLERS, "\tOpening ICMP socket for interface "
00226               "%s (index=%i).\n", i->idx->name, i->idx->index);
00227         *(i->icmp_sock_adv) = open_agent_icmp_adv_socket(i->idx->name,
00228                                                          AGENTADV_FILTER_ADV);
00229         if (*(i->icmp_sock_adv) < 0) {
00230                 DEBUG(DEBUG_HANDLERS,
00231                       "\tOpening ICMP adv. socket failed: %s. "
00232                       "Ignoring this interface.\n",
00233                       strerror(errno));
00234                 return -1;
00235         }
00236         *(i->icmp_sock) = open_agent_icmp_socket(i->idx->name, ICMP_FILTER_MN);
00237         if (*(i->icmp_sock) < 0) {
00238                 DEBUG(DEBUG_HANDLERS, "\tOpening ICMP socket failed: %s."
00239                       " Ignoring this interface.\n",
00240                       strerror(errno));
00241                 close(*(i->icmp_sock_adv));
00242                 *(i->icmp_sock_adv) = -1;
00243                 return -1;
00244         }
00245         DEBUG(DEBUG_HANDLERS, "sockets: sol=%i adv=%i\n",
00246               *i->icmp_sock, *i->icmp_sock_adv);
00247         
00248         *(i->index) = i->idx->index;
00249         DEBUG(DEBUG_HANDLERS, "\tindex = %d\n", i->idx->index);
00250         memcpy(i->ifname, i->idx->name, IFNAMSIZ);
00251 
00252         /* set priority for the device */
00253         if (i->priority == NULL) {
00254                 DEBUG(DEBUG_HANDLERS, "\tpriority pointers is NULL!\n");
00255                 return -1;
00256         }
00257         *(i->priority) = DEFAULT_INTERFACE_PRIORITY;
00258         prio = mn_get_device_priority(i->idx->index);
00259         if (prio > 0) {
00260                 DEBUG(DEBUG_HANDLERS, "\tGot priority from interface info "
00261                       "daemon: %d\n", prio);
00262                 *(i->priority) = prio;
00263         }
00264         DEBUG(DEBUG_HANDLERS, "\tinterface priority = %d\n", *(i->priority));
00265 
00266         /* send agent solicitation */
00267         send_agent_solicitation(*(i->icmp_sock));
00268         if (i->iface != NULL)
00269                 gettimeofday(&i->iface->last_solicitation, NULL);
00270 
00271         return 0;
00272 }
00273 
00274 
00275 static int remove_agentadv_data(struct node *node, void *data)
00276 {
00277         struct agentadv_data *adv;
00278         int *ifindex;
00279 
00280         adv = (struct agentadv_data *) node;
00281         ifindex = (int*) data;
00282         if (*ifindex == adv->ifindex) {
00283                 DEBUG(DEBUG_AGENTADV, "\tremoving agentadv item: %s (%s)\n",
00284                       inet_ntoa(adv->addr), adv->ifname);
00285                 clean_agentadv(node, NULL);
00286         }
00287         
00288         return TRUE;
00289 }
00290 
00291 
00292 static int mn_default_INTERFACE_DOWN_handler(void *data)
00293 {
00294         struct event_INTERFACE *i = (struct event_INTERFACE *)data;
00295 
00296         if(!i)
00297                 return -1;
00298 
00299         /* close sockets */
00300         DEBUG(DEBUG_HANDLERS,
00301               "Closing ICMP socket for interface %s (index=%d)\n",
00302               i->ifname, *(i->index));
00303         close(*(i->icmp_sock));
00304         *(i->icmp_sock) = -1;
00305         if (*(i->icmp_sock_adv) > -1)
00306                 close(*(i->icmp_sock_adv));
00307         *(i->icmp_sock_adv) = -1;
00308 
00309         if (mn.current_adv != NULL && *(i->index) == mn.current_adv->ifindex) {
00310                 DEBUG(DEBUG_HANDLERS, "Current interface down - resetting "
00311                       "connections\n");
00312                 mn.tunnel_addr.s_addr = 0;
00313                 real_tunnel_up = 0;
00314         }
00315 
00316         /* clear saved agent advertisement entries that came from 
00317            this interface */
00318         DEBUG(DEBUG_AGENTADV, "Clearing agentadv cache for interface: %s "
00319               "(index=%i)\n", i->ifname, *(i->index));
00320         hashtable_iterator(mn.agentadv, remove_agentadv_data, i->index);
00321 
00322         return 0;
00323 }
00324 
00325 
00326 /* Initialize all handler lists. Called once, when first handler is added. */
00327 static void init_handler_lists(void)
00328 {
00329         DEBUG(DEBUG_HANDLERS, "init_handler_lists: begin\n");
00330         list_init(&fa_adv_rec_handlers);     /* FA_ADV_EXPIRE  */
00331         list_init(&fa_adv_exp_handlers);     /* FA_ADV_RECEIVE */
00332         list_init(&fa_get_handlers);         /* FA_GET         */
00333         list_init(&interface_init_handlers); /* INTERFACE_INIT */
00334         list_init(&interface_down_handlers); /* INTERFACE_DOWN */
00335         DEBUG(DEBUG_HANDLERS, "init_handler_lists: end\n");
00336 }
00337 
00338 
00339 /* Register handler to the <event_type> list */
00340 int handler_register(int event_type, int (*func)(void *data))
00341 {
00342         static int inited = 0;
00343         struct handler *new;
00344 
00345         /* Init all lists for now */
00346         if (!inited) {
00347                 init_handler_lists();
00348                 inited = 1;
00349         }
00350 
00351         new = calloc(1, sizeof(struct handler));
00352         if (new == NULL) {
00353                 DEBUG(DEBUG_HANDLERS, "handler_register: calloc: %s",
00354                       strerror(errno));
00355                 return 1;
00356         }
00357 
00358         list_init_node(&new->listnode);
00359         new->func = func;
00360 
00361         switch (event_type) {
00362         case FA_ADV_RECEIVE:
00363                 list_add_tail(&fa_adv_rec_handlers, &new->listnode);
00364                 break;
00365         case FA_ADV_EXPIRE:
00366                 list_add_tail(&fa_adv_exp_handlers, &new->listnode);
00367                 break;
00368         case FA_GET:
00369                 list_add_tail(&fa_get_handlers, &new->listnode);
00370                 break;
00371         case INTERFACE_INIT:
00372                 list_add_tail(&interface_init_handlers, &new->listnode);
00373                 break;
00374         case INTERFACE_DOWN:
00375                 list_add_tail(&interface_down_handlers, &new->listnode);
00376                 break;
00377         default:
00378                 DEBUG(DEBUG_HANDLERS, "handler_register: Unknown event "
00379                       "type (%d)\n", event_type);
00380                 return 2;
00381         }
00382 
00383         DEBUG(DEBUG_HANDLERS, "handler_register: \"%s\" Event handler "
00384               "registered\n", event_type_str(event_type));
00385 
00386         return 0;
00387 }
00388 
00389 
00390 /* Unregister handler from the <event_type> list
00391  * return:
00392  *  0 success
00393  *  -1 list is empty or no such handler
00394  *  -2 no such event type
00395  */
00396 int handler_unregister(int event_type, int (*func)(void *data))
00397 {
00398         struct list *handlers;
00399         struct node *iterator;
00400         struct handler *p;
00401 
00402         switch (event_type) {
00403         case FA_ADV_RECEIVE:
00404                 handlers = &fa_adv_rec_handlers;
00405                 break;
00406         case FA_ADV_EXPIRE:
00407                 handlers = &fa_adv_exp_handlers;
00408                 break;
00409         case FA_GET:
00410                 handlers = &fa_get_handlers;
00411                 break;
00412         case INTERFACE_INIT:
00413                 handlers = &interface_init_handlers;
00414                 break;
00415         case INTERFACE_DOWN:
00416                 handlers = &interface_down_handlers;
00417                 break;
00418         default:
00419                 DEBUG(DEBUG_HANDLERS, "handler_unregister: Unknown event type "
00420                       "(%d)\n", event_type);
00421                 return -2;
00422         }
00423 
00424         iterator = list_get_first(handlers);
00425         while (iterator != NULL) {
00426                 p = (struct handler *) iterator;
00427                 if (p->func == func) {
00428                         list_remove(iterator);
00429                         DEBUG(DEBUG_HANDLERS, "handler_unregister: "
00430                               "\"%s\" Event handler unregistered\n",
00431                               event_type_str(event_type));
00432                         free(p);
00433                         return 0;
00434                 }
00435                 iterator = list_get_next(iterator);
00436         }
00437 
00438         /* List is empty or no such handler found */
00439         return -1;
00440 }
00441 
00442 
00443 /* Remove all hooked handlers for this <event_type> */
00444 int handler_unregister_all(int event_type)
00445 {
00446         struct node *iterator;
00447         struct list *handlers;
00448         struct handler *p;
00449         int i = 0, r;
00450 
00451         switch (event_type) {
00452         case FA_ADV_RECEIVE:
00453                 handlers = &fa_adv_rec_handlers;
00454                 break;
00455         case FA_ADV_EXPIRE:
00456                 handlers = &fa_adv_exp_handlers;
00457                 break;
00458         case FA_GET:
00459                 handlers = &fa_get_handlers;
00460                 break;
00461         case INTERFACE_INIT:
00462                 handlers = &interface_init_handlers;
00463                 break;
00464         case INTERFACE_DOWN:
00465                 handlers = &interface_down_handlers;
00466                 break;
00467         default:
00468                 DEBUG(DEBUG_HANDLERS, "handler_unregister_all: Unknown event "
00469                       "type (%d)\n", event_type);
00470                 return -2;
00471         }
00472 
00473         iterator = list_get_first(handlers);
00474         while (iterator != NULL) {
00475                 p = (struct handler *) iterator;
00476                 iterator = list_get_next(iterator);
00477                 r = handler_unregister(event_type, p->func);
00478                 if (!r)
00479                         i++;
00480         }
00481 
00482         return i;
00483 }
00484 
00485 
00486 /* Call all hooked handlers for this <event_type> */
00487 int handler_call_all(int event_type, void *data)
00488 {
00489         struct list *handlers;
00490         struct node *iterator;
00491         struct handler *p;
00492         int num = 0;
00493         int ret = 0;
00494 
00495         switch (event_type) {
00496         case FA_ADV_RECEIVE:
00497                 handlers = &fa_adv_rec_handlers;
00498                 break;
00499         case FA_ADV_EXPIRE:
00500                 handlers = &fa_adv_exp_handlers;
00501                 break;
00502         case FA_GET:
00503                 handlers = &fa_get_handlers;
00504                 break;
00505         case INTERFACE_INIT:
00506                 handlers = &interface_init_handlers;
00507                 break;
00508         case INTERFACE_DOWN:
00509                 handlers = &interface_down_handlers;
00510                 break;
00511         default:
00512                 DEBUG(DEBUG_HANDLERS, "handler_call_all: Unknown event "
00513                       "type (%d)", event_type);
00514                 return 2;
00515         }
00516 
00517         iterator = list_get_first(handlers);
00518         while (iterator != NULL) {
00519                 p = (struct handler *) iterator;
00520                 if (p->func != NULL) {
00521                         ret = (*p->func)(data);
00522                         num++;
00523                         if (ret == -1) {
00524                                 DEBUG(DEBUG_HANDLERS, "handler_call_all: "
00525                                       "handler returned -1. %d handlers "
00526                                       "called\n", num);
00527                                 return -1;
00528                         }
00529                 }
00530                 iterator = list_get_next(iterator);
00531         }
00532 
00533         DEBUG(DEBUG_HANDLERS, "handler_call_all: %d \"%s\" Event "
00534               "handlers called\n", num, event_type_str(event_type));
00535 
00536         return 0;
00537 }
00538 
00539 
00540 int mn_handlers_init(void)
00541 {
00542         /* Register the MN default handler for FA selection (for now
00543          * must be the first one in the handler list) */
00544         DEBUG(DEBUG_HANDLERS, "Register MN default FA_GET handler\n");
00545         handler_register(FA_GET, mn_default_FA_GET_handler);
00546         
00547         /* Register the MN default handler for interface initialization */
00548         DEBUG(DEBUG_HANDLERS, "Register MN default INTERFACE_INIT handler\n");
00549         handler_register(INTERFACE_INIT, mn_default_INTERFACE_INIT_handler);
00550         
00551         /* Register the MN default handler for interface down event */
00552         DEBUG(DEBUG_HANDLERS, "Register MN default INTERFACE_DOWN handler\n");
00553         handler_register(INTERFACE_DOWN, mn_default_INTERFACE_DOWN_handler);
00554         
00555         return 0;
00556 }
00557 

Generated on Tue Jan 15 08:50:43 2008 for Virtual foreign agent generator version 0.1 by  doxygen 1.5.1