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);
291 silc_pkcs_public_key_free(public_key);
295 ident = &silc_pubkey->identifier;
296 key_len = silc_pkcs_public_key_get_len(public_key);
297 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
299 silc_pkcs_public_key_free(public_key);
302 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
303 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
305 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
307 printf("Key length (bits) : %d\n", (unsigned int)key_len);
309 printf("Version : %s\n", ident->version);
311 printf("Real name : %s\n", ident->realname);
313 printf("Username : %s\n", ident->username);
315 printf("Hostname : %s\n", ident->host);
317 printf("Email : %s\n", ident->email);
319 printf("Organization : %s\n", ident->org);
321 printf("Country : %s\n", ident->country);
322 printf("Fingerprint (SHA1) : %s\n", fingerprint);
323 printf("Babbleprint (SHA1) : %s\n", babbleprint);
327 silc_free(fingerprint);
328 silc_free(babbleprint);
334 /* Dump public key into stdout */
336 SilcBool silc_show_public_key_file(const char *pub_filename)
338 SilcPublicKey public_key;
341 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
342 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
346 printf("Public key file : %s\n", pub_filename);
347 ret = silc_show_public_key(public_key);
348 silc_pkcs_public_key_free(public_key);
353 /* Change private key passphrase */
355 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
356 const char *old_passphrase,
357 const char *new_passphrase)
359 SilcPrivateKey private_key;
363 pass = old_passphrase ? strdup(old_passphrase) : NULL;
365 pass = silc_get_input("Old passphrase: ", TRUE);
370 if (!silc_pkcs_load_private_key(prv_filename,
371 (const unsigned char *)pass, strlen(pass),
373 memset(pass, 0, strlen(pass));
375 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
379 memset(pass, 0, strlen(pass));
382 pass = new_passphrase ? strdup(new_passphrase) : NULL;
385 fprintf(stdout, "\n");
386 pass = silc_get_input("New passphrase: ", TRUE);
392 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
395 if (!strcmp(pass, pass2))
397 fprintf(stderr, "\nPassphrases do not match");
403 rng = silc_rng_alloc();
406 silc_pkcs_save_private_key((char *)prv_filename, private_key,
407 (unsigned char *)pass, strlen(pass),
408 SILC_PKCS_FILE_BIN, rng);
410 fprintf(stdout, "\nPassphrase changed\n");
412 memset(pass, 0, strlen(pass));
415 silc_pkcs_private_key_free(private_key);
421 /* Checks that the 'identifier' string is valid identifier string
422 and does not contain any unassigned or prohibited character. This
423 function is used to check for valid nicknames, channel names,
424 server names, usernames, hostnames, service names, algorithm names,
425 other security property names, and SILC Public Key name. */
427 unsigned char *silc_identifier_check(const unsigned char *identifier,
428 SilcUInt32 identifier_len,
429 SilcStringEncoding identifier_encoding,
430 SilcUInt32 max_allowed_length,
433 unsigned char *utf8s;
434 SilcUInt32 utf8s_len;
435 SilcStringprepStatus status;
437 if (!identifier || !identifier_len)
440 if (max_allowed_length && identifier_len > max_allowed_length)
443 status = silc_stringprep(identifier, identifier_len,
444 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
445 &utf8s, &utf8s_len, SILC_STRING_UTF8);
446 if (status != SILC_STRINGPREP_OK) {
447 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
452 *out_len = utf8s_len;
457 /* Same as above but does not allocate memory, just checks the
458 validity of the string. */
460 SilcBool silc_identifier_verify(const unsigned char *identifier,
461 SilcUInt32 identifier_len,
462 SilcStringEncoding identifier_encoding,
463 SilcUInt32 max_allowed_length)
465 SilcStringprepStatus status;
467 if (!identifier || !identifier_len)
470 if (max_allowed_length && identifier_len > max_allowed_length)
473 status = silc_stringprep(identifier, identifier_len,
474 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
475 NULL, NULL, SILC_STRING_UTF8);
476 if (status != SILC_STRINGPREP_OK) {
477 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
484 unsigned char *silc_channel_name_check(const unsigned char *identifier,
485 SilcUInt32 identifier_len,
486 SilcStringEncoding identifier_encoding,
487 SilcUInt32 max_allowed_length,
490 unsigned char *utf8s;
491 SilcUInt32 utf8s_len;
492 SilcStringprepStatus status;
494 if (!identifier || !identifier_len)
497 if (max_allowed_length && identifier_len > max_allowed_length)
500 status = silc_stringprep(identifier, identifier_len,
501 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
502 &utf8s, &utf8s_len, SILC_STRING_UTF8);
503 if (status != SILC_STRINGPREP_OK) {
504 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
509 *out_len = utf8s_len;
514 /* Same as above but does not allocate memory, just checks the
515 validity of the string. */
517 SilcBool silc_channel_name_verify(const unsigned char *identifier,
518 SilcUInt32 identifier_len,
519 SilcStringEncoding identifier_encoding,
520 SilcUInt32 max_allowed_length)
522 SilcStringprepStatus status;
524 if (!identifier || !identifier_len)
527 if (max_allowed_length && identifier_len > max_allowed_length)
530 status = silc_stringprep(identifier, identifier_len,
531 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
532 NULL, NULL, SILC_STRING_UTF8);
533 if (status != SILC_STRINGPREP_OK) {
534 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
541 /* Return mode list */
543 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
548 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
551 *list = silc_calloc(mode_list_count, sizeof(**list));
553 for (i = 0; i < mode_list_count; i++) {
554 SILC_GET32_MSB((*list)[i], mode_list->data);
555 silc_buffer_pull(mode_list, 4);
558 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
563 /* Status message structure. Messages are defined below. */
569 #define STAT(x) SILC_STATUS_ERR_##x
570 static const SilcStatusMessage silc_status_messages[] = {
572 { STAT(NO_SUCH_NICK), "There was no such nickname" },
573 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
574 { STAT(NO_SUCH_SERVER), "There was no such server" },
575 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
576 { STAT(NO_RECIPIENT), "No recipient given" },
577 { STAT(UNKNOWN_COMMAND), "Unknown command" },
578 { STAT(WILDCARDS), "Wilcrads not allowed" },
579 { STAT(NO_CLIENT_ID), "No Client ID given" },
580 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
581 { STAT(NO_SERVER_ID), "No Server ID given" },
582 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
583 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
584 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
585 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
586 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
587 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
588 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
589 { STAT(USER_ON_CHANNEL), "User already on the channel" },
590 { STAT(NOT_REGISTERED), "You have not registered" },
591 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
592 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
593 { STAT(PERM_DENIED), "Permission denied" },
594 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
595 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
596 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
597 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
598 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
599 { STAT(UNKNOWN_MODE), "Unknown mode" },
600 { STAT(NOT_YOU), "Cannot change mode for other users" },
601 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
602 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
603 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
604 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
605 { STAT(BAD_NICKNAME), "Bad nickname" },
606 { STAT(BAD_CHANNEL), "Bad channel name" },
607 { STAT(AUTH_FAILED), "Authentication failed" },
608 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
609 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
610 { STAT(RESOURCE_LIMIT), "No more free resources" },
611 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
612 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
613 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
614 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
615 { STAT(BAD_VERSION), "Bad version" },
616 { STAT(TIMEDOUT), "Service timed out" },
617 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
618 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
619 { STAT(BAD_SERVER), "Bad server name" },
620 { STAT(BAD_USERNAME), "Bad user name" },
621 { STAT(NO_SUCH_PUBLIC_KEY), "Unknown public key" },
626 /* Returns status message string */
628 const char *silc_get_status_message(unsigned char status)
632 for (i = 0; silc_status_messages[i].message; i++) {
633 if (silc_status_messages[i].status == status)
637 if (silc_status_messages[i].message == NULL)
640 return silc_status_messages[i].message;
643 static const char *packet_name[] = {
654 "PRIVATE MESSAGE KEY",
660 "CONNECTION AUTH REQUEST",
675 /* Returns packet type name */
677 const char *silc_get_packet_name(unsigned char type)
679 if (type >= SILC_PACKET_MAX)
681 if (type >= SILC_PACKET_PRIVATE)
682 return "PRIVATE RANGE";
683 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
685 return packet_name[type];
688 static const char *command_name[] = {
719 /* Returns command name */
721 const char *silc_get_command_name(unsigned char command)
723 if (command >= SILC_COMMAND_RESERVED)
725 if (command >= SILC_COMMAND_PRIVATE)
726 return "PRIVATE RANGE";
727 if (command > (sizeof(command_name) / sizeof(*command_name)))
729 return command_name[command];
732 /* Parses SILC protocol style version string. */
734 SilcBool silc_parse_version_string(const char *version,
735 SilcUInt32 *protocol_version,
736 char **protocol_version_string,
737 SilcUInt32 *software_version,
738 char **software_version_string,
739 char **vendor_version)
742 int maj = 0, min = 0;
744 if (!strstr(version, "SILC-"))
747 cp = (char *)version + 5;
751 /* Take protocol version */
754 if (!strchr(cp, '.'))
756 cp = strchr(cp, '.') + 1;
761 memset(buf, 0, sizeof(buf));
762 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
763 if (protocol_version)
764 *protocol_version = atoi(buf);
765 memset(buf, 0, sizeof(buf));
766 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
767 if (protocol_version_string)
768 *protocol_version_string = strdup(buf);
770 /* Take software version */
774 if (!strchr(cp, '-'))
776 cp = strchr(cp, '-') + 1;
781 if (strchr(cp, '.')) {
782 cp = strchr(cp, '.') + 1;
787 memset(buf, 0, sizeof(buf));
788 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
789 if (software_version)
790 *software_version = atoi(buf);
791 memset(buf, 0, sizeof(buf));
792 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
793 if (software_version_string)
794 *software_version_string = strdup(buf);
796 /* Take vendor string */
798 if (strchr(cp, '.')) {
799 cp = strchr(cp, '.') + 1;
800 if (cp && *cp && vendor_version)
801 *vendor_version = strdup(cp);
802 } else if (strchr(cp, ' ')) {
803 cp = strchr(cp, ' ') + 1;
804 if (cp && *cp && vendor_version)
805 *vendor_version = strdup(cp);
811 /* Converts version string x.x into number representation. */
813 SilcUInt32 silc_version_to_num(const char *version)
815 int maj = 0, min = 0;
821 cp = (char *)version;
823 cp = strchr(cp, '.');
827 memset(buf, 0, sizeof(buf));
828 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
829 return (SilcUInt32)atoi(buf);
832 /* Parses mode mask and returns the mode as string. */
834 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
841 memset(string, 0, sizeof(string));
843 if (mode & SILC_CHANNEL_MODE_PRIVATE)
844 strncat(string, "p", 1);
846 if (mode & SILC_CHANNEL_MODE_SECRET)
847 strncat(string, "s", 1);
849 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
850 strncat(string, "k", 1);
852 if (mode & SILC_CHANNEL_MODE_INVITE)
853 strncat(string, "i", 1);
855 if (mode & SILC_CHANNEL_MODE_TOPIC)
856 strncat(string, "t", 1);
858 if (mode & SILC_CHANNEL_MODE_ULIMIT)
859 strncat(string, "l", 1);
861 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
862 strncat(string, "a", 1);
864 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
865 strncat(string, "f", 1);
867 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
868 strncat(string, "C", 1);
870 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
871 strncat(string, "m", 1);
873 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
874 strncat(string, "M", 1);
876 if (mode & SILC_CHANNEL_MODE_CIPHER)
877 strncat(string, "c", 1);
879 if (mode & SILC_CHANNEL_MODE_HMAC)
880 strncat(string, "h", 1);
882 if (mode & SILC_CHANNEL_MODE_CIPHER) {
883 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
884 strncat(string, " ", 1);
885 strncat(string, cipher, strlen(cipher));
889 if (mode & SILC_CHANNEL_MODE_HMAC) {
890 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
891 strncat(string, " ", 1);
892 strncat(string, hmac, strlen(hmac));
896 /* Rest of mode is ignored */
898 return strdup(string);
901 /* Parses channel user mode mask and returns te mode as string */
903 char *silc_client_chumode(SilcUInt32 mode)
910 memset(string, 0, sizeof(string));
912 if (mode & SILC_CHANNEL_UMODE_CHANFO)
913 strncat(string, "f", 1);
915 if (mode & SILC_CHANNEL_UMODE_CHANOP)
916 strncat(string, "o", 1);
918 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
919 strncat(string, "b", 1);
921 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
922 strncat(string, "u", 1);
924 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
925 strncat(string, "r", 1);
927 if (mode & SILC_CHANNEL_UMODE_QUIET)
928 strncat(string, "q", 1);
930 return strdup(string);
933 /* Parses channel user mode and returns it as special mode character. */
935 char *silc_client_chumode_char(SilcUInt32 mode)
942 memset(string, 0, sizeof(string));
944 if (mode & SILC_CHANNEL_UMODE_CHANFO)
945 strncat(string, "*", 1);
947 if (mode & SILC_CHANNEL_UMODE_CHANOP)
948 strncat(string, "@", 1);
950 if (mode & SILC_CHANNEL_UMODE_QUIET)
951 strncat(string, "&", 1);
953 return strdup(string);
956 /* Renders ID to suitable to print for example to log file. */
958 static char rid[256];
959 #define _PUT_STRING(__d__, __s__) \
961 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
962 if (__sp < strlen(__s__)) { \
964 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
966 strncat(__d__, __s__, strlen(__s__)); \
970 char *silc_id_render(void *id, SilcIdType id_type)
973 unsigned char tmps[2];
976 memset(rid, 0, sizeof(rid));
980 SilcServerID *server_id = (SilcServerID *)id;
981 if (server_id->ip.data_len > 4) {
983 struct sockaddr_in6 ipv6;
984 memset(&ipv6, 0, sizeof(ipv6));
985 ipv6.sin6_family = AF_INET6;
986 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
987 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
988 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
989 _PUT_STRING(rid, tmp);
993 memmove(&ipv4.s_addr, server_id->ip.data, 4);
994 cp = inet_ntoa(ipv4);
996 _PUT_STRING(rid, cp);
999 memset(tmp, 0, sizeof(tmp));
1000 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
1001 _PUT_STRING(rid, tmp);
1002 SILC_PUT16_MSB(server_id->rnd, tmps);
1003 memset(tmp, 0, sizeof(tmp));
1004 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1005 _PUT_STRING(rid, tmp);
1008 case SILC_ID_CLIENT:
1010 SilcClientID *client_id = (SilcClientID *)id;
1011 if (client_id->ip.data_len > 4) {
1013 struct sockaddr_in6 ipv6;
1014 memset(&ipv6, 0, sizeof(ipv6));
1015 ipv6.sin6_family = AF_INET6;
1016 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1017 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1018 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1019 _PUT_STRING(rid, tmp);
1022 struct in_addr ipv4;
1023 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1024 cp = inet_ntoa(ipv4);
1026 _PUT_STRING(rid, cp);
1029 memset(tmp, 0, sizeof(tmp));
1030 silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1031 _PUT_STRING(rid, tmp);
1032 memset(tmp, 0, sizeof(tmp));
1033 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1034 client_id->hash[0], client_id->hash[1],
1035 client_id->hash[2], client_id->hash[3]);
1036 _PUT_STRING(rid, tmp);
1039 case SILC_ID_CHANNEL:
1041 SilcChannelID *channel_id = (SilcChannelID *)id;
1042 if (channel_id->ip.data_len > 4) {
1044 struct sockaddr_in6 ipv6;
1045 memset(&ipv6, 0, sizeof(ipv6));
1046 ipv6.sin6_family = AF_INET6;
1047 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1048 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1049 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1050 _PUT_STRING(rid, tmp);
1053 struct in_addr ipv4;
1054 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1055 cp = inet_ntoa(ipv4);
1057 _PUT_STRING(rid, cp);
1060 memset(tmp, 0, sizeof(tmp));
1061 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1062 _PUT_STRING(rid, tmp);
1063 SILC_PUT16_MSB(channel_id->rnd, tmps);
1064 memset(tmp, 0, sizeof(tmp));
1065 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1066 _PUT_STRING(rid, tmp);