5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2007 Pekka Riikonen
9 This program is free software; you can redistribute it and/or modify
10 it under the terms of the GNU General Public License as published by
11 the Free Software Foundation; version 2 of the License.
13 This program is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
23 static char *silc_create_pk_identifier(void)
25 char *username = NULL, *realname = NULL;
26 char *hostname, email[256];
30 realname = silc_get_real_name();
33 hostname = silc_net_localhost();
37 /* Get username (mandatory) */
38 username = silc_get_username();
42 /* Create default email address, whether it is right or not */
43 silc_snprintf(email, sizeof(email), "%s@%s", username, hostname);
45 ident = silc_pkcs_silc_encode_identifier(username, hostname, realname,
46 email, NULL, NULL, NULL);
55 /* Generate key pair */
57 SilcBool silc_create_key_pair(const char *pkcs_name,
58 SilcUInt32 key_len_bits,
59 const char *pub_filename,
60 const char *prv_filename,
61 const char *pub_identifier,
62 const char *passphrase,
63 SilcPublicKey *return_public_key,
64 SilcPrivateKey *return_private_key,
69 char *pkfile = pub_filename ? strdup(pub_filename) : NULL;
70 char *prvfile = prv_filename ? strdup(prv_filename) : NULL;
71 char *alg = pkcs_name ? strdup(pkcs_name) : NULL;
72 char *identifier = pub_identifier ? strdup(pub_identifier) : NULL;
73 char *pass = passphrase ? strdup(passphrase) : NULL;
74 SilcPublicKey public_key;
75 SilcPrivateKey private_key;
77 if (interactive && (!alg || !pub_filename || !prv_filename))
79 New pair of keys will be created. Please, answer to following questions.\n\
85 alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
89 if (*alg == 'l' || *alg == 'L') {
90 char *list = silc_pkcs_get_supported();
102 if (!silc_pkcs_find_algorithm(alg, NULL)) {
103 fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
104 "is not initialized", alg);
111 length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
113 key_len_bits = atoi(length);
121 char *def = silc_create_pk_identifier();
124 memset(line, 0, sizeof(line));
126 silc_snprintf(line, sizeof(line), "Identifier [%s]: ", def);
128 silc_snprintf(line, sizeof(line),
129 "Identifier (eg. UN=jon, HN=jon.dummy.com, "
130 "RN=Jon Johnson, E=jon@dummy.com): ");
132 while (!identifier) {
133 identifier = silc_get_input(line, FALSE);
134 if (!identifier && def)
135 identifier = strdup(def);
139 fprintf(stderr, "Could not create public key identifier: %s\n",
143 identifier = strdup(def);
149 rng = silc_rng_alloc();
151 silc_rng_global_init(rng);
155 memset(line, 0, sizeof(line));
156 silc_snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
157 pkfile = silc_get_input(line, FALSE);
160 pkfile = strdup("public_key.pub");
165 memset(line, 0, sizeof(line));
166 silc_snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
167 prvfile = silc_get_input(line, FALSE);
170 prvfile = strdup("private_key.prv");
176 pass = silc_get_input("Private key passphrase: ", TRUE);
183 pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
186 match = !strcmp(pass, pass2);
190 fprintf(stderr, "\nPassphrases do not match\n\n");
196 printf("\nGenerating the key pair...\n");
199 if (!silc_pkcs_silc_generate_key(alg, key_len_bits,
200 identifier, rng, &public_key,
204 /* Save public key into file */
205 silc_pkcs_save_public_key(pkfile, public_key, SILC_PKCS_FILE_BASE64);
207 /* Save private key into file */
208 silc_pkcs_save_private_key(prvfile, private_key,
209 (const unsigned char *)pass, strlen(pass),
210 SILC_PKCS_FILE_BIN, rng);
212 if (return_public_key)
213 *return_public_key = public_key;
215 silc_pkcs_public_key_free(public_key);
217 if (return_private_key)
218 *return_private_key = private_key;
220 silc_pkcs_private_key_free(private_key);
222 printf("Public key has been saved into `%s'.\n", pkfile);
223 printf("Private key has been saved into `%s'.\n", prvfile);
225 printf("Press <Enter> to continue...\n");
233 silc_free(identifier);
234 memset(pass, 0, strlen(pass));
242 SilcBool silc_load_key_pair(const char *pub_filename,
243 const char *prv_filename,
244 const char *passphrase,
245 SilcPublicKey *return_public_key,
246 SilcPrivateKey *return_private_key)
248 char *pass = passphrase ? strdup(passphrase) : NULL;
250 SILC_LOG_DEBUG(("Loading public and private keys"));
252 if (!silc_pkcs_load_public_key(pub_filename, return_public_key)) {
254 memset(pass, 0, strlen(pass));
260 pass = silc_get_input("Private key passphrase: ", TRUE);
265 if (!silc_pkcs_load_private_key(prv_filename,
266 (const unsigned char *)pass, strlen(pass),
267 return_private_key)) {
268 memset(pass, 0, strlen(pass));
273 memset(pass, 0, strlen(pass));
278 /* Dump public key into stdout */
280 SilcBool silc_show_public_key(SilcPublicKey public_key)
282 SilcSILCPublicKey silc_pubkey;
283 SilcPublicKeyIdentifier ident;
284 char *fingerprint, *babbleprint;
287 SilcUInt32 key_len = 0;
289 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
293 ident = &silc_pubkey->identifier;
294 key_len = silc_pkcs_public_key_get_len(public_key);
295 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
298 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
299 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
301 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
303 printf("Key length (bits) : %d\n", (unsigned int)key_len);
305 printf("Version : %s\n", ident->version);
307 printf("Real name : %s\n", ident->realname);
309 printf("Username : %s\n", ident->username);
311 printf("Hostname : %s\n", ident->host);
313 printf("Email : %s\n", ident->email);
315 printf("Organization : %s\n", ident->org);
317 printf("Country : %s\n", ident->country);
318 printf("Fingerprint (SHA1) : %s\n", fingerprint);
319 printf("Babbleprint (SHA1) : %s\n", babbleprint);
323 silc_free(fingerprint);
324 silc_free(babbleprint);
330 /* Dump public key into stdout */
332 SilcBool silc_show_public_key_file(const char *pub_filename)
334 SilcPublicKey public_key;
337 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
338 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
342 printf("Public key file : %s\n", pub_filename);
343 ret = silc_show_public_key(public_key);
344 silc_pkcs_public_key_free(public_key);
349 /* Change private key passphrase */
351 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
352 const char *old_passphrase,
353 const char *new_passphrase)
355 SilcPrivateKey private_key;
359 pass = old_passphrase ? strdup(old_passphrase) : NULL;
361 pass = silc_get_input("Old passphrase: ", TRUE);
366 if (!silc_pkcs_load_private_key(prv_filename,
367 (const unsigned char *)pass, strlen(pass),
369 memset(pass, 0, strlen(pass));
371 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
375 memset(pass, 0, strlen(pass));
378 pass = new_passphrase ? strdup(new_passphrase) : NULL;
381 fprintf(stdout, "\n");
382 pass = silc_get_input("New passphrase: ", TRUE);
388 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
391 if (!strcmp(pass, pass2))
393 fprintf(stderr, "\nPassphrases do not match");
399 rng = silc_rng_alloc();
402 silc_pkcs_save_private_key((char *)prv_filename, private_key,
403 (unsigned char *)pass, strlen(pass),
404 SILC_PKCS_FILE_BIN, rng);
406 fprintf(stdout, "\nPassphrase changed\n");
408 memset(pass, 0, strlen(pass));
411 silc_pkcs_private_key_free(private_key);
417 /* Checks that the 'identifier' string is valid identifier string
418 and does not contain any unassigned or prohibited character. This
419 function is used to check for valid nicknames, channel names,
420 server names, usernames, hostnames, service names, algorithm names,
421 other security property names, and SILC Public Key name. */
423 unsigned char *silc_identifier_check(const unsigned char *identifier,
424 SilcUInt32 identifier_len,
425 SilcStringEncoding identifier_encoding,
426 SilcUInt32 max_allowed_length,
429 unsigned char *utf8s;
430 SilcUInt32 utf8s_len;
431 SilcStringprepStatus status;
433 if (!identifier || !identifier_len)
436 if (max_allowed_length && identifier_len > max_allowed_length)
439 status = silc_stringprep(identifier, identifier_len,
440 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
441 &utf8s, &utf8s_len, SILC_STRING_UTF8);
442 if (status != SILC_STRINGPREP_OK) {
443 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
448 *out_len = utf8s_len;
453 /* Same as above but does not allocate memory, just checks the
454 validity of the string. */
456 SilcBool silc_identifier_verify(const unsigned char *identifier,
457 SilcUInt32 identifier_len,
458 SilcStringEncoding identifier_encoding,
459 SilcUInt32 max_allowed_length)
461 SilcStringprepStatus status;
463 if (!identifier || !identifier_len)
466 if (max_allowed_length && identifier_len > max_allowed_length)
469 status = silc_stringprep(identifier, identifier_len,
470 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
471 NULL, NULL, SILC_STRING_UTF8);
472 if (status != SILC_STRINGPREP_OK) {
473 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
480 unsigned char *silc_channel_name_check(const unsigned char *identifier,
481 SilcUInt32 identifier_len,
482 SilcStringEncoding identifier_encoding,
483 SilcUInt32 max_allowed_length,
486 unsigned char *utf8s;
487 SilcUInt32 utf8s_len;
488 SilcStringprepStatus status;
490 if (!identifier || !identifier_len)
493 if (max_allowed_length && identifier_len > max_allowed_length)
496 status = silc_stringprep(identifier, identifier_len,
497 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
498 &utf8s, &utf8s_len, SILC_STRING_UTF8);
499 if (status != SILC_STRINGPREP_OK) {
500 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
505 *out_len = utf8s_len;
510 /* Same as above but does not allocate memory, just checks the
511 validity of the string. */
513 SilcBool silc_channel_name_verify(const unsigned char *identifier,
514 SilcUInt32 identifier_len,
515 SilcStringEncoding identifier_encoding,
516 SilcUInt32 max_allowed_length)
518 SilcStringprepStatus status;
520 if (!identifier || !identifier_len)
523 if (max_allowed_length && identifier_len > max_allowed_length)
526 status = silc_stringprep(identifier, identifier_len,
527 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
528 NULL, NULL, SILC_STRING_UTF8);
529 if (status != SILC_STRINGPREP_OK) {
530 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
537 /* Return mode list */
539 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
544 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
547 *list = silc_calloc(mode_list_count, sizeof(**list));
549 for (i = 0; i < mode_list_count; i++) {
550 SILC_GET32_MSB((*list)[i], mode_list->data);
551 silc_buffer_pull(mode_list, 4);
554 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
559 /* Status message structure. Messages are defined below. */
565 #define STAT(x) SILC_STATUS_ERR_##x
566 static const SilcStatusMessage silc_status_messages[] = {
568 { STAT(NO_SUCH_NICK), "There was no such nickname" },
569 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
570 { STAT(NO_SUCH_SERVER), "There was no such server" },
571 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
572 { STAT(NO_RECIPIENT), "No recipient given" },
573 { STAT(UNKNOWN_COMMAND), "Unknown command" },
574 { STAT(WILDCARDS), "Wilcrads not allowed" },
575 { STAT(NO_CLIENT_ID), "No Client ID given" },
576 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
577 { STAT(NO_SERVER_ID), "No Server ID given" },
578 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
579 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
580 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
581 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
582 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
583 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
584 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
585 { STAT(USER_ON_CHANNEL), "User already on the channel" },
586 { STAT(NOT_REGISTERED), "You have not registered" },
587 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
588 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
589 { STAT(PERM_DENIED), "Permission denied" },
590 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
591 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
592 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
593 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
594 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
595 { STAT(UNKNOWN_MODE), "Unknown mode" },
596 { STAT(NOT_YOU), "Cannot change mode for other users" },
597 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
598 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
599 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
600 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
601 { STAT(BAD_NICKNAME), "Bad nickname" },
602 { STAT(BAD_CHANNEL), "Bad channel name" },
603 { STAT(AUTH_FAILED), "Authentication failed" },
604 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
605 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
606 { STAT(RESOURCE_LIMIT), "No more free resources" },
607 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
608 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
609 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
610 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
611 { STAT(BAD_VERSION), "Bad version" },
612 { STAT(TIMEDOUT), "Service timed out" },
613 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
614 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
615 { STAT(BAD_SERVER), "Bad server name" },
616 { STAT(BAD_USERNAME), "Bad user name" },
617 { STAT(NO_SUCH_PUBLIC_KEY), "Unknown public key" },
622 /* Returns status message string */
624 const char *silc_get_status_message(unsigned char status)
628 for (i = 0; silc_status_messages[i].message; i++) {
629 if (silc_status_messages[i].status == status)
633 if (silc_status_messages[i].message == NULL)
636 return silc_status_messages[i].message;
639 static const char *packet_name[] = {
650 "PRIVATE MESSAGE KEY",
656 "CONNECTION AUTH REQUEST",
671 /* Returns packet type name */
673 const char *silc_get_packet_name(unsigned char type)
675 if (type >= SILC_PACKET_MAX)
677 if (type >= SILC_PACKET_PRIVATE)
678 return "PRIVATE RANGE";
679 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
681 return packet_name[type];
684 static const char *command_name[] = {
715 /* Returns command name */
717 const char *silc_get_command_name(unsigned char command)
719 if (command >= SILC_COMMAND_RESERVED)
721 if (command >= SILC_COMMAND_PRIVATE)
722 return "PRIVATE RANGE";
723 if (command > (sizeof(command_name) / sizeof(*command_name)))
725 return command_name[command];
728 /* Parses SILC protocol style version string. */
730 SilcBool silc_parse_version_string(const char *version,
731 SilcUInt32 *protocol_version,
732 char **protocol_version_string,
733 SilcUInt32 *software_version,
734 char **software_version_string,
735 char **vendor_version)
738 int maj = 0, min = 0;
740 if (!strstr(version, "SILC-"))
743 cp = (char *)version + 5;
747 /* Take protocol version */
750 if (!strchr(cp, '.'))
752 cp = strchr(cp, '.') + 1;
757 memset(buf, 0, sizeof(buf));
758 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
759 if (protocol_version)
760 *protocol_version = atoi(buf);
761 memset(buf, 0, sizeof(buf));
762 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
763 if (protocol_version_string)
764 *protocol_version_string = strdup(buf);
766 /* Take software version */
770 if (!strchr(cp, '-'))
772 cp = strchr(cp, '-') + 1;
777 if (strchr(cp, '.')) {
778 cp = strchr(cp, '.') + 1;
783 memset(buf, 0, sizeof(buf));
784 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
785 if (software_version)
786 *software_version = atoi(buf);
787 memset(buf, 0, sizeof(buf));
788 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
789 if (software_version_string)
790 *software_version_string = strdup(buf);
792 /* Take vendor string */
794 if (strchr(cp, '.')) {
795 cp = strchr(cp, '.') + 1;
796 if (cp && *cp && vendor_version)
797 *vendor_version = strdup(cp);
798 } else if (strchr(cp, ' ')) {
799 cp = strchr(cp, ' ') + 1;
800 if (cp && *cp && vendor_version)
801 *vendor_version = strdup(cp);
807 /* Converts version string x.x into number representation. */
809 SilcUInt32 silc_version_to_num(const char *version)
811 int maj = 0, min = 0;
817 cp = (char *)version;
819 cp = strchr(cp, '.');
823 memset(buf, 0, sizeof(buf));
824 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
825 return (SilcUInt32)atoi(buf);
828 /* Parses mode mask and returns the mode as string. */
830 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
837 memset(string, 0, sizeof(string));
839 if (mode & SILC_CHANNEL_MODE_PRIVATE)
840 strncat(string, "p", 1);
842 if (mode & SILC_CHANNEL_MODE_SECRET)
843 strncat(string, "s", 1);
845 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
846 strncat(string, "k", 1);
848 if (mode & SILC_CHANNEL_MODE_INVITE)
849 strncat(string, "i", 1);
851 if (mode & SILC_CHANNEL_MODE_TOPIC)
852 strncat(string, "t", 1);
854 if (mode & SILC_CHANNEL_MODE_ULIMIT)
855 strncat(string, "l", 1);
857 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
858 strncat(string, "a", 1);
860 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
861 strncat(string, "f", 1);
863 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
864 strncat(string, "C", 1);
866 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
867 strncat(string, "m", 1);
869 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
870 strncat(string, "M", 1);
872 if (mode & SILC_CHANNEL_MODE_CIPHER)
873 strncat(string, "c", 1);
875 if (mode & SILC_CHANNEL_MODE_HMAC)
876 strncat(string, "h", 1);
878 if (mode & SILC_CHANNEL_MODE_CIPHER) {
879 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
880 strncat(string, " ", 1);
881 strncat(string, cipher, strlen(cipher));
885 if (mode & SILC_CHANNEL_MODE_HMAC) {
886 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
887 strncat(string, " ", 1);
888 strncat(string, hmac, strlen(hmac));
892 /* Rest of mode is ignored */
894 return strdup(string);
897 /* Parses channel user mode mask and returns te mode as string */
899 char *silc_client_chumode(SilcUInt32 mode)
906 memset(string, 0, sizeof(string));
908 if (mode & SILC_CHANNEL_UMODE_CHANFO)
909 strncat(string, "f", 1);
911 if (mode & SILC_CHANNEL_UMODE_CHANOP)
912 strncat(string, "o", 1);
914 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
915 strncat(string, "b", 1);
917 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
918 strncat(string, "u", 1);
920 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
921 strncat(string, "r", 1);
923 if (mode & SILC_CHANNEL_UMODE_QUIET)
924 strncat(string, "q", 1);
926 return strdup(string);
929 /* Parses channel user mode and returns it as special mode character. */
931 char *silc_client_chumode_char(SilcUInt32 mode)
938 memset(string, 0, sizeof(string));
940 if (mode & SILC_CHANNEL_UMODE_CHANFO)
941 strncat(string, "*", 1);
943 if (mode & SILC_CHANNEL_UMODE_CHANOP)
944 strncat(string, "@", 1);
946 if (mode & SILC_CHANNEL_UMODE_QUIET)
947 strncat(string, "&", 1);
949 return strdup(string);
952 /* Renders ID to suitable to print for example to log file. */
954 static char rid[256];
955 #define _PUT_STRING(__d__, __s__) \
957 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
958 if (__sp < strlen(__s__)) { \
960 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
962 strncat(__d__, __s__, strlen(__s__)); \
966 char *silc_id_render(void *id, SilcIdType id_type)
969 unsigned char tmps[2];
972 memset(rid, 0, sizeof(rid));
976 SilcServerID *server_id = (SilcServerID *)id;
977 if (server_id->ip.data_len > 4) {
979 struct sockaddr_in6 ipv6;
980 memset(&ipv6, 0, sizeof(ipv6));
981 ipv6.sin6_family = AF_INET6;
982 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
983 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
984 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
985 _PUT_STRING(rid, tmp);
989 memmove(&ipv4.s_addr, server_id->ip.data, 4);
990 cp = inet_ntoa(ipv4);
992 _PUT_STRING(rid, cp);
995 memset(tmp, 0, sizeof(tmp));
996 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
997 _PUT_STRING(rid, tmp);
998 SILC_PUT16_MSB(server_id->rnd, tmps);
999 memset(tmp, 0, sizeof(tmp));
1000 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1001 _PUT_STRING(rid, tmp);
1004 case SILC_ID_CLIENT:
1006 SilcClientID *client_id = (SilcClientID *)id;
1007 if (client_id->ip.data_len > 4) {
1009 struct sockaddr_in6 ipv6;
1010 memset(&ipv6, 0, sizeof(ipv6));
1011 ipv6.sin6_family = AF_INET6;
1012 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1013 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1014 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1015 _PUT_STRING(rid, tmp);
1018 struct in_addr ipv4;
1019 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1020 cp = inet_ntoa(ipv4);
1022 _PUT_STRING(rid, cp);
1025 memset(tmp, 0, sizeof(tmp));
1026 silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1027 _PUT_STRING(rid, tmp);
1028 memset(tmp, 0, sizeof(tmp));
1029 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1030 client_id->hash[0], client_id->hash[1],
1031 client_id->hash[2], client_id->hash[3]);
1032 _PUT_STRING(rid, tmp);
1035 case SILC_ID_CHANNEL:
1037 SilcChannelID *channel_id = (SilcChannelID *)id;
1038 if (channel_id->ip.data_len > 4) {
1040 struct sockaddr_in6 ipv6;
1041 memset(&ipv6, 0, sizeof(ipv6));
1042 ipv6.sin6_family = AF_INET6;
1043 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1044 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1045 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1046 _PUT_STRING(rid, tmp);
1049 struct in_addr ipv4;
1050 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1051 cp = inet_ntoa(ipv4);
1053 _PUT_STRING(rid, cp);
1056 memset(tmp, 0, sizeof(tmp));
1057 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1058 _PUT_STRING(rid, tmp);
1059 SILC_PUT16_MSB(channel_id->rnd, tmps);
1060 memset(tmp, 0, sizeof(tmp));
1061 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1062 _PUT_STRING(rid, tmp);