1 | /*************************************** 2 | $Revision: 1.9 $ 3 | 4 | Example code: Determine which keys to look for. 5 | 6 | This is based on the C code that was reversed engineered from existing Perl 7 | code. (~ottrey/which_table/which_table.c) 8 | 9 | ******************/ /****************** 10 | Copyright (c) 1999 RIPE NCC 11 | 12 | All Rights Reserved 13 | 14 | Permission to use, copy, modify, and distribute this software and its 15 | documentation for any purpose and without fee is hereby granted, 16 | provided that the above copyright notice appear in all copies and that 17 | both that copyright notice and this permission notice appear in 18 | supporting documentation, and that the name of the author not be 19 | used in advertising or publicity pertaining to distribution of the 20 | software without specific, written prior permission. 21 | 22 | THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING 23 | ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS; IN NO EVENT SHALL 24 | AUTHOR BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY 25 | DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN 26 | AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF 27 | OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. 28 | ***************************************/ 29 | #include <stdio.h> 30 | #include <strings.h> 31 | #include <libgen.h> 32 | #include <glib.h> 33 | 34 | #include "isnic.h" 35 | #include "bitmask.h" 36 | #include "which_keytypes.h" 37 | 38 | 39 | #define DOMAINNAME "^[ ]*[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*[ ]*$" 40 | 41 | #define LEN_MIN 0 42 | #define LEN_MAX 32 43 | 44 | #define NETLEN 16 45 | #define NETQUADS 4 46 | #define NETQUAD_MIN 0 47 | #define NETQUAD_MAX 255 48 | 49 | #define ASNUM_MIN 1 50 | #define ASNUM_MAX 65535 51 | #define ASNUM_NUMOFFSET 2 /* XXX - (This is really kludgy!) Offset to the number bit of ASNUM */ 52 | 53 | #define VALIDIP6 "^[0-9A-F]{1,4}(:[0-9A-F]{1,4}){7}$" 54 | /* 55 | XXX Why doesn't this work? 56 | #define NET "^([0-9]{1,3}.){4}$" 57 | */ 58 | #define NET "^[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}.[0-9]{1,3}$" 59 | 60 | #define ASNUM "^AS[1-9]+[0-9]*$" 61 | 62 | #define NETNAME "^[A-Z][A-Z0-9-]*$" 63 | 64 | #define MAINTAINER "^[A-Z][A-Z0-9-]*$" 65 | 66 | #define LIMERICK "^LIM-[A-Z0-9-]+$" 67 | 68 | #define KEYCERT "^PGPKEY-[0-9A-F]{8}$" 69 | 70 | #define ASMACRO "^AS-[A-Z]+$" 71 | 72 | #define ROUTESETNAME "^RS-[A-Z0-9-]*$" 73 | 74 | #define ASSETNAME "^AS-[A-Z0-9-]*$" 75 | 76 | #define AUTONICPREFIXREGULAR "^AUTO-" 77 | 78 | /* 79 | XXX This seems to be the same as the Perl code. But I don't see where a " " is allowed for. 80 | I.e. Perl -> ^[a-zA-Z][\w\-\.\'\|\`]*$ 81 | Does \w include [ ;:,?/}{()+*#] ? 82 | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`-]*$" 83 | */ 84 | #define NAME_B "^[a-zA-Z][a-zA-Z_0-9.'|`;:,?/}{()+*#&-]*$" 85 | 86 | #define PHONE_A "^[ ]*[+][0-9 ]*[(]{0,1}[0-9 -]+[)]{0,1}[0-9 -]*(ext\\.){0,1}[0-9 ]*$" 87 | 88 | #define VALIDIP4PREFIX 89 | 90 | #define EMAIL "^[.a-zA-Z0-9--]*@[a-zA-Z0-9--]*(\\.[a-zA-Z0-9--]+)*$" 91 | 92 | 93 | /*+ Keytype strings +*/ 94 | char * const Keytypes[] = { 95 | "name", 96 | "nic_hdl", 97 | "email", 98 | "mntner", 99 | "key_cert", 100 | "iprange", 101 | "ipprefix", 102 | "ip6prefix", 103 | "netname", 104 | "net6name", 105 | "autnum", 106 | "assetname", 107 | "routesetname", 108 | "domain", 109 | "hostname", 110 | "limerick", 111 | NULL 112 | }; /* Keytypes[] */ 113 | 114 | /*+ Peerword strings +*/ 115 | const char * Peerword[] = { 116 | "EGP", 117 | "BGP", 118 | "BGP4", 119 | "IDRP", 120 | "IGP", 121 | "HELLO", 122 | "IGRP", 123 | "EIGRP", 124 | "OSPF", 125 | "ISIS", 126 | "RIP", 127 | "RIP2", 128 | "OTHER", 129 | "" 130 | }; /* Peerword[] */ 131 | 132 | static int matching(char *string, char left_c, char right_c) { 133 | int result; 134 | 135 | int i; 136 | int length; 137 | int count=0; 138 | 139 | length = strlen(string); 140 | 141 | for(i=0; i < length; i++) { 142 | /* 143 | switch ((int)string[i]) { 144 | case left_c: 145 | break; 146 | 147 | case right_c: 148 | count--; 149 | break; 150 | 151 | default: 152 | } 153 | */ 154 | if (string[i] == left_c) { 155 | count++; 156 | } 157 | if (string[i] == right_c) { 158 | count--; 159 | } 160 | } 161 | 162 | if (count == 0) { 163 | /* Matching characters */ 164 | result=1; 165 | } 166 | else { 167 | /* Non-matching characters */ 168 | result=0; 169 | } 170 | 171 | return result; 172 | 173 | } /* matching() */ 174 | 175 | 176 | static int perform_regex_test(const char *pattern, char *string) { 177 | char *return_value; 178 | int match; 179 | 180 | char *re; 181 | 182 | re = regcmp(pattern, (char*)0); 183 | if (regex(re, string) == NULL) { 184 | match = 0; 185 | } 186 | else { 187 | match = 1; 188 | } 189 | 190 | free(re); 191 | 192 | return match; 193 | 194 | } 195 | 196 | static int isipv6prefix_a(char *string) { 197 | /* 198 | printf("isipv6prefix\n"); 199 | */ 200 | int result='-'; 201 | 202 | result = perform_regex_test(VALIDIP6, string); 203 | 204 | return result; 205 | } 206 | 207 | static int isipv6prefix(char *string) { 208 | /* 209 | printf("isipv6prefix\n"); 210 | */ 211 | int result='-'; 212 | 213 | return result; 214 | } 215 | 216 | static int islen(char *string) { 217 | /* 218 | printf("islen\n"); 219 | */ 220 | int result='-'; 221 | int length; 222 | 223 | length = strlen(string); 224 | 225 | if ((length <= LEN_MAX) && (length >= LEN_MIN)) { 226 | /* A valid length */ 227 | result=1; 228 | } 229 | else if (length < 0) { 230 | /* An invalid length */ 231 | result=-1; 232 | } 233 | else { 234 | /* An invalid length */ 235 | result=0; 236 | } 237 | 238 | return result; 239 | } 240 | 241 | static int isnet(char *string) { 242 | /* 243 | printf("isnet\n"); 244 | */ 245 | int result='-'; 246 | int i; 247 | int quad_value; 248 | gchar **quad_value_strs; 249 | 250 | /* First check if the string is in quad form */ 251 | result = perform_regex_test(NET, string); 252 | 253 | /* Then check if the quad values are between NETQUAD_MIN and NETQUAD_MAX */ 254 | if (result == 1) { 255 | quad_value_strs = g_strsplit(string, ".", 0); 256 | for (i=0; quad_value_strs[i] != NULL; i++) { 257 | quad_value = atoi(quad_value_strs[i]); 258 | if ((quad_value < NETQUAD_MIN) || (quad_value > NETQUAD_MAX)) { 259 | /* an invalid value */ 260 | result=0; 261 | break; 262 | } 263 | } 264 | } 265 | 266 | return result; 267 | } 268 | 269 | static int isasnum(char *string) { 270 | /* 271 | printf("isasnum\n"); 272 | */ 273 | int result='-'; 274 | int as_value; 275 | 276 | /* First check if the string matches an ASNUM */ 277 | result = perform_regex_test(ASNUM, string); 278 | 279 | /* Then check if the value is between ASNUM_MIN and ASNUM_MAX */ 280 | if (result == 1) { 281 | as_value = atoi(string+ASNUM_NUMOFFSET); 282 | if ((as_value < ASNUM_MIN) || (as_value > ASNUM_MAX)) { 283 | /* an invalid value */ 284 | result=0; 285 | } 286 | } 287 | 288 | return result; 289 | } 290 | 291 | static int isnetname(char *string) { 292 | /* 293 | printf("isnetname\n"); 294 | */ 295 | int result='-'; 296 | 297 | result = perform_regex_test(NETNAME, string); 298 | 299 | return result; 300 | } 301 | 302 | static int ismaintainer(char *string) { 303 | /* 304 | printf("ismaintainer\n"); 305 | */ 306 | int result='-'; 307 | 308 | result = perform_regex_test(MAINTAINER, string); 309 | 310 | return result; 311 | } 312 | 313 | static int islimerick(char *string) { 314 | /* 315 | printf("islimerick\n"); 316 | */ 317 | int result='-'; 318 | 319 | result = perform_regex_test(LIMERICK, string); 320 | 321 | return result; 322 | } 323 | 324 | /******************************************************* 325 | # the problem is as follows: 326 | # 327 | # we can never find out which NIC handles are possible on the 328 | # globe since we don't know that they exist 329 | # 330 | # we want to solve this with once with DNS : 331 | # 332 | # RIPE.registries.int CNAME whois.ripe.net 333 | # InterNIC.registries.int CNAME whois.internic.net 334 | # and so on... 335 | 336 | # 337 | # 1) it first does a basic syntax check 338 | # 339 | # notes: 340 | # 341 | # - catches InterNIC handles 342 | # - catches the JP|JP-JP APNIC exceptions 343 | # - limits the number of initials to three with a good reason: 344 | # we have a much better chance to find syntax errors like: 345 | # RIPE-DK13 and other problems like this 346 | # 347 | # 2) checks for valid suffixes 348 | # - all 'source:' attribute values from sites that we mirror 349 | # are allowed 350 | # - country codes are allowed for APNIC compatibility 351 | # - APNIC AP|CC-AU exceptions are handled correctly 352 | # - -ORG organization InterNIC handles 353 | # - -ARIN ARIN handles 354 | # - -ORG-ARIN ARIN handles 355 | ********************************************************/ 356 | static int isnichandle_joao(char *nichdl) { 357 | 358 | char *regexp, *match; 359 | char ret[1024]; 360 | char *suffix; 361 | 362 | int i; 363 | 364 | /* set ret to the empty string *. 365 | ret[0]='\0'; 366 | /** Return if there are any lower case characters */ 367 | 368 | regexp = regcmp("[a-z]",(char *)0); 369 | match = regex(regexp,nichdl); 370 | free(regexp); 371 | if (match) return 0; 372 | 373 | /* 374 | # Japanese NIC handles 375 | # 376 | # leading zeros in the number part *are* allowed 377 | # 378 | # e.g. AB021JP AB199JP-JP 379 | # 380 | */ 381 | regexp = regcmp("[A-Z]{2}[0-9]{3}JP(-JP){0,1}",(char *)0); 382 | match = regex(regexp,nichdl); 383 | free(regexp); 384 | if (match) return 1; 385 | 386 | /* 387 | # Standard NIC handles 388 | # 389 | # leading zeros in the number part are *not* allowed 390 | # 391 | # InterNIC - TBQ, IP4 392 | # RIPE format - AB1-RIPE 393 | # APNIC use two letter country code suffix 394 | # Austraila have used -1-AU, -2-AU, -CC-AU suffix. 395 | # Internic used -ORG suffix 396 | # ARIN use -ARIN suffix 397 | # ARIN also use -ORG-ARIN suffix 398 | # 399 | */ 400 | regexp = regcmp("^[A-Z]{2,4}([1-9][0-9]{0,5}){0,1}((-[^ ]+){0,1})$0$",(char *)0); 401 | match = regex(regexp,nichdl,ret); 402 | 403 | free(regexp); 404 | 405 | if (match == NULL) { 406 | return 0; 407 | } else { 408 | if (ret[0] == '\0') { 409 | return 1; 410 | } else { 411 | /* strip leading '-' */ 412 | suffix = ret+1; 413 | /* suffix of local sources */ 414 | for (i=0;i<=NUM_NICPOSTFIX;i++) { 415 | if ( !strcmp(suffix,nicpostfix[i]) ) { 416 | return 1; 417 | } 418 | } 419 | /* country codes */ 420 | for (i=0;i<NUM_COUNTRIES;i++) { 421 | if ( !strcmp(suffix,countries[i]) ) { 422 | return 1; 423 | } 424 | } 425 | /* special suffix */ 426 | for (i=0;i<NUM_SPECIAL;i++) { 427 | if ( !strcmp(suffix,special[i]) ) { 428 | return 1; 429 | } 430 | } 431 | } 432 | } 433 | return 0; 434 | } /* isnichandle_joao() */ 435 | 436 | 437 | static int isnichandle(char *string) { 438 | return isnichandle_joao(string); 439 | } 440 | 441 | static int isaskeyword(char *string) { 442 | /* 443 | printf("isaskeyword\n"); 444 | */ 445 | int result='-'; 446 | 447 | return result; 448 | } 449 | 450 | static int isasmacro(char *string) { 451 | /* 452 | printf("isasmacro\n"); 453 | */ 454 | int result='-'; 455 | 456 | result = perform_regex_test(ASMACRO, string); 457 | 458 | return result; 459 | } 460 | 461 | static int isclnskeyword(char *string) { 462 | /* 463 | printf("isclnskeyword\n"); 464 | */ 465 | int result='-'; 466 | 467 | return result; 468 | } 469 | 470 | static int ispeerkeyword(char *string) { 471 | /* 472 | printf("ispeerkeyword\n"); 473 | */ 474 | int result='-'; 475 | int i; 476 | 477 | result=0; 478 | for (i=0; Peerword[i] != ""; i++) { 479 | if ( strcmp(Peerword[i], string) == 0 ) { 480 | result=1; 481 | break; 482 | } 483 | } 484 | 485 | return result; 486 | } 487 | 488 | static int isnetlist(char *string) { 489 | /* 490 | printf("isnetlist\n"); 491 | */ 492 | int result='-'; 493 | 494 | return result; 495 | } 496 | 497 | static int iscommunity(char *string) { 498 | /* 499 | printf("iscommunity\n"); 500 | */ 501 | int result='-'; 502 | 503 | return result; 504 | } 505 | 506 | static int isaspref(char *string) { 507 | /* 508 | printf("isaspref\n"); 509 | */ 510 | int result='-'; 511 | 512 | return result; 513 | } 514 | 515 | static int isnetnum(char *string) { 516 | /* 517 | printf("isnetnum\n"); 518 | */ 519 | int result='-'; 520 | 521 | /* XXX - I don't see the difference between isnet and isnetnum */ 522 | result=isnet(string); 523 | 524 | return result; 525 | } 526 | 527 | static int isipaddr(char *string) { 528 | /* 529 | printf("isipaddr\n"); 530 | */ 531 | int result='-'; 532 | 533 | return result; 534 | } 535 | 536 | static int ismask(char *string) { 537 | /* 538 | printf("ismask\n"); 539 | */ 540 | int result='-'; 541 | 542 | return result; 543 | } 544 | 545 | static int isclnsprefix(char *string) { 546 | /* 547 | printf("isclnsprefix\n"); 548 | */ 549 | int result='-'; 550 | 551 | return result; 552 | } 553 | 554 | static int issubdomname(char *string) { 555 | /* 556 | printf("issubdomname\n"); 557 | */ 558 | int result='-'; 559 | 560 | result = perform_regex_test(DOMAINNAME, string); 561 | 562 | return result; 563 | } 564 | 565 | static int isdomname(char *string) { 566 | /* 567 | printf("isdomname\n"); 568 | */ 569 | int result='-'; 570 | 571 | result = perform_regex_test(DOMAINNAME, string); 572 | 573 | return result; 574 | } 575 | 576 | /* 577 | I split the isname up into isname_a & isname_b. And created isname_ab to join them together. 578 | - So I can test it properly. -ottrey 579 | */ 580 | static int isname_a(char *string) { 581 | /* 582 | printf("isname_a\n"); 583 | */ 584 | int result='-'; 585 | 586 | result = perform_regex_test(AUTONICPREFIXREGULAR, string); 587 | 588 | return result; 589 | } 590 | 591 | static int isname_b(char *string) { 592 | /* 593 | printf("isname_b\n"); 594 | */ 595 | int result='-'; 596 | 597 | result = perform_regex_test(NAME_B, string); 598 | 599 | return result; 600 | } 601 | 602 | static int isname_ab(char *string) { 603 | /* 604 | printf("isname_ab\n"); 605 | */ 606 | int result='-'; 607 | 608 | /* Note: the different logic here because I use 0 to be a match and 1 to not be a match. 609 | The Perl code uses the opposite. - ottrey */ 610 | result = !(isname_a(string) && !isname_b(string)); 611 | 612 | return result; 613 | } 614 | 615 | static int isname(char *string) { 616 | /* 617 | printf("isname\n"); 618 | */ 619 | int result='-'; 620 | 621 | return result; 622 | } 623 | 624 | static int isphone_a(char *string) { 625 | /* 626 | printf("isphone_a\n"); 627 | */ 628 | int result='-'; 629 | 630 | result = perform_regex_test(PHONE_A, string); 631 | 632 | return result; 633 | } 634 | static int isphone_b(char *string) { 635 | /* 636 | printf("isphone_b\n"); 637 | */ 638 | int result='-'; 639 | 640 | result = isparen(string); 641 | 642 | return result; 643 | } 644 | static int isphone_ab(char *string) { 645 | /* 646 | printf("isphone_ab\n"); 647 | */ 648 | int result='-'; 649 | 650 | /* Note: the different logic here because I use 0 to be a match and 1 to not be a match. 651 | The Perl code uses the opposite. - ottrey */ 652 | result = !(!isphone_a(string) && !isphone_b(string)); 653 | 654 | return result; 655 | } 656 | static int isphone(char *string) { 657 | /* 658 | printf("isphone\n"); 659 | */ 660 | int result='-'; 661 | 662 | return result; 663 | } 664 | 665 | static int isemail(char *string) { 666 | /* 667 | printf("isemail\n"); 668 | */ 669 | int result='-'; 670 | 671 | result = perform_regex_test(EMAIL, string); 672 | 673 | return result; 674 | } 675 | 676 | static int isbrace(char *string) { 677 | /* 678 | printf("isbrace\n"); 679 | */ 680 | int result='-'; 681 | 682 | result=matching(string, '{', '}'); 683 | 684 | return result; 685 | } 686 | 687 | static int isparen(char *string) { 688 | /* 689 | printf("isparen\n"); 690 | */ 691 | int result='-'; 692 | 693 | result=matching(string, '(', ')'); 694 | 695 | return result; 696 | } 697 | 698 | 699 | 700 | 701 | 702 | 703 | 704 | 705 | 706 | 707 | 708 | 709 | 710 | /* ****** The new bunch ******* */ 711 | static int wk_is_name(char *key) { 712 | 713 | /* Everything matches to name */ 714 | return 1; 715 | 716 | } /* wk_is_name() */ 717 | 718 | static int wk_is_nic_hdl(char *key) { 719 | 720 | return isnichandle(key); 721 | 722 | } /* wk_is_nic_hdl() */ 723 | 724 | static int wk_is_email(char *key) { 725 | 726 | return isemail(key); 727 | 728 | } /* wk_is_email() */ 729 | 730 | static int wk_is_mntner(char *key) { 731 | 732 | return ismaintainer(key); 733 | 734 | } /* wk_is_mntner() */ 735 | 736 | static int wk_is_key_cert(char *key) { 737 | int result=1; 738 | 739 | result = perform_regex_test(KEYCERT, key); 740 | 741 | return result; 742 | 743 | } /* wk_is_key_cert() */ 744 | 745 | static int wk_is_iprange(char *key) { 746 | int result=1; 747 | 748 | /* XXX This is not very strict - but will cut out a lot of invalids */ 749 | /* XXX And has been given a bad name and does a few things. */ 750 | /* XXX This needs work. */ 751 | #define IPRANGE "^[0-9./ -]*$" 752 | result = perform_regex_test(IPRANGE, key); 753 | 754 | return result; 755 | 756 | } /* wk_is_iprange() */ 757 | 758 | static int wk_is_ipprefix(char *key) { 759 | int result=1; 760 | 761 | /* XXX INSERT check here! */ 762 | return result; 763 | 764 | } /* wk_is_iprange() */ 765 | 766 | static int wk_is_ip6prefix(char *key) { 767 | 768 | return isipv6prefix_a(key); 769 | 770 | } /* wk_is_ip6prefix() */ 771 | 772 | static int wk_is_netname(char *key) { 773 | 774 | return isnetname(key); 775 | 776 | } /* wk_is_netname() */ 777 | 778 | /* XXX Note: This function uses the same call as wk_is_netname(). */ 779 | static int wk_is_net6name(char *key) { 780 | 781 | return isnetname(key); 782 | 783 | } /* wk_is_netname() */ 784 | 785 | static int wk_is_autnum(char *key) { 786 | 787 | return isasnum(key); 788 | 789 | } /* wk_is_autnum() */ 790 | 791 | static int wk_is_assetname(char *key) { 792 | int result=1; 793 | 794 | result = perform_regex_test(ASSETNAME, key); 795 | 796 | return result; 797 | 798 | } /* wk_is_assetname() */ 799 | 800 | static int wk_is_routesetname(char *key) { 801 | int result=1; 802 | 803 | result = perform_regex_test(ROUTESETNAME, key); 804 | 805 | return result; 806 | 807 | } /* wk_is_routesetname() */ 808 | 809 | static int wk_is_domain(char *key) { 810 | 811 | return isdomname(key); 812 | 813 | } /* wk_is_domname() */ 814 | 815 | static int wk_is_hostname(char *key) { 816 | 817 | /* XXX Why is there a hostname & a domainname? */ 818 | /* Answer - hostname can be a domainname or an IP */ 819 | return (isdomname(key) || wk_is_iprange(key)); 820 | 821 | } /* wk_is_hostname() */ 822 | 823 | static int wk_is_limerick(char *key) { 824 | 825 | return islimerick(key); 826 | 827 | } /* wk_is_limerick() */ 828 | 829 | 830 | /* WK_to_string() */ 831 | /*++++++++++++++++++++++++++++++++++++++ 832 | Convert the which keytypes bitmap into a string. 833 | 834 | mask_t wk The which keytypes mask to be converted. 835 | 836 | More: 837 | +html+ <PRE> 838 | Authors: 839 | ottrey 840 | +html+ </PRE><DL COMPACT> 841 | +html+ <DT>Online References: 842 | +html+ <DD><UL> 843 | +html+ </UL></DL> 844 | 845 | ++++++++++++++++++++++++++++++++++++++*/ 846 | char *WK_to_string(mask_t wk) { 847 | 848 | return MA_to_string(wk, Keytypes); 849 | 850 | } /* WK_to_string() */ 851 | 852 | 853 | /* WK_new() */ 854 | /*++++++++++++++++++++++++++++++++++++++ 855 | Create a new which keytypes bitmap. 856 | 857 | char *key The key to be examined. 858 | 859 | More: 860 | +html+ <PRE> 861 | Authors: 862 | ottrey 863 | +html+ </PRE><DL COMPACT> 864 | +html+ <DT>Online References: 865 | +html+ <DD><UL> 866 | +html+ </UL></DL> 867 | 868 | ++++++++++++++++++++++++++++++++++++++*/ 869 | mask_t WK_new(char *key) { 870 | mask_t wk; 871 | 872 | wk = MA_new(MA_END); 873 | 874 | MA_set(&wk, WK_NAME, wk_is_name(key)); 875 | MA_set(&wk, WK_NIC_HDL, wk_is_nic_hdl(key)); 876 | MA_set(&wk, WK_EMAIL, wk_is_email(key)); 877 | MA_set(&wk, WK_MNTNER, wk_is_mntner(key)); 878 | MA_set(&wk, WK_KEY_CERT, wk_is_key_cert(key)); 879 | MA_set(&wk, WK_IPRANGE, wk_is_iprange(key)); 880 | MA_set(&wk, WK_IPPREFIX, wk_is_ipprefix(key)); 881 | MA_set(&wk, WK_IP6PREFIX, wk_is_ip6prefix(key)); 882 | MA_set(&wk, WK_NETNAME, wk_is_netname(key)); 883 | MA_set(&wk, WK_NET6NAME, wk_is_net6name(key)); 884 | MA_set(&wk, WK_AUTNUM, wk_is_autnum(key)); 885 | MA_set(&wk, WK_ASSETNAME, wk_is_assetname(key)); 886 | MA_set(&wk, WK_ROUTESETNAME, wk_is_routesetname(key)); 887 | MA_set(&wk, WK_DOMAIN, wk_is_domain(key)); 888 | MA_set(&wk, WK_HOSTNAME, wk_is_hostname(key)); 889 | MA_set(&wk, WK_LIMERICK, wk_is_limerick(key)); 890 | 891 | return wk; 892 | 893 | } /* WK_new() */