## tests/wk/full_wk_test.c

/* [<][>][^][v][top][bottom][index][help] */

## DEFINITIONS

This source file includes following functions.

1. match_and_check_attribute
2. read_rpsl_attribute
3. strip_nl
4. main

       1 /*
       2    This test will verify that the which_keytypes.c routines will
       3    properly identify each key type for all records in the database.
       4
       5    To use it, you should take the text dump of the database,
       6    e.g. ripe.db.long.gz, and feed it as standard input to this
       7    program.  Any mismatches will be detected.
       8
       9    Note that this test insures that all handles can be searched, but
      10    not that extra searches will not be performed.  For example,
      11    a person/role search will be made for all maintainer searches.
      12    This is not considered a bug, because those searches are for the
      13    most part necessary.
      14   */
      15
      16 /*
      17    Currently some fields are not being checked:
      18
      19     mbrs-by-ref, member-of (list valued)
      20
      21     nserver (list valued) ... ns1.delfi.lt 213.197.128.71
      22
      23     rev-srv (list valued) ... ns.piro.net ns2.piro.net sec2.piro.net
      24                               195.210.0.34
      25     sub-dom (list valued) ... gca gca1
      26                               atr, amb, wsp
      27                               nans2.levi.com 155.57.243.3
      28
      29     ifaddr (strange format) ... x.y.z.w masklen q
      30
      31    Neither WK_IPADDRESS nor WK_HOSTNAME is checked here.
      32 */
      33
      34
      35 #include <stdio.h>
      36 #include <stdlib.h>
      37 #include <string.h>
      38 #include <ctype.h>
      39
      40 #include "bitmask.h"
      41 #include "which_keytypes.h"
      42
      43 /* prototypes */
      44 char *read_rpsl_attribute(FILE *in);
      45 void strip_nl(char *line);
      46 int match_and_check_attribute(char *attr);
      47
      48 /* structure containing our key definition and types */
      49 struct {
      50     const char *attr;
      51     int key_type;
      52 } key_attr[] = {
      53     { "as-block",    WK_ASRANGE },
      54     { "tech-c",      WK_NIC_HDL },
      55     { "admin-c",     WK_NIC_HDL },
      56     { "mnt-by",      WK_MNTNER },
      57     { "mnt-lower",   WK_MNTNER },
      58     { "as-set",      WK_ASSETNAME },
      59     { "domain",      WK_DOMAIN },
      60     { "zone-c",      WK_NIC_HDL },
      61     { "notify",      WK_EMAIL },
      62     { "filter-set",  WK_FILTERSET },
      63     { "inet-rtr",    WK_DOMAIN },
      64     { "local-as",    WK_AUTNUM },
      65     { "inet6num",    WK_IP6PREFIX },
      66     { "netname",     WK_NETNAME },
      67     { "inetnum",     WK_IPRANGE },
      68     { "mnt-routes",  WK_MNTNER },
      69     { "key-cert",    WK_KEY_CERT },
      70     { "limerick",    WK_LIMERICK },
      71     { "mntner",      WK_MNTNER },
      72     { "upd-to",      WK_EMAIL },
      73     { "mnt-nfy",     WK_EMAIL },
      74     { "referral-by", WK_MNTNER },
      75     { "peering-set", WK_PEERINGSET },
      76     { "route-set",   WK_ROUTESETNAME },
      77     { "route",       WK_IPPREFIX },
      78     { "origin",      WK_AUTNUM },
      79     { "cross-mnt",   WK_MNTNER },
      80     { "cross-nfy",   WK_NIC_HDL },
      81     { "rtr-set",     WK_RTRSET },
      82     { "person",      WK_NAME },
      83     { "nic-hdl",     WK_NIC_HDL },
      84     { "e-mail",      WK_EMAIL },
      85     { "role",        WK_NAME }
      86 };
      87 #define NUM_KEY_ATTR (sizeof(key_attr) / sizeof(key_attr[0]))
      88
      89
      90 /* search thru the list of attribute names and see if this one matches */
      91 /* if it does, verify WK can match it! */
      92 /* note: we munge the passed string, because we're lazy and it doesn't matter */
      93 /* return '1' on error, else '0' */
      94 int
      95 match_and_check_attribute(char *attr)
         /* [<][>][^][v][top][bottom][index][help] */
      96 {
      97     char *key;
      98     char *p;
      99     int i;
     100     mask_t which_keys;
     101
     102     /* grab attribute name */
     103     p = strchr(attr, ':');
     104     if (p == NULL) {
     105         return 0;
     106     }
     107     *p = '\0';
     108
     109     /* clean up key */
     110     key = p+1;
     111     while (isspace(*key)) {
     112         key++;
     113     }
     114     /* remove comment, if any */
     115     p = strchr(key, '#');
     116     if (p != NULL) {
     117         *p = '\0';
     118     }
     119     /* drop trailing whitespace */
     120     p = key + strlen(key) - 1;
     121     while ((p >= key) && isspace(*p)) {
     122         *p = '\0';
     123         p--;
     124     }
     125     /* convert to upper case */
     126     p = key;
     127     while (*p != '\0') {
     128         *p = toupper(*p);
     129         p++;
     130     }
     131
     132     /* now see if we have an attribute of this type to check */
     133     for (i=0; i<NUM_KEY_ATTR; i++) {
     134         if (strcmp(key_attr[i].attr, attr) == 0) {
     135             which_keys = WK_new(key);
     136             if (!MA_isset(which_keys, key_attr[i].key_type)) {
     137
     138                 /* special-case reference by name (yuck) */
     139                 if ((key_attr[i].key_type == WK_NIC_HDL) &&
     140                     MA_isset(which_keys, WK_NAME))
     141                 {
     142                     return 0;
     143                 }
     144
     145                 /* error! */
     146                 printf("ERROR: attribute \"%s\" key \"%s\" failed to match\n",
     147                        attr,
     148                        key);
     149                 return 1;
     150             }
     151             return 0;
     152         }
     153     }
     154
     155     /* didn't match, no error */
     156     return 0;
     157 }
     158
     159 /* read the next RPSL attribute from the input stream */
     160 char *
     161 read_rpsl_attribute(FILE *in)
         /* [<][>][^][v][top][bottom][index][help] */
     162 {
     163     /* any data left over from the last read */
     164     static char *last_line = NULL;
     165     static int last_len = 0;
     166
     167     /* current line */
     168     char *line;
     169     int len;
     170
     171     /* buffer */
     172     char buf[4096];
     173     int buf_len;
     174
     175     /* check for eof */
     176     if (feof(in)) {
     177         return NULL;
     178     }
     179
     180     /* initialize */
     181     if (last_line != NULL) {
     182         line = last_line;
     183         len = last_len;
     184     } else {
     185         line = (char *)malloc(1);
     186         if (line == NULL) {
     187             printf("ERROR: out of memory\n");
     188             exit(1);
     189         }
     190         line[0] = '\0';
     191         len = 0;
     192     }
     193
     194     /* read until we get to exit */
     195     for (;;) {
     196         /* EOF */
     197         if (fgets(buf, sizeof(buf), in) == NULL) {
     198             /* clean up static data */
     199             last_line = NULL;
     200             last_len = 0;
     201
     202             /* return our attribute so far */
     203             return line;
     204         }
     205
     206         /* strip off any trailing newline */
     207         strip_nl(buf);
     208
     209         /* if it's not line continuation, return what we have so far */
     210         if ((buf[0] != ' ') && (buf[0] != '\t') && (buf[0] != '+')) {
     211             last_len = strlen(buf);
     212             last_line = (char *)malloc(last_len+1);
     213             if (last_line == NULL) {
     214                 printf("Error: out of memory\n");
     215                 exit(1);
     216             }
     217             strcpy(last_line, buf);
     218             return line;
     219         }
     220
     221         /* if it is line continuation, add to the current buffer */
     222         buf_len = strlen(buf);
     223         line = (char *)realloc(line, len + buf_len + 1);
     224         if (line == NULL) {
     225             printf("Error: out of memory\n");
     226             exit(1);
     227         }
     228         len += buf_len;
     229         strcat(line, buf);
     230     }
     231 }
     232
     233 /* strip terminating newlines, if any */
     234 void
     235 strip_nl(char *line)
         /* [<][>][^][v][top][bottom][index][help] */
     236 {
     237     char *p;
     238
     239     p = strchr(line, '\n');
     240     if (p != NULL) {
     241         *p = '\0';
     242     }
     243 }
     244
     245
     246 /* main routine */
     247 int
     248 main()
         /* [<][>][^][v][top][bottom][index][help] */
     249 {
     250     char *attr;
     251     int num_error;
     252
     253     /* disable output buffering */
     254     setbuf(stdout, NULL);
     255
     256     num_error = 0;
     257     for (;;) {
     258         attr = read_rpsl_attribute(stdin);
     259         if (attr == NULL) {
     260             if (num_error == 0) {
     261                 printf("SUCCESS: all attributes matched\n");
     262                 exit(0);
     263             } else {
     264                 exit(1);
     265             }
     266         }
     267         num_error += match_and_check_attribute(attr);
     268         free(attr);
     269     }
     270 }
     271

/* [<][>][^][v][top][bottom][index][help] */