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(SilcPublicKey public_key)
267 SilcSILCPublicKey silc_pubkey;
268 SilcPublicKeyIdentifier ident;
269 char *fingerprint, *babbleprint;
272 SilcUInt32 key_len = 0;
274 silc_pubkey = silc_pkcs_get_context(SILC_PKCS_SILC, public_key);
276 silc_pkcs_public_key_free(public_key);
280 ident = &silc_pubkey->identifier;
281 key_len = silc_pkcs_public_key_get_len(public_key);
282 pk = silc_pkcs_public_key_encode(public_key, &pk_len);
284 silc_pkcs_public_key_free(public_key);
287 fingerprint = silc_hash_fingerprint(NULL, pk, pk_len);
288 babbleprint = silc_hash_babbleprint(NULL, pk, pk_len);
290 printf("Algorithm : %s\n", silc_pkcs_get_name(public_key));
292 printf("Key length (bits) : %d\n", (unsigned int)key_len);
294 printf("Real name : %s\n", ident->realname);
296 printf("Username : %s\n", ident->username);
298 printf("Hostname : %s\n", ident->host);
300 printf("Email : %s\n", ident->email);
302 printf("Organization : %s\n", ident->org);
304 printf("Country : %s\n", ident->country);
305 printf("Fingerprint (SHA1) : %s\n", fingerprint);
306 printf("Babbleprint (SHA1) : %s\n", babbleprint);
310 silc_free(fingerprint);
311 silc_free(babbleprint);
317 /* Dump public key into stdout */
319 SilcBool silc_show_public_key_file(const char *pub_filename)
321 SilcPublicKey public_key;
324 if (!silc_pkcs_load_public_key((char *)pub_filename, &public_key)) {
325 fprintf(stderr, "Could not load public key file `%s'\n", pub_filename);
329 printf("Public key file : %s\n", pub_filename);
330 ret = silc_show_public_key(public_key);
331 silc_pkcs_public_key_free(public_key);
336 /* Change private key passphrase */
338 SilcBool silc_change_private_key_passphrase(const char *prv_filename,
339 const char *old_passphrase,
340 const char *new_passphrase)
342 SilcPrivateKey private_key;
346 pass = old_passphrase ? strdup(old_passphrase) : NULL;
348 pass = silc_get_input("Old passphrase: ", TRUE);
353 if (!silc_pkcs_load_private_key(prv_filename,
354 (const unsigned char *)pass, strlen(pass),
356 memset(pass, 0, strlen(pass));
358 fprintf(stderr, "Could not load private key `%s' file\n", prv_filename);
362 memset(pass, 0, strlen(pass));
365 pass = new_passphrase ? strdup(new_passphrase) : NULL;
368 fprintf(stdout, "\n");
369 pass = silc_get_input("New passphrase: ", TRUE);
375 pass2 = silc_get_input("Retype new passphrase: ", TRUE);
378 if (!strcmp(pass, pass2))
380 fprintf(stderr, "\nPassphrases do not match");
386 rng = silc_rng_alloc();
389 silc_pkcs_save_private_key((char *)prv_filename, private_key,
390 (unsigned char *)pass, strlen(pass),
391 SILC_PKCS_FILE_BIN, rng);
393 fprintf(stdout, "\nPassphrase changed\n");
395 memset(pass, 0, strlen(pass));
398 silc_pkcs_private_key_free(private_key);
404 /* Checks that the 'identifier' string is valid identifier string
405 and does not contain any unassigned or prohibited character. This
406 function is used to check for valid nicknames, channel names,
407 server names, usernames, hostnames, service names, algorithm names,
408 other security property names, and SILC Public Key name. */
410 unsigned char *silc_identifier_check(const unsigned char *identifier,
411 SilcUInt32 identifier_len,
412 SilcStringEncoding identifier_encoding,
413 SilcUInt32 max_allowed_length,
416 unsigned char *utf8s;
417 SilcUInt32 utf8s_len;
418 SilcStringprepStatus status;
420 if (!identifier || !identifier_len)
423 if (max_allowed_length && identifier_len > max_allowed_length)
426 status = silc_stringprep(identifier, identifier_len,
427 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
428 &utf8s, &utf8s_len, SILC_STRING_UTF8);
429 if (status != SILC_STRINGPREP_OK) {
430 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
435 *out_len = utf8s_len;
440 /* Same as above but does not allocate memory, just checks the
441 validity of the string. */
443 SilcBool silc_identifier_verify(const unsigned char *identifier,
444 SilcUInt32 identifier_len,
445 SilcStringEncoding identifier_encoding,
446 SilcUInt32 max_allowed_length)
448 SilcStringprepStatus status;
450 if (!identifier || !identifier_len)
453 if (max_allowed_length && identifier_len > max_allowed_length)
456 status = silc_stringprep(identifier, identifier_len,
457 identifier_encoding, SILC_IDENTIFIER_PREP, 0,
458 NULL, NULL, SILC_STRING_UTF8);
459 if (status != SILC_STRINGPREP_OK) {
460 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
467 unsigned char *silc_channel_name_check(const unsigned char *identifier,
468 SilcUInt32 identifier_len,
469 SilcStringEncoding identifier_encoding,
470 SilcUInt32 max_allowed_length,
473 unsigned char *utf8s;
474 SilcUInt32 utf8s_len;
475 SilcStringprepStatus status;
477 if (!identifier || !identifier_len)
480 if (max_allowed_length && identifier_len > max_allowed_length)
483 status = silc_stringprep(identifier, identifier_len,
484 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
485 &utf8s, &utf8s_len, SILC_STRING_UTF8);
486 if (status != SILC_STRINGPREP_OK) {
487 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
492 *out_len = utf8s_len;
497 /* Same as above but does not allocate memory, just checks the
498 validity of the string. */
500 SilcBool silc_channel_name_verify(const unsigned char *identifier,
501 SilcUInt32 identifier_len,
502 SilcStringEncoding identifier_encoding,
503 SilcUInt32 max_allowed_length)
505 SilcStringprepStatus status;
507 if (!identifier || !identifier_len)
510 if (max_allowed_length && identifier_len > max_allowed_length)
513 status = silc_stringprep(identifier, identifier_len,
514 identifier_encoding, SILC_IDENTIFIER_CH_PREP, 0,
515 NULL, NULL, SILC_STRING_UTF8);
516 if (status != SILC_STRINGPREP_OK) {
517 SILC_LOG_DEBUG(("silc_stringprep() status error %d", status));
524 /* Return mode list */
526 SilcBool silc_get_mode_list(SilcBuffer mode_list, SilcUInt32 mode_list_count,
531 if (silc_buffer_len(mode_list) / 4 != mode_list_count)
534 *list = silc_calloc(mode_list_count, sizeof(**list));
536 for (i = 0; i < mode_list_count; i++) {
537 SILC_GET32_MSB((*list)[i], mode_list->data);
538 silc_buffer_pull(mode_list, 4);
541 silc_buffer_push(mode_list, mode_list->data - mode_list->head);
546 /* Status message structure. Messages are defined below. */
552 #define STAT(x) SILC_STATUS_ERR_##x
553 static const SilcStatusMessage silc_status_messages[] = {
555 { STAT(NO_SUCH_NICK), "There was no such nickname" },
556 { STAT(NO_SUCH_CHANNEL), "There was no such channel" },
557 { STAT(NO_SUCH_SERVER), "There was no such server" },
558 { STAT(INCOMPLETE_INFORMATION), "Incomplete registration information" },
559 { STAT(NO_RECIPIENT), "No recipient given" },
560 { STAT(UNKNOWN_COMMAND), "Unknown command" },
561 { STAT(WILDCARDS), "Wilcrads not allowed" },
562 { STAT(NO_CLIENT_ID), "No Client ID given" },
563 { STAT(NO_CHANNEL_ID), "No Channel ID given" },
564 { STAT(NO_SERVER_ID), "No Server ID given" },
565 { STAT(BAD_CLIENT_ID), "Bad Client ID" },
566 { STAT(BAD_CHANNEL_ID), "Bad Channel ID" },
567 { STAT(NO_SUCH_CLIENT_ID), "There is no such client" },
568 { STAT(NO_SUCH_CHANNEL_ID),"There is no such channel" },
569 { STAT(NICKNAME_IN_USE), "Nickname already exists" },
570 { STAT(NOT_ON_CHANNEL), "You are not on that channel" },
571 { STAT(USER_NOT_ON_CHANNEL),"They are not on the channel" },
572 { STAT(USER_ON_CHANNEL), "User already on the channel" },
573 { STAT(NOT_REGISTERED), "You have not registered" },
574 { STAT(NOT_ENOUGH_PARAMS), "Not enough parameters" },
575 { STAT(TOO_MANY_PARAMS), "Too many parameters" },
576 { STAT(PERM_DENIED), "Permission denied" },
577 { STAT(BANNED_FROM_SERVER),"You are not allowed to connect" },
578 { STAT(BAD_PASSWORD), "Cannot join channel. Incorrect password" },
579 { STAT(CHANNEL_IS_FULL), "Cannot join channel. Channel is full" },
580 { STAT(NOT_INVITED), "Cannot join channel. You have not been invited" },
581 { STAT(BANNED_FROM_CHANNEL), "Cannot join channel. You have been banned" },
582 { STAT(UNKNOWN_MODE), "Unknown mode" },
583 { STAT(NOT_YOU), "Cannot change mode for other users" },
584 { STAT(NO_CHANNEL_PRIV), "Permission denied. You are not channel operator" },
585 { STAT(NO_CHANNEL_FOPRIV),"Permission denied. You are not channel founder" },
586 { STAT(NO_SERVER_PRIV), "Permission denied. You are not server operator" },
587 { STAT(NO_ROUTER_PRIV), "Permission denied. You are not SILC operator" },
588 { STAT(BAD_NICKNAME), "Bad nickname" },
589 { STAT(BAD_CHANNEL), "Bad channel name" },
590 { STAT(AUTH_FAILED), "Authentication failed" },
591 { STAT(UNKNOWN_ALGORITHM), "Unsupported algorithm" },
592 { STAT(NO_SUCH_SERVER_ID), "No such Server ID" },
593 { STAT(RESOURCE_LIMIT), "No more free resources" },
594 { STAT(NO_SUCH_SERVICE), "Service doesn't exist" },
595 { STAT(NOT_AUTHENTICATED), "You have not been authenticated" },
596 { STAT(BAD_SERVER_ID), "Server ID is not valid" },
597 { STAT(KEY_EXCHANGE_FAILED), "Key exchange failed" },
598 { STAT(BAD_VERSION), "Bad version" },
599 { STAT(TIMEDOUT), "Service timed out" },
600 { STAT(UNSUPPORTED_PUBLIC_KEY), "Unsupported public key type" },
601 { STAT(OPERATION_ALLOWED), "Operation is not allowed" },
602 { STAT(BAD_SERVER), "Bad server name" },
603 { STAT(BAD_USERNAME), "Bad user name" },
608 /* Returns status message string */
610 const char *silc_get_status_message(unsigned char status)
614 for (i = 0; silc_status_messages[i].message; i++) {
615 if (silc_status_messages[i].status == status)
619 if (silc_status_messages[i].message == NULL)
622 return silc_status_messages[i].message;
625 static const char *packet_name[] = {
636 "PRIVATE MESSAGE KEY",
642 "CONNECTION AUTH REQUEST",
657 /* Returns packet type name */
659 const char *silc_get_packet_name(unsigned char type)
661 if (type >= SILC_PACKET_MAX)
663 if (type >= SILC_PACKET_PRIVATE)
664 return "PRIVATE RANGE";
665 if (type > (sizeof(packet_name) / sizeof(*packet_name)))
667 return packet_name[type];
670 static const char *command_name[] = {
701 /* Returns command name */
703 const char *silc_get_command_name(unsigned char command)
705 if (command >= SILC_COMMAND_RESERVED)
707 if (command >= SILC_COMMAND_PRIVATE)
708 return "PRIVATE RANGE";
709 if (command > (sizeof(command_name) / sizeof(*command_name)))
711 return command_name[command];
714 /* Parses SILC protocol style version string. */
716 SilcBool silc_parse_version_string(const char *version,
717 SilcUInt32 *protocol_version,
718 char **protocol_version_string,
719 SilcUInt32 *software_version,
720 char **software_version_string,
721 char **vendor_version)
724 int maj = 0, min = 0;
726 if (!strstr(version, "SILC-"))
729 cp = (char *)version + 5;
733 /* Take protocol version */
736 if (!strchr(cp, '.'))
738 cp = strchr(cp, '.') + 1;
743 memset(buf, 0, sizeof(buf));
744 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
745 if (protocol_version)
746 *protocol_version = atoi(buf);
747 memset(buf, 0, sizeof(buf));
748 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
749 if (protocol_version_string)
750 *protocol_version_string = strdup(buf);
752 /* Take software version */
756 if (!strchr(cp, '-'))
758 cp = strchr(cp, '-') + 1;
763 if (strchr(cp, '.')) {
764 cp = strchr(cp, '.') + 1;
769 memset(buf, 0, sizeof(buf));
770 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
771 if (software_version)
772 *software_version = atoi(buf);
773 memset(buf, 0, sizeof(buf));
774 snprintf(buf, sizeof(buf) - 1, "%d.%d", maj, min);
775 if (software_version_string)
776 *software_version_string = strdup(buf);
778 /* Take vendor string */
780 if (strchr(cp, '.')) {
781 cp = strchr(cp, '.') + 1;
782 if (cp && *cp && vendor_version)
783 *vendor_version = strdup(cp);
789 /* Converts version string x.x into number representation. */
791 SilcUInt32 silc_version_to_num(const char *version)
793 int maj = 0, min = 0;
799 cp = (char *)version;
801 cp = strchr(cp, '.');
805 memset(buf, 0, sizeof(buf));
806 snprintf(buf, sizeof(buf) - 1, "%d%d", maj, min);
807 return (SilcUInt32)atoi(buf);
810 /* Parses mode mask and returns the mode as string. */
812 char *silc_client_chmode(SilcUInt32 mode, const char *cipher, const char *hmac)
819 memset(string, 0, sizeof(string));
821 if (mode & SILC_CHANNEL_MODE_PRIVATE)
822 strncat(string, "p", 1);
824 if (mode & SILC_CHANNEL_MODE_SECRET)
825 strncat(string, "s", 1);
827 if (mode & SILC_CHANNEL_MODE_PRIVKEY)
828 strncat(string, "k", 1);
830 if (mode & SILC_CHANNEL_MODE_INVITE)
831 strncat(string, "i", 1);
833 if (mode & SILC_CHANNEL_MODE_TOPIC)
834 strncat(string, "t", 1);
836 if (mode & SILC_CHANNEL_MODE_ULIMIT)
837 strncat(string, "l", 1);
839 if (mode & SILC_CHANNEL_MODE_PASSPHRASE)
840 strncat(string, "a", 1);
842 if (mode & SILC_CHANNEL_MODE_FOUNDER_AUTH)
843 strncat(string, "f", 1);
845 if (mode & SILC_CHANNEL_MODE_CHANNEL_AUTH)
846 strncat(string, "C", 1);
848 if (mode & SILC_CHANNEL_MODE_SILENCE_USERS)
849 strncat(string, "m", 1);
851 if (mode & SILC_CHANNEL_MODE_SILENCE_OPERS)
852 strncat(string, "M", 1);
854 if (mode & SILC_CHANNEL_MODE_CIPHER)
855 strncat(string, "c", 1);
857 if (mode & SILC_CHANNEL_MODE_HMAC)
858 strncat(string, "h", 1);
860 if (mode & SILC_CHANNEL_MODE_CIPHER) {
861 if (strlen(cipher) + strlen(string) + 1< sizeof(string)) {
862 strncat(string, " ", 1);
863 strncat(string, cipher, strlen(cipher));
867 if (mode & SILC_CHANNEL_MODE_HMAC) {
868 if (strlen(hmac) + strlen(string) + 1< sizeof(string)) {
869 strncat(string, " ", 1);
870 strncat(string, hmac, strlen(hmac));
874 /* Rest of mode is ignored */
876 return strdup(string);
879 /* Parses channel user mode mask and returns te mode as string */
881 char *silc_client_chumode(SilcUInt32 mode)
888 memset(string, 0, sizeof(string));
890 if (mode & SILC_CHANNEL_UMODE_CHANFO)
891 strncat(string, "f", 1);
893 if (mode & SILC_CHANNEL_UMODE_CHANOP)
894 strncat(string, "o", 1);
896 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES)
897 strncat(string, "b", 1);
899 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_USERS)
900 strncat(string, "u", 1);
902 if (mode & SILC_CHANNEL_UMODE_BLOCK_MESSAGES_ROBOTS)
903 strncat(string, "r", 1);
905 if (mode & SILC_CHANNEL_UMODE_QUIET)
906 strncat(string, "q", 1);
908 return strdup(string);
911 /* Parses channel user mode and returns it as special mode character. */
913 char *silc_client_chumode_char(SilcUInt32 mode)
920 memset(string, 0, sizeof(string));
922 if (mode & SILC_CHANNEL_UMODE_CHANFO)
923 strncat(string, "*", 1);
925 if (mode & SILC_CHANNEL_UMODE_CHANOP)
926 strncat(string, "@", 1);
928 if (mode & SILC_CHANNEL_UMODE_QUIET)
929 strncat(string, "&", 1);
931 return strdup(string);
934 /* Renders ID to suitable to print for example to log file. */
936 static char rid[256];
937 #define _PUT_STRING(__d__, __s__) \
939 int __sp = sizeof(__d__) - 1 - strlen(__d__); \
940 if (__sp < strlen(__s__)) { \
942 strncat(__d__, __s__, (sizeof(__d__) - 1) - strlen(__d__)); \
944 strncat(__d__, __s__, strlen(__s__)); \
948 char *silc_id_render(void *id, SilcIdType id_type)
951 unsigned char tmps[2];
954 memset(rid, 0, sizeof(rid));
958 SilcServerID *server_id = (SilcServerID *)id;
959 if (server_id->ip.data_len > 4) {
961 struct sockaddr_in6 ipv6;
962 memset(&ipv6, 0, sizeof(ipv6));
963 ipv6.sin6_family = AF_INET6;
964 memmove(&ipv6.sin6_addr, server_id->ip.data, sizeof(ipv6.sin6_addr));
965 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
966 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
967 _PUT_STRING(rid, tmp);
971 memmove(&ipv4.s_addr, server_id->ip.data, 4);
972 cp = inet_ntoa(ipv4);
974 _PUT_STRING(rid, cp);
977 memset(tmp, 0, sizeof(tmp));
978 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(server_id->port));
979 _PUT_STRING(rid, tmp);
980 SILC_PUT16_MSB(server_id->rnd, tmps);
981 memset(tmp, 0, sizeof(tmp));
982 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
983 _PUT_STRING(rid, tmp);
988 SilcClientID *client_id = (SilcClientID *)id;
989 if (client_id->ip.data_len > 4) {
991 struct sockaddr_in6 ipv6;
992 memset(&ipv6, 0, sizeof(ipv6));
993 ipv6.sin6_family = AF_INET6;
994 memmove(&ipv6.sin6_addr, client_id->ip.data, sizeof(ipv6.sin6_addr));
995 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
996 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
997 _PUT_STRING(rid, tmp);
1000 struct in_addr ipv4;
1001 memmove(&ipv4.s_addr, client_id->ip.data, 4);
1002 cp = inet_ntoa(ipv4);
1004 _PUT_STRING(rid, cp);
1007 memset(tmp, 0, sizeof(tmp));
1008 snprintf(tmp, sizeof(tmp) - 1, ",%02x,", client_id->rnd);
1009 _PUT_STRING(rid, tmp);
1010 memset(tmp, 0, sizeof(tmp));
1011 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x %02x %02x...]",
1012 client_id->hash[0], client_id->hash[1],
1013 client_id->hash[2], client_id->hash[3]);
1014 _PUT_STRING(rid, tmp);
1017 case SILC_ID_CHANNEL:
1019 SilcChannelID *channel_id = (SilcChannelID *)id;
1020 if (channel_id->ip.data_len > 4) {
1022 struct sockaddr_in6 ipv6;
1023 memset(&ipv6, 0, sizeof(ipv6));
1024 ipv6.sin6_family = AF_INET6;
1025 memmove(&ipv6.sin6_addr, channel_id->ip.data, sizeof(ipv6.sin6_addr));
1026 if (!getnameinfo((struct sockaddr *)&ipv6, sizeof(ipv6),
1027 tmp, sizeof(tmp) - 1, NULL, 0, NI_NUMERICHOST))
1028 _PUT_STRING(rid, tmp);
1031 struct in_addr ipv4;
1032 memmove(&ipv4.s_addr, channel_id->ip.data, 4);
1033 cp = inet_ntoa(ipv4);
1035 _PUT_STRING(rid, cp);
1038 memset(tmp, 0, sizeof(tmp));
1039 snprintf(tmp, sizeof(tmp) - 1, ",%d,", ntohs(channel_id->port));
1040 _PUT_STRING(rid, tmp);
1041 SILC_PUT16_MSB(channel_id->rnd, tmps);
1042 memset(tmp, 0, sizeof(tmp));
1043 snprintf(tmp, sizeof(tmp) - 1, "[%02x %02x]", tmps[0], tmps[1]);
1044 _PUT_STRING(rid, tmp);