5 Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
7 Copyright (C) 1997 - 2000 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; either version 2 of the License, or
12 (at your option) any later version.
14 This program is distributed in the hope that it will be useful,
15 but WITHOUT ANY WARRANTY; without even the implied warranty of
16 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 GNU General Public License for more details.
21 * Created: Fri Jul 25 18:52:14 1997
26 * Revision 1.4 2000/07/18 06:51:58 priikone
27 * Debug version bug fixes.
29 * Revision 1.3 2000/07/14 06:10:15 priikone
30 * Moved all the generic packet sending, enryption, reception,
31 * decryption and processing function from client and server to
32 * here as they were duplicated code in the applications. Now they
33 * are generic code over generic API. Some functions were rewritter;
34 * packet reception and HMAC computation and checking is now more
37 * Revision 1.2 2000/07/05 06:06:35 priikone
38 * Global cosmetic change.
40 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
41 * Imported from internal CVS/Added Log headers.
46 #include "silcincludes.h"
48 /******************************************************************************
50 Packet Sending Routines
52 ******************************************************************************/
54 /* Writes data from encrypted buffer to the socket connection. If the
55 data cannot be written at once, it will be written later with a timeout.
56 The data is written from the data section of the buffer, not from head
57 or tail section. This automatically pulls the data section towards end
58 after writing the data. */
60 int silc_packet_write(int sock, SilcBuffer src)
64 SILC_LOG_DEBUG(("Writing data to socket %d", sock));
67 ret = write(sock, src->data, src->len);
69 if (errno == EAGAIN) {
70 SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
73 SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
77 silc_buffer_pull(src, ret);
80 SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
85 /* Actually sends the packet. This flushes the connections outgoing data
86 buffer. If data is sent directly to the network this returns the bytes
87 written, if error occured this returns -1 and if the data could not
88 be written directly to the network at this time this returns -2, in
89 which case the data should be queued by the caller and sent at some
90 later time. If `force_send' is TRUE this attempts to write the data
91 directly to the network, if FALSE, this returns -2. */
93 int silc_packet_send(SilcSocketConnection sock, int force_send)
95 /* Send now if forced to do so */
96 if (force_send == TRUE) {
99 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
101 /* Write to network */
102 ret = silc_packet_write(sock->sock, sock->outbuf);
105 SILC_LOG_ERROR(("Error sending packet, dropped"));
110 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
113 SILC_LOG_DEBUG(("Packet in queue"));
118 /* Encrypts a packet. This also creates HMAC of the packet before
119 encryption and adds the HMAC at the end of the buffer. This assumes
120 that there is enough free space at the end of the buffer to add the
121 computed HMAC. This is the normal way of encrypting packets, if some
122 other process of HMAC computing and encryption is needed this function
125 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
126 SilcBuffer buffer, unsigned int len)
128 unsigned char mac[32];
131 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
132 cipher->cipher->name, len, len - 2));
135 /* Compute HMAC. This assumes that HMAC is created from the entire
136 data area thus this uses the length found in buffer, not the length
139 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
140 silc_buffer_put_tail(buffer, mac, hmac->hash->hash->hash_len);
141 memset(mac, 0, sizeof(mac));
144 /* Encrypt the data area of the packet. 2 bytes of the packet
145 are not encrypted. */
147 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
148 buffer->data + 2, len - 2, cipher->iv);
150 /* Pull the HMAC into the visible data area in the buffer */
152 silc_buffer_pull_tail(buffer, hmac->hash->hash->hash_len);
155 /* Assembles a new packet to be ready for send out. The buffer sent as
156 argument must include the data to be sent and it must not be encrypted.
157 The packet also must have enough free space so that the SILC header
158 and padding maybe added to the packet. The packet is encrypted after
159 this function has returned.
161 The buffer sent as argument should be something like following:
163 --------------------------------------------
164 | head | data | tail |
165 --------------------------------------------
169 So that the SILC header and 1 - 16 bytes of padding can fit to
170 the buffer. After assembly the buffer might look like this:
172 --------------------------------------------
174 --------------------------------------------
176 Start of assembled packet
178 Packet construct is as follows (* = won't be encrypted):
181 2 bytes Payload length (*)
184 1 byte Source ID Type
185 2 bytes Source ID Length
187 1 byte Destination ID Type
188 2 bytes Destination ID Length
189 x bytes Destination ID
195 All fields in the packet will be authenticated by MAC. The MAC is
196 not computed here, it must be computed differently before encrypting
201 void silc_packet_assemble(SilcPacketContext *ctx)
203 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
206 SILC_LOG_DEBUG(("Assembling outgoing packet"));
208 /* Get the true length of the packet. This is saved as payload length
209 into the packet header. This does not include the length of the
212 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
213 ctx->src_id_len + ctx->dst_id_len;
215 /* Calculate the length of the padding. The padding is calculated from
216 the data that will be encrypted. As protocol states 3 first bytes
217 of the packet are not encrypted they are not included in the
218 padding calculation. */
220 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
222 /* Put the start of the data section to the right place. */
223 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
224 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
226 /* Get random padding */
228 for (i = 0; i < ctx->padlen; i++)
229 tmppad[i] = silc_rng_get_byte(ctx->rng);
231 /* XXX: For testing - to be removed */
232 memset(tmppad, 65, sizeof(tmppad));
235 /* Create the packet. This creates the SILC header and adds padding,
236 rest of the buffer remains as it is. */
237 silc_buffer_format(ctx->buffer,
238 SILC_STR_UI_SHORT(ctx->truelen),
239 SILC_STR_UI_CHAR(ctx->flags),
240 SILC_STR_UI_CHAR(ctx->type),
241 SILC_STR_UI_SHORT(ctx->src_id_len),
242 SILC_STR_UI_SHORT(ctx->dst_id_len),
243 SILC_STR_UI_CHAR(ctx->src_id_type),
244 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
245 SILC_STR_UI_CHAR(ctx->dst_id_type),
246 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
247 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
250 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
251 ctx->buffer->data, ctx->buffer->len);
253 SILC_LOG_DEBUG(("Outgoing packet assembled"));
256 /* Prepare outgoing data buffer for packet sending. This moves the data
257 area so that new packet may be added into it. If needed this allocates
258 more space to the buffer. This handles directly the connection's
259 outgoing buffer in SilcSocketConnection object. */
261 void silc_packet_send_prepare(SilcSocketConnection sock,
262 unsigned int header_len,
264 unsigned int data_len)
268 totlen = header_len + padlen + data_len;
270 /* Prepare the outgoing buffer for packet sending. */
272 /* Allocate new buffer. This is done only once per connection. */
273 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
275 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
276 silc_buffer_pull_tail(sock->outbuf, totlen);
277 silc_buffer_pull(sock->outbuf, header_len + padlen);
279 if (SILC_IS_OUTBUF_PENDING(sock)) {
280 /* There is some pending data in the buffer. */
282 /* Allocate more space if needed */
283 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
284 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
285 sock->outbuf = silc_buffer_realloc(sock->outbuf,
286 sock->outbuf->truelen + totlen);
289 oldlen = sock->outbuf->len;
290 silc_buffer_pull_tail(sock->outbuf, totlen);
291 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
293 /* Buffer is free for use */
294 silc_buffer_clear(sock->outbuf);
295 silc_buffer_pull_tail(sock->outbuf, totlen);
296 silc_buffer_pull(sock->outbuf, header_len + padlen);
301 /******************************************************************************
303 Packet Reception Routines
305 ******************************************************************************/
307 /* Reads data from the socket connection into the incoming data buffer.
308 However, this does not parse the packet, it only reads some amount from
309 the network. If there are more data available that can be read at a time
310 the rest of the data will be read later with a timeout and only after
311 that the packet is ready to be parsed.
313 The destination buffer sent as argument must be initialized before
314 calling this function, and, the data section and the start of the tail
315 section must be same. Ie. we add the read data to the tail section of
316 the buffer hence the data section is the start of the buffer.
318 This returns amount of bytes read or -1 on error or -2 on case where
319 all of the data could not be read at once. */
321 int silc_packet_read(int sock, SilcBuffer dest)
324 unsigned char buf[SILC_PACKET_READ_SIZE];
326 SILC_LOG_DEBUG(("Reading data from socket %d", sock));
328 /* Read the data from the socket. */
329 len = read(sock, buf, sizeof(buf));
331 if (errno == EAGAIN) {
332 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
335 SILC_LOG_ERROR(("Cannot read from socket: %d", strerror(errno)));
342 /* Insert the data to the buffer. If the data doesn't fit to the
343 buffer space is allocated for the buffer. */
344 /* XXX: This may actually be bad thing as if there is pending data in
345 the buffer they will be lost! */
348 /* If the data doesn't fit we just have to allocate a whole new
350 if (dest->truelen <= len) {
352 /* Free the old buffer */
353 memset(dest->head, 'F', dest->truelen);
354 silc_free(dest->head);
356 /* Allocate new data area */
357 len += SILC_PACKET_DEFAULT_SIZE;
358 dest->data = silc_calloc(len, sizeof(char));
361 dest->head = dest->data;
362 dest->data = dest->data;
363 dest->tail = dest->data;
364 dest->end = dest->data + dest->truelen;
365 len -= SILC_PACKET_DEFAULT_SIZE;
368 silc_buffer_put_tail(dest, buf, len);
369 silc_buffer_pull_tail(dest, len);
372 SILC_LOG_DEBUG(("Read %d bytes", len));
377 /* Processes the received data. This checks the received data and
378 calls parser callback that handles the actual packet decryption
379 and parsing. If more than one packet was received this calls the
380 parser multiple times. The parser callback will get context
381 SilcPacketParserContext that includes the packet and the `context'
382 sent to this function. Returns TRUE on success and FALSE on error. */
384 int silc_packet_receive_process(SilcSocketConnection sock,
385 SilcCipher cipher, SilcHmac hmac,
386 SilcPacketParserCallback parser,
389 SilcPacketParserContext *parse_ctx;
390 int packetlen, paddedlen, mac_len = 0;
392 /* Check whether we received a whole packet. If reading went without
393 errors we either read a whole packet or the read packet is
394 incorrect and will be dropped. */
395 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
396 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
397 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
398 silc_buffer_clear(sock->inbuf);
402 /* Parse the packets from the data */
403 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
404 /* Received possibly many packets at once */
407 mac_len = hmac->hash->hash->hash_len;
409 while(sock->inbuf->len > 0) {
410 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
412 if (sock->inbuf->len < paddedlen) {
413 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
418 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
419 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
420 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
421 parse_ctx->sock = sock;
422 parse_ctx->cipher = cipher;
423 parse_ctx->hmac = hmac;
424 parse_ctx->context = context;
426 silc_buffer_pull_tail(parse_ctx->packet->buffer,
427 SILC_BUFFER_END(parse_ctx->packet->buffer));
428 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
429 paddedlen + mac_len);
431 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
432 parse_ctx->packet->buffer->len),
433 parse_ctx->packet->buffer->data,
434 parse_ctx->packet->buffer->len);
436 /* Call the parser */
438 (*parser)(parse_ctx);
440 /* Pull the packet from inbuf thus we'll get the next one
442 silc_buffer_pull(sock->inbuf, paddedlen);
444 silc_buffer_pull(sock->inbuf, mac_len);
447 /* All packets are processed, return successfully. */
448 silc_buffer_clear(sock->inbuf);
452 /* Received one packet */
454 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
455 sock->inbuf->data, sock->inbuf->len);
457 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
458 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
459 parse_ctx->packet->buffer = silc_buffer_copy(sock->inbuf);
460 parse_ctx->sock = sock;
461 parse_ctx->cipher = cipher;
462 parse_ctx->hmac = hmac;
463 parse_ctx->context = context;
464 silc_buffer_clear(sock->inbuf);
466 /* Call the parser */
468 (*parser)(parse_ctx);
470 /* Return successfully */
475 /* Receives packet from network and reads the data into connection's
476 incoming data buffer. If the data was read directly this returns the
477 read bytes, if error occured this returns -1, if the data could not
478 be read directly at this time this returns -2 in which case the data
479 should be read again at some later time, or If EOF occured this returns
482 int silc_packet_receive(SilcSocketConnection sock)
486 /* Allocate the incoming data buffer if not done already. */
488 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
490 /* Read some data from connection */
491 ret = silc_packet_read(sock->sock, sock->inbuf);
495 SILC_LOG_ERROR(("Error reading packet, dropped"));
501 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
502 after packet has been totally decrypted and parsed. */
504 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
508 unsigned char mac[32];
510 SILC_LOG_DEBUG(("Verifying MAC"));
512 /* Compute HMAC of packet */
513 memset(mac, 0, sizeof(mac));
514 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
516 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
517 if (memcmp(mac, buffer->tail, hmac->hash->hash->hash_len)) {
518 SILC_LOG_DEBUG(("MAC failed"));
522 SILC_LOG_DEBUG(("MAC is Ok"));
523 memset(mac, 0, sizeof(mac));
529 /* Decrypts rest of the packet (after decrypting just the SILC header).
530 After calling this function the packet is ready to be parsed by calling
531 silc_packet_parse. If everything goes without errors this returns TRUE,
532 if packet is malformed this returns FALSE. */
534 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
539 /* Pull MAC from packet before decryption */
541 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
542 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
544 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
549 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
551 /* Decrypt rest of the packet */
552 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
553 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
554 buffer->data + 2, buffer->len - 2,
556 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
558 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
559 buffer->data, buffer->len);
565 /* Decrypts rest of the SILC Packet header that has been decrypted partly
566 already. This decrypts the padding of the packet also. After calling
567 this function the packet is ready to be parsed by calling function
568 silc_packet_parse. This is used in special packet reception (protocol
569 defines the way of decrypting special packets). */
571 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
575 /* Decrypt rest of the header plus padding */
577 unsigned short truelen, len1, len2, padlen;
579 /* Pull MAC from packet before decryption */
581 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
582 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
584 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
589 SILC_LOG_DEBUG(("Decrypting rest of the header"));
591 SILC_GET16_MSB(len1, &buffer->data[4]);
592 SILC_GET16_MSB(len2, &buffer->data[6]);
594 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
595 padlen = SILC_PACKET_PADLEN(truelen);
596 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
598 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
599 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
600 buffer->data + 2, len1 - 2,
602 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
608 /* Decrypts a packet. This assumes that typical SILC packet is the
609 packet to be decrypted and thus checks for normal and special SILC
610 packets and can handle both of them. This also computes and checks
611 the HMAC of the packet. If any other special or customized decryption
612 processing is required this function cannot be used. This returns
613 -1 on error, 0 when packet is normal packet and 1 when the packet
614 is special and requires special processing. */
616 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
617 SilcBuffer buffer, SilcPacketContext *packet)
620 SILC_LOG_DEBUG(("Decrypting packet, cipher %s, len %d (%d)",
621 cipher->cipher->name, len, len - 2));
624 /* Decrypt start of the packet header */
626 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
627 buffer->data + 2, SILC_PACKET_MIN_HEADER_LEN - 2,
630 /* If the packet type is not any special type lets decrypt rest
631 of the packet here. */
632 if ((buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
633 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY)) ||
634 buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE) {
636 /* Normal packet, decrypt rest of the packet */
637 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
641 if (!silc_packet_check_mac(hmac, buffer))
646 /* Packet requires special handling, decrypt rest of the header.
647 This only decrypts. */
648 silc_packet_decrypt_rest_special(cipher, hmac, buffer);
651 if (!silc_packet_check_mac(hmac, buffer))
658 /* Parses the packet. This is called when a whole packet is ready to be
659 parsed. The buffer sent must be already decrypted before calling this
660 function. The len argument must be the true length of the packet. This
661 function returns the type of the packet. The data section of the
662 buffer is parsed, not head or tail sections. */
664 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
666 SilcBuffer buffer = ctx->buffer;
669 SILC_LOG_DEBUG(("Parsing incoming packet"));
671 /* Check the length of the buffer */
672 if (buffer->len < SILC_PACKET_MIN_LEN) {
673 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
674 return SILC_PACKET_NONE;
677 /* Parse the buffer. This parses the SILC header of the packet. */
678 len = silc_buffer_unformat(buffer,
679 SILC_STR_UI_SHORT(&ctx->truelen),
680 SILC_STR_UI_CHAR(&ctx->flags),
681 SILC_STR_UI_CHAR(&ctx->type),
682 SILC_STR_UI_SHORT(&ctx->src_id_len),
683 SILC_STR_UI_SHORT(&ctx->dst_id_len),
684 SILC_STR_UI_CHAR(&ctx->src_id_type),
687 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
688 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
689 SILC_LOG_ERROR(("Bad ID lengths in packet"));
690 return SILC_PACKET_NONE;
693 /* Calculate length of padding in packet */
694 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
696 silc_buffer_pull(buffer, len);
697 silc_buffer_unformat(buffer,
698 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
700 SILC_STR_UI_CHAR(&ctx->dst_id_type),
701 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
703 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
705 silc_buffer_push(buffer, len);
707 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
708 ctx->buffer->data, ctx->buffer->len);
710 /* Pull SILC header and padding from packet */
711 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
712 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
714 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
719 /* Perform special SILC Packet header parsing. This is required to some
720 packet types that have the data payload encrypted with different key
721 than the header area plus padding of the packet. Hence, this parses
722 the header in a way that it does not take the data area into account
723 and parses the header and padding area only. */
725 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
727 SilcBuffer buffer = ctx->buffer;
730 SILC_LOG_DEBUG(("Parsing incoming packet"));
732 /* Check the length of the buffer */
733 if (buffer->len < SILC_PACKET_MIN_LEN) {
734 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
735 return SILC_PACKET_NONE;
738 /* Parse the buffer. This parses the SILC header of the packet. */
739 len = silc_buffer_unformat(buffer,
740 SILC_STR_UI_SHORT(&ctx->truelen),
741 SILC_STR_UI_CHAR(&ctx->flags),
742 SILC_STR_UI_CHAR(&ctx->type),
743 SILC_STR_UI_SHORT(&ctx->src_id_len),
744 SILC_STR_UI_SHORT(&ctx->dst_id_len),
745 SILC_STR_UI_CHAR(&ctx->src_id_type),
748 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
749 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
750 SILC_LOG_ERROR(("Bad ID lengths in packet"));
751 return SILC_PACKET_NONE;
754 /* Calculate length of padding in packet. As this is special packet
755 the data area is not used in the padding calculation as it won't
756 be decrypted by the caller. */
757 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
758 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
760 silc_buffer_pull(buffer, len);
761 silc_buffer_unformat(buffer,
762 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
764 SILC_STR_UI_CHAR(&ctx->dst_id_type),
765 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
767 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
769 silc_buffer_push(buffer, len);
771 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
772 ctx->buffer->data, ctx->buffer->len);
774 /* Pull SILC header and padding from packet */
775 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
776 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
778 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));