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;
75 if (interactive && (!alg || !pub_filename || !prv_filename))
77 New pair of keys will be created. Please, answer to following questions.\n\
83 alg = silc_get_input("PKCS name (l to list names) [rsa]: ", FALSE);
87 if (*alg == 'l' || *alg == 'L') {
88 char *list = silc_pkcs_get_supported();
100 if (!silc_pkcs_find_algorithm(alg, NULL)) {
101 fprintf(stderr, "Unknown PKCS algorithm `%s' or crypto library"
102 "is not initialized", alg);
109 length = silc_get_input("Key length in key_len_bits [2048]: ", FALSE);
111 key_len_bits = atoi(length);
119 char *def = silc_create_pk_identifier();
122 memset(line, 0, sizeof(line));
124 snprintf(line, sizeof(line), "Identifier [%s]: ", def);
126 snprintf(line, sizeof(line),
127 "Identifier (eg. UN=jon, HN=jon.dummy.com, "
128 "RN=Jon Johnson, E=jon@dummy.com): ");
130 while (!identifier) {
131 identifier = silc_get_input(line, FALSE);
132 if (!identifier && def)
133 identifier = strdup(def);
137 fprintf(stderr, "Could not create public key identifier: %s\n",
141 identifier = strdup(def);
147 rng = silc_rng_alloc();
149 silc_rng_global_init(rng);
153 memset(line, 0, sizeof(line));
154 snprintf(line, sizeof(line), "Public key filename [public_key.pub]: ");
155 pkfile = silc_get_input(line, FALSE);
158 pkfile = strdup("public_key.pub");
163 memset(line, 0, sizeof(line));
164 snprintf(line, sizeof(line), "Private key filename [private_key.prv]: ");
165 prvfile = silc_get_input(line, FALSE);
168 prvfile = strdup("private_key.prv");
174 pass = silc_get_input("Private key passphrase: ", TRUE);
181 pass2 = silc_get_input("Retype private key passphrase: ", TRUE);
184 match = !strcmp(pass, pass2);
188 fprintf(stderr, "\nPassphrases do not match\n\n");
194 if (!silc_pkcs_silc_generate_key(alg, "pkcs1-no-oid", key_len_bits,
195 identifier, rng, return_public_key,
199 /* Save public key into file */
200 silc_pkcs_save_public_key(pkfile, *return_public_key, SILC_PKCS_FILE_BASE64);
202 /* Save private key into file */
203 silc_pkcs_save_private_key(prvfile, *return_private_key,
204 (const unsigned char *)pass, strlen(pass),
205 SILC_PKCS_FILE_BIN, rng);
207 printf("Public key has been saved into `%s'.\n", pkfile);
208 printf("Private key has been saved into `%s'.\n", prvfile);
210 printf("Press <Enter> to continue...\n");
218 silc_free(identifier);
219 memset(pass, 0, strlen(pass));
227 SilcBool silc_load_key_pair(const char *pub_filename,
228 const char *prv_filename,
229 const char *passphrase,
230 SilcPublicKey *return_public_key,
231 SilcPrivateKey *return_private_key)
233 char *pass = passphrase ? strdup(passphrase) : NULL;
235 SILC_LOG_DEBUG(("Loading public and private keys"));
237 if (!silc_pkcs_load_public_key(pub_filename, return_public_key)) {
239 memset(pass, 0, strlen(pass));
245 pass = silc_get_input("Private key passphrase: ", TRUE);
250 if (!silc_pkcs_load_private_key(prv_filename,
251 (const unsigned char *)pass, strlen(pass),
252 return_private_key)) {
253 memset(pass, 0, strlen(pass));
258 memset(pass, 0, strlen(pass));
263 /* Dump public key into stdout */
265 SilcBool silc_show_public_key(const char *pub_filename)
267 SilcPublicKey public_key;
268 SilcSILCPublicKey silc_pubkey;
269 SilcPublicKeyIdentifier ident;
270 char *fingerprint, *babbleprint;
273 SilcUInt32 key_len = 0;
275 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
276 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
280 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
282 silc_pkcs_public_key_free(public_key);
286 ident = &silc_pubkey->identifier;
287 key_len = silc_pkcs_public_key_get_len(public_key);
288 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
290 silc_pkcs_public_key_free(public_key);
293 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
294 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
296 printf("Public key file : %s\n", pub_filename);
297 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
299 printf("Key length (bits) : %d\n", (unsigned int)key_len);
301 printf("Real name : %s\n", ident->realname);
303 printf("Username : %s\n", ident->username);
305 printf("Hostname : %s\n", ident->host);
307 printf("Email : %s\n", ident->email);
309 printf("Organization : %s\n", ident->org);
311 printf("Country : %s\n", ident->country);
312 printf("Fingerprint (SHA1) : %s\n", fingerprint);
313 printf("Babbleprint (SHA1) : %s\n", babbleprint);
317 silc_free(fingerprint);
318 silc_free(babbleprint);
320 silc_pkcs_public_key_free(public_key);
325 /* Change private key passphrase */
327 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
328 const char *old_passphrase,
329 const char *new_passphrase)
331 SilcPrivateKey private_key;
335 pass = old_passphrase ? strdup(old_passphrase) : NULL;
337 pass = silc_get_input("Old passphrase: ", TRUE);
342 if (!silc_pkcs_load_private_key(prv_filename,
343 (const unsigned char *)pass, strlen(pass),
345 memset(pass, 0, strlen(pass));
347 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
351 memset(pass, 0, strlen(pass));
354 pass = new_passphrase ? strdup(new_passphrase) : NULL;
357 fprintf(stdout, "\n");
358 pass = silc_get_input("New passphrase: ", TRUE);
364 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
367 if (!strcmp(pass, pass2))
369 fprintf(stderr, "\nPassphrases do not match");
375 rng = silc_rng_alloc();
378 silc_pkcs_save_private_key((char *)prv_filename, private_key,
379 (unsigned char *)pass, strlen(pass),
380 SILC_PKCS_FILE_BIN, rng);
382 fprintf(stdout, "\nPassphrase changed\n");
384 memset(pass, 0, strlen(pass));
387 silc_pkcs_private_key_free(private_key);
393 /* Checks that the 'identifier' string is valid identifier string
394 and does not contain any unassigned or prohibited character. This
395 function is used to check for valid nicknames, channel names,
396 server names, usernames, hostnames, service names, algorithm names,
397 other security property names, and SILC Public Key name. */
399 unsigned char *silc_identifier_check(const unsigned char *identifier,
400 SilcUInt32 identifier_len,
401 SilcStringEncoding identifier_encoding,
402 SilcUInt32 max_allowed_length,
405 unsigned char *utf8s;
406 SilcUInt32 utf8s_len;
407 SilcStringprepStatus status;
409 if (!identifier || !identifier_len)
412 if (max_allowed_length && identifier_len > max_allowed_length)
415 status = silc_stringprep(identifier, identifier_len,
416 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
417 &utf8s, &utf8s_len, SILC_STRING_UTF8);
418 if (status != SILC_STRINGPREP_OK) {
419 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
424 *out_len = utf8s_len;
429 /* Same as above but does not allocate memory, just checks the
430 validity of the string. */
432 SilcBool silc_identifier_verify(const unsigned char *identifier,
433 SilcUInt32 identifier_len,
434 SilcStringEncoding identifier_encoding,
435 SilcUInt32 max_allowed_length)
437 SilcStringprepStatus status;
439 if (!identifier || !identifier_len)
442 if (max_allowed_length && identifier_len > max_allowed_length)
445 status = silc_stringprep(identifier, identifier_len,
446 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
447 NULL, NULL, SILC_STRING_UTF8);
448 if (status != SILC_STRINGPREP_OK) {
449 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
456 unsigned char *silc_channel_name_check(const unsigned char *identifier,
457 SilcUInt32 identifier_len,
458 SilcStringEncoding identifier_encoding,
459 SilcUInt32 max_allowed_length,
462 unsigned char *utf8s;
463 SilcUInt32 utf8s_len;
464 SilcStringprepStatus status;
466 if (!identifier || !identifier_len)
469 if (max_allowed_length && identifier_len > max_allowed_length)
472 status = silc_stringprep(identifier, identifier_len,
473 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
474 &utf8s, &utf8s_len, SILC_STRING_UTF8);
475 if (status != SILC_STRINGPREP_OK) {
476 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
481 *out_len = utf8s_len;
486 /* Same as above but does not allocate memory, just checks the
487 validity of the string. */
489 SilcBool silc_channel_name_verify(const unsigned char *identifier,
490 SilcUInt32 identifier_len,
491 SilcStringEncoding identifier_encoding,
492 SilcUInt32 max_allowed_length)
494 SilcStringprepStatus status;
496 if (!identifier || !identifier_len)
499 if (max_allowed_length && identifier_len > max_allowed_length)
502 status = silc_stringprep(identifier, identifier_len,
503 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
504 NULL, NULL, SILC_STRING_UTF8);
505 if (status != SILC_STRINGPREP_OK) {
506 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
513 /* Return mode list */
515 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
520 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
523 *list = silc_calloc(mode_list_count, sizeof(**list));
525 for (i = 0; i < mode_list_count; i++) {
526 SILC_GET32_MSB((*list)[i], mode_list->data);
527 silc_buffer_pull(mode_list, 4);
530 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
535 /* Status message structure. Messages are defined below. */
541 #define STAT(x) SILC_STATUS_ERR_##x
542 static const SilcStatusMessage silc_status_messages[] = {
544 { STAT(NO_SUCH_NICK), "There was no such nickname" },
545 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
546 { STAT(NO_SUCH_SERVER), "There was no such server" },
547 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
548 { STAT(NO_RECIPIENT), "No recipient given" },
549 { STAT(UNKNOWN_COMMAND), "Unknown command" },
550 { STAT(WILDCARDS), "Wilcrads not allowed" },
551 { STAT(NO_CLIENT_ID), "No Client ID given" },
552 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
553 { STAT(NO_SERVER_ID), "No Server ID given" },
554 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
555 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
556 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
557 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
558 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
559 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
560 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
561 { STAT(USER_ON_CHANNEL), "User already on the channel" },
562 { STAT(NOT_REGISTERED), "You have not registered" },
563 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
564 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
565 { STAT(PERM_DENIED), "Permission denied" },
566 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
567 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
568 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
569 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
570 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
571 { STAT(UNKNOWN_MODE), "Unknown mode" },
572 { STAT(NOT_YOU), "Cannot change mode for other users" },
573 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
574 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
575 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
576 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
577 { STAT(BAD_NICKNAME), "Bad nickname" },
578 { STAT(BAD_CHANNEL), "Bad channel name" },
579 { STAT(AUTH_FAILED), "Authentication failed" },
580 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
581 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
582 { STAT(RESOURCE_LIMIT), "No more free resources" },
583 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
584 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
585 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
586 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
587 { STAT(BAD_VERSION), "Bad version" },
588 { STAT(TIMEDOUT), "Service timed out" },
589 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
590 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
591 { STAT(BAD_SERVER), "Bad server name" },
592 { STAT(BAD_USERNAME), "Bad user name" },
597 /* Returns status message string */
599 const char *silc_get_status_message(unsigned char status)
603 for (i = 0; silc_status_messages[i].message; i++) {
604 if (silc_status_messages[i].status == status)
608 if (silc_status_messages[i].message == NULL)
611 return silc_status_messages[i].message;
614 static const char *packet_name[] = {
625 "PRIVATE MESSAGE KEY",
631 "CONNECTION AUTH REQUEST",
646 /* Returns packet type name */
648 const char *silc_get_packet_name(unsigned char type)
650 if (type >= SILC_PACKET_MAX)
652 if (type >= SILC_PACKET_PRIVATE)
653 return "PRIVATE RANGE";
654 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
656 return packet_name[type];
659 static const char *command_name[] = {
690 /* Returns command name */
692 const char *silc_get_command_name(unsigned char command)
694 if (command >= SILC_COMMAND_RESERVED)
696 if (command >= SILC_COMMAND_PRIVATE)
697 return "PRIVATE RANGE";
698 if (command > (sizeof(command_name) / sizeof(*command_name)))
700 return command_name[command];
703 /* Parses SILC protocol style version string. */
705 SilcBool silc_parse_version_string(const char *version,
706 SilcUInt32 *protocol_version,
707 char **protocol_version_string,
708 SilcUInt32 *software_version,
709 char **software_version_string,
710 char **vendor_version)
713 int maj = 0, min = 0;
715 if (!strstr(version, "SILC-"))
718 cp = (char *)version + 5;
722 /* Take protocol version */
725 if (!strchr(cp, '.'))
727 cp = strchr(cp, '.') + 1;
732 memset(buf, 0, sizeof(buf));
733 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
734 if (protocol_version)
735 *protocol_version = atoi(buf);
736 memset(buf, 0, sizeof(buf));
737 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
738 if (protocol_version_string)
739 *protocol_version_string = strdup(buf);
741 /* Take software version */
745 if (!strchr(cp, '-'))
747 cp = strchr(cp, '-') + 1;
752 if (strchr(cp, '.')) {
753 cp = strchr(cp, '.') + 1;
758 memset(buf, 0, sizeof(buf));
759 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
760 if (software_version)
761 *software_version = atoi(buf);
762 memset(buf, 0, sizeof(buf));
763 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
764 if (software_version_string)
765 *software_version_string = strdup(buf);
767 /* Take vendor string */
769 if (strchr(cp, '.')) {
770 cp = strchr(cp, '.') + 1;
771 if (cp && *cp && vendor_version)
772 *vendor_version = strdup(cp);
778 /* Converts version string x.x into number representation. */
780 SilcUInt32 silc_version_to_num(const char *version)
782 int maj = 0, min = 0;
788 cp = (char *)version;
790 cp = strchr(cp, '.');
794 memset(buf, 0, sizeof(buf));
795 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
796 return (SilcUInt32)atoi(buf);
799 /* Parses mode mask and returns the mode as string. */
801 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
808 memset(string, 0, sizeof(string));
810 if (mode & SILC_CHANNEL_MODE_PRIVATE)
811 strncat(string, "p", 1);
813 if (mode & SILC_CHANNEL_MODE_SECRET)
814 strncat(string, "s", 1);
816 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
817 strncat(string, "k", 1);
819 if (mode & SILC_CHANNEL_MODE_INVITE)
820 strncat(string, "i", 1);
822 if (mode & SILC_CHANNEL_MODE_TOPIC)
823 strncat(string, "t", 1);
825 if (mode & SILC_CHANNEL_MODE_ULIMIT)
826 strncat(string, "l", 1);
828 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
829 strncat(string, "a", 1);
831 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
832 strncat(string, "f", 1);
834 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
835 strncat(string, "C", 1);
837 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
838 strncat(string, "m", 1);
840 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
841 strncat(string, "M", 1);
843 if (mode & SILC_CHANNEL_MODE_CIPHER)
844 strncat(string, "c", 1);
846 if (mode & SILC_CHANNEL_MODE_HMAC)
847 strncat(string, "h", 1);
849 if (mode & SILC_CHANNEL_MODE_CIPHER) {
850 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
851 strncat(string, " ", 1);
852 strncat(string, cipher, strlen(cipher));
856 if (mode & SILC_CHANNEL_MODE_HMAC) {
857 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
858 strncat(string, " ", 1);
859 strncat(string, hmac, strlen(hmac));
863 /* Rest of mode is ignored */
865 return strdup(string);
868 /* Parses channel user mode mask and returns te mode as string */
870 char *silc_client_chumode(SilcUInt32 mode)
877 memset(string, 0, sizeof(string));
879 if (mode & SILC_CHANNEL_UMODE_CHANFO)
880 strncat(string, "f", 1);
882 if (mode & SILC_CHANNEL_UMODE_CHANOP)
883 strncat(string, "o", 1);
885 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
886 strncat(string, "b", 1);
888 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
889 strncat(string, "u", 1);
891 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
892 strncat(string, "r", 1);
894 if (mode & SILC_CHANNEL_UMODE_QUIET)
895 strncat(string, "q", 1);
897 return strdup(string);
900 /* Parses channel user mode and returns it as special mode character. */
902 char *silc_client_chumode_char(SilcUInt32 mode)
909 memset(string, 0, sizeof(string));
911 if (mode & SILC_CHANNEL_UMODE_CHANFO)
912 strncat(string, "*", 1);
914 if (mode & SILC_CHANNEL_UMODE_CHANOP)
915 strncat(string, "@", 1);
917 if (mode & SILC_CHANNEL_UMODE_QUIET)
918 strncat(string, "&", 1);
920 return strdup(string);
923 /* Renders ID to suitable to print for example to log file. */
925 static char rid[256];
926 #define _PUT_STRING(__d__, __s__) \
928 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
929 if (__sp < strlen(__s__)) { \
931 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
933 strncat(__d__, __s__, strlen(__s__)); \
937 char *silc_id_render(void *id, SilcIdType id_type)
940 unsigned char tmps[2];
943 memset(rid, 0, sizeof(rid));
947 SilcServerID *server_id = (SilcServerID *)id;
948 if (server_id->ip.data_len > 4) {
950 struct sockaddr_in6 ipv6;
951 memset(&ipv6, 0, sizeof(ipv6));
952 ipv6.sin6_family = AF_INET6;
953 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
954 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
955 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
956 _PUT_STRING(rid, tmp);
960 memmove(&ipv4.s_addr, server_id->ip.data, 4);
961 cp = inet_ntoa(ipv4);
963 _PUT_STRING(rid, cp);
966 memset(tmp, 0, sizeof(tmp));
967 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
968 _PUT_STRING(rid, tmp);
969 SILC_PUT16_MSB(server_id->rnd, tmps);
970 memset(tmp, 0, sizeof(tmp));
971 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
972 _PUT_STRING(rid, tmp);
977 SilcClientID *client_id = (SilcClientID *)id;
978 if (client_id->ip.data_len > 4) {
980 struct sockaddr_in6 ipv6;
981 memset(&ipv6, 0, sizeof(ipv6));
982 ipv6.sin6_family = AF_INET6;
983 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
984 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
985 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
986 _PUT_STRING(rid, tmp);
990 memmove(&ipv4.s_addr, client_id->ip.data, 4);
991 cp = inet_ntoa(ipv4);
993 _PUT_STRING(rid, cp);
996 memset(tmp, 0, sizeof(tmp));
997 snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
998 _PUT_STRING(rid, tmp);
999 memset(tmp, 0, sizeof(tmp));
1000 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1001 client_id->hash[0], client_id->hash[1],
1002 client_id->hash[2], client_id->hash[3]);
1003 _PUT_STRING(rid, tmp);
1006 case SILC_ID_CHANNEL:
1008 SilcChannelID *channel_id = (SilcChannelID *)id;
1009 if (channel_id->ip.data_len > 4) {
1011 struct sockaddr_in6 ipv6;
1012 memset(&ipv6, 0, sizeof(ipv6));
1013 ipv6.sin6_family = AF_INET6;
1014 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1015 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1016 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1017 _PUT_STRING(rid, tmp);
1020 struct in_addr ipv4;
1021 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1022 cp = inet_ntoa(ipv4);
1024 _PUT_STRING(rid, cp);
1027 memset(tmp, 0, sizeof(tmp));
1028 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1029 _PUT_STRING(rid, tmp);
1030 SILC_PUT16_MSB(channel_id->rnd, tmps);
1031 memset(tmp, 0, sizeof(tmp));
1032 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1033 _PUT_STRING(rid, tmp);