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.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() */