5 Author: Pekka Riikonen <priikone@silcnet.org>
7 Copyright (C) 2002 - 2006 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 snprintf(email, sizeof(email), "%s@%s", username, hostname);
45 ident = silc_pkcs_silc_encode_identifier(username, hostname, realname,
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 snprintf(line, sizeof(line), "Identifier [%s]: ", def);
128 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 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 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 if (!silc_pkcs_silc_generate_key(alg, "pkcs1-no-oid", key_len_bits,
197 identifier, rng, &public_key,
201 /* Save public key into file */
202 silc_pkcs_save_public_key(pkfile, public_key, SILC_PKCS_FILE_BASE64);
204 /* Save private key into file */
205 silc_pkcs_save_private_key(prvfile, private_key,
206 (const unsigned char *)pass, strlen(pass),
207 SILC_PKCS_FILE_BIN, rng);
209 if (return_public_key)
210 *return_public_key = public_key;
212 silc_pkcs_public_key_free(public_key);
214 if (return_private_key)
215 *return_private_key = private_key;
217 silc_pkcs_private_key_free(private_key);
219 printf("Public key has been saved into `%s'.\n", pkfile);
220 printf("Private key has been saved into `%s'.\n", prvfile);
222 printf("Press <Enter> to continue...\n");
230 silc_free(identifier);
231 memset(pass, 0, strlen(pass));
239 SilcBool silc_load_key_pair(const char *pub_filename,
240 const char *prv_filename,
241 const char *passphrase,
242 SilcPublicKey *return_public_key,
243 SilcPrivateKey *return_private_key)
245 char *pass = passphrase ? strdup(passphrase) : NULL;
247 SILC_LOG_DEBUG(("Loading public and private keys"));
249 if (!silc_pkcs_load_public_key(pub_filename, return_public_key)) {
251 memset(pass, 0, strlen(pass));
257 pass = silc_get_input("Private key passphrase: ", TRUE);
262 if (!silc_pkcs_load_private_key(prv_filename,
263 (const unsigned char *)pass, strlen(pass),
264 return_private_key)) {
265 memset(pass, 0, strlen(pass));
270 memset(pass, 0, strlen(pass));
275 /* Dump public key into stdout */
277 SilcBool silc_show_public_key(SilcPublicKey public_key)
279 SilcSILCPublicKey silc_pubkey;
280 SilcPublicKeyIdentifier ident;
281 char *fingerprint, *babbleprint;
284 SilcUInt32 key_len = 0;
286 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
288 silc_pkcs_public_key_free(public_key);
292 ident = &silc_pubkey->identifier;
293 key_len = silc_pkcs_public_key_get_len(public_key);
294 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
296 silc_pkcs_public_key_free(public_key);
299 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
300 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
302 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
304 printf("Key length (bits) : %d\n", (unsigned int)key_len);
306 printf("Real name : %s\n", ident->realname);
308 printf("Username : %s\n", ident->username);
310 printf("Hostname : %s\n", ident->host);
312 printf("Email : %s\n", ident->email);
314 printf("Organization : %s\n", ident->org);
316 printf("Country : %s\n", ident->country);
317 printf("Fingerprint (SHA1) : %s\n", fingerprint);
318 printf("Babbleprint (SHA1) : %s\n", babbleprint);
322 silc_free(fingerprint);
323 silc_free(babbleprint);
329 /* Dump public key into stdout */
331 SilcBool silc_show_public_key_file(const char *pub_filename)
333 SilcPublicKey public_key;
336 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
337 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
341 printf("Public key file : %s\n", pub_filename);
342 ret = silc_show_public_key(public_key);
343 silc_pkcs_public_key_free(public_key);
348 /* Change private key passphrase */
350 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
351 const char *old_passphrase,
352 const char *new_passphrase)
354 SilcPrivateKey private_key;
358 pass = old_passphrase ? strdup(old_passphrase) : NULL;
360 pass = silc_get_input("Old passphrase: ", TRUE);
365 if (!silc_pkcs_load_private_key(prv_filename,
366 (const unsigned char *)pass, strlen(pass),
368 memset(pass, 0, strlen(pass));
370 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
374 memset(pass, 0, strlen(pass));
377 pass = new_passphrase ? strdup(new_passphrase) : NULL;
380 fprintf(stdout, "\n");
381 pass = silc_get_input("New passphrase: ", TRUE);
387 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
390 if (!strcmp(pass, pass2))
392 fprintf(stderr, "\nPassphrases do not match");
398 rng = silc_rng_alloc();
401 silc_pkcs_save_private_key((char *)prv_filename, private_key,
402 (unsigned char *)pass, strlen(pass),
403 SILC_PKCS_FILE_BIN, rng);
405 fprintf(stdout, "\nPassphrase changed\n");
407 memset(pass, 0, strlen(pass));
410 silc_pkcs_private_key_free(private_key);
416 /* Checks that the 'identifier' string is valid identifier string
417 and does not contain any unassigned or prohibited character. This
418 function is used to check for valid nicknames, channel names,
419 server names, usernames, hostnames, service names, algorithm names,
420 other security property names, and SILC Public Key name. */
422 unsigned char *silc_identifier_check(const unsigned char *identifier,
423 SilcUInt32 identifier_len,
424 SilcStringEncoding identifier_encoding,
425 SilcUInt32 max_allowed_length,
428 unsigned char *utf8s;
429 SilcUInt32 utf8s_len;
430 SilcStringprepStatus status;
432 if (!identifier || !identifier_len)
435 if (max_allowed_length && identifier_len > max_allowed_length)
438 status = silc_stringprep(identifier, identifier_len,
439 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
440 &utf8s, &utf8s_len, SILC_STRING_UTF8);
441 if (status != SILC_STRINGPREP_OK) {
442 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
447 *out_len = utf8s_len;
452 /* Same as above but does not allocate memory, just checks the
453 validity of the string. */
455 SilcBool silc_identifier_verify(const unsigned char *identifier,
456 SilcUInt32 identifier_len,
457 SilcStringEncoding identifier_encoding,
458 SilcUInt32 max_allowed_length)
460 SilcStringprepStatus status;
462 if (!identifier || !identifier_len)
465 if (max_allowed_length && identifier_len > max_allowed_length)
468 status = silc_stringprep(identifier, identifier_len,
469 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
470 NULL, NULL, SILC_STRING_UTF8);
471 if (status != SILC_STRINGPREP_OK) {
472 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
479 unsigned char *silc_channel_name_check(const unsigned char *identifier,
480 SilcUInt32 identifier_len,
481 SilcStringEncoding identifier_encoding,
482 SilcUInt32 max_allowed_length,
485 unsigned char *utf8s;
486 SilcUInt32 utf8s_len;
487 SilcStringprepStatus status;
489 if (!identifier || !identifier_len)
492 if (max_allowed_length && identifier_len > max_allowed_length)
495 status = silc_stringprep(identifier, identifier_len,
496 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
497 &utf8s, &utf8s_len, SILC_STRING_UTF8);
498 if (status != SILC_STRINGPREP_OK) {
499 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
504 *out_len = utf8s_len;
509 /* Same as above but does not allocate memory, just checks the
510 validity of the string. */
512 SilcBool silc_channel_name_verify(const unsigned char *identifier,
513 SilcUInt32 identifier_len,
514 SilcStringEncoding identifier_encoding,
515 SilcUInt32 max_allowed_length)
517 SilcStringprepStatus status;
519 if (!identifier || !identifier_len)
522 if (max_allowed_length && identifier_len > max_allowed_length)
525 status = silc_stringprep(identifier, identifier_len,
526 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
527 NULL, NULL, SILC_STRING_UTF8);
528 if (status != SILC_STRINGPREP_OK) {
529 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
536 /* Return mode list */
538 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
543 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
546 *list = silc_calloc(mode_list_count, sizeof(**list));
548 for (i = 0; i < mode_list_count; i++) {
549 SILC_GET32_MSB((*list)[i], mode_list->data);
550 silc_buffer_pull(mode_list, 4);
553 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
558 /* Status message structure. Messages are defined below. */
564 #define STAT(x) SILC_STATUS_ERR_##x
565 static const SilcStatusMessage silc_status_messages[] = {
567 { STAT(NO_SUCH_NICK), "There was no such nickname" },
568 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
569 { STAT(NO_SUCH_SERVER), "There was no such server" },
570 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
571 { STAT(NO_RECIPIENT), "No recipient given" },
572 { STAT(UNKNOWN_COMMAND), "Unknown command" },
573 { STAT(WILDCARDS), "Wilcrads not allowed" },
574 { STAT(NO_CLIENT_ID), "No Client ID given" },
575 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
576 { STAT(NO_SERVER_ID), "No Server ID given" },
577 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
578 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
579 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
580 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
581 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
582 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
583 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
584 { STAT(USER_ON_CHANNEL), "User already on the channel" },
585 { STAT(NOT_REGISTERED), "You have not registered" },
586 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
587 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
588 { STAT(PERM_DENIED), "Permission denied" },
589 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
590 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
591 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
592 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
593 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
594 { STAT(UNKNOWN_MODE), "Unknown mode" },
595 { STAT(NOT_YOU), "Cannot change mode for other users" },
596 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
597 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
598 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
599 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
600 { STAT(BAD_NICKNAME), "Bad nickname" },
601 { STAT(BAD_CHANNEL), "Bad channel name" },
602 { STAT(AUTH_FAILED), "Authentication failed" },
603 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
604 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
605 { STAT(RESOURCE_LIMIT), "No more free resources" },
606 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
607 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
608 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
609 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
610 { STAT(BAD_VERSION), "Bad version" },
611 { STAT(TIMEDOUT), "Service timed out" },
612 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
613 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
614 { STAT(BAD_SERVER), "Bad server name" },
615 { STAT(BAD_USERNAME), "Bad user name" },
620 /* Returns status message string */
622 const char *silc_get_status_message(unsigned char status)
626 for (i = 0; silc_status_messages[i].message; i++) {
627 if (silc_status_messages[i].status == status)
631 if (silc_status_messages[i].message == NULL)
634 return silc_status_messages[i].message;
637 static const char *packet_name[] = {
648 "PRIVATE MESSAGE KEY",
654 "CONNECTION AUTH REQUEST",
669 /* Returns packet type name */
671 const char *silc_get_packet_name(unsigned char type)
673 if (type >= SILC_PACKET_MAX)
675 if (type >= SILC_PACKET_PRIVATE)
676 return "PRIVATE RANGE";
677 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
679 return packet_name[type];
682 static const char *command_name[] = {
713 /* Returns command name */
715 const char *silc_get_command_name(unsigned char command)
717 if (command >= SILC_COMMAND_RESERVED)
719 if (command >= SILC_COMMAND_PRIVATE)
720 return "PRIVATE RANGE";
721 if (command > (sizeof(command_name) / sizeof(*command_name)))
723 return command_name[command];
726 /* Parses SILC protocol style version string. */
728 SilcBool silc_parse_version_string(const char *version,
729 SilcUInt32 *protocol_version,
730 char **protocol_version_string,
731 SilcUInt32 *software_version,
732 char **software_version_string,
733 char **vendor_version)
736 int maj = 0, min = 0;
738 if (!strstr(version, "SILC-"))
741 cp = (char *)version + 5;
745 /* Take protocol version */
748 if (!strchr(cp, '.'))
750 cp = strchr(cp, '.') + 1;
755 memset(buf, 0, sizeof(buf));
756 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
757 if (protocol_version)
758 *protocol_version = atoi(buf);
759 memset(buf, 0, sizeof(buf));
760 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
761 if (protocol_version_string)
762 *protocol_version_string = strdup(buf);
764 /* Take software version */
768 if (!strchr(cp, '-'))
770 cp = strchr(cp, '-') + 1;
775 if (strchr(cp, '.')) {
776 cp = strchr(cp, '.') + 1;
781 memset(buf, 0, sizeof(buf));
782 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
783 if (software_version)
784 *software_version = atoi(buf);
785 memset(buf, 0, sizeof(buf));
786 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
787 if (software_version_string)
788 *software_version_string = strdup(buf);
790 /* Take vendor string */
792 if (strchr(cp, '.')) {
793 cp = strchr(cp, '.') + 1;
794 if (cp && *cp && vendor_version)
795 *vendor_version = strdup(cp);
801 /* Converts version string x.x into number representation. */
803 SilcUInt32 silc_version_to_num(const char *version)
805 int maj = 0, min = 0;
811 cp = (char *)version;
813 cp = strchr(cp, '.');
817 memset(buf, 0, sizeof(buf));
818 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
819 return (SilcUInt32)atoi(buf);
822 /* Parses mode mask and returns the mode as string. */
824 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
831 memset(string, 0, sizeof(string));
833 if (mode & SILC_CHANNEL_MODE_PRIVATE)
834 strncat(string, "p", 1);
836 if (mode & SILC_CHANNEL_MODE_SECRET)
837 strncat(string, "s", 1);
839 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
840 strncat(string, "k", 1);
842 if (mode & SILC_CHANNEL_MODE_INVITE)
843 strncat(string, "i", 1);
845 if (mode & SILC_CHANNEL_MODE_TOPIC)
846 strncat(string, "t", 1);
848 if (mode & SILC_CHANNEL_MODE_ULIMIT)
849 strncat(string, "l", 1);
851 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
852 strncat(string, "a", 1);
854 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
855 strncat(string, "f", 1);
857 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
858 strncat(string, "C", 1);
860 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
861 strncat(string, "m", 1);
863 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
864 strncat(string, "M", 1);
866 if (mode & SILC_CHANNEL_MODE_CIPHER)
867 strncat(string, "c", 1);
869 if (mode & SILC_CHANNEL_MODE_HMAC)
870 strncat(string, "h", 1);
872 if (mode & SILC_CHANNEL_MODE_CIPHER) {
873 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
874 strncat(string, " ", 1);
875 strncat(string, cipher, strlen(cipher));
879 if (mode & SILC_CHANNEL_MODE_HMAC) {
880 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
881 strncat(string, " ", 1);
882 strncat(string, hmac, strlen(hmac));
886 /* Rest of mode is ignored */
888 return strdup(string);
891 /* Parses channel user mode mask and returns te mode as string */
893 char *silc_client_chumode(SilcUInt32 mode)
900 memset(string, 0, sizeof(string));
902 if (mode & SILC_CHANNEL_UMODE_CHANFO)
903 strncat(string, "f", 1);
905 if (mode & SILC_CHANNEL_UMODE_CHANOP)
906 strncat(string, "o", 1);
908 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
909 strncat(string, "b", 1);
911 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
912 strncat(string, "u", 1);
914 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
915 strncat(string, "r", 1);
917 if (mode & SILC_CHANNEL_UMODE_QUIET)
918 strncat(string, "q", 1);
920 return strdup(string);
923 /* Parses channel user mode and returns it as special mode character. */
925 char *silc_client_chumode_char(SilcUInt32 mode)
932 memset(string, 0, sizeof(string));
934 if (mode & SILC_CHANNEL_UMODE_CHANFO)
935 strncat(string, "*", 1);
937 if (mode & SILC_CHANNEL_UMODE_CHANOP)
938 strncat(string, "@", 1);
940 if (mode & SILC_CHANNEL_UMODE_QUIET)
941 strncat(string, "&", 1);
943 return strdup(string);
946 /* Renders ID to suitable to print for example to log file. */
948 static char rid[256];
949 #define _PUT_STRING(__d__, __s__) \
951 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
952 if (__sp < strlen(__s__)) { \
954 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
956 strncat(__d__, __s__, strlen(__s__)); \
960 char *silc_id_render(void *id, SilcIdType id_type)
963 unsigned char tmps[2];
966 memset(rid, 0, sizeof(rid));
970 SilcServerID *server_id = (SilcServerID *)id;
971 if (server_id->ip.data_len > 4) {
973 struct sockaddr_in6 ipv6;
974 memset(&ipv6, 0, sizeof(ipv6));
975 ipv6.sin6_family = AF_INET6;
976 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
977 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
978 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
979 _PUT_STRING(rid, tmp);
983 memmove(&ipv4.s_addr, server_id->ip.data, 4);
984 cp = inet_ntoa(ipv4);
986 _PUT_STRING(rid, cp);
989 memset(tmp, 0, sizeof(tmp));
990 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
991 _PUT_STRING(rid, tmp);
992 SILC_PUT16_MSB(server_id->rnd, tmps);
993 memset(tmp, 0, sizeof(tmp));
994 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
995 _PUT_STRING(rid, tmp);
1000 SilcClientID *client_id = (SilcClientID *)id;
1001 if (client_id->ip.data_len > 4) {
1003 struct sockaddr_in6 ipv6;
1004 memset(&ipv6, 0, sizeof(ipv6));
1005 ipv6.sin6_family = AF_INET6;
1006 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
1007 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1008 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1009 _PUT_STRING(rid, tmp);
1012 struct in_addr ipv4;
1013 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1014 cp = inet_ntoa(ipv4);
1016 _PUT_STRING(rid, cp);
1019 memset(tmp, 0, sizeof(tmp));
1020 snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1021 _PUT_STRING(rid, tmp);
1022 memset(tmp, 0, sizeof(tmp));
1023 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1024 client_id->hash[0], client_id->hash[1],
1025 client_id->hash[2], client_id->hash[3]);
1026 _PUT_STRING(rid, tmp);
1029 case SILC_ID_CHANNEL:
1031 SilcChannelID *channel_id = (SilcChannelID *)id;
1032 if (channel_id->ip.data_len > 4) {
1034 struct sockaddr_in6 ipv6;
1035 memset(&ipv6, 0, sizeof(ipv6));
1036 ipv6.sin6_family = AF_INET6;
1037 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1038 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1039 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1040 _PUT_STRING(rid, tmp);
1043 struct in_addr ipv4;
1044 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1045 cp = inet_ntoa(ipv4);
1047 _PUT_STRING(rid, cp);
1050 memset(tmp, 0, sizeof(tmp));
1051 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1052 _PUT_STRING(rid, tmp);
1053 SILC_PUT16_MSB(channel_id->rnd, tmps);
1054 memset(tmp, 0, sizeof(tmp));
1055 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1056 _PUT_STRING(rid, tmp);