]> git.decadent.org.uk Git - ap-utils.git/blobdiff - lib/common.c
Imported Upstream version 1.5.1~pre3
[ap-utils.git] / lib / common.c
index 16f342dc00ce196228d3eb64eaee2165efa4355f..3c1b359157728c03ae62d61beaff76a18a410663 100644 (file)
@@ -2,6 +2,7 @@
  *      common.c from Access Point SNMP Utils for Linux
  *
  * Copyright (c) 2002 Roman Festchook <roma at polesye dot net>
+ * Copyright (c) 2005 Jan Rafaj <jr-aputils at cedric dot unob dot cz>
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License Version 2 from
 #include <unistd.h>
 #include <fcntl.h>
 #include <sys/ioctl.h>
+#include <sys/socket.h>
 #include "ap-utils.h"
 
-#define AUTODETECT _("Autodetect AP type? ")
 #define APIP _("Access Point IP-address: ")
 #define APPASS _("Password (community): ")
-#define APTYPE _("AP type: ")
+#define AUTODETECT _("Autodetect AP MIB properties? ")
+#define APTYPE _("AP MIB type: ")
+#define APVENDOREXT _("AP MIB vendor extensions: ")
+#define WANT_SYS_APLABEL _("Do you want to use AP's name as its label? ")
+#define APLABEL _("Access Point label: ")
 #define SAVESETTINGS _("Save connect-settings: ")
+#define POLL_I _("[P] Polling mode interval (tenths of second): ")
+#define POLL_HELP _("P - change polling mode interval; Q - quit to menu")
+
+char *ap_types[] = {
+    "ATMEL410",
+    "NWN",
+    "ATMEL12350"
+};
+
+char *ap_vendorexts[][3] = {
+    { "NONE", "SBRIDGES" },            /* ATMEL410 exts */
+    { "NONE" },                                /* NWN exts */
+    { "NONE", "GEMTEK", "EZYNET" },    /* ATMEL12350 exts */
+    { 0 }                              /* do not delete! */
+};
+
+rdprops regdom_types[] = {
+    { 0x10, "FCC (USA)", 1, 11 },
+    { 0x20, "DOC (Canada)", 1, 11 },
+    { 0x30, "ETSI (Europe)", 1, 13 },
+    { 0x31, "Spain", 10, 2 },
+    { 0x32, "France", 10, 4 },
+    { 0x40, "MKK (Japan)", 14, 1 },
+    { 0x41, "MKK1 (Japan)", 1, 14 },
+    { 0x42, "Israel", 3, 7 },
+    { 0x00, "unknown", 1, 14 } /* hopefully 0x00 is not taken by any? */
+};
+
+char *channels[] = {
+    "01", "02", "03", "04", "05", "06", "07",
+    "08", "09", "10", "11", "12", "13", "14"
+};
 
 extern WINDOW *main_sub;
 extern char *community, *prog_title;
-extern short ap_type;
-extern int sockfd;
 extern struct in_addr ap_ip;
