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" },
625 /* Returns status message string */
627 const char *silc_get_status_message(unsigned char status)
631 for (i = 0; silc_status_messages[i].message; i++) {
632 if (silc_status_messages[i].status == status)
636 if (silc_status_messages[i].message == NULL)
639 return silc_status_messages[i].message;
642 static const char *packet_name[] = {
653 "PRIVATE MESSAGE KEY",
659 "CONNECTION AUTH REQUEST",
674 /* Returns packet type name */
676 const char *silc_get_packet_name(unsigned char type)
678 if (type >= SILC_PACKET_MAX)
680 if (type >= SILC_PACKET_PRIVATE)
681 return "PRIVATE RANGE";
682 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
684 return packet_name[type];
687 static const char *command_name[] = {
718 /* Returns command name */
720 const char *silc_get_command_name(unsigned char command)
722 if (command >= SILC_COMMAND_RESERVED)
724 if (command >= SILC_COMMAND_PRIVATE)
725 return "PRIVATE RANGE";
726 if (command > (sizeof(command_name) / sizeof(*command_name)))
728 return command_name[command];
731 /* Parses SILC protocol style version string. */
733 SilcBool silc_parse_version_string(const char *version,
734 SilcUInt32 *protocol_version,
735 char **protocol_version_string,
736 SilcUInt32 *software_version,
737 char **software_version_string,
738 char **vendor_version)
741 int maj = 0, min = 0;
743 if (!strstr(version, "SILC-"))
746 cp = (char *)version + 5;
750 /* Take protocol version */
753 if (!strchr(cp, '.'))
755 cp = strchr(cp, '.') + 1;
760 memset(buf, 0, sizeof(buf));
761 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
762 if (protocol_version)
763 *protocol_version = atoi(buf);
764 memset(buf, 0, sizeof(buf));
765 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
766 if (protocol_version_string)
767 *protocol_version_string = strdup(buf);
769 /* Take software version */
773 if (!strchr(cp, '-'))
775 cp = strchr(cp, '-') + 1;
780 if (strchr(cp, '.')) {
781 cp = strchr(cp, '.') + 1;
786 memset(buf, 0, sizeof(buf));
787 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
788 if (software_version)
789 *software_version = atoi(buf);
790 memset(buf, 0, sizeof(buf));
791 silc_snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
792 if (software_version_string)
793 *software_version_string = strdup(buf);
795 /* Take vendor string */
797 if (strchr(cp, '.')) {
798 cp = strchr(cp, '.') + 1;
799 if (cp && *cp && vendor_version)
800 *vendor_version = strdup(cp);
801 } else if (strchr(cp, ' ')) {
802 cp = strchr(cp, ' ') + 1;
803 if (cp && *cp && vendor_version)
804 *vendor_version = strdup(cp);
810 /* Converts version string x.x into number representation. */
812 SilcUInt32 silc_version_to_num(const char *version)
814 int maj = 0, min = 0;
820 cp = (char *)version;
822 cp = strchr(cp, '.');
826 memset(buf, 0, sizeof(buf));
827 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
828 return (SilcUInt32)atoi(buf);
831 /* Parses mode mask and returns the mode as string. */
833 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
840 memset(string, 0, sizeof(string));
842 if (mode & SILC_CHANNEL_MODE_PRIVATE)
843 strncat(string, "p", 1);
845 if (mode & SILC_CHANNEL_MODE_SECRET)
846 strncat(string, "s", 1);
848 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
849 strncat(string, "k", 1);
851 if (mode & SILC_CHANNEL_MODE_INVITE)
852 strncat(string, "i", 1);
854 if (mode & SILC_CHANNEL_MODE_TOPIC)
855 strncat(string, "t", 1);
857 if (mode & SILC_CHANNEL_MODE_ULIMIT)
858 strncat(string, "l", 1);
860 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
861 strncat(string, "a", 1);
863 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
864 strncat(string, "f", 1);
866 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
867 strncat(string, "C", 1);
869 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
870 strncat(string, "m", 1);
872 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
873 strncat(string, "M", 1);
875 if (mode & SILC_CHANNEL_MODE_CIPHER)
876 strncat(string, "c", 1);
878 if (mode & SILC_CHANNEL_MODE_HMAC)
879 strncat(string, "h", 1);
881 if (mode & SILC_CHANNEL_MODE_CIPHER) {
882 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
883 strncat(string, " ", 1);
884 strncat(string, cipher, strlen(cipher));
888 if (mode & SILC_CHANNEL_MODE_HMAC) {
889 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
890 strncat(string, " ", 1);
891 strncat(string, hmac, strlen(hmac));
895 /* Rest of mode is ignored */
897 return strdup(string);
900 /* Parses channel user mode mask and returns te mode as string */
902 char *silc_client_chumode(SilcUInt32 mode)
909 memset(string, 0, sizeof(string));
911 if (mode & SILC_CHANNEL_UMODE_CHANFO)
912 strncat(string, "f", 1);
914 if (mode & SILC_CHANNEL_UMODE_CHANOP)
915 strncat(string, "o", 1);
917 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
918 strncat(string, "b", 1);
920 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
921 strncat(string, "u", 1);
923 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
924 strncat(string, "r", 1);
926 if (mode & SILC_CHANNEL_UMODE_QUIET)
927 strncat(string, "q", 1);
929 return strdup(string);
932 /* Parses channel user mode and returns it as special mode character. */
934 char *silc_client_chumode_char(SilcUInt32 mode)
941 memset(string, 0, sizeof(string));
943 if (mode & SILC_CHANNEL_UMODE_CHANFO)
944 strncat(string, "*", 1);
946 if (mode & SILC_CHANNEL_UMODE_CHANOP)
947 strncat(string, "@", 1);
949 if (mode & SILC_CHANNEL_UMODE_QUIET)
950 strncat(string, "&", 1);
952 return strdup(string);
955 /* Renders ID to suitable to print for example to log file. */
957 static char rid[256];
958 #define _PUT_STRING(__d__, __s__) \
960 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
961 if (__sp < strlen(__s__)) { \
963 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
965 strncat(__d__, __s__, strlen(__s__)); \
969 char *silc_id_render(void *id, SilcIdType id_type)
972 unsigned char tmps[2];
975 memset(rid, 0, sizeof(rid));
979 SilcServerID *server_id = (SilcServerID *)id;
980 if (server_id->ip.data_len > 4) {
982 struct sockaddr_in6 ipv6;
983 memset(&ipv6, 0, sizeof(ipv6));
984 ipv6.sin6_family = AF_INET6;
985 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
986 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
987 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
988 _PUT_STRING(rid, tmp);
992 memmove(&ipv4.s_addr, server_id->ip.data, 4);
993 cp = inet_ntoa(ipv4);
995 _PUT_STRING(rid, cp);
998 memset(tmp, 0, sizeof(tmp));
999 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
1000 _PUT_STRING(rid, tmp);
1001 SILC_PUT16_MSB(server_id->rnd, tmps);
1002 memset(tmp, 0, sizeof(tmp));
1003 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1004 _PUT_STRING(rid, tmp);
1007 case SILC_ID_CLIENT:
1009 SilcClientID *client_id = (SilcClientID *)id;
1010 if (client_id->ip.data_len > 4) {
1012 struct sockaddr_in6 ipv6;
1013 memset(&ipv6, 0, sizeof(ipv6));
1014 ipv6.sin6_family = AF_INET6;
1015 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1016 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1017 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1018 _PUT_STRING(rid, tmp);
1021 struct in_addr ipv4;
1022 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1023 cp = inet_ntoa(ipv4);
1025 _PUT_STRING(rid, cp);
1028 memset(tmp, 0, sizeof(tmp));
1029 silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1030 _PUT_STRING(rid, tmp);
1031 memset(tmp, 0, sizeof(tmp));
1032 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1033 client_id->hash[0], client_id->hash[1],
1034 client_id->hash[2], client_id->hash[3]);
1035 _PUT_STRING(rid, tmp);
1038 case SILC_ID_CHANNEL:
1040 SilcChannelID *channel_id = (SilcChannelID *)id;
1041 if (channel_id->ip.data_len > 4) {
1043 struct sockaddr_in6 ipv6;
1044 memset(&ipv6, 0, sizeof(ipv6));
1045 ipv6.sin6_family = AF_INET6;
1046 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1047 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1048 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1049 _PUT_STRING(rid, tmp);
1052 struct in_addr ipv4;
1053 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1054 cp = inet_ntoa(ipv4);
1056 _PUT_STRING(rid, cp);
1059 memset(tmp, 0, sizeof(tmp));
1060 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1061 _PUT_STRING(rid, tmp);
1062 SILC_PUT16_MSB(channel_id->rnd, tmps);
1063 memset(tmp, 0, sizeof(tmp));
1064 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1065 _PUT_STRING(rid, tmp);