modules/wk/which_keytypes.c
/* [<][>][^][v][top][bottom][index][help] */
FUNCTIONS
This source file includes following functions.
- matching
- perform_regex_test
- isipv6prefix_a
- isipv6prefix
- islen
- isnet
- isasnum
- isnetname
- ismaintainer
- islimerick
- isnichandle_joao
- isnichandle
- isaskeyword
- isasmacro
- isclnskeyword
- ispeerkeyword
- isnetlist
- iscommunity
- isaspref
- isnetnum
- isipaddr
- ismask
- isclnsprefix
- issubdomname
- isdomname
- isname_a
- isname_b
- isname_ab
- isname
- isphone_a
- isphone_b
- isphone_ab
- isphone
- isemail
- isbrace
- isparen
- wk_is_name
- wk_is_nichdl
- wk_is_email
- wk_is_maint
- wk_is_keycert
- wk_is_iprange
- wk_is_ip6range
- wk_is_netname
- wk_is_asnum
- wk_is_assetname
- wk_is_routesetname
- wk_is_domname
- wk_is_hostname
- wk_is_limerickname
- WK_to_string
- WK_new
/***************************************
$Revision: 1.5 $
Example code: Determine which keys to look for.
This is based on the C code that was reversed engineered from existing Perl
code. (~ottrey/which_table/which_table.c)
******************/ /******************
Copyright (c) 1999 RIPE NCC
All Rights Reserved
Permission to use, copy, modify, and distribute this software and its
documentation for any purpose and without fee is hereby granted,
provided that the above copyright notice appear in all copies and that
both that copyright notice and this permission notice appear in
supporting documentation, and that the name of the author not be
used in advertising or publicity pertaining to distribution of the
software without specific, written prior permission.
THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL
AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY
DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN
AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
***************************************/
#include <stdio.h>
#include <strings.h>
#include <libgen.h>
#include "isnic.h"
#include "bitmask.h"
#include "which_keytypes.h"
#define DOMAINNAME "^[ ]*[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*[ ]*$"
#define LEN_MIN 0
#define LEN_MAX 32
#define NETLEN 16
#define NETQUADS 4
#define NETQUAD_MIN 0
#define NETQUAD_MAX 255
#define ASNUM_MIN 1
#define ASNUM_MAX 65535
#define ASNUM_NUMOFFSET 2 /* XXX - (This is really kludgy!) Offset to the number bit of ASNUM */
#define VALIDIP6 "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$"
/*
XXX Why doesn't this work?
#define NET "^([0-9]{1,3}.){4}$"
*/
#define NET "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$"
#define ASNUM "^AS[1-9]+[0-9]*$"
#define NETNAME "^[A-Z][A-Z0-9-]*$"
#define MAINTAINER "^[A-Z][A-Z0-9-]*$"
#define LIMERICK "^LIM-[A-Z0-9-]+$"
#define KEYCERT "^PGPKEY-[0-9A-F]{8}$"
#define ASMACRO "^AS-[A-Z]+$"
#define ROUTESETNAME "^RS-[A-Z0-9-]*$"
#define ASSETNAME "^AS-[A-Z0-9-]*$"
#define AUTONICPREFIXREGULAR "^AUTO-"
/*
XXX This seems to be the same as the Perl code. But I don't see where a " " is allowed for.
I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$
Does \w include [ ;:,?/}{()+*#] ?
#define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$"
*/
#define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$"
#define PHONE_A "^[ ]*[+][0-9 ]*[(]{0,1}[0-9 -]+[)]{0,1}[0-9 -]*(ext\\.){0,1}[0-9 ]*$"
#define VALIDIP4PREFIX
#define EMAIL "^[a-zA-Z0-9--]*@[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*$"
/*+ Keytype strings +*/
char * const Keytypes[] = {
"name",
"nichdl",
"email",
"maint",
"pgpkey",
"iprange",
"ip6range",
"netname",
"asnum",
"assetname",
"routesetname",
"domname",
"hostname",
"limerickname",
NULL
}; /* Keytypes[] */
/*+ Peerword strings +*/
const char * Peerword[] = {
"EGP",
"BGP",
"BGP4",
"IDRP",
"IGP",
"HELLO",
"IGRP",
"EIGRP",
"OSPF",
"ISIS",
"RIP",
"RIP2",
"OTHER",
""
}; /* Peerword[] */
static int matching(char *string, char left_c, char right_c) {
/* [<][>][^][v][top][bottom][index][help] */
int result;
int i;
int length;
int count=0;
length = strlen(string);
for(i=0; i < length; i++) {
/*
switch ((int)string[i]) {
case left_c:
break;
case right_c:
count--;
break;
default:
}
*/
if (string[i] == left_c) {
count++;
}
if (string[i] == right_c) {
count--;
}
}
if (count == 0) {
/* Matching characters */
result=1;
}
else {
/* Non-matching characters */
result=0;
}
return result;
} /* matching() */
static int perform_regex_test(const char *pattern, char *string) {
/* [<][>][^][v][top][bottom][index][help] */
char *return_value;
int match;
char *re;
re = regcmp(pattern, (char*)0);
if (regex(re, string) == NULL) {
match = 0;
}
else {
match = 1;
}
free(re);
return match;
}
static int isipv6prefix_a(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isipv6prefix\n");
*/
int result='-';
result = perform_regex_test(VALIDIP6, string);
return result;
}
static int isipv6prefix(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isipv6prefix\n");
*/
int result='-';
return result;
}
static int islen(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("islen\n");
*/
int result='-';
int length;
length = strlen(string);
if ((length <= LEN_MAX) && (length >= LEN_MIN)) {
/* A valid length */
result=1;
}
else if (length < 0) {
/* An invalid length */
result=-1;
}
else {
/* An invalid length */
result=0;
}
return result;
}
static int isnet(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isnet\n");
*/
int result='-';
char tmp_string[NETLEN];
int quad_value;
char *quad_value_str;
/* First check if the string is in quad form */
result = perform_regex_test(NET, string);
/* Then check if the quad values are between NETQUAD_MIN and NETQUAD_MAX */
if (result == 1) {
strncpy(tmp_string, string, NETLEN);
quad_value_str = strtok(tmp_string, ".");
while (quad_value_str != NULL) {
quad_value = atoi(quad_value_str);
if ((quad_value < NETQUAD_MIN) || (quad_value > NETQUAD_MAX)) {
/* an invalid value */
result=0;
break;
}
quad_value_str = strtok(NULL, ".");
}
}
return result;
}
static int isasnum(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isasnum\n");
*/
int result='-';
int as_value;
/* First check if the string matches an ASNUM */
result = perform_regex_test(ASNUM, string);
/* Then check if the value is between ASNUM_MIN and ASNUM_MAX */
if (result == 1) {
as_value = atoi(string+ASNUM_NUMOFFSET);
if ((as_value < ASNUM_MIN) || (as_value > ASNUM_MAX)) {
/* an invalid value */
result=0;
}
}
return result;
}
static int isnetname(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isnetname\n");
*/
int result='-';
result = perform_regex_test(NETNAME, string);
return result;
}
static int ismaintainer(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("ismaintainer\n");
*/
int result='-';
result = perform_regex_test(MAINTAINER, string);
return result;
}
static int islimerick(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("islimerick\n");
*/
int result='-';
result = perform_regex_test(LIMERICK, string);
return result;
}
/*******************************************************
# the problem is as follows:
#
# we can never find out which NIC handles are possible on the
# globe since we don't know that they exist
#
# we want to solve this with once with DNS :
#
# RIPE.registries.int CNAME whois.ripe.net
# InterNIC.registries.int CNAME whois.internic.net
# and so on...
#
# 1) it first does a basic syntax check
#
# notes:
#
# - catches InterNIC handles
# - catches the JP|JP-JP APNIC exceptions
# - limits the number of initials to three with a good reason:
# we have a much better chance to find syntax errors like:
# RIPE-DK13 and other problems like this
#
# 2) checks for valid suffixes
# - all 'source:' attribute values from sites that we mirror
# are allowed
# - country codes are allowed for APNIC compatibility
# - APNIC AP|CC-AU exceptions are handled correctly
# - -ORG organization InterNIC handles
# - -ARIN ARIN handles
# - -ORG-ARIN ARIN handles
********************************************************/
static int isnichandle_joao(char *nichdl) {
/* [<][>][^][v][top][bottom][index][help] */
char *regexp, *match;
char ret[1024];
char *suffix;
int i;
/* set ret to the empty string *.
ret[0]='\0';
/** Return if there are any lower case characters */
regexp = regcmp("[a-z]",(char *)0);
match = regex(regexp,nichdl);
free(regexp);
if (match) return 0;
/*
# Japanese NIC handles
#
# leading zeros in the number part *are* allowed
#
# e.g. AB021JP AB199JP-JP
#
*/
regexp = regcmp("[A-Z]{2}[0-9]{3}JP(-JP){0,1}",(char *)0);
match = regex(regexp,nichdl);
free(regexp);
if (match) return 1;
/*
# Standard NIC handles
#
# leading zeros in the number part are *not* allowed
#
# InterNIC - TBQ, IP4
# RIPE format - AB1-RIPE
# APNIC use two letter country code suffix
# Austraila have used -1-AU, -2-AU, -CC-AU suffix.
# Internic used -ORG suffix
# ARIN use -ARIN suffix
# ARIN also use -ORG-ARIN suffix
#
*/
regexp = regcmp("^[A-Z]{2,4}([1-9][0-9]{0,5}){0,1}((-[^ ]+){0,1})$0$",(char *)0);
match = regex(regexp,nichdl,ret);
free(regexp);
if (match == NULL) {
return 0;
} else {
if (ret[0] == '\0') {
return 1;
} else {
/* strip leading '-' */
suffix = ret+1;
/* suffix of local sources */
for (i=0;i<=NUM_NICPOSTFIX;i++) {
if ( !strcmp(suffix,nicpostfix[i]) ) {
return 1;
}
}
/* country codes */
for (i=0;i<NUM_COUNTRIES;i++) {
if ( !strcmp(suffix,countries[i]) ) {
return 1;
}
}
/* special suffix */
for (i=0;i<NUM_SPECIAL;i++) {
if ( !strcmp(suffix,special[i]) ) {
return 1;
}
}
}
}
return 0;
} /* isnichandle_joao() */
static int isnichandle(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
return isnichandle_joao(string);
}
static int isaskeyword(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isaskeyword\n");
*/
int result='-';
return result;
}
static int isasmacro(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isasmacro\n");
*/
int result='-';
result = perform_regex_test(ASMACRO, string);
return result;
}
static int isclnskeyword(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isclnskeyword\n");
*/
int result='-';
return result;
}
static int ispeerkeyword(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("ispeerkeyword\n");
*/
int result='-';
int i;
result=0;
for (i=0; Peerword[i] != ""; i++) {
if ( strcmp(Peerword[i], string) == 0 ) {
result=1;
break;
}
}
return result;
}
static int isnetlist(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isnetlist\n");
*/
int result='-';
return result;
}
static int iscommunity(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("iscommunity\n");
*/
int result='-';
return result;
}
static int isaspref(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isaspref\n");
*/
int result='-';
return result;
}
static int isnetnum(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isnetnum\n");
*/
int result='-';
/* XXX - I don't see the difference between isnet and isnetnum */
result=isnet(string);
return result;
}
static int isipaddr(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isipaddr\n");
*/
int result='-';
return result;
}
static int ismask(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("ismask\n");
*/
int result='-';
return result;
}
static int isclnsprefix(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isclnsprefix\n");
*/
int result='-';
return result;
}
static int issubdomname(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("issubdomname\n");
*/
int result='-';
result = perform_regex_test(DOMAINNAME, string);
return result;
}
static int isdomname(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isdomname\n");
*/
int result='-';
result = perform_regex_test(DOMAINNAME, string);
return result;
}
/*
I split the isname up into isname_a & isname_b. And created isname_ab to join them together.
- So I can test it properly. -ottrey
*/
static int isname_a(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isname_a\n");
*/
int result='-';
result = perform_regex_test(AUTONICPREFIXREGULAR, string);
return result;
}
static int isname_b(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isname_b\n");
*/
int result='-';
result = perform_regex_test(NAME_B, string);
return result;
}
static int isname_ab(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isname_ab\n");
*/
int result='-';
/* Note: the different logic here because I use 0 to be a match and 1 to not be a match.
The Perl code uses the opposite. - ottrey */
result = !(isname_a(string) && !isname_b(string));
return result;
}
static int isname(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isname\n");
*/
int result='-';
return result;
}
static int isphone_a(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isphone_a\n");
*/
int result='-';
result = perform_regex_test(PHONE_A, string);
return result;
}
static int isphone_b(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isphone_b\n");
*/
int result='-';
result = isparen(string);
return result;
}
static int isphone_ab(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isphone_ab\n");
*/
int result='-';
/* Note: the different logic here because I use 0 to be a match and 1 to not be a match.
The Perl code uses the opposite. - ottrey */
result = !(!isphone_a(string) && !isphone_b(string));
return result;
}
static int isphone(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isphone\n");
*/
int result='-';
return result;
}
static int isemail(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isemail\n");
*/
int result='-';
result = perform_regex_test(EMAIL, string);
return result;
}
static int isbrace(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isbrace\n");
*/
int result='-';
result=matching(string, '{', '}');
return result;
}
static int isparen(char *string) {
/* [<][>][^][v][top][bottom][index][help] */
/*
printf("isparen\n");
*/
int result='-';
result=matching(string, '(', ')');
return result;
}
/* ****** The new bunch ******* */
static int wk_is_name(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
/* Everything matches to name */
return 1;
} /* wk_is_name() */
static int wk_is_nichdl(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isnichandle(key);
} /* wk_is_nichdl() */
static int wk_is_email(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isemail(key);
} /* wk_is_email() */
static int wk_is_maint(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return ismaintainer(key);
} /* wk_is_maint() */
static int wk_is_keycert(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
int result=1;
result = perform_regex_test(KEYCERT, key);
return result;
} /* wk_is_pgpkey() */
static int wk_is_iprange(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
int result=1;
/* XXX This is not very strict - but will cut out a lot of invalids */
/* XXX And has been given a bad name and does a few things. */
/* XXX This needs work. */
#define IPRANGE "^[0-9./ -]*$"
result = perform_regex_test(IPRANGE, key);
return result;
} /* wk_is_iprange() */
static int wk_is_ip6range(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isipv6prefix_a(key);
} /* wk_is_ip6range() */
static int wk_is_netname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isnetname(key);
} /* wk_is_netname() */
static int wk_is_asnum(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isasnum(key);
} /* wk_is_asnum() */
static int wk_is_assetname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
int result=1;
result = perform_regex_test(ASSETNAME, key);
return result;
} /* wk_is_assetname() */
static int wk_is_routesetname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
int result=1;
result = perform_regex_test(ROUTESETNAME, key);
return result;
} /* wk_is_routesetname() */
static int wk_is_domname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return isdomname(key);
} /* wk_is_domname() */
static int wk_is_hostname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
/* XXX Why is there a hostname & a domainname? */
/* Answer - hostname can be a domainname or an IP */
return (isdomname(key) || wk_is_iprange(key));
} /* wk_is_hostname() */
static int wk_is_limerickname(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
return islimerick(key);
} /* wk_is_limerickname() */
/* WK_to_string() */
/*++++++++++++++++++++++++++++++++++++++
Convert the which keytypes bitmap into a string.
mask_t wk The which keytypes mask to be converted.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
char *WK_to_string(mask_t wk) {
/* [<][>][^][v][top][bottom][index][help] */
return MA_to_string(wk, Keytypes, 1, 0);
} /* WK_to_string() */
/* WK_new() */
/*++++++++++++++++++++++++++++++++++++++
Create a new which keytypes bitmap.
char *key The key to be examined.
More:
+html+ <PRE>
Authors:
ottrey
+html+ </PRE><DL COMPACT>
+html+ <DT>Online References:
+html+ <DD><UL>
+html+ </UL></DL>
++++++++++++++++++++++++++++++++++++++*/
mask_t WK_new(char *key) {
/* [<][>][^][v][top][bottom][index][help] */
mask_t wk;
wk = MA_new(MA_END);
MA_set(&wk, WK_NAME, wk_is_name(key));
MA_set(&wk, WK_NICHDL, wk_is_nichdl(key));
MA_set(&wk, WK_EMAIL, wk_is_email(key));
MA_set(&wk, WK_MAINT, wk_is_maint(key));
MA_set(&wk, WK_KEYCERT, wk_is_keycert(key));
MA_set(&wk, WK_IPRANGE, wk_is_iprange(key));
MA_set(&wk, WK_IP6RANGE, wk_is_ip6range(key));
MA_set(&wk, WK_NETNAME, wk_is_netname(key));
MA_set(&wk, WK_ASNUM, wk_is_asnum(key));
MA_set(&wk, WK_ASSETNAME, wk_is_assetname(key));
MA_set(&wk, WK_ROUTESETNAME, wk_is_routesetname(key));
MA_set(&wk, WK_DOMNAME, wk_is_domname(key));
MA_set(&wk, WK_HOSTNAME, wk_is_hostname(key));
MA_set(&wk, WK_LIMERICKNAME, wk_is_limerickname(key));
return wk;
} /* WK_new() */