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.3 2000/07/14 06:10:15 priikone
27 * Moved all the generic packet sending, enryption, reception,
28 * decryption and processing function from client and server to
29 * here as they were duplicated code in the applications. Now they
30 * are generic code over generic API. Some functions were rewritter;
31 * packet reception and HMAC computation and checking is now more
34 * Revision 1.2 2000/07/05 06:06:35 priikone
35 * Global cosmetic change.
37 * Revision 1.1.1.1 2000/06/27 11:36:55 priikone
38 * Imported from internal CVS/Added Log headers.
43 #include "silcincludes.h"
45 /******************************************************************************
47 Packet Sending Routines
49 ******************************************************************************/
51 /* Writes data from encrypted buffer to the socket connection. If the
52 data cannot be written at once, it will be written later with a timeout.
53 The data is written from the data section of the buffer, not from head
54 or tail section. This automatically pulls the data section towards end
55 after writing the data. */
57 int silc_packet_write(int sock, SilcBuffer src)
61 SILC_LOG_DEBUG(("Writing data to socket %d", sock));
64 ret = write(sock, src->data, src->len);
66 if (errno == EAGAIN) {
67 SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
70 SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
74 silc_buffer_pull(src, ret);
77 SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
82 /* Actually sends the packet. This flushes the connections outgoing data
83 buffer. If data is sent directly to the network this returns the bytes
84 written, if error occured this returns -1 and if the data could not
85 be written directly to the network at this time this returns -2, in
86 which case the data should be queued by the caller and sent at some
87 later time. If `force_send' is TRUE this attempts to write the data
88 directly to the network, if FALSE, this returns -2. */
90 int silc_packet_send(SilcSocketConnection sock, int force_send)
92 /* Send now if forced to do so */
93 if (force_send == TRUE) {
96 SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
98 /* Write to network */
99 ret = silc_packet_write(sock->sock, sock->outbuf);
102 SILC_LOG_ERROR(("Error sending packet, dropped"));
106 SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
109 SILC_LOG_DEBUG(("Packet in queue"));
114 /* Encrypts a packet. This also creates HMAC of the packet before
115 encryption and adds the HMAC at the end of the buffer. This assumes
116 that there is enough free space at the end of the buffer to add the
117 computed HMAC. This is the normal way of encrypting packets, if some
118 other process of HMAC computing and encryption is needed this function
121 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
122 SilcBuffer buffer, unsigned int len)
124 unsigned char mac[32];
127 SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)",
128 cipher->cipher->name, len, len - 2));
131 /* Compute HMAC. This assumes that HMAC is created from the entire
132 data area thus this uses the length found in buffer, not the length
135 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
136 silc_buffer_put_tail(buffer, mac, hmac->hash->hash->hash_len);
137 memset(mac, 0, sizeof(mac));
140 /* Encrypt the data area of the packet. 2 bytes of the packet
141 are not encrypted. */
143 cipher->cipher->encrypt(cipher->context, buffer->data + 2,
144 buffer->data + 2, len - 2, cipher->iv);
146 /* Pull the HMAC into the visible data area in the buffer */
148 silc_buffer_pull_tail(buffer, hmac->hash->hash->hash_len);
151 /* Assembles a new packet to be ready for send out. The buffer sent as
152 argument must include the data to be sent and it must not be encrypted.
153 The packet also must have enough free space so that the SILC header
154 and padding maybe added to the packet. The packet is encrypted after
155 this function has returned.
157 The buffer sent as argument should be something like following:
159 --------------------------------------------
160 | head | data | tail |
161 --------------------------------------------
165 So that the SILC header and 1 - 16 bytes of padding can fit to
166 the buffer. After assembly the buffer might look like this:
168 --------------------------------------------
170 --------------------------------------------
172 Start of assembled packet
174 Packet construct is as follows (* = won't be encrypted):
177 2 bytes Payload length (*)
180 1 byte Source ID Type
181 2 bytes Source ID Length
183 1 byte Destination ID Type
184 2 bytes Destination ID Length
185 x bytes Destination ID
191 All fields in the packet will be authenticated by MAC. The MAC is
192 not computed here, it must be computed differently before encrypting
197 void silc_packet_assemble(SilcPacketContext *ctx)
199 unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
202 SILC_LOG_DEBUG(("Assembling outgoing packet"));
204 /* Get the true length of the packet. This is saved as payload length
205 into the packet header. This does not include the length of the
208 ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN +
209 ctx->src_id_len + ctx->dst_id_len;
211 /* Calculate the length of the padding. The padding is calculated from
212 the data that will be encrypted. As protocol states 3 first bytes
213 of the packet are not encrypted they are not included in the
214 padding calculation. */
216 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
218 /* Put the start of the data section to the right place. */
219 silc_buffer_push(ctx->buffer, SILC_PACKET_HEADER_LEN +
220 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
222 /* Get random padding */
224 for (i = 0; i < ctx->padlen; i++)
225 tmppad[i] = silc_rng_get_byte(ctx->rng);
227 /* XXX: For testing - to be removed */
228 memset(tmppad, 65, sizeof(tmppad));
231 /* Create the packet. This creates the SILC header and adds padding,
232 rest of the buffer remains as it is. */
233 silc_buffer_format(ctx->buffer,
234 SILC_STR_UI_SHORT(ctx->truelen),
235 SILC_STR_UI_CHAR(ctx->flags),
236 SILC_STR_UI_CHAR(ctx->type),
237 SILC_STR_UI_SHORT(ctx->src_id_len),
238 SILC_STR_UI_SHORT(ctx->dst_id_len),
239 SILC_STR_UI_CHAR(ctx->src_id_type),
240 SILC_STR_UI_XNSTRING(ctx->src_id, ctx->src_id_len),
241 SILC_STR_UI_CHAR(ctx->dst_id_type),
242 SILC_STR_UI_XNSTRING(ctx->dst_id, ctx->dst_id_len),
243 SILC_STR_UI_XNSTRING(tmppad, ctx->padlen),
246 SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len),
247 ctx->buffer->data, ctx->buffer->len);
249 SILC_LOG_DEBUG(("Outgoing packet assembled"));
252 /* Prepare outgoing data buffer for packet sending. This moves the data
253 area so that new packet may be added into it. If needed this allocates
254 more space to the buffer. This handles directly the connection's
255 outgoing buffer in SilcSocketConnection object. */
257 void silc_packet_send_prepare(SilcSocketConnection sock,
258 unsigned int header_len,
260 unsigned int data_len)
264 totlen = header_len + padlen + data_len;
266 /* Prepare the outgoing buffer for packet sending. */
268 /* Allocate new buffer. This is done only once per connection. */
269 SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
271 sock->outbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
272 silc_buffer_pull_tail(sock->outbuf, totlen);
273 silc_buffer_pull(sock->outbuf, header_len + padlen);
275 if (SILC_IS_OUTBUF_PENDING(sock)) {
276 /* There is some pending data in the buffer. */
278 /* Allocate more space if needed */
279 if ((sock->outbuf->end - sock->outbuf->tail) < data_len) {
280 SILC_LOG_DEBUG(("Reallocating outgoing data buffer"));
281 sock->outbuf = silc_buffer_realloc(sock->outbuf,
282 sock->outbuf->truelen + totlen);
285 oldlen = sock->outbuf->len;
286 silc_buffer_pull_tail(sock->outbuf, totlen);
287 silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
289 /* Buffer is free for use */
290 silc_buffer_clear(sock->outbuf);
291 silc_buffer_pull_tail(sock->outbuf, totlen);
292 silc_buffer_pull(sock->outbuf, header_len + padlen);
297 /******************************************************************************
299 Packet Reception Routines
301 ******************************************************************************/
303 /* Reads data from the socket connection into the incoming data buffer.
304 However, this does not parse the packet, it only reads some amount from
305 the network. If there are more data available that can be read at a time
306 the rest of the data will be read later with a timeout and only after
307 that the packet is ready to be parsed.
309 The destination buffer sent as argument must be initialized before
310 calling this function, and, the data section and the start of the tail
311 section must be same. Ie. we add the read data to the tail section of
312 the buffer hence the data section is the start of the buffer.
314 This returns amount of bytes read or -1 on error or -2 on case where
315 all of the data could not be read at once. */
317 int silc_packet_read(int sock, SilcBuffer dest)
320 unsigned char buf[SILC_PACKET_READ_SIZE];
322 SILC_LOG_DEBUG(("Reading data from socket %d", sock));
324 /* Read the data from the socket. */
325 len = read(sock, buf, sizeof(buf));
327 if (errno == EAGAIN) {
328 SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
331 SILC_LOG_ERROR(("Cannot read from socket: %d", strerror(errno)));
338 /* Insert the data to the buffer. If the data doesn't fit to the
339 buffer space is allocated for the buffer. */
340 /* XXX: This may actually be bad thing as if there is pending data in
341 the buffer they will be lost! */
344 /* If the data doesn't fit we just have to allocate a whole new
346 if (dest->truelen <= len) {
348 /* Free the old buffer */
349 memset(dest->head, 'F', dest->truelen);
350 silc_free(dest->head);
352 /* Allocate new data area */
353 len += SILC_PACKET_DEFAULT_SIZE;
354 dest->data = silc_calloc(len, sizeof(char));
357 dest->head = dest->data;
358 dest->data = dest->data;
359 dest->tail = dest->data;
360 dest->end = dest->data + dest->truelen;
361 len -= SILC_PACKET_DEFAULT_SIZE;
364 silc_buffer_put_tail(dest, buf, len);
365 silc_buffer_pull_tail(dest, len);
368 SILC_LOG_DEBUG(("Read %d bytes", len));
373 /* Processes the received data. This checks the received data and
374 calls parser callback that handles the actual packet decryption
375 and parsing. If more than one packet was received this calls the
376 parser multiple times. The parser callback will get context
377 SilcPacketParserContext that includes the packet and the `context'
378 sent to this function. Returns TRUE on success and FALSE on error. */
380 int silc_packet_receive_process(SilcSocketConnection sock,
381 SilcCipher cipher, SilcHmac hmac,
382 SilcPacketParserCallback parser,
385 SilcPacketParserContext *parse_ctx;
386 int packetlen, paddedlen, mac_len = 0;
388 /* Check whether we received a whole packet. If reading went without
389 errors we either read a whole packet or the read packet is
390 incorrect and will be dropped. */
391 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
392 if (sock->inbuf->len < paddedlen || (packetlen < SILC_PACKET_MIN_LEN)) {
393 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
394 silc_buffer_clear(sock->inbuf);
398 /* Parse the packets from the data */
399 if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
400 /* Received possibly many packets at once */
403 mac_len = hmac->hash->hash->hash_len;
405 while(sock->inbuf->len > 0) {
406 SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
408 if (sock->inbuf->len < paddedlen) {
409 SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
414 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
415 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
416 parse_ctx->packet->buffer = silc_buffer_alloc(paddedlen + mac_len);
417 parse_ctx->sock = sock;
418 parse_ctx->cipher = cipher;
419 parse_ctx->hmac = hmac;
420 parse_ctx->context = context;
422 silc_buffer_pull_tail(parse_ctx->packet->buffer,
423 SILC_BUFFER_END(parse_ctx->packet->buffer));
424 silc_buffer_put(parse_ctx->packet->buffer, sock->inbuf->data,
425 paddedlen + mac_len);
427 SILC_LOG_HEXDUMP(("Incoming packet, len %d",
428 parse_ctx->packet->buffer->len),
429 parse_ctx->packet->buffer->data,
430 parse_ctx->packet->buffer->len);
432 /* Call the parser */
434 (*parser)(parse_ctx);
436 /* Pull the packet from inbuf thus we'll get the next one
438 silc_buffer_pull(sock->inbuf, paddedlen);
440 silc_buffer_pull(sock->inbuf, mac_len);
443 /* All packets are processed, return successfully. */
444 silc_buffer_clear(sock->inbuf);
448 /* Received one packet */
450 SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
451 sock->inbuf->data, sock->inbuf->len);
453 parse_ctx = silc_calloc(1, sizeof(*parse_ctx));
454 parse_ctx->packet = silc_calloc(1, sizeof(*parse_ctx->packet));
455 parse_ctx->packet->buffer = silc_buffer_copy(sock->inbuf);
456 parse_ctx->sock = sock;
457 parse_ctx->cipher = cipher;
458 parse_ctx->hmac = hmac;
459 parse_ctx->context = context;
460 silc_buffer_clear(sock->inbuf);
462 /* Call the parser */
464 (*parser)(parse_ctx);
466 /* Return successfully */
471 /* Receives packet from network and reads the data into connection's
472 incoming data buffer. If the data was read directly this returns the
473 read bytes, if error occured this returns -1, if the data could not
474 be read directly at this time this returns -2 in which case the data
475 should be read again at some later time, or If EOF occured this returns
478 int silc_packet_receive(SilcSocketConnection sock)
482 /* Allocate the incoming data buffer if not done already. */
484 sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
486 /* Read some data from connection */
487 ret = silc_packet_read(sock->sock, sock->inbuf);
491 SILC_LOG_ERROR(("Error reading packet, dropped"));
496 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
497 after packet has been totally decrypted and parsed. */
499 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
503 unsigned char mac[32];
505 SILC_LOG_DEBUG(("Verifying MAC"));
507 /* Compute HMAC of packet */
508 memset(mac, 0, sizeof(mac));
509 silc_hmac_make(hmac, buffer->data, buffer->len, mac);
511 /* Compare the HMAC's (buffer->tail has the packet's HMAC) */
512 if (memcmp(mac, buffer->tail, hmac->hash->hash->hash_len)) {
513 SILC_LOG_DEBUG(("MAC failed"));
517 SILC_LOG_DEBUG(("MAC is Ok"));
518 memset(mac, 0, sizeof(mac));
524 /* Decrypts rest of the packet (after decrypting just the SILC header).
525 After calling this function the packet is ready to be parsed by calling
526 silc_packet_parse. If everything goes without errors this returns TRUE,
527 if packet is malformed this returns FALSE. */
529 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
534 /* Pull MAC from packet before decryption */
536 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
537 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
539 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
544 SILC_LOG_DEBUG(("Decrypting rest of the packet"));
546 /* Decrypt rest of the packet */
547 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
548 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
549 buffer->data + 2, buffer->len - 2,
551 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
553 SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
554 buffer->data, buffer->len);
560 /* Decrypts rest of the SILC Packet header that has been decrypted partly
561 already. This decrypts the padding of the packet also. After calling
562 this function the packet is ready to be parsed by calling function
563 silc_packet_parse. This is used in special packet reception (protocol
564 defines the way of decrypting special packets). */
566 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
570 /* Decrypt rest of the header plus padding */
572 unsigned short truelen, len1, len2, padlen;
574 /* Pull MAC from packet before decryption */
576 if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
577 silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
579 SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
584 SILC_LOG_DEBUG(("Decrypting rest of the header"));
586 SILC_GET16_MSB(len1, &buffer->data[4]);
587 SILC_GET16_MSB(len2, &buffer->data[6]);
589 truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
590 padlen = SILC_PACKET_PADLEN(truelen);
591 len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
593 silc_buffer_pull(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
594 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
595 buffer->data + 2, len1 - 2,
597 silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
603 /* Decrypts a packet. This assumes that typical SILC packet is the
604 packet to be decrypted and thus checks for normal and special SILC
605 packets and can handle both of them. This also computes and checks
606 the HMAC of the packet. If any other special or customized decryption
607 processing is required this function cannot be used. This returns
608 -1 on error, 0 when packet is normal packet and 1 when the packet
609 is special and requires special processing. */
611 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
612 SilcBuffer buffer, SilcPacketContext *packet)
615 SILC_LOG_DEBUG(("Decrypting packet, cipher %s, len %d (%d)",
616 cipher->cipher->name, len, len - 2));
619 /* Decrypt start of the packet header */
621 cipher->cipher->decrypt(cipher->context, buffer->data + 2,
622 buffer->data + 2, SILC_PACKET_MIN_HEADER_LEN - 2,
625 /* If the packet type is not any special type lets decrypt rest
626 of the packet here. */
627 if ((buffer->data[3] == SILC_PACKET_PRIVATE_MESSAGE &&
628 !(buffer->data[2] & SILC_PACKET_FLAG_PRIVMSG_KEY)) ||
629 buffer->data[3] != SILC_PACKET_CHANNEL_MESSAGE) {
631 /* Normal packet, decrypt rest of the packet */
632 if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
636 if (!silc_packet_check_mac(hmac, buffer))
641 /* Packet requires special handling, decrypt rest of the header.
642 This only decrypts. */
643 silc_packet_decrypt_rest_special(cipher, hmac, buffer);
646 if (!silc_packet_check_mac(hmac, buffer))
653 /* Parses the packet. This is called when a whole packet is ready to be
654 parsed. The buffer sent must be already decrypted before calling this
655 function. The len argument must be the true length of the packet. This
656 function returns the type of the packet. The data section of the
657 buffer is parsed, not head or tail sections. */
659 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
661 SilcBuffer buffer = ctx->buffer;
664 SILC_LOG_DEBUG(("Parsing incoming packet"));
666 /* Check the length of the buffer */
667 if (buffer->len < SILC_PACKET_MIN_LEN) {
668 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
669 return SILC_PACKET_NONE;
672 /* Parse the buffer. This parses the SILC header of the packet. */
673 len = silc_buffer_unformat(buffer,
674 SILC_STR_UI_SHORT(&ctx->truelen),
675 SILC_STR_UI_CHAR(&ctx->flags),
676 SILC_STR_UI_CHAR(&ctx->type),
677 SILC_STR_UI_SHORT(&ctx->src_id_len),
678 SILC_STR_UI_SHORT(&ctx->dst_id_len),
679 SILC_STR_UI_CHAR(&ctx->src_id_type),
682 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
683 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
684 SILC_LOG_ERROR(("Bad ID lengths in packet"));
685 return SILC_PACKET_NONE;
688 /* Calculate length of padding in packet */
689 ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
691 silc_buffer_pull(buffer, len);
692 silc_buffer_unformat(buffer,
693 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
695 SILC_STR_UI_CHAR(&ctx->dst_id_type),
696 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
698 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
700 silc_buffer_push(buffer, len);
702 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
703 ctx->buffer->data, ctx->buffer->len);
705 /* Pull SILC header and padding from packet */
706 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
707 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
709 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
714 /* Perform special SILC Packet header parsing. This is required to some
715 packet types that have the data payload encrypted with different key
716 than the header area plus padding of the packet. Hence, this parses
717 the header in a way that it does not take the data area into account
718 and parses the header and padding area only. */
720 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
722 SilcBuffer buffer = ctx->buffer;
725 SILC_LOG_DEBUG(("Parsing incoming packet"));
727 /* Check the length of the buffer */
728 if (buffer->len < SILC_PACKET_MIN_LEN) {
729 SILC_LOG_ERROR(("Bad packet length: %d, packet dropped", buffer->len));
730 return SILC_PACKET_NONE;
733 /* Parse the buffer. This parses the SILC header of the packet. */
734 len = silc_buffer_unformat(buffer,
735 SILC_STR_UI_SHORT(&ctx->truelen),
736 SILC_STR_UI_CHAR(&ctx->flags),
737 SILC_STR_UI_CHAR(&ctx->type),
738 SILC_STR_UI_SHORT(&ctx->src_id_len),
739 SILC_STR_UI_SHORT(&ctx->dst_id_len),
740 SILC_STR_UI_CHAR(&ctx->src_id_type),
743 if (ctx->src_id_len > SILC_PACKET_MAX_ID_LEN ||
744 ctx->dst_id_len > SILC_PACKET_MAX_ID_LEN) {
745 SILC_LOG_ERROR(("Bad ID lengths in packet"));
746 return SILC_PACKET_NONE;
749 /* Calculate length of padding in packet. As this is special packet
750 the data area is not used in the padding calculation as it won't
751 be decrypted by the caller. */
752 tmplen = SILC_PACKET_HEADER_LEN + ctx->src_id_len + ctx->dst_id_len;
753 ctx->padlen = SILC_PACKET_PADLEN(tmplen);
755 silc_buffer_pull(buffer, len);
756 silc_buffer_unformat(buffer,
757 SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
759 SILC_STR_UI_CHAR(&ctx->dst_id_type),
760 SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
762 SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
764 silc_buffer_push(buffer, len);
766 SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len),
767 ctx->buffer->data, ctx->buffer->len);
769 /* Pull SILC header and padding from packet */
770 silc_buffer_pull(buffer, SILC_PACKET_HEADER_LEN +
771 ctx->src_id_len + ctx->dst_id_len + ctx->padlen);
773 SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));