00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
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;
00038
00039
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
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
00076
00077
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
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
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
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
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
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
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
00317
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
00327 static void init_handler_lists(void)
00328 {
00329 DEBUG(DEBUG_HANDLERS, "init_handler_lists: begin\n");
00330 list_init(&fa_adv_rec_handlers);
00331 list_init(&fa_adv_exp_handlers);
00332 list_init(&fa_get_handlers);
00333 list_init(&interface_init_handlers);
00334 list_init(&interface_down_handlers);
00335 DEBUG(DEBUG_HANDLERS, "init_handler_lists: end\n");
00336 }
00337
00338
00339
00340 int handler_register(int event_type, int (*func)(void *data))
00341 {
00342 static int inited = 0;
00343 struct handler *new;
00344
00345
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
00391
00392
00393
00394
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
00439 return -1;
00440 }
00441
00442
00443
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
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
00543
00544 DEBUG(DEBUG_HANDLERS, "Register MN default FA_GET handler\n");
00545 handler_register(FA_GET, mn_default_FA_GET_handler);
00546
00547
00548 DEBUG(DEBUG_HANDLERS, "Register MN default INTERFACE_INIT handler\n");
00549 handler_register(INTERFACE_INIT, mn_default_INTERFACE_INIT_handler);
00550
00551
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