X-Git-Url: http://git.silcnet.org/gitweb/?a=blobdiff_plain;f=lib%2Fsilccore%2Fsilcid.c;h=655601efffc5ce0ff65afd0b3b6cacc9da204b8c;hb=a818c5b5411bbc4436d1c5f011236985c96bb787;hp=f9ca89dcb2f439ab8776dd301e50afe5725cdc50;hpb=2dc218143c7859f7529396dc121ae08e2fd78da0;p=silc.git diff --git a/lib/silccore/silcid.c b/lib/silccore/silcid.c index f9ca89dc..655601ef 100644 --- a/lib/silccore/silcid.c +++ b/lib/silccore/silcid.c @@ -27,15 +27,183 @@ #define ID_CLIENT_LEN_PART CLIENTID_HASH_LEN + 1 #define ID_CHANNEL_LEN_PART 4 +/****************************************************************************** + + ID Payload + +******************************************************************************/ + +struct SilcIDPayloadStruct { + SilcIdType type; + SilcUInt16 len; + unsigned char *id; +}; + +/* Parses buffer and return ID payload into payload structure */ + +SilcIDPayload silc_id_payload_parse(const unsigned char *payload, + SilcUInt32 payload_len) +{ + SilcBufferStruct buffer; + SilcIDPayload new; + int ret; + + SILC_LOG_DEBUG(("Parsing ID payload")); + + silc_buffer_set(&buffer, (unsigned char *)payload, payload_len); + new = silc_calloc(1, sizeof(*new)); + + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&new->type), + SILC_STR_UI_SHORT(&new->len), + SILC_STR_END); + if (ret == -1) + goto err; + + silc_buffer_pull(&buffer, 4); + + if (new->len > buffer.len) + goto err; + + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_XNSTRING_ALLOC(&new->id, new->len), + SILC_STR_END); + if (ret == -1) + goto err; + + silc_buffer_push(&buffer, 4); + + return new; + + err: + silc_free(new); + return NULL; +} + +/* Return the ID directly from the raw payload data. */ + +void *silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len) +{ + SilcBufferStruct buffer; + SilcIdType type; + SilcUInt16 idlen; + unsigned char *id_data = NULL; + int ret; + void *id; + + silc_buffer_set(&buffer, (unsigned char *)data, len); + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_SHORT(&type), + SILC_STR_UI_SHORT(&idlen), + SILC_STR_END); + if (ret == -1) + goto err; + + silc_buffer_pull(&buffer, 4); + + if (idlen > buffer.len) + goto err; + + ret = silc_buffer_unformat(&buffer, + SILC_STR_UI_XNSTRING_ALLOC(&id_data, idlen), + SILC_STR_END); + if (ret == -1) + goto err; + + id = silc_id_str2id(id_data, idlen, type); + silc_free(id_data); + return id; + + err: + return NULL; +} + +/* Encodes ID Payload */ + +SilcBuffer silc_id_payload_encode(const void *id, SilcIdType type) +{ + SilcBuffer buffer; + unsigned char *id_data; + SilcUInt32 len; + + id_data = silc_id_id2str(id, type); + len = silc_id_get_len(id, type); + buffer = silc_id_payload_encode_data((const unsigned char *)id_data, + len, type); + silc_free(id_data); + return buffer; +} + +SilcBuffer silc_id_payload_encode_data(const unsigned char *id, + SilcUInt32 id_len, SilcIdType type) +{ + SilcBuffer buffer; + + SILC_LOG_DEBUG(("Encoding %s ID payload", + type == SILC_ID_CLIENT ? "Client" : + type == SILC_ID_SERVER ? "Server" : "Channel")); + + buffer = silc_buffer_alloc(4 + id_len); + silc_buffer_pull_tail(buffer, SILC_BUFFER_END(buffer)); + silc_buffer_format(buffer, + SILC_STR_UI_SHORT(type), + SILC_STR_UI_SHORT(id_len), + SILC_STR_UI_XNSTRING(id, id_len), + SILC_STR_END); + return buffer; +} + +/* Free ID Payload */ + +void silc_id_payload_free(SilcIDPayload payload) +{ + if (payload) { + silc_free(payload->id); + silc_free(payload); + } +} + +/* Get ID type */ + +SilcIdType silc_id_payload_get_type(SilcIDPayload payload) +{ + return payload ? payload->type : 0; +} + +/* Get ID */ + +void *silc_id_payload_get_id(SilcIDPayload payload) +{ + return payload ? silc_id_str2id(payload->id, payload->len, + payload->type) : NULL; +} + +/* Get raw ID data. Data is duplicated. */ + +unsigned char *silc_id_payload_get_data(SilcIDPayload payload) +{ + if (!payload) + return NULL; + + return silc_memdup(payload->id, payload->len); +} + +/* Get length of ID */ + +SilcUInt32 silc_id_payload_get_len(SilcIDPayload payload) +{ + return payload ? payload->len : 0; +} + /* Converts ID to string. */ -unsigned char *silc_id_id2str(void *id, SilcIdType type) +unsigned char *silc_id_id2str(const void *id, SilcIdType type) { unsigned char *ret_id; SilcServerID *server_id; SilcClientID *client_id; SilcChannelID *channel_id; - uint32 id_len = silc_id_get_len(id, type); + SilcUInt32 id_len = silc_id_get_len(id, type); switch(type) { case SILC_ID_SERVER: @@ -69,7 +237,7 @@ unsigned char *silc_id_id2str(void *id, SilcIdType type) /* Converts string to a ID */ -void *silc_id_str2id(unsigned char *id, uint32 id_len, SilcIdType type) +void *silc_id_str2id(const unsigned char *id, SilcUInt32 id_len, SilcIdType type) { switch(type) { @@ -131,7 +299,7 @@ void *silc_id_str2id(unsigned char *id, uint32 id_len, SilcIdType type) /* Returns length of the ID */ -uint32 silc_id_get_len(void *id, SilcIdType type) +SilcUInt32 silc_id_get_len(const void *id, SilcIdType type) { switch(type) { case SILC_ID_SERVER: @@ -159,31 +327,25 @@ uint32 silc_id_get_len(void *id, SilcIdType type) /* Duplicate ID data */ -void *silc_id_dup(void *id, SilcIdType type) +void *silc_id_dup(const void *id, SilcIdType type) { switch(type) { case SILC_ID_SERVER: { - SilcServerID *server_id = (SilcServerID *)id, *new; - new = silc_calloc(1, sizeof(*server_id)); - memcpy(new, server_id, sizeof(*server_id)); - return new; + SilcServerID *server_id = (SilcServerID *)id; + return silc_memdup(server_id, sizeof(*server_id)); } break; case SILC_ID_CLIENT: { - SilcClientID *client_id = (SilcClientID *)id, *new; - new = silc_calloc(1, sizeof(*client_id)); - memcpy(new, client_id, sizeof(*client_id)); - return new; + SilcClientID *client_id = (SilcClientID *)id; + return silc_memdup(client_id, sizeof(*client_id)); } break; case SILC_ID_CHANNEL: { - SilcChannelID *channel_id = (SilcChannelID *)id, *new; - new = silc_calloc(1, sizeof(*channel_id)); - memcpy(new, channel_id, sizeof(*channel_id)); - return new; + SilcChannelID *channel_id = (SilcChannelID *)id; + return silc_memdup(channel_id, sizeof(*channel_id)); } break; }