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.29 $
   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,2002               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 IRT "^IRT-[A-Z0-9_-]+[A-Z0-9]$"
  91 
  92 #define NICHANDLE "^[A-Z0-9-]+$"
  93 
  94 /*
  95   XXX This seems to be the same as the Perl code.  But I don't see where a " " is allowed for.
  96   I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
  97   Does \w include [ ;:,?/}{()+*#] ?
  98 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
  99 */
 100 #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
 101 
 102 #define EMAIL "@[a-zA-Z0-9-]+(\\.[a-zA-Z0-9-]+)*$"
 103 
 104 /* structure for simple keys, with a single regular expression to match */
 105 /* NOTE: the WK_NAME, WK_DOMAIN, and WK_HOSTNAME are not handled here   */
 106 struct {
 107     int key_type;               /* identifier for key, e.g. WK_RTRSET */
 108     char *pattern;              /* string for regular expression */
 109     regex_t regex;              /* regular expression */
 110 } wk_regex_list[] = {
 111     { WK_NIC_HDL,       NICHANDLE },
 112     { WK_EMAIL,         EMAIL },
 113     { WK_MNTNER,        MAINTAINER },
 114     { WK_KEY_CERT,      KEYCERT },
 115     { WK_IPRANGE,       IPRANGE },
 116     { WK_IPADDRESS,     IPADDRESS },
 117     { WK_IPPREFIX,      IPPREFIX },
 118     { WK_IP6PREFIX,     VALIDIP6PREFIX },
 119     { WK_NETNAME,       NETNAME },
 120     { WK_NET6NAME,      NETNAME },
 121     { WK_AUTNUM,        ASNUM },
 122     { WK_ASSETNAME,     ASSETNAME },
 123     { WK_ROUTESETNAME,  ROUTESETNAME },
 124     { WK_LIMERICK,      LIMERICK },
 125     { WK_ASRANGE,       ASRANGE },
 126     { WK_PEERINGSET,    PEERINGSET },
 127     { WK_FILTERSET,     FILTERSET },
 128     { WK_RTRSET,        RTRSET },
 129     { WK_IRT,           IRT }
 130 };
 131 #define WK_REGEX_LIST_LEN  (sizeof(wk_regex_list)/sizeof(wk_regex_list[0]))
 132 
 133 /* regular expressions used by wk_is_name() */
 134 static regex_t ipaddress;
 135 static regex_t ipprefix;
 136 static regex_t validip6prefix;
 137 
 138 /* regular expression used by isdomname() */
 139 static regex_t domainname;
 140 static regex_t domainalpha;
 141 
 142 /* initialize regular expressions */
 143 static void 
 144 wk_regex_init ()
     /* [<][>][^][v][top][bottom][index][help] */
 145 {
 146     int i;
 147     int errcode;
 148 
 149     /* initialize our table */
 150     for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 151         errcode = regcomp(&wk_regex_list[i].regex, 
 152                           wk_regex_list[i].pattern, 
 153                           REG_EXTENDED|REG_NOSUB);
 154         dieif(errcode != 0);
 155     }
 156 
 157     /* add some special cases used by our other functions */
 158     errcode = regcomp(&ipaddress, IPADDRESS, REG_EXTENDED|REG_NOSUB);
 159     dieif(errcode != 0);
 160     errcode = regcomp(&ipprefix, IPPREFIX, REG_EXTENDED|REG_NOSUB);
 161     dieif(errcode != 0);
 162     errcode = regcomp(&validip6prefix, VALIDIP6PREFIX, REG_EXTENDED|REG_NOSUB);
 163     dieif(errcode != 0);
 164     errcode = regcomp(&domainname, DOMAINNAME, REG_EXTENDED|REG_NOSUB);
 165     dieif(errcode != 0);
 166     errcode = regcomp(&domainalpha, DOMAINALPHA, REG_EXTENDED|REG_NOSUB);
 167     dieif(errcode != 0);
 168 }
 169 
 170 
 171 /* see if the key looks like it could be a name */
 172 static unsigned int 
 173 wk_is_name (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 174 {
 175     /* if it's an address, it cannot be a name */
 176     if (regexec(&ipaddress, key, 0, NULL, 0) == 0) { 
 177         return 0;
 178     }
 179     if (regexec(&ipprefix, key, 0, NULL, 0) == 0) { 
 180         return 0;
 181     }
 182     if (regexec(&validip6prefix, key, 0, NULL, 0) == 0) { 
 183         return 0;
 184     }
 185 
 186     /* Everything apart from addresses matches to name */
 187     return 1;
 188 } /* wk_is_name() */
 189 
 190 /* check for domain name */
 191 static unsigned int 
 192 wk_is_domain (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 193 {
 194     /* if it matches the general domain name search, and contains an */
 195     /* alphabetic character, consider it a possible domain name */
 196     if (regexec(&domainname, key, 0, NULL, 0) == 0) {
 197         if (regexec(&domainalpha, key, 0, NULL, 0) == 0) {
 198             return 1;
 199         }
 200     }
 201     return 0;
 202 } 
 203 
 204 /* check for a host name (could be a domain, or an IP) */
 205 static unsigned int 
 206 wk_is_hostname (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 207 {
 208     /* Fix - should check for IPADDRESS, not IPRANGE.  - Shane */
 209     return (wk_is_domain(key) || (regexec(&ipaddress, key, 0, NULL, 0) == 0));
 210 } /* wk_is_hostname() */
 211 
 212 /* WK_to_string() */
 213 /*++++++++++++++++++++++++++++++++++++++
 214   Convert the which keytypes bitmap into a string.
 215 
 216   mask_t wk The which keytypes mask to be converted.
 217 
 218   More:
 219   +html+ <PRE>
 220   Authors:
 221         ottrey
 222   +html+ </PRE><DL COMPACT>
 223   +html+ <DT>Online References:
 224   +html+ <DD><UL>
 225   +html+ </UL></DL>
 226 
 227   ++++++++++++++++++++++++++++++++++++++*/
 228 char *
 229 WK_to_string (mask_t wk) 
     /* [<][>][^][v][top][bottom][index][help] */
 230 {
 231 
 232   return MA_to_string(wk, Keytypes);
 233 
 234 } /* WK_to_string() */
 235 
 236 /* WK_new() */
 237 /*++++++++++++++++++++++++++++++++++++++
 238   Create a new which keytypes bitmap.
 239 
 240   This checks the string to see which keys it looks like.  This helps 
 241   us decide what SQL tables (or radix trees) we need to query for a
 242   match.
 243 
 244   char *key The key to be examined.
 245 
 246   More:
 247   +html+ <PRE>
 248   Authors:
 249         ottrey
 250         shane
 251   +html+ </PRE><DL COMPACT>
 252   +html+ <DT>Online References:
 253   +html+ <DD><UL>
 254   +html+ </UL></DL>
 255 
 256   ++++++++++++++++++++++++++++++++++++++*/
 257 mask_t 
 258 WK_new (char *key) 
     /* [<][>][^][v][top][bottom][index][help] */
 259 {
 260   static pthread_once_t once_control = PTHREAD_ONCE_INIT;
 261 
 262   mask_t wk; 
 263   int i;
 264 
 265   /* initialize our regular expressions on the first call */
 266   pthread_once(&once_control, wk_regex_init);
 267 
 268   /* empty bitmask */
 269   wk = MA_new(MA_END);
 270 
 271   /* search regular expressions in the list */
 272   for (i=0; i<WK_REGEX_LIST_LEN; i++) {
 273       if (regexec(&wk_regex_list[i].regex, key, 0, NULL, 0) == 0) { 
 274           MA_set(&wk, wk_regex_list[i].key_type, 1);
 275       }
 276   }
 277 
 278   /* check our more complicated key patterns */
 279   MA_set(&wk, WK_NAME,         wk_is_name(key));
 280   MA_set(&wk, WK_DOMAIN,       wk_is_domain(key));
 281   MA_set(&wk, WK_HOSTNAME,     wk_is_hostname(key));
 282   
 283   /* return resulting bitmask */
 284   return wk;
 285 
 286 } /* WK_new() */

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