-extern char *ap_types[];
+
+short ap_type, ap_vendorext;
+int poll_delay = 10;
 
 void about()
 {
-    int nrow = 12, ncol = 47, brow = (LINES - 4 - nrow) / 2, bcol =
+    int nrow = 14, ncol = 47, brow = (LINES - 5 - nrow) / 2, bcol =
        (COLS - MCOLS - 2 - ncol) / 2, i;
     char message[100];
 
     noecho();
     curs_set(0);
 
-    print_title(_("About"));
+    print_top(NULL, _("About"));
 
     /* drawing the box */
     mvwaddch(main_sub, brow, bcol, ACS_ULCORNER);
@@ -71,60 +108,53 @@ void about()
     sprintf(message, _("Version %s"), VERSION);
     mvwaddstr(main_sub, brow + 3, bcol + 2, message);
     mvwaddstr(main_sub, brow + 5, bcol + 2,
-             _("Written by Roman Festchook roma@polesye.net"));
+       _("Written by Roman Festchook roma@polesye.net"));
     mvwaddstr(main_sub, brow + 6, bcol + 2,
-             _("Copyright (c) Roman Festchook 2001-2004"));
-    mvwaddstr(main_sub, brow + 7, bcol + 2, "http://ap-utils.polesye.net/");
-    mvwaddstr(main_sub, brow + 9, bcol + 2,
-             _("This program is distributed under the terms"));
-    mvwaddstr(main_sub, brow +10, bcol + 2,
-             _("of the GNU General Public License version 2."));
+       _("and Jan Rafaj jr-aputils@cedric.unob.cz"));
+    mvwaddstr(main_sub, brow + 7, bcol + 2,
+       _("Copyright (c) 2001-2006"));
+    mvwaddstr(main_sub, brow + 8, bcol + 2,
+       _("Roman Festchook and Jan Rafaj"));
+    mvwaddstr(main_sub, brow + 9, bcol + 2, "http://ap-utils.polesye.net/");
     mvwaddstr(main_sub, brow + 11, bcol + 2,
-             _("See the included COPYING file for details."));
-
+       _("This program is distributed under the terms"));
+    mvwaddstr(main_sub, brow +12, bcol + 2,
+       _("of the GNU General Public License version 2."));
+    mvwaddstr(main_sub, brow + 13, bcol + 2,
+       _("See the included COPYING file for details."));
 
     wrefresh(main_sub);
 
     print_help(ANY_KEY);
     getch();
     print_help("");
-    print_title("");
+    print_top(NULL, NULL);
     clear_main(0);
     return;
 }
 
 void connect_options(unsigned long int ip, int type)
 {
-    int i;
-    struct sockaddr_in client;
-    unsigned char message[16];
-    int fd;
+    /*
+     * operAccessPointName OIDs used to retrieve AP NAME [in order of
+     * corresponding AP MIB types: ATMEL410, NWN, ATMEL12350]
+     */
+    char operAccessPointName[3][12] = {
+      {0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x01, 0x0A, 0x00},
+      {0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x05, 0x00},
+      {0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x01, 0x0A, 0x00}
+    };
+
+    extern int atmel410_filter; /* boolean; = 1 if we call from ap-gl utility */
+    unsigned char message[256];
+    unsigned char label[17];
+    int fd, i;
     char *home_dir;
     char save_settings=1;
-    char sysDescr_NWN[] = { 0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00 };
-    char sysDescr_ATMEL410[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A,
-       0x01, 0x01, 0x01, 0x01, 0x00 };
-    char sysDescr_ATMEL12350[] = { 0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E,
-       0x01, 0x01, 0x01, 0x01, 0x00 };
     varbind varbinds[1];
 
-
-    memset(&client, 0, sizeof client);
-    client.sin_family = AF_INET;
-    client.sin_port = INADDR_ANY;
-    client.sin_addr.s_addr = INADDR_ANY;
-
-    if (sockfd)
-       close(sockfd);
-
-    if ((sockfd = socket(AF_INET, SOCK_DGRAM, 0)) == -1) {
-       print_helperr(CREATE_SOCKET_ERROR);
-       getch();
-       goto exit;
-    }
-
-    if (bind(sockfd, (struct sockaddr *) &client, SIZE) == -1) {
-       print_helperr(BIND_SOCKET_ERROR);
+    if (reopen_sockfd() == -1) {
+       print_helperr(ERR_SOCKET);
        getch();
        goto exit;
     }
@@ -132,10 +162,12 @@ void connect_options(unsigned long int ip, int type)
     noecho();
     curs_set(0);
 
-    print_title(_("Connect options"));
+    print_top(NULL, _("Connect options"));
 
 get_all_again:
     mvwaddstr(main_sub, 1, 1, APIP);
+    wrefresh(main_sub);
+    
     if (ip) {
        ap_ip.s_addr = ip;
        mvwaddstr(main_sub, 1, 1 + strlen(APIP), inet_ntoa(ap_ip));
@@ -145,8 +177,12 @@ get_all_again:
     }
 
     mvwaddstr(main_sub, 2, 1, APPASS);
+
+    i = 0;
+    print_help("");
+
     print_help(_("Entered characters will not be displayed "
-       "for security reason."));
+                "for security reasons."));
     get_pass(message, 2, 1 + strlen(APPASS), 16);
     if (community)
        free(community);
