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);
806 /* Converts version string x.x into number representation. */
808 SilcUInt32 silc_version_to_num(const char *version)
810 int maj = 0, min = 0;
816 cp = (char *)version;
818 cp = strchr(cp, '.');
822 memset(buf, 0, sizeof(buf));
823 silc_snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
824 return (SilcUInt32)atoi(buf);
827 /* Parses mode mask and returns the mode as string. */
829 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
836 memset(string, 0, sizeof(string));
838 if (mode & SILC_CHANNEL_MODE_PRIVATE)
839 strncat(string, "p", 1);
841 if (mode & SILC_CHANNEL_MODE_SECRET)
842 strncat(string, "s", 1);
844 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
845 strncat(string, "k", 1);
847 if (mode & SILC_CHANNEL_MODE_INVITE)
848 strncat(string, "i", 1);
850 if (mode & SILC_CHANNEL_MODE_TOPIC)
851 strncat(string, "t", 1);
853 if (mode & SILC_CHANNEL_MODE_ULIMIT)
854 strncat(string, "l", 1);
856 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
857 strncat(string, "a", 1);
859 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
860 strncat(string, "f", 1);
862 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
863 strncat(string, "C", 1);
865 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
866 strncat(string, "m", 1);
868 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
869 strncat(string, "M", 1);
871 if (mode & SILC_CHANNEL_MODE_CIPHER)
872 strncat(string, "c", 1);
874 if (mode & SILC_CHANNEL_MODE_HMAC)
875 strncat(string, "h", 1);
877 if (mode & SILC_CHANNEL_MODE_CIPHER) {
878 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
879 strncat(string, " ", 1);
880 strncat(string, cipher, strlen(cipher));
884 if (mode & SILC_CHANNEL_MODE_HMAC) {
885 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
886 strncat(string, " ", 1);
887 strncat(string, hmac, strlen(hmac));
891 /* Rest of mode is ignored */
893 return strdup(string);
896 /* Parses channel user mode mask and returns te mode as string */
898 char *silc_client_chumode(SilcUInt32 mode)
905 memset(string, 0, sizeof(string));
907 if (mode & SILC_CHANNEL_UMODE_CHANFO)
908 strncat(string, "f", 1);
910 if (mode & SILC_CHANNEL_UMODE_CHANOP)
911 strncat(string, "o", 1);
913 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
914 strncat(string, "b", 1);
916 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
917 strncat(string, "u", 1);
919 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
920 strncat(string, "r", 1);
922 if (mode & SILC_CHANNEL_UMODE_QUIET)
923 strncat(string, "q", 1);
925 return strdup(string);
928 /* Parses channel user mode and returns it as special mode character. */
930 char *silc_client_chumode_char(SilcUInt32 mode)
937 memset(string, 0, sizeof(string));
939 if (mode & SILC_CHANNEL_UMODE_CHANFO)
940 strncat(string, "*", 1);
942 if (mode & SILC_CHANNEL_UMODE_CHANOP)
943 strncat(string, "@", 1);
945 if (mode & SILC_CHANNEL_UMODE_QUIET)
946 strncat(string, "&", 1);
948 return strdup(string);
951 /* Renders ID to suitable to print for example to log file. */
953 static char rid[256];
954 #define _PUT_STRING(__d__, __s__) \
956 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
957 if (__sp < strlen(__s__)) { \
959 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
961 strncat(__d__, __s__, strlen(__s__)); \
965 char *silc_id_render(void *id, SilcIdType id_type)
968 unsigned char tmps[2];
971 memset(rid, 0, sizeof(rid));
975 SilcServerID *server_id = (SilcServerID *)id;
976 if (server_id->ip.data_len > 4) {
978 struct sockaddr_in6 ipv6;
979 memset(&ipv6, 0, sizeof(ipv6));
980 ipv6.sin6_family = AF_INET6;
981 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
982 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
983 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
984 _PUT_STRING(rid, tmp);
988 memmove(&ipv4.s_addr, server_id->ip.data, 4);
989 cp = inet_ntoa(ipv4);
991 _PUT_STRING(rid, cp);
994 memset(tmp, 0, sizeof(tmp));
995 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
996 _PUT_STRING(rid, tmp);
997 SILC_PUT16_MSB(server_id->rnd, tmps);
998 memset(tmp, 0, sizeof(tmp));
999 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1000 _PUT_STRING(rid, tmp);
1003 case SILC_ID_CLIENT:
1005 SilcClientID *client_id = (SilcClientID *)id;
1006 if (client_id->ip.data_len > 4) {
1008 struct sockaddr_in6 ipv6;
1009 memset(&ipv6, 0, sizeof(ipv6));
1010 ipv6.sin6_family = AF_INET6;
1011 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1012 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1013 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1014 _PUT_STRING(rid, tmp);
1017 struct in_addr ipv4;
1018 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1019 cp = inet_ntoa(ipv4);
1021 _PUT_STRING(rid, cp);
1024 memset(tmp, 0, sizeof(tmp));
1025 silc_snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1026 _PUT_STRING(rid, tmp);
1027 memset(tmp, 0, sizeof(tmp));
1028 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1029 client_id->hash[0], client_id->hash[1],
1030 client_id->hash[2], client_id->hash[3]);
1031 _PUT_STRING(rid, tmp);
1034 case SILC_ID_CHANNEL:
1036 SilcChannelID *channel_id = (SilcChannelID *)id;
1037 if (channel_id->ip.data_len > 4) {
1039 struct sockaddr_in6 ipv6;
1040 memset(&ipv6, 0, sizeof(ipv6));
1041 ipv6.sin6_family = AF_INET6;
1042 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1043 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1044 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1045 _PUT_STRING(rid, tmp);
1048 struct in_addr ipv4;
1049 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1050 cp = inet_ntoa(ipv4);
1052 _PUT_STRING(rid, cp);
1055 memset(tmp, 0, sizeof(tmp));
1056 silc_snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1057 _PUT_STRING(rid, tmp);
1058 SILC_PUT16_MSB(channel_id->rnd, tmps);
1059 memset(tmp, 0, sizeof(tmp));
1060 silc_snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1061 _PUT_STRING(rid, tmp);