modules/wk/which_keytypes.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- wk_regex_init
- wk_is_name
- wk_is_domain
- wk_is_hostname
- WK_to_string
- 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() */