@@ -154,85 +190,278 @@ get_all_again:
     community = (char *) malloc(i);
     strncpy(community, message, i);
 
-    print_help("");
-    if (type) {
+    if (type && !atmel410_filter) {
+       /* entered from ap_search() */
+
+       /* community already exists */
+/*     wattrset(main_sub, A_BOLD);
+       for(i = 0; community[i++]; waddch(main_sub, '*'));
+       wattrset(main_sub, A_NORMAL);
+*/
        ap_type = --type;
-       mvwaddstr(main_sub, 3, 1, APTYPE);
+
+       print_menusel(3, 1, APTYPE, ap_types[ap_type]);
+
+       /* well, we already know the MIB type, but lets find out MIB ext */
+       get_mib_details();
+
+       /* marks that we want offer AP name -> AP label later */
+       i = 1;
+
+       mvwaddstr(main_sub, 4, 1, APVENDOREXT);
     } else {
-       mvwaddstr(main_sub, 3, 1, AUTODETECT);
-       wrefresh(main_sub);
-       i = yes_no(3, 1 + strlen(AUTODETECT));
-       clear_main_new(3, 4);
-       mvwaddstr(main_sub, 3, 1, APTYPE);
-       if (i == 2) { /* NO */
+       if (atmel410_filter) {
+           ap_type = --type;
+           print_menusel(3, 1, APTYPE, ap_types[ap_type]);
+           ap_vendorext = NONE; /* no need to choose here, really */
+           /* marks that we want offer AP name -> AP label later */
+           i = 1;
+           mvwaddstr(main_sub, 4, 1, APVENDOREXT);
+       } else {
+           mvwaddstr(main_sub, 3, 1, AUTODETECT);
            wrefresh(main_sub);
-           ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3);
-       } else { /* YES */
-           print_help(_("Determining AP type. Please wait..."));
-           varbinds[0].oid = sysDescr_NWN;
-           varbinds[0].len_oid = sizeof(sysDescr_NWN);
-           varbinds[0].value = NULL;
-           varbinds[0].len_val = 0;
+           i = yes_no(3, 1 + strlen(AUTODETECT));
+           clear_main_new(3, 4);
+           mvwaddstr(main_sub, 3, 1, APTYPE);
+           if (i == 2) { /* NO */
+               wrefresh(main_sub);
+               ap_type = menu_choose(3, 1 + strlen(APTYPE), ap_types, 3);
+               print_bold(main_sub, ap_types[ap_type]);
+               mvwaddstr(main_sub, 4, 1, APVENDOREXT);
+               wrefresh(main_sub);
+               for (i = 0; ap_vendorexts[ap_type][i]; i++);
+               if (i == 1)
+                   ap_vendorext = NONE; /* no need to choose here, really */
+               else
+                   ap_vendorext = menu_choose(4, 1 + strlen(APVENDOREXT),
+                   ap_vendorexts[ap_type], i);
+           } else { /* YES */
+               if (get_mib_details() == -1) {
+                   clear_main_new(1, 4);
+                   goto get_all_again;
+               }
+               print_bold(main_sub, ap_types[ap_type]);
+               mvwaddstr(main_sub, 4, 1, APVENDOREXT);
+           }
+       }
+    }
+    print_bold(main_sub, ap_vendorexts[ap_type][ap_vendorext]);
+
+    print_help(
+       _("This label will be stored on HDD (independently on AP name!)."));
+    if (i == 1) {
+       /*
+        * (being called from ap_search()) or (YES for AP type autodetection)
+        * => offer possibility to use AP's name as the label
+        */
+       mvwaddstr(main_sub, 5, 1, WANT_SYS_APLABEL);
+       wrefresh(main_sub);
+       if (yes_no(5, 1 + strlen(WANT_SYS_APLABEL)) == 1) { /* YES */
+           varbinds[0].oid = operAccessPointName[ap_type];
+           varbinds[0].len_oid = (ap_type == NWN ?
+               8 : sizeof(operAccessPointName[ap_type]));
            varbinds[0].type = NULL_VALUE;
-           if (snmp(varbinds, 1, GET) > 0) {
-               ap_type = NWN;
+           varbinds[0].len_val = 0;
+
+           print_help(WAIT_RET);
+           if (snmp(varbinds, i, GET) <= 0) {
+               print_helperr(ERR_RET);
+               getch();
            } else {
-               varbinds[0].oid = sysDescr_ATMEL410;
-               varbinds[0].len_oid = sizeof(sysDescr_ATMEL410);
-               varbinds[0].value = NULL;
-               varbinds[0].len_val = 0;
-               varbinds[0].type = NULL_VALUE;
-               if (snmp(varbinds, 1, GET) > 0) {
-                   ap_type = ATMEL410;
-               } else {
-                   varbinds[0].oid = sysDescr_ATMEL12350;
-                   varbinds[0].len_oid = sizeof(sysDescr_ATMEL12350);
-                   varbinds[0].value = NULL;
-                   varbinds[0].len_val = 0;
-                   varbinds[0].type = NULL_VALUE;
-                   if (snmp(varbinds, 1, GET) > 0) {
-                       ap_type = ATMEL12350;
-                   } else {
-                       print_helperr(_("Unable to determine AP type "
-                           "(no response). Press any key."));
-                       getch();
-                       clear_main_new(1, 4);
-                       goto get_all_again;
-                   }
+               clear_main_new(5, 6);
+               mvwaddstr(main_sub, 5, 1, APLABEL);
+               wattrset(main_sub, A_BOLD);
+               for (i = 0; i < varbinds[0].len_val && i < 16 &&
+                    *(varbinds[0].value + i); i++) {
+                   label[i] = *(varbinds[0].value + i);
+                   waddch(main_sub, label[i]);
+               }
+               label[i] = '\0';
+               wattrset(main_sub, A_NORMAL);
+               if (strlen(varbinds[0].value) > 16) {
+                   print_helperr("Warning! AP LABEL truncated to first 16 characters of AP NAME. Press any key.");
+                   getch();
                }
            }
-       }                           
-       wattrset(main_sub, A_BOLD);
+           print_help("");
+           i = -1;
+       }
     }
-    waddstr(main_sub, ap_types[ap_type]);
-    wattrset(main_sub, A_NORMAL);
 
-    mvwaddstr(main_sub, 4, 1, SAVESETTINGS);
+    if (i != -1) { /* we have NOT been asked with WANT_SYS_APLABEL */
+       clear_main_new(5, 6);
+       mvwaddstr(main_sub, 5, 1, APLABEL);
+        wrefresh(main_sub);
+       get_value(message, 5, 1 + strlen(APLABEL), -sizeof(label), ANY_STRING,
+           0, 0, NULL);
+       strncpy(label, message, strlen(message) + 1);
+    }
+
+    mvwaddstr(main_sub, 6, 1, SAVESETTINGS);
     wrefresh(main_sub);
-    save_settings = on_off(4, 1 + strlen(SAVESETTINGS));
+    save_settings = on_off(6, 1 + strlen(SAVESETTINGS));
+    clear_main_new(6, 7);
+    print_menusel(6, 1, SAVESETTINGS, (save_settings == 1) ? ON : OFF);
 
     print_bottom(inet_ntoa(ap_ip));
 
     if(save_settings == 1) {
        if ((home_dir = getenv("HOME"))) {
            sprintf(message, "%s/.ap-config", home_dir);
-           if ((fd = open(message, O_CREAT | O_WRONLY | O_APPEND, 0600)) != -1) {
-               sprintf(message, "%s:%s:%d\n", inet_ntoa(ap_ip),
-                   community, ap_type);
+           if ((fd = open(message, O_CREAT|O_WRONLY|O_APPEND, 0600)) != -1) {
+               sprintf(message, "%s:%s:%s:%d:%d\n", inet_ntoa(ap_ip),
+                   community, label, ap_type, ap_vendorext);
                write(fd, message, strlen(message));
                close(fd);
-           }
+               wbkgd(main_sub, A_NORMAL);
+               wrefresh(main_sub);
+               print_help(DONE_WRITING_APCONF);
+           } else
+               print_helperr(ERR_WRITING_APCONF);
+
+           getch();
        }
     }
   exit:
     print_help("");
-    print_title("");
+    print_top(NULL, NULL);
     clear_main(0);
     return;
 }
 
+/*
+ * Determines AP MIB type (fills ap_type global), and AP MIB vendor extensions
+ * (fills ap_vendorext global). Returns with -1 on error or 0
+ * if everything is OK.
+ */
+int get_mib_details()
+{
+    char sysDescr_NWN[] = {
+       0x2B, 0x06, 0x01, 0x02, 0x01, 0x01, 0x01, 0x00
+    };
+    char sysDescr_ATMEL[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x01, 0x01, 0x01, 0x00
+    };
+    /*
+     * ATMEL410: SMARTBRIDGES MIB define this with length 4 (IpAddress); others
+     * (hopefully) do not define this but eventually return (hopefully)
+     * different value than 4.
+     */
+    char AuthRadiusIP_ATMEL[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0x83, 0x1A, 0x01, 0x02, 0x06, 0x03, 0x00
+    };
+    /* ATMEL12350: GEMTEK and EZYNET MIBs define length 160, others 92 or 128 */
+    char sysDeviceInfo_ATMEL[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x01, 0x01, 0x05, 0x00
+    };
+    /* ATMEL12350: EZYNET MIB defines length 104, others 88 */
+    char wirelessStatistics_ATMEL[] = {
+       0x2B, 0x06, 0x01, 0x04, 0x01, 0xE0, 0x3E, 0x01, 0x02, 0x03, 0x01, 0x00
+    };
+
+    varbind varbinds[2];
+    int i;
+
+    print_help(_("Trying to probe AP for MIB properties. Please wait..."));
+
+    /* first, determine the private MIB types according to enterprises ID */
+    varbinds[0].oid = sysDescr_NWN;
+    varbinds[0].len_oid = sizeof(sysDescr_NWN);
+    varbinds[0].value = NULL;
+    varbinds[0].len_val = 0;
+    varbinds[0].type = NULL_VALUE;
+    if (snmp(varbinds, 1, GET) > 0) {
+       ap_type = NWN;
+    } else {
+       varbinds[0].oid = sysDescr_ATMEL;
+       varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
+       varbinds[0].value = NULL;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+       if (snmp(varbinds, 1, GET) > 0) {
+           ap_type = ATMEL410;
+       } else {
+           sysDescr_ATMEL[5] = 0xE0;
+           sysDescr_ATMEL[6] = 0x3E;
+           varbinds[0].oid = sysDescr_ATMEL;
+           varbinds[0].len_oid = sizeof(sysDescr_ATMEL);
+           varbinds[0].value = NULL;
+           varbinds[0].len_val = 0;
+           varbinds[0].type = NULL_VALUE;
+           if (snmp(varbinds, 1, GET) > 0) {
+               ap_type = ATMEL12350;
+           } else {
+               print_helperr(_("Unable to determine AP MIB properties "
+                   "(no response from AP). Press any key."));
+               getch();
+               return -1;
+           }
+       }
+    }
+
+    /*
+     * It is best to do the following HERE and FOR ONCE ONLY: find out more
+     * about specific MIB vendor extensions - we'll check against them
+     * on different places later.
+     */
+
+    ap_vendorext = NONE;
+
+    if (ap_type == ATMEL410) {
+       varbinds[0].oid = AuthRadiusIP_ATMEL;
+       varbinds[0].len_oid = sizeof(AuthRadiusIP_ATMEL);
+       varbinds[0].value = NULL;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+
+       i = snmp(varbinds, 1, GET);
+       if (i < 0) {
+           print_helperr(ERR_RET);
+           getch();
+           return -1;
+       }
+
+       /*
+        * i == 0 => 'no such variable in the MIB' returned =>
+        * consider 'ap_vendorext = NONE' too.
+        */
+
+       if (varbinds[0].len_val == 4)
+           ap_vendorext = SBRIDGES;
+    }
+
+    if (ap_type == ATMEL12350) {
+       varbinds[0].oid = sysDeviceInfo_ATMEL;
+       varbinds[0].len_oid = sizeof(sysDeviceInfo_ATMEL);
+       varbinds[0].value = NULL;
+       varbinds[0].len_val = 0;
+       varbinds[0].type = NULL_VALUE;
+       varbinds[1].oid = wirelessStatistics_ATMEL;
+       varbinds[1].len_oid = sizeof(wirelessStatistics_ATMEL);
+       varbinds[1].value = NULL;
+       varbinds[1].len_val = 0;
+       varbinds[1].type = NULL_VALUE;
+
+       if (snmp(varbinds, 2, GET) <= 0) {
+           print_helperr(ERR_RET);
+           getch();
+           return -1;
+       }
+
+       if (varbinds[0].len_val == 160)
+           ap_vendorext = GEMTEK;
+
+       if (varbinds[1].len_val == 104)
+           ap_vendorext = EZYNET;
+    }
+
+    return 0;
+}
+
 void exit_program()
 {
+    erase();
+    refresh();
     endwin();
     exit(0);
 }
@@ -246,45 +475,57 @@ void exit_shell()
     refresh();
 }
 
