modules/wk/which_keytypes.c

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

FUNCTIONS

This source file includes following functions.
  1. wk_regex_init
  2. wk_is_name
  3. wk_is_domain
  4. wk_is_hostname
  5. WK_to_string
  6. WK_new

   1 /***************************************
   2   $Revision: 1.26 $
   3 
   4   which_keytypes:  Determine which keys to look for.
   5   
   6   This is based on the existing Perl code. 
   7 
   8   Authors: ottrey, marek
   9 
  10   ******************/ /******************
  11   Copyright (c) 1999,2000,2001                    RIPE NCC
  12  
  13   All Rights Reserved
  14   
  15   Permission to use, copy, modify, and distribute this software and its
  16   documentation for any purpose and without fee is hereby granted,
  17   provided that the above copyright notice appear in all copies and that
  18   both that copyright notice and this permission notice appear in
  19   supporting documentation, and that the name of the author not be
  20   used in advertising or publicity pertaining to distribution of the
  21   software without specific, written prior permission.
  22   
  23   THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
  24   ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
  25   AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
  26   DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
  27   AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  28   OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  29   ***************************************/
  30 
  31 #define  WK_IMPL
  32 #include "rip.h"
  33 
  34 #include <stdio.h>
  35 #include <stdlib.h>
  36 #include <strings.h>
  37 #include <glib.h>
  38 #include <pthread.h>
  39 #include <regex.h>
  40 
  41 #define DOMAINNAME "^[ ]*[a-zA-Z0-9-]*(\\.[a-zA-Z0-9-]+)*[ ]*$"
  42 /* add a constraint: there must be at least one character in the domain name
  43    because the TLD must not be composed of digits only */
  44 #define DOMAINALPHA  "[a-zA-Z]"
  45 
  46 #define VALIDIP6PREFIX "^[0-9A-F:]*:[0-9A-F:/]*$"     /* at least one colon */
  47 /* "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"*/
  48 
  49 /* AS numbers, prepared for 32-bit AS numbers */
  50 #define ASNUM "^AS[1-9][0-9]{0,9}$"
  51 
  52 /* AS numbers, prepared for 32-bit AS numbers */
  53 #define ASRANGE "^AS[1-9][0-9]{0,9}[ ]*([-][ ]*AS[1-9][0-9]{0,9}){0,1}$"   /* [ ]*(-[ ]*AS[0-9]+)?   */
  54 
  55 #define NETNAME "^[A-Z][A-Z0-9_-]*$"
  56 
  57 #define MAINTAINER "^[A-Z][A-Z0-9_-]*$"
  58 
  59 #define LIMERICK "^LIM-[A-Z0-9_-]+$"
  60 
  61 #define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
  62 
  63 /* made less restrictive to make consistent with other sets ... shane */
  64 /* made to match what we're actually looking for - shane */
  65 /*#define ROUTESETNAME "^RS-[A-Z0-9_:-]*$"*/
  66 #define ROUTESETNAME "(^|:)RS-[A-Z0-9_-]*[A-Z0-9](:|$)"
  67 
  68 /* made less restrictive to make consistent with other sets ... shane */
  69 /* made to match what we're actually looking for - shane */
  70 /*#define ASSETNAME "^AS-[A-Z0-9_:-]*$"*/
  71 #define ASSETNAME "(^|:)AS-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  72 
  73 #define AUTONICPREFIXREGULAR "^AUTO-"
  74 
  75 #define IPRANGE "^[0-9]{1,3}(\\.[0-9]{1,3}){0,3}[ ]*-[ ]*[0-9]{1,3}(\\.[0-9]{1,3}){0,3}$"
  76 
  77 #define IPADDRESS "^[0-9.]+$"
  78 
  79 #define IPPREFIX "^[0-9.]+/[0-9]+$"
  80 
  81 /*#define PEERINGSET "^PRNG-"*/
  82 #define PEERINGSET "(^|:)PRNG-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  83 
  84 /*#define FILTERSET  "^FLTR-"*/
  85 #define FILTERSET "(^|:)FLTR-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  86 
  87 /*#define RTRSET     "^RTRS-"*/
  88 #define RTRSET "(^|:)RTRS-[A-Z0-9_-]*[A-Z0-9](:|$)" 
  89 
  90 #define NICHANDLE "^[A-Z0-9-]+$"
  91 
  92 /*
  93   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
  94   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
  95   Does \w include [ ;:,?/}{()+*#] ?
  96 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
  97 */
  98 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
  99 
 100 #define EMAIL "@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"
 101 
 102 /* structure for simple keys, with a single regular expression to match */
 103 /* NOTE: the WK_NAME, WK_DOMAIN, and WK_HOSTNAME are not handled here   */
 104 struct {
 105     int key_type;               /* identifier for key, e.g. WK_RTRSET */
 106     char *pattern;              /* string for regular expression */
 107     regex_t regex;              /* regular expression */
 108 } wk_regex_list[] = {
 109     { WK_NIC_HDL,       NICHANDLE },
 110     { WK_EMAIL,         EMAIL },
 111     { WK_MNTNER,        MAINTAINER },
 112     { WK_KEY_CERT,      KEYCERT },
 113     { WK_IPRANGE,       IPRANGE },
 114     { WK_IPADDRESS,     IPADDRESS },
 115     { WK_IPPREFIX,      IPPREFIX },
 116     { WK_IP6PREFIX,     VALIDIP6PREFIX },
 117     { WK_NETNAME,       NETNAME },
 118     { WK_NET6NAME,      NETNAME },
 119     { WK_AUTNUM,        ASNUM },
 120     { WK_ASSETNAME,     ASSETNAME },
 121     { WK_ROUTESETNAME,  ROUTESETNAME },
 122     { WK_LIMERICK,      LIMERICK },
 123     { WK_ASRANGE,       ASRANGE },
 124     { WK_PEERINGSET,    PEERINGSET },
 125     { WK_FILTERSET,     FILTERSET },
 126     { WK_RTRSET,        RTRSET }
 127 };
 128 #define WK_REGEX_LIST_LEN  (sizeof(wk_regex_list)/sizeof(wk_regex_list[0]))
 129 
 130 /* regular expressions used by wk_is_name() */
 131 static regex_t ipaddress;
 132 static regex_t ipprefix;
 133 static regex_t validip6prefix;
 134 
 135 /* regular expression used by isdomname() */
 136 static regex_t domainname;
 137 static regex_t domainalpha;
 138 
 139 /* initialize regular expressions */
 140 static void 
 141 wk_regex_init ()
     /* [<][>][^][v][top][bottom][index][help] */
 142 {
 143     int i;
 144     int errcode;
 145 
 146     /* initialize our table */
 147     for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 148         errcode = regcomp(&wk_regex_list[i].regex, 
 149                           wk_regex_list[i].pattern, 
 150                           REG_EXTENDED|REG_NOSUB);
 151         dieif(errcode != 0);
 152     }
 153 
 154     /* add some special cases used by our other functions */
 155     errcode = regcomp(&ipaddress, IPADDRESS, REG_EXTENDED|REG_NOSUB);
 156     dieif(errcode != 0);
 157     errcode = regcomp(&ipprefix, IPPREFIX, REG_EXTENDED|REG_NOSUB);
 158     dieif(errcode != 0);
 159     errcode = regcomp(&validip6prefix, VALIDIP6PREFIX, REG_EXTENDED|REG_NOSUB);
 160     dieif(errcode != 0);
 161     errcode = regcomp(&domainname, DOMAINNAME, REG_EXTENDED|REG_NOSUB);
 162     dieif(errcode != 0);
 163     errcode = regcomp(&domainalpha, DOMAINALPHA, REG_EXTENDED|REG_NOSUB);
 164     dieif(errcode != 0);
 165 }
 166 
 167 
 168 /* see if the key looks like it could be a name */
 169 static unsigned int 
 170 wk_is_name (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 171 {
 172     /* if it's an address, it cannot be a name */
 173     if (regexec(&ipaddress, key, 0, NULL, 0) == 0) { 
 174         return 0;
 175     }
 176     if (regexec(&ipprefix, key, 0, NULL, 0) == 0) { 
 177         return 0;
 178     }
 179     if (regexec(&validip6prefix, key, 0, NULL, 0) == 0) { 
 180         return 0;
 181     }
 182 
 183     /* Everything apart from addresses matches to name */
 184     return 1;
 185 } /* wk_is_name() */
 186 
 187 /* check for domain name */
 188 static unsigned int 
 189 wk_is_domain (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 190 {
 191     /* if it matches the general domain name search, and contains an */
 192     /* alphabetic character, consider it a possible domain name */
 193     if (regexec(&domainname, key, 0, NULL, 0) == 0) {
 194         if (regexec(&domainalpha, key, 0, NULL, 0) == 0) {
 195             return 1;
 196         }
 197     }
 198     return 0;
 199 } 
 200 
 201 /* check for a host name (could be a domain, or an IP) */
 202 static unsigned int 
 203 wk_is_hostname (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 204 {
 205     /* Fix - should check for IPADDRESS, not IPRANGE.  - Shane */
 206     return (wk_is_domain(key) || (regexec(&ipaddress, key, 0, NULL, 0) == 0));
 207 } /* wk_is_hostname() */
 208 
 209 /* WK_to_string() */
 210 /*++++++++++++++++++++++++++++++++++++++
 211   Convert the which keytypes bitmap into a string.
 212 
 213   mask_t wk The which keytypes mask to be converted.
 214 
 215   More:
 216   +html+ <PRE>
 217   Authors:
 218         ottrey
 219   +html+ </PRE><DL COMPACT>
 220   +html+ <DT>Online References:
 221   +html+ <DD><UL>
 222   +html+ </UL></DL>
 223 
 224   ++++++++++++++++++++++++++++++++++++++*/
 225 char *
 226 WK_to_string (mask_t wk) 
     /* [<][>][^][v][top][bottom][index][help] */
 227 {
 228 
 229   return MA_to_string(wk, Keytypes);
 230 
 231 } /* WK_to_string() */
 232 
 233 /* WK_new() */
 234 /*++++++++++++++++++++++++++++++++++++++
 235   Create a new which keytypes bitmap.
 236 
 237   This checks the string to see which keys it looks like.  This helps 
 238   us decide what SQL tables (or radix trees) we need to query for a
 239   match.
 240 
 241   char *key The key to be examined.
 242 
 243   More:
 244   +html+ <PRE>
 245   Authors:
 246         ottrey
 247         shane
 248   +html+ </PRE><DL COMPACT>
 249   +html+ <DT>Online References:
 250   +html+ <DD><UL>
 251   +html+ </UL></DL>
 252 
 253   ++++++++++++++++++++++++++++++++++++++*/
 254 mask_t 
 255 WK_new (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 256 {
 257   static pthread_once_t once_control = PTHREAD_ONCE_INIT;
 258 
 259   mask_t wk; 
 260   int i;
 261 
 262   /* initialize our regular expressions on the first call */
 263   pthread_once(&once_control, wk_regex_init);
 264 
 265   /* empty bitmask */
 266   wk = MA_new(MA_END);
 267 
 268   /* search regular expressions in the list */
 269   for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 270       if (regexec(&wk_regex_list[i].regex, key, 0, NULL, 0) == 0) { 
 271           MA_set(&wk, wk_regex_list[i].key_type, 1);
 272       }
 273   }
 274 
 275   /* check our more complicated key patterns */
 276   MA_set(&wk, WK_NAME,         wk_is_name(key));
 277   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
 278   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
 279   
 280   /* return resulting bitmask */
 281   return wk;
 282 
 283 } /* WK_new() */

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