Fixed a buf in data reading. The code now assures that all data
[silc.git] / lib / silccore / silcpacket.c
1 /*
2
3   silcpacket.c
4
5   Author: Pekka Riikonen <priikone@poseidon.pspt.fi>
6
7   Copyright (C) 1997 - 2000 Pekka Riikonen
8
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.
13   
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.
18
19 */
20 /*
21  * Created: Fri Jul 25 18:52:14 1997
22  */
23 /* $Id$ */
24
25 #include "silcincludes.h"
26
27 /******************************************************************************
28
29                           Packet Sending Routines
30
31 ******************************************************************************/
32
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. */
38
39 int silc_packet_write(int sock, SilcBuffer src)
40 {
41   int ret = 0;
42
43   SILC_LOG_DEBUG(("Writing data to socket %d", sock));
44
45   if (src->len > 0) {
46     ret = write(sock, src->data, src->len);
47     if (ret < 0) {
48       if (errno == EAGAIN) {
49         SILC_LOG_DEBUG(("Could not write immediately, will do it later"));
50         return -2;
51       }
52       SILC_LOG_ERROR(("Cannot write to socket: %s", strerror(errno)));
53       return -1;
54     }
55
56     silc_buffer_pull(src, ret);
57   }
58
59   SILC_LOG_DEBUG(("Wrote data %d bytes", ret));
60
61   return ret;
62 }
63
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. */
71
72 int silc_packet_send(SilcSocketConnection sock, int force_send)
73 {
74   /* Send now if forced to do so */
75   if (force_send == TRUE) {
76     int ret;
77
78     SILC_LOG_DEBUG(("Forcing packet send, packet sent immediately"));
79
80     /* Write to network */
81     ret = silc_packet_write(sock->sock, sock->outbuf);
82
83     if (ret == -1) {
84       SILC_LOG_ERROR(("Error sending packet, dropped"));
85     }
86     if (ret != -2)
87       return ret;
88
89     SILC_LOG_DEBUG(("Could not force the send, packet put to queue"));
90   }  
91
92   SILC_LOG_DEBUG(("Packet in queue"));
93
94   return -2;
95 }
96
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
102    cannot be used. */
103
104 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac, 
105                          SilcBuffer buffer, unsigned int len)
106 {
107   unsigned char mac[32];
108
109   if (cipher) {
110     SILC_LOG_DEBUG(("Encrypting packet, cipher %s, len %d (%d)", 
111                     cipher->cipher->name, len, len - 2));
112   }
113
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
116      sent as argument. */
117   if (hmac) {
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));
121   }
122
123   /* Encrypt the data area of the packet. 2 bytes of the packet
124      are not encrypted. */
125   if (cipher)
126     cipher->cipher->encrypt(cipher->context, buffer->data + 2, 
127                             buffer->data + 2, len - 2, cipher->iv);
128
129   /* Pull the HMAC into the visible data area in the buffer */
130   if (hmac)
131     silc_buffer_pull_tail(buffer, hmac->hash->hash->hash_len);
132 }
133
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.
139
140    The buffer sent as argument should be something like following:
141
142    --------------------------------------------
143    | head             | data           | tail |
144    --------------------------------------------
145    ^                  ^
146    58 bytes           x bytes
147
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:
150
151    --------------------------------------------
152    | data                              |      |
153    --------------------------------------------
154    ^                                   ^
155    Start of assembled packet
156
157    Packet construct is as follows (* = won't be encrypted):
158
159    x bytes       SILC Header
160       2 bytes     Payload length  (*)
161       1 byte      Flags
162       1 byte      Packet type
163       1 byte      Source ID Type
164       2 bytes     Source ID Length
165       x bytes     Source ID
166       1 byte      Destination ID Type
167       2 bytes     Destination ID Length
168       x bytes     Destination ID
169
170    1 - 16 bytes    Padding
171
172    x bytes        Data payload
173
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
176    the packet.
177
178 */
179
180 void silc_packet_assemble(SilcPacketContext *ctx)
181 {
182   unsigned char tmppad[SILC_PACKET_MAX_PADLEN];
183   int i;
184
185   SILC_LOG_DEBUG(("Assembling outgoing packet"));
186   
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
189      padding. */
190   if (!ctx->truelen)
191     ctx->truelen = ctx->buffer->len + SILC_PACKET_HEADER_LEN + 
192       ctx->src_id_len + ctx->dst_id_len;
193
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. */
198   if (!ctx->padlen)
199     ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
200
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);
204
205   /* Get random padding */
206 #if 1
207   for (i = 0; i < ctx->padlen; i++)
208     tmppad[i] = silc_rng_get_byte(ctx->rng);
209 #else
210   /* XXX: For testing - to be removed */
211   memset(tmppad, 65, sizeof(tmppad));
212 #endif
213
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),
227                      SILC_STR_END);
228
229   SILC_LOG_HEXDUMP(("Assembled packet, len %d", ctx->buffer->len), 
230                    ctx->buffer->data, ctx->buffer->len);
231
232   SILC_LOG_DEBUG(("Outgoing packet assembled"));
233 }
234
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. */
239
240 void silc_packet_send_prepare(SilcSocketConnection sock,
241                               unsigned int header_len,
242                               unsigned int padlen,
243                               unsigned int data_len)
244 {
245   int totlen, oldlen;
246
247   totlen = header_len + padlen + data_len;
248
249   /* Prepare the outgoing buffer for packet sending. */
250   if (!sock->outbuf) {
251     /* Allocate new buffer. This is done only once per connection. */
252     SILC_LOG_DEBUG(("Allocating outgoing data buffer"));
253     
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);
257   } else {
258     if (SILC_IS_OUTBUF_PENDING(sock)) {
259       /* There is some pending data in the buffer. */
260
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);
266       }
267
268       oldlen = sock->outbuf->len;
269       silc_buffer_pull_tail(sock->outbuf, totlen);
270       silc_buffer_pull(sock->outbuf, header_len + padlen + oldlen);
271     } else {
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);
276     }
277   }
278 }
279
280 /******************************************************************************
281
282                          Packet Reception Routines
283
284 ******************************************************************************/
285
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. 
291
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.
296
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. */
299
300 int silc_packet_read(int sock, SilcBuffer dest)
301 {
302   int len = 0;
303   unsigned char buf[SILC_PACKET_READ_SIZE];
304
305   SILC_LOG_DEBUG(("Reading data from socket %d", sock));
306
307   /* Read the data from the socket. */
308   len = read(sock, buf, sizeof(buf));
309   if (len < 0) {
310     if (errno == EAGAIN) {
311       SILC_LOG_DEBUG(("Could not read immediately, will do it later"));
312       return -2;
313     }
314     SILC_LOG_ERROR(("Cannot read from socket: %d", strerror(errno)));
315     return -1;
316   }
317
318   if (!len)
319     return 0;
320
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! */
325   if (dest) {
326
327     /* If the data doesn't fit we just have to allocate a whole new 
328        data area */
329     if (dest->truelen <= len) {
330
331       /* Free the old buffer */
332       memset(dest->head, 'F', dest->truelen);
333       silc_free(dest->head);
334
335       /* Allocate new data area */
336       len += SILC_PACKET_DEFAULT_SIZE;
337       dest->data = silc_calloc(len, sizeof(char));
338       dest->truelen = len;
339       dest->len = 0;
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;
345     }
346
347     silc_buffer_put_tail(dest, buf, len);
348     silc_buffer_pull_tail(dest, len);
349   }
350
351   SILC_LOG_DEBUG(("Read %d bytes", len));
352
353   return len;
354 }
355
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. */
362
363 int silc_packet_receive_process(SilcSocketConnection sock, 
364                                 SilcCipher cipher, SilcHmac hmac,
365                                 SilcPacketParserCallback parser, 
366                                 void *context)
367 {
368   SilcPacketParserContext *parse_ctx;
369   int packetlen, paddedlen, mac_len = 0;
370
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);
378     return FALSE;
379   }
380
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);
389       return FALSE;
390     }
391   }
392
393   /* Parse the packets from the data */
394   if (sock->inbuf->len - 2 > (paddedlen + mac_len)) {
395     /* Received possibly many packets at once */
396
397     if (hmac)
398       mac_len = hmac->hash->hash->hash_len;
399
400     while (sock->inbuf->len > 0) {
401       SILC_PACKET_LENGTH(sock->inbuf, packetlen, paddedlen);
402
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) 
409           continue;
410
411         SILC_LOG_DEBUG(("Received incorrect packet, dropped"));
412         return FALSE;
413       }
414
415       paddedlen += 2;
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;
423
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);
428
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);
433
434       /* Call the parser */
435       if (parser)
436         (*parser)(parse_ctx);
437
438       /* Pull the packet from inbuf thus we'll get the next one
439          in the inbuf. */
440       silc_buffer_pull(sock->inbuf, paddedlen);
441       if (hmac)
442         silc_buffer_pull(sock->inbuf, mac_len);
443     }
444
445     /* All packets are processed, return successfully. */
446     silc_buffer_clear(sock->inbuf);
447     return TRUE;
448
449   } else {
450     /* Received one packet */
451     
452     SILC_LOG_HEXDUMP(("An incoming packet, len %d", sock->inbuf->len),
453                      sock->inbuf->data, sock->inbuf->len);
454
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);
463
464     /* Call the parser */
465     if (parser)
466       (*parser)(parse_ctx);
467
468     /* Return successfully */
469     return TRUE;
470   }
471 }
472
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
478    0. */
479
480 int silc_packet_receive(SilcSocketConnection sock)
481 {
482   int ret;
483
484   /* Allocate the incoming data buffer if not done already. */
485   if (!sock->inbuf)
486     sock->inbuf = silc_buffer_alloc(SILC_PACKET_DEFAULT_SIZE);
487   
488   /* Read some data from connection */
489   ret = silc_packet_read(sock->sock, sock->inbuf);
490
491   /* Error */
492   if (ret == -1) {
493     SILC_LOG_ERROR(("Error reading packet, dropped"));
494   }
495
496   return ret;
497 }
498
499 /* Checks MAC in the packet. Returns TRUE if MAC is Ok. This is called
500    after packet has been totally decrypted and parsed. */
501
502 static int silc_packet_check_mac(SilcHmac hmac, SilcBuffer buffer)
503 {
504   /* Check MAC */
505   if (hmac) {
506     unsigned char mac[32];
507     
508     SILC_LOG_DEBUG(("Verifying MAC"));
509
510     /* Compute HMAC of packet */
511     memset(mac, 0, sizeof(mac));
512     silc_hmac_make(hmac, buffer->data, buffer->len, mac);
513
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"));
517       return FALSE;
518     }
519     
520     SILC_LOG_DEBUG(("MAC is Ok"));
521     memset(mac, 0, sizeof(mac));
522   }
523   
524   return TRUE;
525 }
526
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. */
531
532 static int silc_packet_decrypt_rest(SilcCipher cipher, SilcHmac hmac,
533                                     SilcBuffer buffer)
534 {
535   if (cipher) {
536
537     /* Pull MAC from packet before decryption */
538     if (hmac) {
539       if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
540         silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
541       } else {
542         SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
543         return FALSE;
544       }
545     }
546
547     SILC_LOG_DEBUG(("Decrypting rest of the packet"));
548
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,
553                             cipher->iv);
554     silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
555
556     SILC_LOG_HEXDUMP(("Fully decrypted packet, len %d", buffer->len),
557                      buffer->data, buffer->len);
558   }
559
560   return TRUE;
561 }
562
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). */
568
569 static int silc_packet_decrypt_rest_special(SilcCipher cipher,
570                                             SilcHmac hmac,
571                                             SilcBuffer buffer)
572 {
573   /* Decrypt rest of the header plus padding */
574   if (cipher) {
575     unsigned short truelen, len1, len2, padlen;
576
577     /* Pull MAC from packet before decryption */
578     if (hmac) {
579       if ((buffer->len - hmac->hash->hash->hash_len) > SILC_PACKET_MIN_LEN) {
580         silc_buffer_push_tail(buffer, hmac->hash->hash->hash_len);
581       } else {
582         SILC_LOG_DEBUG(("Bad MAC length in packet, packet dropped"));
583         return FALSE;
584       }
585     }
586   
587     SILC_LOG_DEBUG(("Decrypting rest of the header"));
588
589     SILC_GET16_MSB(len1, &buffer->data[4]);
590     SILC_GET16_MSB(len2, &buffer->data[6]);
591
592     truelen = SILC_PACKET_HEADER_LEN + len1 + len2;
593     padlen = SILC_PACKET_PADLEN(truelen);
594     len1 = (truelen + padlen) - (SILC_PACKET_MIN_HEADER_LEN - 2);
595
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,
599                             cipher->iv);
600     silc_buffer_push(buffer, SILC_PACKET_MIN_HEADER_LEN - 2);
601   }
602
603   return TRUE;
604 }
605
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. */
613
614 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
615                         SilcBuffer buffer, SilcPacketContext *packet)
616 {
617 #if 0
618   SILC_LOG_DEBUG(("Decrypting packet, cipher %s, len %d (%d)", 
619                   cipher->cipher->name, len, len - 2));
620 #endif
621
622   /* Decrypt start of the packet header */
623   if (cipher)
624     cipher->cipher->decrypt(cipher->context, buffer->data + 2,
625                             buffer->data + 2, SILC_PACKET_MIN_HEADER_LEN - 2,
626                             cipher->iv);
627
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) {
633
634     /* Normal packet, decrypt rest of the packet */
635     if (!silc_packet_decrypt_rest(cipher, hmac, buffer))
636       return -1;
637
638     /* Check MAC */
639     if (!silc_packet_check_mac(hmac, buffer))
640       return FALSE;
641
642     return 0;
643   } else {
644     /* Packet requires special handling, decrypt rest of the header.
645        This only decrypts. */
646     silc_packet_decrypt_rest_special(cipher, hmac, buffer);
647
648     /* Check MAC */
649     if (!silc_packet_check_mac(hmac, buffer))
650       return FALSE;
651
652     return 1;
653   }
654 }
655
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. */
661
662 SilcPacketType silc_packet_parse(SilcPacketContext *ctx)
663 {
664   SilcBuffer buffer = ctx->buffer;
665   int len;
666
667   SILC_LOG_DEBUG(("Parsing incoming packet"));
668
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;
673   }
674
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),
683                              SILC_STR_END);
684
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;
689   }
690
691   /* Calculate length of padding in packet */
692   ctx->padlen = SILC_PACKET_PADLEN(ctx->truelen);
693
694   silc_buffer_pull(buffer, len);
695   silc_buffer_unformat(buffer, 
696                        SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
697                                                   ctx->src_id_len),
698                        SILC_STR_UI_CHAR(&ctx->dst_id_type),
699                        SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
700                                                   ctx->dst_id_len),
701                        SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
702                        SILC_STR_END);
703   silc_buffer_push(buffer, len);
704
705   SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len), 
706                    ctx->buffer->data, ctx->buffer->len);
707
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);
711
712   SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
713
714   return ctx->type;
715 }
716
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. */
722
723 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx)
724 {
725   SilcBuffer buffer = ctx->buffer;
726   int len, tmplen;
727
728   SILC_LOG_DEBUG(("Parsing incoming packet"));
729
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;
734   }
735
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),
744                              SILC_STR_END);
745
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;
750   }
751
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);
757
758   silc_buffer_pull(buffer, len);
759   silc_buffer_unformat(buffer, 
760                        SILC_STR_UI_XNSTRING_ALLOC(&ctx->src_id,
761                                                   ctx->src_id_len),
762                        SILC_STR_UI_CHAR(&ctx->dst_id_type),
763                        SILC_STR_UI_XNSTRING_ALLOC(&ctx->dst_id,
764                                                   ctx->dst_id_len),
765                        SILC_STR_UI_XNSTRING(NULL, ctx->padlen),
766                        SILC_STR_END);
767   silc_buffer_push(buffer, len);
768
769   SILC_LOG_HEXDUMP(("parsed packet, len %d", ctx->buffer->len), 
770                    ctx->buffer->data, ctx->buffer->len);
771
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);
775
776   SILC_LOG_DEBUG(("Incoming packet type: %d", ctx->type));
777
778   return ctx->type;
779 }