-/* 
- * Fill channels list string array using regulation domain
- * restrictions and return number of the channels
+/*
+ * Sets different-than-default (1 sec.) polling interval for polling-active
+ * modes, from interval <0.1;86400> seconds.
+ * poll_delay is natively in tenths of second.
  */
-int ch_list(int regulation_domain, char **list)
+void polling_interval()
 {
-    int FIRST_CHANNEL, LAST_CHANNEL, i;
-
-#ifndef NO_REG_DOMAIN
-    switch (regulation_domain) {
-    case 0x10:
-    case 0x20:
-       FIRST_CHANNEL = 1;
-       LAST_CHANNEL = 11;
-       break;
-    case 0x30:
-       FIRST_CHANNEL = 1;
-       LAST_CHANNEL = 13;
-       break;
-    case 0x31:
-       FIRST_CHANNEL = 10;
-       LAST_CHANNEL = 11;
-       break;
-    case 0x32:
-       FIRST_CHANNEL = 10;
-       LAST_CHANNEL = 13;
-       break;
-    default: /* also case 0x40 */
-#endif    
-       FIRST_CHANNEL = 1;
-       LAST_CHANNEL = 14;
-#ifndef NO_REG_DOMAIN
-    }
-#endif    
+    unsigned char message[256];
+    int c = 0;
+
+    noecho();
+    print_help(POLL_HELP);
 
-    for (i = 0; i < LAST_CHANNEL - FIRST_CHANNEL + 1; i++) {
-       list[i] = (char *) malloc(3);
-       sprintf(list[i], "%02u", FIRST_CHANNEL + i);
+    while (1) {
+       sprintf(message, "%s%u", POLL_I, poll_delay);
+       mvwaddstr(main_sub, 0, 0, message);
+       sprintf(message, _("(%0.1f seconds)"), (float) poll_delay / 10);
+       mvwaddstr(main_sub, 1, strlen(POLL_I), message);
+       wrefresh(main_sub);
+       c = getch();
+       switch (c) {
+           case 'P':
+           case 'p':
+               get_value(message, 0, strlen(POLL_I), 7, INT_STRING, 1, 864000,
+                   POLL_HELP);
+               poll_delay = atoi(message);
+               clear_main_new(0, 2);
+               break;
+           case 'Q':
+           case 'q':
+               goto quit;
+       }
     }
-    return i;
+
+quit:
+    print_help("");
+    clear_main(0);
+    return;
 }
 
+/*
+ * Expects regulatory domain code on input and returns index of a corresponding
+ * regdom_types[] member, that describes the given regulatory domain properties.
+ */
+int regdom_idx(char regdom)
+{
+    int i;
+
+    for (i = 0; &regdom_types[i]; i++)
+       if (regdom_types[i].code == regdom)
+           return i;
+
+    return i;
+}