mn_config.c

Go to the documentation of this file.
00001 /* $Id: mn_config.c,v 1.42 2001/09/01 14:52:18 jm Exp $
00002  * Mobile Node configuration file handling
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 <stdlib.h>
00018 #include <stdio.h>
00019 #include <string.h>
00020 #include <assert.h>
00021 
00022 #include "fileio.h"
00023 #include "debug.h"
00024 #include "auth.h"
00025 #include "mn.h"
00026 
00027 #define DEBUG_FLAG 'M'
00028 
00029 struct load_mn_data {
00030         struct mn_config *cfg;
00031         int process_fa_spi_list;
00032         int process_ignore_iflist;
00033         int process_dev_prio_list;
00034 };
00035 
00036 static int check_config_data(struct mn_config *cfg) {
00037         int ret = TRUE;
00038 
00039         if (!auth_supported_auth_alg(cfg->auth_alg)) {
00040                 fprintf(stderr, "Unsupported authentication algorithm %i\n",
00041                         cfg->auth_alg);
00042                 ret = FALSE;
00043         }
00044 
00045         if (cfg->replay_meth < 0 || cfg->replay_meth > 2) {
00046                 fprintf(stderr, "Unsupported authentication algorithm %i\n",
00047                         cfg->auth_alg);
00048                 ret = FALSE;
00049         }
00050 
00051         if (cfg->tunneling_mode != TUNMODE_AUTO_REVERSE &&
00052             cfg->tunneling_mode != TUNMODE_AUTO_TRIANGLE &&
00053             cfg->tunneling_mode != TUNMODE_REVERSE &&
00054             cfg->tunneling_mode != TUNMODE_TRIANGLE) {
00055                 fprintf(stderr, "Unknown TunnelingMode: %i\n",
00056                         cfg->tunneling_mode);
00057                 ret = FALSE;
00058         }
00059 
00060         if (cfg->mndecaps_route_handling != MNDECAPS_ROUTE_DEFAULT &&
00061             cfg->mndecaps_route_handling != MNDECAPS_ROUTE_HOME_NET &&
00062             cfg->mndecaps_route_handling != MNDECAPS_ROUTE_NONE) {
00063                 fprintf(stderr, "Unknown MNDecapsRouteHandling: %i\n",
00064                         cfg->mndecaps_route_handling);
00065                 ret = FALSE;
00066         }
00067 
00068         if (cfg->mndecaps_route_handling == MNDECAPS_ROUTE_HOME_NET &&
00069             cfg->home_net_addr_plen == -1) {
00070                 fprintf(stderr, "MNDecapsRouteHandling: home net, but home net"
00071                         " address not properly configured.\n");
00072                 ret = FALSE;
00073         }
00074 
00075         return ret;
00076 }
00077 
00078 static int process_load_ignore_iflist(struct load_mn_data *mn, char *key,
00079                                       char *data)
00080 {
00081         struct mn_config *cfg;
00082         struct ignore_iflist_entry *ifs;
00083         int len;
00084 
00085         if (strcmp(key, "IGNORE_INTERFACES_END") == 0) {
00086                 ASSERT(mn->process_ignore_iflist == TRUE);
00087                 mn->process_ignore_iflist = FALSE;
00088                 return 0;
00089         }
00090         cfg = mn->cfg;
00091         ifs = malloc(sizeof(struct ignore_iflist_entry));
00092         if (ifs == NULL) {
00093                 fprintf(stderr,
00094                         "process_load_ignore_iflist: not enough memory for "
00095                         "struct ignore_iflist_entry");
00096                 return -1;
00097         }
00098         
00099         list_init_node(&ifs->node);
00100         len = strlen(key);
00101 
00102         if (len > IFNAMSIZ - 1) {
00103                 fprintf(stderr, 
00104                         "process_load_ignore_iflist: name too long (%d/%d)\n",
00105                         len, IFNAMSIZ);
00106                 free(ifs);
00107                 return -1;
00108         }
00109         if (sscanf(key, "%s", ifs->ifname) != 1) {
00110                 fprintf(stderr, 
00111                         "process_load_ignore_iflist: couldn't read interface "
00112                         "name\n");
00113                 free(ifs);
00114                 return -1;
00115         }
00116 
00117         ASSERT(ifs->ifname != NULL);
00118         list_add_tail(&cfg->ignore_iflist, &ifs->node);
00119         
00120         return 0;
00121 }
00122 
00123 static int process_load_fa_spi_list(struct load_mn_data *mn, char *key,
00124                                     char *data)
00125 {
00126         struct mn_config *cfg;
00127         struct fa_spi_entry *spi;
00128         char *pos;
00129         int res;
00130 
00131         if (strcmp(key, "FA_SECURITY_END") == 0) {
00132                 ASSERT(mn->process_fa_spi_list == TRUE);
00133                 mn->process_fa_spi_list = FALSE;
00134                 return 0;
00135         }
00136         cfg = mn->cfg;
00137         spi = malloc(sizeof(struct fa_spi_entry));
00138         if (spi == NULL) {
00139                 fprintf(stderr,
00140                         "process_load_fa_spi_list: not enough memory for "
00141                         "struct spi_entry\n");
00142                 return -1;
00143         }
00144         memset(spi, 0, sizeof(struct fa_spi_entry));
00145 
00146         list_init_node(&spi->node);
00147 
00148         if (key[0] == '0' && key[1] == 'x')
00149                 res = sscanf(key, "%x", &spi->spi);
00150         else
00151                 res = sscanf(key, "%d", &spi->spi);
00152 
00153         if (res != 1) {
00154                 fprintf(stderr,
00155                         "process_load_fa_spi_list: invalid SPI number\n");
00156                 free(spi);
00157                 return -1;
00158         }
00159 
00160         pos = data;
00161 
00162         while (*pos == ' ' || *pos == '\t') pos++;
00163         if (load_ip_address(pos, &spi->addr) != TRUE) {
00164                 fprintf(stderr,
00165                         "process_load_fa_authorized_list: invalid "
00166                         "IP address\n");
00167                 free(spi);
00168                 return -1;
00169         }
00170 
00171         while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00172         while (*pos == ' ' || *pos == '\t') pos++;
00173         if (*pos == '\0' || sscanf(pos, "%d", &spi->alg) != 1) {
00174                 fprintf(stderr,
00175                         "process_load_fa_spi_list: invalid algorithm "
00176                         "number\n");
00177                 free(spi);
00178                 return -1;
00179         }
00180 
00181         if (!auth_supported_auth_alg(spi->alg)) {
00182                 fprintf(stderr, "process_load_fa_spi_list: unsupported "
00183                         "algorithm %i\n", spi->alg);
00184                 free(spi);
00185                 return -1;
00186         }
00187 
00188         while (*pos != ' ' && *pos != '\t' && *pos != '\0') pos++;
00189         while (*pos == ' ' || *pos == '\t') pos++;
00190         if (*pos == '\0' || load_hex_table(pos, spi->shared_secret,
00191                                            MAXSHAREDSECRETLEN,
00192                                            &spi->shared_secret_len) == FALSE) {
00193                 fprintf(stderr,
00194                         "process_load_fa_spi_list: invalid shared secret\n");
00195                 free(spi);
00196                 return -1;
00197         }
00198 
00199         spi->created = 0; /* static security association */
00200 
00201         ASSERT(spi->shared_secret_len >= 0);
00202         ASSERT(spi->shared_secret_len <= MAXSHAREDSECRETLEN);
00203         list_add_tail(&cfg->fa_spi_list, &spi->node);
00204 
00205         return 0;
00206 }
00207 
00208 
00209 /* Process loading of the mn_data
00210  * Return values: -2: consistency error, -1: error, 0: ok, 1: end */
00211 static int process_load_mn(void *voidptr, char *key, char *data)
00212 {
00213         struct load_mn_data *mn;
00214         struct mn_config *cfg;
00215 
00216         mn = voidptr;
00217         cfg = mn->cfg;
00218 
00219         if (mn->process_fa_spi_list == TRUE) {
00220                 return process_load_fa_spi_list(mn, key, data);
00221         }
00222         if (mn->process_ignore_iflist == TRUE) {
00223                 return process_load_ignore_iflist(mn, key, data);
00224         }
00225         if (strcmp(key, "FA_SECURITY_BEGIN") == 0) {
00226                 if (mn->process_fa_spi_list) {
00227                         fprintf(stderr, "List processing error while handling "
00228                                 "FA_SECURITY_BEGIN\n");
00229                         return -1;
00230                 }
00231                 mn->process_fa_spi_list = TRUE;
00232                 return 0;
00233         }
00234         if (strcmp(key, "IGNORE_INTERFACES_BEGIN") == 0) {
00235                 if (mn->process_ignore_iflist) {
00236                         fprintf(stderr, "List processing error while handling "
00237                                 "IGNORE_INTERFACES_BEGIN\n");
00238                         return -1;
00239                 }
00240                 mn->process_ignore_iflist = TRUE;
00241                 return 0;
00242         }
00243         if (strcmp(key, "MNHomeIPAddress") == 0) {
00244                 if (load_ip_address(data, &cfg->mn_home_ip_addr) == TRUE)
00245                         return 0;
00246                 return -1;
00247         }
00248         if (strcmp(key, "HAIPAddress") == 0) {
00249                 if (load_ip_address(data, &cfg->ha_ip_addr) == TRUE) return 0;
00250                 return -1;
00251         }
00252         if (strcmp(key, "AlternativeHAIPAddress") == 0) {
00253                 struct in_addr tmpaddr;
00254                 if (load_ip_address(data, &tmpaddr) == TRUE) {
00255                         struct alt_ha_entry *alt;
00256                         alt = (struct alt_ha_entry *) malloc(sizeof(*alt));
00257                         if (alt == NULL)
00258                                 return -1;
00259                         list_init_node(&alt->node);
00260                         alt->addr.s_addr = tmpaddr.s_addr;
00261                         list_add_tail(&cfg->alt_ha_ip_addrs, &alt->node);
00262                         return 0;
00263                 }
00264                 return -1;
00265         }
00266         if (strcmp(key, "AllowHomeAddrFromForeignNet") == 0) {
00267                 if (load_bool(data, &cfg->allow_home_addr_from_foreign_net) ==
00268                     TRUE)
00269                         return 0;
00270                 return -1;
00271         }
00272         /* obsolete, remove sometime */
00273         if (strcmp(key, "HomeNetAddr") == 0) {
00274                 fprintf(stderr, "Please use HomeNetPrefix instead of "
00275                         "HomeNetAddr/HomeNetAddrPrefixLen\n");
00276                 if (load_ip_address(data, &cfg->home_net_addr) == TRUE)
00277                         return 0;
00278                 return -1;
00279         }
00280         /* obsolete, remove sometime */
00281         if (strcmp(key, "HomeNetAddrPrefixLen") == 0) {
00282                 if (load_int(data, &cfg->home_net_addr_plen) == TRUE) return 0;
00283                 return -1;
00284         }
00285         /* makes HomeNetAddr/HomeNetAddrPrefixLen obsolete */
00286         if (strcmp(key, "HomeNetPrefix") == 0) {
00287                 if (load_ip_prefix(data, &cfg->home_net_addr, 
00288                                    &cfg->home_net_addr_plen) == TRUE)
00289                         return 0;
00290                 return -1;
00291         }
00292                 
00293         if (strcmp(key, "HomeNetGateway") == 0) {
00294                 if (load_ip_address(data, &cfg->home_net_gateway) == TRUE)
00295                         return 0;
00296                 return -1;
00297         }
00298         if (strcmp(key, "MNDecapsRouteHandling") == 0) {
00299                 if (load_int(data, &cfg->mndecaps_route_handling) == TRUE)
00300                         return 0;
00301                 return -1;
00302         }
00303         if (strcmp(key, "SharedSecret") == 0) {
00304                 if (load_hex_table(data, cfg->shared_secret,
00305                                    MAXSHAREDSECRETLEN,
00306                                    &cfg->shared_secret_len) == TRUE) {
00307                         assert(cfg->shared_secret_len >= 0);
00308                         assert(cfg->shared_secret_len <= MAXSHAREDSECRETLEN);
00309                         return 0;
00310                 }
00311                 return -1;
00312         }
00313         if (strcmp(key, "SPI") == 0) {
00314                 if (load_int(data, &cfg->spi) == TRUE) return 0;
00315                 return -1;
00316         }
00317         if (strcmp(key, "UDPPort") == 0) {
00318                 if (load_int(data, &cfg->udp_port) == TRUE) {
00319                         return 0;
00320                 }
00321                 return -1;
00322         }
00323         if (strcmp(key, "AuthenticationAlgorithm") == 0) {
00324                 if (load_int(data, &cfg->auth_alg) == TRUE) {
00325                         return 0;
00326                 }
00327                 return -1;
00328         }
00329         if (strcmp(key, "ReplayMethod") == 0) {
00330                 if (load_int(data, &cfg->replay_meth) == TRUE) {
00331                         return 0;
00332                 }
00333                 return -1;
00334         }
00335         if (strcmp(key, "UseAAA") == 0) {
00336                 if (load_bool(data, &cfg->use_aaa) == TRUE)
00337                         return 0;
00338                 return -1;
00339         }
00340         if (strcmp(key, "MN-AAA-SharedSecret") == 0) {
00341                 if (load_hex_table(data, cfg->mn_aaa_shared_secret,
00342                                    MAXSHAREDSECRETLEN,
00343                                    &cfg->mn_aaa_shared_secret_len) == TRUE) {
00344                         assert(cfg->mn_aaa_shared_secret_len >= 0);
00345                         assert(cfg->mn_aaa_shared_secret_len <=
00346                                MAXSHAREDSECRETLEN);
00347                         return 0;
00348                 }
00349                 return -1;
00350         }
00351         if (strcmp(key, "MN-AAA-SPI") == 0) {
00352                 if (load_int(data, &cfg->mn_aaa_spi) == TRUE) return 0;
00353                 return -1;
00354         }
00355         if (strcmp(key, "MN-AAA-AuthenticationAlgorithm") == 0) {
00356                 if (load_int(data, &cfg->mn_aaa_auth_alg) == TRUE) {
00357                         return 0;
00358                 }
00359                 return -1;
00360         }
00361         if (strcmp(key, "MN-AAA-KeyGenerationAlgorithm") == 0) {
00362                 if (load_int(data, &cfg->mn_aaa_keygen_alg) == TRUE)
00363                         return 0;
00364                 return -1;
00365         }
00366         if (strcmp(key, "EnableFADecapsulation") == 0) {
00367                 if (load_bool(data, &cfg->enable_fa_decapsulation) == TRUE) {
00368                         return 0;
00369                 }
00370                 return -1;
00371         }
00372         if (strcmp(key, "TunnelingMode") == 0) {
00373                 if (load_int(data, &cfg->tunneling_mode) == TRUE) {
00374                         return 0;
00375                 }
00376                 return -1;
00377         }
00378         if (strcmp(key, "MNDefaultTunnelLifetime") == 0) {
00379                 if (load_int(data, (int*)&cfg->mn_default_tunnel_lifetime)
00380                     == TRUE) {
00381                         return 0;
00382                 }
00383                 return -1;
00384         }
00385         if (strcmp(key, "SyslogFacility") == 0) {
00386                 if (load_syslog_facility(data,
00387                                          &cfg->syslog_facility) == TRUE) {
00388                         return 0;
00389                 }
00390                 return -1;
00391         }
00392         if (strcmp(key, "MNAPIReadSocketPath") == 0) {
00393                 if (load_char_table(data, cfg->mn_api_read_socket_path,
00394                                     MAXFILENAMELEN) == TRUE) {
00395                         return 0;
00396                 }
00397                 return -1;
00398         }
00399         if (strcmp(key, "MNAPIReadSocketGroup") == 0) {
00400                 if (load_char_table(data, cfg->mn_api_read_socket_group,
00401                                     MAXGROUPNAMELEN) == TRUE) {
00402                         return 0;
00403                 }
00404                 return -1;
00405         }
00406         if (strcmp(key, "MNAPIReadSocketOwner") == 0) {
00407                 if (load_char_table(data, cfg->mn_api_read_socket_owner,
00408                                     MAXOWNERNAMELEN) == TRUE) {
00409                         return 0;
00410                 }
00411                 return -1;
00412         }
00413         if (strcmp(key, "MNAPIReadSocketPermissions") == 0) {
00414                 if (load_int(data,
00415                              &cfg->mn_api_read_socket_permissions) == TRUE) {
00416                         return 0;
00417                 }
00418                 return -1;
00419         }
00420         if (strcmp(key, "MNAPIAdminSocketPath") == 0) {
00421                 if (load_char_table(data, cfg->mn_api_admin_socket_path,
00422                                     MAXFILENAMELEN) == TRUE) {
00423                         return 0;
00424                 }
00425                 return -1;
00426         }
00427         if (strcmp(key, "MNAPIAdminSocketGroup") == 0) {
00428                 if (load_char_table(data, cfg->mn_api_admin_socket_group,
00429                                     MAXGROUPNAMELEN) == TRUE) {
00430                         return 0;
00431                 }
00432                 return -1;
00433         }
00434         if (strcmp(key, "MNAPIAdminSocketOwner") == 0) {
00435                 if (load_char_table(data, cfg->mn_api_admin_socket_owner,
00436                                     MAXOWNERNAMELEN) == TRUE) {
00437                         return 0;
00438                 }
00439                 return -1;
00440         }
00441         if (strcmp(key, "MNAPIAdminSocketPermissions") == 0) {
00442                 if (load_int(data,
00443                              &cfg->mn_api_admin_socket_permissions) == TRUE) {
00444                         return 0;
00445                 }
00446                 return -1;
00447         }
00448         if (strcmp(key, "SocketPriority") == 0) {
00449                 if (load_int(data, &cfg->socket_priority) == TRUE) {
00450                         return 0;
00451                 }
00452                 return -1;
00453         }
00454         if (strcmp(key, "EnforceRoutes") == 0) {
00455                 if (load_bool(data, &cfg->enforce_routes) == TRUE) {
00456                         return 0;
00457                 }
00458                 return -1;
00459         }
00460         if (strcmp(key, "APPollingInterval") == 0) {
00461                 if (load_int(data, &cfg->wlan_ap_poll_interval) == TRUE) {
00462                         return 0;
00463                 }
00464                 return -1;
00465         }
00466         if (strcmp(key, "SolicitationInterval") == 0) {
00467                 if (load_int(data, &cfg->solicitation_interval) == TRUE) {
00468                         return 0;
00469                 }
00470                 return -1;
00471         }
00472         if (strcmp(key, "PrivateHAIPAddress") == 0) {
00473                 if (load_ip_address(data, &cfg->priv_ha_ip_addr) == TRUE)
00474                         return 0;
00475                 return -1;
00476         }
00477         if (strcmp(key, "PrivateHAIdentifier") == 0) {
00478                 if (load_int(data, (int *) &cfg->priv_ha) == TRUE) {
00479                         return 0;
00480                 }
00481                 return -1;
00482         }
00483         if (strcmp(key, "MNNetworkAccessIdentifier") == 0) {
00484                 if (load_nai(data, cfg->mn_nai, &cfg->mn_nai_len) == TRUE)
00485                         return 0;
00486                 return -1;
00487         }
00488         if (strcmp(key, "HANetworkAccessIdentifier") == 0) {
00489                 if (load_nai(data, cfg->ha_nai, &cfg->ha_nai_len) == TRUE)
00490                         return 0;
00491                 return -1;
00492         }
00493 #ifdef BIND_UDP_SOCKET
00494         if (strcmp(key, "BindAddress") == 0) {
00495                 if (load_ip_address(data, &cfg->bind_addr) == TRUE)
00496                         return 0;
00497                 return -1;
00498         }
00499         if (strcmp(key, "BindPort") == 0) {
00500                 int port;
00501                 if (load_int(data, &port) == TRUE) {
00502                         cfg->bind_port = htons((unsigned short) port);
00503                         return 0;
00504                 }
00505                 return -1;
00506         }
00507 #endif
00508 #ifdef INCLUDE_IPAY
00509         if (strcmp(key, "IpayMNAddress") == 0) {
00510                 if (load_ip_address(data, &cfg->ipay_mn_addr) == TRUE)
00511                         return 0;
00512                 return -1;
00513         }
00514         if (strcmp(key, "IpayMNPort") == 0) {
00515                 if (load_int(data, &cfg->ipay_mn_port) == TRUE) {
00516                         return 0;
00517                 }
00518                 return -1;
00519         }
00520         if (strcmp(key, "IpayBuyerAddress") == 0) {
00521                 if (load_ip_address(data, &cfg->ipay_buyer_addr) == TRUE)
00522                         return 0;
00523                 return -1;
00524         }
00525         if (strcmp(key, "IpayBuyerPort") == 0) {
00526                 if (load_int(data, &cfg->ipay_buyer_port) == TRUE) {
00527                         return 0;
00528                 }
00529                 return -1;
00530         }
00531         if (strcmp(key, "IpayFAPort") == 0) {
00532                 if (load_int(data, &cfg->ipay_fa_port) == TRUE) {
00533                         return 0;
00534                 }
00535                 return -1;
00536         }
00537 #endif
00538         if (strcmp(key, "END") == 0) return 1;
00539         return -1;
00540 }
00541 
00542 
00543 int load_mn(struct mn_config *cfg, char *program_name, char *config_file) {
00544         FILE *file;
00545         struct load_mn_data mn;
00546         int i;
00547 
00548         mn.cfg = cfg;
00549         memset(cfg, '\0', sizeof(struct mn_config));
00550         cfg->mn_default_tunnel_lifetime = MN_DEFAULT_TUNNEL_LIFETIME;
00551         cfg->syslog_facility = MN_DEFAULT_SYSLOG_FACILITY;
00552 
00553         cfg->shared_secret_len = -1;
00554         cfg->auth_alg = 1;
00555         cfg->replay_meth = 1;
00556         cfg->udp_port = 434;
00557         cfg->socket_priority = -1;
00558         cfg->home_net_addr_plen = -1;
00559         cfg->mndecaps_route_handling = MNDECAPS_ROUTE_DEFAULT;
00560         cfg->tunneling_mode = TUNMODE_AUTO_REVERSE;
00561         cfg->wlan_ap_poll_interval = -1;
00562         cfg->solicitation_interval = -1;
00563         mn.process_fa_spi_list = FALSE;
00564         mn.process_ignore_iflist = FALSE;
00565         list_init(&cfg->fa_spi_list);
00566         list_init(&cfg->ignore_iflist);
00567         list_init(&cfg->alt_ha_ip_addrs);
00568 
00569 #ifdef BIND_UDP_SOCKET
00570         cfg->bind_addr.s_addr = INADDR_ANY;
00571         cfg->bind_port = htons(cfg->udp_port);
00572 #endif
00573 
00574         file = fopen(config_file, "r");
00575         if (file == NULL) {
00576                 fprintf(stderr,
00577                         "%s: Could not open configuration file '%s'.\n",
00578                         program_name, config_file);
00579                 return FALSE;
00580         }
00581         if (load_data(&mn, file, process_load_mn) == FALSE) {
00582                 fprintf(stderr,
00583                         "load_mn: Error while interpreting file '%s'!\n",
00584                         config_file);
00585                 fclose(file);
00586                 return FALSE;
00587         }
00588         fclose(file);
00589 
00590         if (cfg->home_net_addr_plen > -1) {
00591                 /* determine home net's subnet-direct broadcast address */
00592                 __u32 ones = 0;
00593                 for (i = cfg->home_net_addr_plen; i < 32; i++) {
00594                         ones |= 1 << (31 - i);
00595                 }
00596                 cfg->home_net_subnet_bc.s_addr = cfg->home_net_addr.s_addr |
00597                         htonl(ones);
00598         }
00599 
00600         if (cfg->ha_ip_addr.s_addr == 0)
00601                 cfg->use_hadisc = TRUE;
00602 
00603         cfg->ha_ip_addr_orig.s_addr = cfg->ha_ip_addr.s_addr;
00604         cfg->mn_home_ip_addr_orig.s_addr = cfg->mn_home_ip_addr.s_addr;
00605 
00606         return check_config_data(cfg);
00607 }

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