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
25 #include "silcincludes.h"
27 /******************************************************************************
29 Packet Sending Routines
31 ******************************************************************************/
33 /* Writes data from encrypted buffer to the socket connection. If the
34 data cannot be written at once, it will be written later with a timeout.
35 The data is written from the data section of the buffer, not from head
36 or tail section. This automatically pulls the data section towards end
37 after writing the data. */
39 int silc_packet_write(int sock, SilcBuffer src)
43 SILC_LOG_DEBUG(("Writing data to socket %d", sock));
46 ret = write(sock, src->data, src->len);
48 if (errno == EAGAIN) {
49 SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
52 SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
56 silc_buffer_pull(src, ret);
59 SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
64 /* Actually sends the packet. This flushes the connections outgoing data
65 buffer. If data is sent directly to the network this returns the bytes
66 written, if error occured this returns -1 and if the data could not
67 be written directly to the network at this time this returns -2, in
68 which case the data should be queued by the caller and sent at some
69 later time. If `force_send' is TRUE this attempts to write the data
70 directly to the network, if FALSE, this returns -2. */
72 int silc_packet_send(SilcSocketConnection sock, int force_send)
74 /* Send now if forced to do so */
75 if (force_send == TRUE) {
78 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
80 /* Write to network */
81 ret = silc_packet_write(sock->sock, sock->outbuf);
84 SILC_LOG_ERROR(("Error sending packet, dropped"));
89 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
92 SILC_LOG_DEBUG(("Packet in queue"));
97 /* Encrypts a packet. This also creates HMAC of the packet before
98 encryption and adds the HMAC at the end of the buffer. This assumes
99 that there is enough free space at the end of the buffer to add the
100 computed HMAC. This is the normal way of encrypting packets, if some
101 other process of HMAC computing and encryption is needed this function
104 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
105 SilcBuffer buffer, unsigned int len)
107 unsigned char mac[32];
110 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
111 cipher->cipher->name, len, len - 2));
114 /* Compute HMAC. This assumes that HMAC is created from the entire
115 data area thus this uses the length found in buffer, not the length
118 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
119 silc_buffer_put_tail(buffer, mac, hmac->hash->hash->hash_len);
120 memset(mac, 0, sizeof(mac));
123 /* Encrypt the data area of the packet. 2 bytes of the packet
124 are not encrypted. */
126 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
127 buffer->data + 2, len - 2, cipher->iv);
129 /* Pull the HMAC into the visible data area in the buffer */
131 silc_buffer_pull_tail(buffer, hmac->hash->hash->hash_len);
134 /* Assembles a new packet to be ready for send out. The buffer sent as
135 argument must include the data to be sent and it must not be encrypted.
136 The packet also must have enough free space so that the SILC header
137 and padding maybe added to the packet. The packet is encrypted after
138 this function has returned.
140 The buffer sent as argument should be something like following:
142 --------------------------------------------
143 | head | data | tail |
144 --------------------------------------------
148 So that the SILC header and 1 - 16 bytes of padding can fit to
149 the buffer. After assembly the buffer might look like this:
151 --------------------------------------------
153 --------------------------------------------
155 Start of assembled packet
157 Packet construct is as follows (* = won't be encrypted):
160 2 bytes Payload length (*)
163 1 byte Source ID Type
164 2 bytes Source ID Length
166 1 byte Destination ID Type
167 2 bytes Destination ID Length
168 x bytes Destination ID
174 All fields in the packet will be authenticated by MAC. The MAC is
175 not computed here, it must be computed differently before encrypting
180 void silc_packet_assemble(SilcPacketContext *ctx)
182 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
185 SILC_LOG_DEBUG(("Assembling outgoing packet"));
187 /* Get the true length of the packet. This is saved as payload length
188 into the packet header. This does not include the length of the
191 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
192 ctx->src_id_len + ctx->dst_id_len;
194 /* Calculate the length of the padding. The padding is calculated from
195 the data that will be encrypted. As protocol states 3 first bytes
196 of the packet are not encrypted they are not included in the
197 padding calculation. */
199 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
201 /* Put the start of the data section to the right place. */
202 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
203 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
205 /* Get random padding */
207 for (i = 0; i < ctx->padlen; i++)
208 tmppad[i] = silc_rng_get_byte(ctx->rng);
210 /* XXX: For testing - to be removed */
211 memset(tmppad, 65, sizeof(tmppad));
214 /* Create the packet. This creates the SILC header and adds padding,
215 rest of the buffer remains as it is. */
216 silc_buffer_format(ctx->buffer,
217 SILC_STR_UI_SHORT(ctx->truelen),
218 SILC_STR_UI_CHAR(ctx->flags),
219 SILC_STR_UI_CHAR(ctx->type),
220 SILC_STR_UI_SHORT(ctx->src_id_len),
221 SILC_STR_UI_SHORT(ctx->dst_id_len),
222 SILC_STR_UI_CHAR(ctx->src_id_type),
223 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
224 SILC_STR_UI_CHAR(ctx->dst_id_type),
225 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
226 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
229 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
230 ctx->buffer->data, ctx->buffer->len);
232 SILC_LOG_DEBUG(("Outgoing packet assembled"));
235 /* Prepare outgoing data buffer for packet sending. This moves the data
236 area so that new packet may be added into it. If needed this allocates
237 more space to the buffer. This handles directly the connection's
238 outgoing buffer in SilcSocketConnection object. */
240 void silc_packet_send_prepare(SilcSocketConnection sock,
241 unsigned int header_len,
243 unsigned int data_len)
247 totlen = header_len + padlen + data_len;
249 /* Prepare the outgoing buffer for packet sending. */
251 /* Allocate new buffer. This is done only once per connection. */
252 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
254 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
255 silc_buffer_pull_tail(sock->outbuf, totlen);
256 silc_buffer_pull(sock->outbuf, header_len + padlen);
258 if (SILC_IS_OUTBUF_PENDING(sock)) {
259 /* There is some pending data in the buffer. */
261 /* Allocate more space if needed */
262 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
263 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
264 sock->outbuf = silc_buffer_realloc(sock->outbuf,
265 sock->outbuf->truelen + totlen);
268 oldlen = sock->outbuf->len;
269 silc_buffer_pull_tail(sock->outbuf, totlen);
270 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
272 /* Buffer is free for use */
273 silc_buffer_clear(sock->outbuf);
274 silc_buffer_pull_tail(sock->outbuf, totlen);
275 silc_buffer_pull(sock->outbuf, header_len + padlen);
280 /******************************************************************************
282 Packet Reception Routines
284 ******************************************************************************/
286 /* Reads data from the socket connection into the incoming data buffer.
287 However, this does not parse the packet, it only reads some amount from
288 the network. If there are more data available that can be read at a time
289 the rest of the data will be read later with a timeout and only after
290 that the packet is ready to be parsed.
292 The destination buffer sent as argument must be initialized before
293 calling this function, and, the data section and the start of the tail
294 section must be same. Ie. we add the read data to the tail section of
295 the buffer hence the data section is the start of the buffer.
297 This returns amount of bytes read or -1 on error or -2 on case where
298 all of the data could not be read at once. */
300 int silc_packet_read(int sock, SilcBuffer dest)
303 unsigned char buf[SILC_PACKET_READ_SIZE];
305 SILC_LOG_DEBUG(("Reading data from socket %d", sock));
307 /* Read the data from the socket. */
308 len = read(sock, buf, sizeof(buf));
310 if (errno == EAGAIN) {
311 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
314 SILC_LOG_ERROR(("Cannot read from socket: %d", strerror(errno)));
321 /* Insert the data to the buffer. If the data doesn't fit to the
322 buffer space is allocated for the buffer. */
323 /* XXX: This may actually be bad thing as if there is pending data in
324 the buffer they will be lost! */
327 /* If the data doesn't fit we just have to allocate a whole new
329 if (dest->truelen <= len) {
331 /* Free the old buffer */
332 memset(dest->head, 'F', dest->truelen);
333 silc_free(dest->head);
335 /* Allocate new data area */
336 len += SILC_PACKET_DEFAULT_SIZE;
337 dest->data = silc_calloc(len, sizeof(char));
340 dest->head = dest->data;
341 dest->data = dest->data;
342 dest->tail = dest->data;
343 dest->end = dest->data + dest->truelen;
344 len -= SILC_PACKET_DEFAULT_SIZE;
347 silc_buffer_put_tail(dest, buf, len);
348 silc_buffer_pull_tail(dest, len);
351 SILC_LOG_DEBUG(("Read %d bytes", len));
356 /* Processes the received data. This checks the received data and
357 calls parser callback that handles the actual packet decryption
358 and parsing. If more than one packet was received this calls the
359 parser multiple times. The parser callback will get context
360 SilcPacketParserContext that includes the packet and the `context'
361 sent to this function. Returns TRUE on success and FALSE on error. */
363 int silc_packet_receive_process(SilcSocketConnection sock,
364 SilcCipher cipher, SilcHmac hmac,
365 SilcPacketParserCallback parser,
368 SilcPacketParserContext *parse_ctx;
369 int packetlen, paddedlen, mac_len = 0;
371 /* Check whether we received a whole packet. If reading went without
372 errors we either read a whole packet or the read packet is
373 incorrect and will be dropped. */
374 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
375 if (packetlen < SILC_PACKET_MIN_LEN) {
376 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
377 silc_buffer_clear(sock->inbuf);
381 if (sock->inbuf->len < paddedlen) {
382 /* Two cases: either we haven't read all of the data or this
383 packet is malformed. Try to read data from the connection.
384 If it fails this packet is malformed. */
385 silc_schedule_with_fd(sock->sock, SILC_TASK_READ, 0, 1);
386 if (silc_packet_receive(sock) < 0) {
387 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
388 silc_buffer_clear(sock->inbuf);
393 /* Parse the packets from the data */
394 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
395 /* Received possibly many packets at once */
398 mac_len = hmac->hash->hash->hash_len;
400 while (sock->inbuf->len > 0) {
401 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
403 if (sock->inbuf->len < paddedlen) {
404 /* Two cases: either we haven't read all of the data or this
405 packet is malformed. Try to read data from the connection.
406 If it fails this packet is malformed. */
407 silc_schedule_with_fd(sock->sock, SILC_TASK_READ, 0, 1);
408 if (silc_packet_receive(sock) > 0)
411 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
416 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
417 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
418 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
419 parse_ctx->sock = sock;
420 parse_ctx->cipher = cipher;
421 parse_ctx->hmac = hmac;
422 parse_ctx->context = context;
424 silc_buffer_pull_tail(parse_ctx->packet->buffer,
425 SILC_BUFFER_END(parse_ctx->packet->buffer));
426 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
427 paddedlen + mac_len);
429 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
430 parse_ctx->packet->buffer->len),
431 parse_ctx->packet->buffer->data,
432 parse_ctx->packet->buffer->len);
434 /* Call the parser */
436 (*parser)(parse_ctx);
438 /* Pull the packet from inbuf thus we'll get the next one
440 silc_buffer_pull(sock->inbuf, paddedlen);
442 silc_buffer_pull(sock->inbuf, mac_len);
445 /* All packets are processed, return successfully. */
446 silc_buffer_clear(sock->inbuf);
450 /* Received one packet */
452 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
453 sock->inbuf->data, sock->inbuf->len);
455 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
456 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
457 parse_ctx->packet->buffer = silc_buffer_copy(sock->inbuf);
458 parse_ctx->sock = sock;
459 parse_ctx->cipher = cipher;
460 parse_ctx->hmac = hmac;
461 parse_ctx->context = context;
462 silc_buffer_clear(sock->inbuf);
464 /* Call the parser */
466 (*parser)(parse_ctx);
468 /* Return successfully */
473 /* Receives packet from network and reads the data into connection's
474 incoming data buffer. If the data was read directly this returns the
475 read bytes, if error occured this returns -1, if the data could not
476 be read directly at this time this returns -2 in which case the data
477 should be read again at some later time, or If EOF occured this returns
480 int silc_packet_receive(SilcSocketConnection sock)
484 /* Allocate the incoming data buffer if not done already. */
486 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
488 /* Read some data from connection */
489 ret = silc_packet_read(sock->sock, sock->inbuf);
493 SILC_LOG_ERROR(("Error reading packet, dropped"));
499 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
500 after packet has been totally decrypted and parsed. */
502 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
506 unsigned char mac[32];
508 SILC_LOG_DEBUG(("Verifying MAC"));
510 /* Compute HMAC of packet */
511 memset(mac, 0, sizeof(mac));
512 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
514 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
515 if (memcmp(mac, buffer->tail, hmac->hash->hash->hash_len)) {
516 SILC_LOG_DEBUG(("MAC failed"));
520 SILC_LOG_DEBUG(("MAC is Ok"));
521 memset(mac, 0, sizeof(mac));
527 /* Decrypts rest of the packet (after decrypting just the SILC header).
528 After calling this function the packet is ready to be parsed by calling
529 silc_packet_parse. If everything goes without errors this returns TRUE,
530 if packet is malformed this returns FALSE. */
532 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
537 /* Pull MAC from packet before decryption */
539 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
540 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
542 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
547 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
549 /* Decrypt rest of the packet */
550 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
551 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
552 buffer->data + 2, buffer->len - 2,
554 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
556 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
557 buffer->data, buffer->len);
563 /* Decrypts rest of the SILC Packet header that has been decrypted partly
564 already. This decrypts the padding of the packet also. After calling
565 this function the packet is ready to be parsed by calling function
566 silc_packet_parse. This is used in special packet reception (protocol
567 defines the way of decrypting special packets). */
569 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
573 /* Decrypt rest of the header plus padding */
575 unsigned short truelen, len1, len2, padlen;
577 /* Pull MAC from packet before decryption */
579 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
580 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
582 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
587 SILC_LOG_DEBUG(("Decrypting rest of the header"));
589 SILC_GET16_MSB(len1, &buffer->data[4]);
590 SILC_GET16_MSB(len2, &buffer->data[6]);
592 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
593 padlen = SILC_PACKET_PADLEN(truelen);
594 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
596 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
597 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
598 buffer->data + 2, len1 - 2,
600 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
606 /* Decrypts a packet. This assumes that typical SILC packet is the
607 packet to be decrypted and thus checks for normal and special SILC
608 packets and can handle both of them. This also computes and checks
609 the HMAC of the packet. If any other special or customized decryption
610 processing is required this function cannot be used. This returns
611 -1 on error, 0 when packet is normal packet and 1 when the packet
612 is special and requires special processing. */
614 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
615 SilcBuffer buffer, SilcPacketContext *packet)
618 SILC_LOG_DEBUG(("Decrypting packet, cipher %s, len %d (%d)",
619 cipher->cipher->name, len, len - 2));
622 /* Decrypt start of the packet header */
624 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
625 buffer->data + 2, SILC_PACKET_MIN_HEADER_LEN - 2,
628 /* If the packet type is not any special type lets decrypt rest
629 of the packet here. */
630 if ((buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
631 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY)) ||
632 buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE) {
634 /* Normal packet, decrypt rest of the packet */
635 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
639 if (!silc_packet_check_mac(hmac, buffer))
644 /* Packet requires special handling, decrypt rest of the header.
645 This only decrypts. */
646 silc_packet_decrypt_rest_special(cipher, hmac, buffer);
649 if (!silc_packet_check_mac(hmac, buffer))
656 /* Parses the packet. This is called when a whole packet is ready to be
657 parsed. The buffer sent must be already decrypted before calling this
658 function. The len argument must be the true length of the packet. This
659 function returns the type of the packet. The data section of the
660 buffer is parsed, not head or tail sections. */
662 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
664 SilcBuffer buffer = ctx->buffer;
667 SILC_LOG_DEBUG(("Parsing incoming packet"));
669 /* Check the length of the buffer */
670 if (buffer->len < SILC_PACKET_MIN_LEN) {
671 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
672 return SILC_PACKET_NONE;
675 /* Parse the buffer. This parses the SILC header of the packet. */
676 len = silc_buffer_unformat(buffer,
677 SILC_STR_UI_SHORT(&ctx->truelen),
678 SILC_STR_UI_CHAR(&ctx->flags),
679 SILC_STR_UI_CHAR(&ctx->type),
680 SILC_STR_UI_SHORT(&ctx->src_id_len),
681 SILC_STR_UI_SHORT(&ctx->dst_id_len),
682 SILC_STR_UI_CHAR(&ctx->src_id_type),
685 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
686 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
687 SILC_LOG_ERROR(("Bad ID lengths in packet"));
688 return SILC_PACKET_NONE;
691 /* Calculate length of padding in packet */
692 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
694 silc_buffer_pull(buffer, len);
695 silc_buffer_unformat(buffer,
696 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
698 SILC_STR_UI_CHAR(&ctx->dst_id_type),
699 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
701 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
703 silc_buffer_push(buffer, len);
705 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
706 ctx->buffer->data, ctx->buffer->len);
708 /* Pull SILC header and padding from packet */
709 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
710 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
712 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
717 /* Perform special SILC Packet header parsing. This is required to some
718 packet types that have the data payload encrypted with different key
719 than the header area plus padding of the packet. Hence, this parses
720 the header in a way that it does not take the data area into account
721 and parses the header and padding area only. */
723 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
725 SilcBuffer buffer = ctx->buffer;
728 SILC_LOG_DEBUG(("Parsing incoming packet"));
730 /* Check the length of the buffer */
731 if (buffer->len < SILC_PACKET_MIN_LEN) {
732 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
733 return SILC_PACKET_NONE;
736 /* Parse the buffer. This parses the SILC header of the packet. */
737 len = silc_buffer_unformat(buffer,
738 SILC_STR_UI_SHORT(&ctx->truelen),
739 SILC_STR_UI_CHAR(&ctx->flags),
740 SILC_STR_UI_CHAR(&ctx->type),
741 SILC_STR_UI_SHORT(&ctx->src_id_len),
742 SILC_STR_UI_SHORT(&ctx->dst_id_len),
743 SILC_STR_UI_CHAR(&ctx->src_id_type),
746 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
747 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
748 SILC_LOG_ERROR(("Bad ID lengths in packet"));
749 return SILC_PACKET_NONE;
752 /* Calculate length of padding in packet. As this is special packet
753 the data area is not used in the padding calculation as it won't
754 be decrypted by the caller. */
755 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
756 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
758 silc_buffer_pull(buffer, len);
759 silc_buffer_unformat(buffer,
760 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
762 SILC_STR_UI_CHAR(&ctx->dst_id_type),
763 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
765 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
767 silc_buffer_push(buffer, len);
769 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
770 ctx->buffer->data, ctx->buffer->len);
772 /* Pull SILC header and padding from packet */
773 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
774 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
776 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));