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.
24 /* Amount of bytes to be read from the socket connection at once. */
25 #define SILC_PACKET_READ_SIZE 16384
27 /* Default byte size of the packet. This can be set larger if this
28 is not enough, we shall see. */
29 #define SILC_PACKET_DEFAULT_SIZE 2048
31 /* Header length without source and destination ID's. */
32 #define SILC_PACKET_HEADER_LEN 8 + 2
34 /* Minimum length of SILC Packet Header. This much is decrypted always
35 when packet is received to be able to get all the relevant data out
37 #define SILC_PACKET_MIN_HEADER_LEN 16 + 2
39 /* Maximum padding length */
40 #define SILC_PACKET_MAX_PADLEN 16
42 /* Minimum packet length */
43 #define SILC_PACKET_MIN_LEN (SILC_PACKET_HEADER_LEN + 1)
45 /* Maximum length of ID */
46 #define SILC_PACKET_MAX_ID_LEN 16
48 /* SILC packet type definition. For now, it is defined like this and I don't
49 expect it to change in any near future. If one byte as a packet type is
50 not enough we can, then, think something else. */
51 typedef unsigned char SilcPacketType;
53 /* SILC packet version type definition. */
54 typedef unsigned char SilcPacketVersion;
56 /* SILC packet flags type definition. */
57 typedef unsigned char SilcPacketFlags;
59 /* All defined packet flags */
60 #define SILC_PACKET_FLAG_NONE 0x00
61 #define SILC_PACKET_FLAG_PRIVMSG_KEY 0x01
62 #define SILC_PACKET_FLAG_BROADCAST 0x02
63 #define SILC_PACKET_FLAG_TUNNELED 0x04
64 /* Rest of flags still available
65 #define SILC_PACKET_FLAG_XXX 0x08
66 #define SILC_PACKET_FLAG_XXX 0x10
67 #define SILC_PACKET_FLAG_XXX 0x20
68 #define SILC_PACKET_FLAG_XXX 0x40
69 #define SILC_PACKET_FLAG_XXX 0x80
75 In packet sending this is filled and sent to silc_packet_assemble
76 which then uses it to assemble new packet. In packet reception pointer
77 to this context is sent to silc_packet_parse which parses the packet
78 and returns the relevant information to this structure. On packet
79 reception returned ID's are always the hash values of the ID's from
82 Short description of the fields following:
90 Type of the packet. Types are defined below.
94 Packet flags. Flags are defined above.
97 unsigned short src_id_len
98 unsigned char src_id_type
100 Source ID, its length and type. On packet reception retuned ID's
101 are always the hash values of the ID's from the packet.
103 unsigned char *dst_id;
104 unsigned short dst_id_len;
105 unsigned char src_id_type;
107 Destination ID, its length and type. On packet reception retuned
108 ID's are always the hash values of the ID's from the packet.
112 Pointer to allocated hash object. This must be MD5 hash object.
113 This is used to calculate checksum of the packet.
119 SilcPacketFlags flags;
121 unsigned char *src_id;
122 unsigned short src_id_len;
123 unsigned char src_id_type;
125 unsigned char *dst_id;
126 unsigned short dst_id_len;
127 unsigned char dst_id_type;
129 unsigned short truelen;
130 unsigned short padlen;
132 /* For padding generation */
137 SilcSocketConnection sock;
139 /* Reference count for this context. The context is free'd only
140 after the reference count is zero. */
145 Silc Packet Parser context.
147 This context is used in packet reception when silc_packet_receive_process
148 function calls parser callback that performs the actual packet decryption
149 and parsing. This context is sent as argument to the parser function.
150 This context must be free'd by the parser callback function.
152 Following description of the fields:
154 SilcPacketContext *packet
156 The actual packet received from the network. In this phase the
157 context is not parsed, only the packet->buffer is allocated and
158 it includes the raw packet data, which is encrypted.
160 SilcSocketConnection sock
162 The associated connection.
166 The cipher to be used in the decryption.
170 The HMAC to be used in the decryption.
174 User context that is sent to the silc_packet_receive_process
175 function. This usually includes application and connection specific
181 SilcPacketContext *packet;
182 SilcSocketConnection sock;
186 } SilcPacketParserContext;
188 /* The parser callback function. */
189 typedef void (*SilcPacketParserCallback)(SilcPacketParserContext
193 /* SILC Packet types. */
194 #define SILC_PACKET_NONE 0 /* NULL, never sent */
195 #define SILC_PACKET_DISCONNECT 1 /* Disconnection */
196 #define SILC_PACKET_SUCCESS 2 /* Success */
197 #define SILC_PACKET_FAILURE 3 /* Failure */
198 #define SILC_PACKET_REJECT 4 /* Rejected */
199 #define SILC_PACKET_NOTIFY 5 /* Notify message */
200 #define SILC_PACKET_ERROR 6 /* Error message */
201 #define SILC_PACKET_CHANNEL_MESSAGE 7 /* Message for channel */
202 #define SILC_PACKET_CHANNEL_KEY 8 /* Key of the channel */
203 #define SILC_PACKET_PRIVATE_MESSAGE 9 /* Private message */
204 #define SILC_PACKET_PRIVATE_MESSAGE_KEY 10 /* Private message key*/
205 #define SILC_PACKET_COMMAND 11 /* Command */
206 #define SILC_PACKET_COMMAND_REPLY 12 /* Reply to a command */
207 #define SILC_PACKET_KEY_EXCHANGE 13 /* Start of KE */
208 #define SILC_PACKET_KEY_EXCHANGE_1 14 /* KE1 */
209 #define SILC_PACKET_KEY_EXCHANGE_2 15 /* KE2 */
210 #define SILC_PACKET_CONNECTION_AUTH_REQUEST 16 /* Request of auth meth */
211 #define SILC_PACKET_CONNECTION_AUTH 17 /* Connectinon auth */
212 #define SILC_PACKET_NEW_ID 18 /* Sending new ID */
213 #define SILC_PACKET_NEW_ID_LIST 19 /* Sending list of them */
214 #define SILC_PACKET_NEW_CLIENT 20 /* Registering client */
215 #define SILC_PACKET_NEW_SERVER 21 /* Registering server */
216 #define SILC_PACKET_NEW_CHANNEL 22 /* Registering channel */
217 #define SILC_PACKET_NEW_CHANNEL_USER 23 /* "" user on channel */
218 #define SILC_PACKET_NEW_CHANNEL_LIST 24 /* List of new channels */
219 #define SILC_PACKET_NEW_CHANNEL_USER_LIST 25 /* List of users on "" */
220 #define SILC_PACKET_REPLACE_ID 26 /* To replace old ID */
221 #define SILC_PACKET_REMOVE_ID 27 /* To remove ID */
222 #define SILC_PACKET_REMOVE_CHANNEL_USER 28 /* Remove user from channel */
223 #define SILC_PACKET_REKEY 29
224 #define SILC_PACKET_REKEY_DONE 30
225 /* #define SILC_PACKET_MAX 255 */
229 /* Returns true length of the packet and padded length of the packet */
230 #define SILC_PACKET_LENGTH(__packet, __ret_truelen, __ret_padlen) \
232 SILC_GET16_MSB((__ret_truelen), (__packet)->data); \
233 (__ret_padlen) = (((__ret_truelen) - 2) + \
234 SILC_PACKET_MAX_PADLEN) & ~(SILC_PACKET_MAX_PADLEN - 1); \
237 /* Returns pad length of the packet */
238 #define SILC_PACKET_PADLEN(__packetlen) \
239 SILC_PACKET_MAX_PADLEN - ((__packetlen) - 2) % SILC_PACKET_MAX_PADLEN;
242 int silc_packet_write(int sock, SilcBuffer src);
243 int silc_packet_send(SilcSocketConnection sock, int force_send);
244 void silc_packet_encrypt(SilcCipher cipher, SilcHmac hmac,
245 SilcBuffer buffer, unsigned int len);
246 void silc_packet_assemble(SilcPacketContext *ctx);
247 void silc_packet_send_prepare(SilcSocketConnection sock,
248 unsigned int header_len,
250 unsigned int data_len);
251 int silc_packet_read(int sock, SilcBuffer dest);
252 int silc_packet_receive(SilcSocketConnection sock);
253 int silc_packet_decrypt(SilcCipher cipher, SilcHmac hmac,
254 SilcBuffer buffer, SilcPacketContext *packet);
255 void silc_packet_receive_process(SilcSocketConnection sock,
256 SilcCipher cipher, SilcHmac hmac,
257 SilcPacketParserCallback parser,
259 SilcPacketType silc_packet_parse(SilcPacketContext *ctx);
260 SilcPacketType silc_packet_parse_special(SilcPacketContext *ctx);
261 SilcPacketContext *silc_packet_context_alloc();
262 SilcPacketContext *silc_packet_context_dup(SilcPacketContext *ctx);
263 void silc_packet_context_free(SilcPacketContext *ctx);