1 /*
2 
3   silcid.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 1997 - 2007 Pekka Riikonen
8 
9   The contents of this file are subject to one of the Licenses specified
10   in the COPYING file;  You may not use this file except in compliance
11   with the License.
12 
13   The software distributed under the License is distributed on an "AS IS"
14   basis, in the hope that it will be useful, but WITHOUT WARRANTY OF ANY
15   KIND, either expressed or implied.  See the COPYING file for more
16   information.
17 
18 */
19 
20 /****h* silccore/SILC ID Interface
21  *
22  * DESCRIPTION
23  *
24  * These are important ID types used in SILC. SILC server creates these
25  * but SILC client has to handle these as well since these are used in
26  * packet sending and reception. However, client never creates these
27  * but it receives the correct ID's from server. Clients, servers and
28  * channels are identified by the these ID's.
29  *
30  * The ID's are based on IP addresses. The IP address provides a good
31  * way to distinguish the ID's from other ID's. The ID's supports both
32  * IPv4 and IPv6.
33  *
34  * This file also includes the implementation of the SILC ID Payload
35  * parsing and encoding.
36  *
37  ***/
38 
39 #ifndef SILCID_H
40 #define SILCID_H
41 
42 /* The ID Lenghts. These are IPv4 based and should be noted if used directly
43    that these cannot be used with IPv6. */
44 #define SILC_ID_SERVER_LEN 	(64 / 8)
45 #define SILC_ID_CLIENT_LEN 	(128 / 8)
46 #define SILC_ID_CHANNEL_LEN 	(64 / 8)
47 
48 #define CLIENTID_HASH_LEN       (88 / 8) /* Client ID's 88 bit MD5 hash */
49 
50 /****d* silccore/SilcIDAPI/SilcIdType
51  *
52  * NAME
53  *
54  *    typedef SilcUInt16 SilcIdType;
55  *
56  * DESCRIPTION
57  *
58  *    SILC ID type definitions and the ID types.
59  *
60  * SOURCE
61  */
62 typedef SilcUInt16 SilcIdType;
63 
64 /* The SILC ID Types */
65 #define SILC_ID_NONE        0
66 #define SILC_ID_SERVER      1
67 #define SILC_ID_CLIENT      2
68 #define SILC_ID_CHANNEL     3
69 /***/
70 
71 /****s* silccore/SilcIDAPI/SilcIDIP
72  *
73  * NAME
74  *
75  *    typedef struct { ... } SilcIDIP;
76  *
77  * DESCRIPTION
78  *
79  *    Generic IP address structure to indicate either IPv4 or IPv6 address.
80  *    This structure is used inside all SILC ID's. The true length of the
81  *    ID depends of the length of the IP address.
82  *
83  * SOURCE
84  */
85 typedef struct SilcIDIPStruct {
86   unsigned char data[16];	/* IP data (in MSB first order) */
87   SilcUInt8 data_len;		/* Length of the data (4 or 16) */
88 } SilcIDIP;
89 /***/
90 
91 /****s* silccore/SilcIDAPI/SilcServerID
92  *
93  * NAME
94  *
95  *    typedef struct { ... } SilcServerID;
96  *
97  * DESCRIPTION
98  *
99  *    64 or 160 bit SilcServerID structure:
100  *
101  *     n bit IP address
102  *    16 bit port
103  *    16 bit random number
104  *
105  * SOURCE
106  */
107 typedef struct SilcServerIDStruct {
108   SilcIDIP ip;			/* n bit IP address */
109   SilcUInt16 port;		/* 16 bit port */
110   SilcUInt16 rnd;		/* 16 bit random number */
111 } SilcServerID;
112 /***/
113 
114 /****s* silccore/SilcIDAPI/SilcClientID
115  *
116  * NAME
117  *
118  *    typedef struct { ... } SilcClientID;
119  *
120  * DESCRIPTION
121  *
122  *    128 or 224 bit SilcClientID structure:
123  *
124  *      n bit ServerID IP address [bits 1-32 or bits 1-128]
125  *      8 bit random number
126  *     88 bit hash value from lowercase nickname
127  *
128  * SOURCE
129  */
130 typedef struct SilcClientIDStruct {
131   SilcIDIP ip;					/* n bit IP address */
132   unsigned char rnd;				/* 8 bit random number */
133   unsigned char hash[CLIENTID_HASH_LEN];	/* 88 bit MD5 hash */
134 } SilcClientID;
135 /***/
136 
137 /****s* silccore/SilcIDAPI/SilcChannelID
138  *
139  * NAME
140  *
141  *    typedef struct { ... } SilcChannelID;
142  *
143  * DESCRIPTION
144  *
145  *    64 or 160 bit SilcChannel ID structure:
146  *
147  *     n bit Router's ServerID IP address [bits 1-32 or bits 1-128]
148  *    16 bit Router's ServerID port [bits 33-48 or bits 129-144]
149  *    16 bit random number
150  *
151  * SOURCE
152  */
153 typedef struct SilcChannelIDStruct {
154   SilcIDIP ip;			/* n bit IP address */
155   SilcUInt16 port;		/* 16 bit port */
156   SilcUInt16 rnd;		/* 16 bit random number */
157 } SilcChannelID;
158 /***/
159 
160 /****s* silccore/SilcIDAPI/SilcID
161  *
162  * NAME
163  *
164  *    typedef struct { ... } SilcID;
165  *
166  * DESCRIPTION
167  *
168  *    The generic ID structure that can represent SilcClientID, SilcServerID
169  *    and SilcChannelID.  The silc_id_payload_parse_id returns the ID in the
170  *    SilcID structure.  Other routines except either SilcClientID,
171  *    SilcServerID or SilcChannelID as a void pointer.
172  *
173  * SOURCE
174  */
175 typedef struct SilcIDStruct {
176   union {
177     SilcServerID server_id;
178     SilcChannelID channel_id;
179     SilcClientID client_id;
180   } u;
181   SilcIdType type;
182 } SilcID;
183 /***/
184 
185 /* Macros */
186 
187 /****d* silccore/SilcIDAPI/SILC_ID_GET_ID
188  *
189  * NAME
190  *
191  *    #define SILC_ID_GET_ID ...
192  *
193  * DESCRIPTION
194  *
195  *    Returns the ID type specific pointer from the SilcID structure.  As
196  *    the SilcID is able to house all types of IDs this macro can be used
197  *    to get the specific ID from the structure by its type.
198  *
199  * SOURCE
200  */
201 #define SILC_ID_GET_ID(id)						\
202   ((id).type == SILC_ID_CLIENT  ? (void *)&(id).u.client_id :		\
203    (id).type == SILC_ID_SERVER  ? (void *)&(id).u.server_id :		\
204    (void *)&(id).u.channel_id)
205 /***/
206 
207 /****d* silccore/SilcIDAPI/SILC_ID_COMPARE
208  *
209  * NAME
210  *
211  *    #define SILC_ID_COMPARE ...
212  *
213  * DESCRIPTION
214  *
215  *    Compares two ID's. Returns TRUE if they match and FALSE if they do
216  *    not.
217  *
218  * SOURCE
219  */
220 #define SILC_ID_COMPARE(id1, id2, len) (!memcmp(id1, id2, len))
221 /***/
222 
223 /****d* silccore/SilcIDAPI/SILC_ID_CLIENT_COMPARE
224  *
225  * NAME
226  *
227  *    #define SILC_ID_CLIENT_COMPARE ...
228  *
229  * DESCRIPTION
230  *
231  *    Compares Client ID's. Returns TRUE if they match.
232  *
233  * SOURCE
234  */
235 #define SILC_ID_CLIENT_COMPARE(id1, id2) \
236   SILC_ID_COMPARE(id1, id2, sizeof(SilcClientID))
237 /***/
238 
239 /****d* silccore/SilcIDAPI/SILC_ID_SERVER_COMPARE
240  *
241  * NAME
242  *
243  *    #define SILC_ID_SERVER_COMPARE ...
244  *
245  * DESCRIPTION
246  *
247  *    Compares Server ID's. Returns TRUE if they match.
248  *
249  * SOURCE
250  */
251 #define SILC_ID_SERVER_COMPARE(id1, id2) \
252   SILC_ID_COMPARE(id1, id2, sizeof(SilcServerID))
253 /***/
254 
255 /****d* silccore/SilcIDAPI/SILC_ID_CHANNEL_COMPARE
256  *
257  * NAME
258  *
259  *    #define SILC_ID_CHANNEL_COMPARE ...
260  *
261  * DESCRIPTION
262  *
263  *    Compares Channel ID's. Returns TRUE if they match.
264  *
265  * SOURCE
266  */
267 #define SILC_ID_CHANNEL_COMPARE(id1, id2) \
268   SILC_ID_COMPARE(id1, id2, sizeof(SilcChannelID))
269 /***/
270 
271 /****d* silccore/SilcIDAPI/SILC_ID_COMPARE_TYPE
272  *
273  * NAME
274  *
275  *    #define SILC_ID_COMPARE_TYPE ...
276  *
277  * DESCRIPTION
278  *
279  *    Compares two ID's by type. Returns TRUE if they match.
280  *
281  * SOURCE
282  */
283 #define SILC_ID_COMPARE_TYPE(id1, id2, type)			\
284   (type == SILC_ID_SERVER ? SILC_ID_SERVER_COMPARE(id1, id2) :	\
285    type == SILC_ID_CLIENT ? SILC_ID_CLIENT_COMPARE(id1, id2) :	\
286    SILC_ID_CHANNEL_COMPARE(id1, id2))
287 /***/
288 
289 /****d* silccore/SilcIDAPI/SILC_ID_COMPARE_HASH
290  *
291  * NAME
292  *
293  *    #define SILC_ID_COMPARE_HASH ...
294  *
295  * DESCRIPTION
296  *
297  *    Compares the nickname hash of the Client ID. Returns TRUE if
298  *    they match. Since the nickname hash is based on the nickname of
299  *    the client this can be used to search the ID by nickname (taking
300  *    the hash out of it) or using the hash from the ID.
301  *
302  * SOURCE
303  */
304 #define SILC_ID_COMPARE_HASH(id1, id2) \
305   (!memcmp((id1)->hash, (id2)->hash, CLIENTID_HASH_LEN))
306 /***/
307 
308 /****s* silccore/SilcIDAPI/SilcIDPayload
309  *
310  * NAME
311  *
312  *    typedef struct SilcIDPayloadStruct *SilcIDPayload;
313  *
314  * DESCRIPTION
315  *
316  *    This context is the actual ID Payload and is allocated by
317  *    silc_id_payload_parse and given as argument usually to all
318  *    silc_id_payload_* functions.  It is freed by the function
319  *    silc_id_payload_free.
320  *
321  ***/
322 typedef struct SilcIDPayloadStruct *SilcIDPayload;
323 
324 /* Prototypes */
325 
326 /****f* silccore/SilcIDAPI/silc_id_payload_parse
327  *
328  * SYNOPSIS
329  *
330  *    SilcIDPayload silc_id_payload_parse(const unsigned char *payload,
331  *                                        SilcUInt32 payload_len);
332  *
333  * DESCRIPTION
334  *
335  *    Parses buffer and return ID payload into payload structure. The
336  *    `buffer' is raw payload buffer.  The caller must free the returned
337  *    payload.
338  *
339  ***/
340 SilcIDPayload silc_id_payload_parse(const unsigned char *payload,
341 				    SilcUInt32 payload_len);
342 
343 /****f* silccore/SilcIDAPI/silc_id_payload_parse_id
344  *
345  * SYNOPSIS
346  *
347  *    SilcBool silc_id_payload_parse_id(const unsigned char *data,
348  *                                      SilcUInt32 len, SilcID *ret_id);
349  *
350  * DESCRIPTION
351  *
352  *    Return ID directly from the raw ID Payload data buffer.  This does
353  *    not allocate any memory.
354  *
355  ***/
356 SilcBool silc_id_payload_parse_id(const unsigned char *data, SilcUInt32 len,
357 				  SilcID *ret_id);
358 
359 /****f* silccore/SilcIDAPI/silc_id_payload_encode
360  *
361  * SYNOPSIS
362  *
363  *    SilcBuffer silc_id_payload_encode(const void *id, SilcIdType type);
364  *
365  * DESCRIPTION
366  *
367  *    Encodes ID Payload. The `id' is the ID of the type `type' to put
368  *    into the payload. Returns the encoded payload buffer.
369  *
370  ***/
371 SilcBuffer silc_id_payload_encode(const void *id, SilcIdType type);
372 
373 /****f* silccore/SilcIDAPI/silc_id_payload_encode_data
374  *
375  * SYNOPSIS
376  *
377  *    SilcBuffer silc_id_payload_encode_data(const unsigned char *id,
378  *                                           uin32 id_len, SilcIdType type);
379  *
380  * DESCRIPTION
381  *
382  *    Encodes ID Payload. The `id' is raw ID data of the length of `id_len'
383  *    of type of `type'. Returns the encoded payload buffer.
384  *
385  ***/
386 SilcBuffer silc_id_payload_encode_data(const unsigned char *id,
387 				       SilcUInt32 id_len, SilcIdType type);
388 
389 /****f* silccore/SilcIDAPI/silc_id_payload_free
390  *
391  * SYNOPSIS
392  *
393  *    void silc_id_payload_free(SilcIDPayload payload);
394  *
395  * DESCRIPTION
396  *
397  *    Frees the ID Payload and all data in it.
398  *
399  ***/
400 void silc_id_payload_free(SilcIDPayload payload);
401 
402 /****f* silccore/SilcIDAPI/silc_id_payload_get_type
403  *
404  * SYNOPSIS
405  *
406  *    SilcIdType silc_id_payload_get_type(SilcIDPayload payload);
407  *
408  * DESCRIPTION
409  *
410  *    Returns the ID type from the ID Payload. The type tells the
411  *    type of the ID in the payload.
412  *
413  ***/
414 SilcIdType silc_id_payload_get_type(SilcIDPayload payload);
415 
416 /****f* silccore/SilcIDAPI/silc_id_payload_get_id
417  *
418  * SYNOPSIS
419  *
420  *    SilcBool silc_id_payload_get_id(SilcIDPayload payload, void *ret_id,
421  *                                    SilcUInt32 ret_id_len);
422  *
423  * DESCRIPTION
424  *
425  *    Returns the ID in the ID Payload. This does not allocate any memory.
426  *
427  ***/
428 SilcBool silc_id_payload_get_id(SilcIDPayload payload, void *ret_id,
429 				SilcUInt32 ret_id_len);
430 
431 /****f* silccore/SilcIDAPI/silc_id_payload_get_data
432  *
433  * SYNOPSIS
434  *
435  *    unsigned char *silc_id_payload_get_data(SilcIDPayload payload);
436  *
437  * DESCRIPTION
438  *
439  *    Returns the raw ID data from the ID Payload. The data is duplicated
440  *    and the caller must free it.
441  *
442  ***/
443 unsigned char *silc_id_payload_get_data(SilcIDPayload payload);
444 
445 /****f* silccore/SilcIDAPI/silc_id_payload_get_len
446  *
447  * SYNOPSIS
448  *
449  *    SilcUInt32 silc_id_payload_get_len(SilcIDPayload payload);
450  *
451  * DESCRIPTION
452  *
453  *    Returns the length of the ID in the ID Payload.
454  *
455  ***/
456 SilcUInt32 silc_id_payload_get_len(SilcIDPayload payload);
457 
458 /****f* silccore/SilcIDAPI/silc_id_id2str
459  *
460  * SYNOPSIS
461  *
462  *    SilcBool silc_id_id2str(const void *id, SilcIdType type,
463  *                            unsigned char *ret_id, SilcUInt32 ret_id_size,
464  *                            SilcUInt32 *ret_id_len);
465  *
466  * DESCRIPTION
467  *
468  *    Converts an ID of type `type' to data. This can be used to
469  *    convert the ID's to data for inclusion in the packets.  This does
470  *    not allocate any memory.
471  *
472  ***/
473 SilcBool silc_id_id2str(const void *id, SilcIdType type,
474 			unsigned char *ret_id, SilcUInt32 ret_id_size,
475 			SilcUInt32 *ret_id_len);
476 
477 /****f* silccore/SilcIDAPI/silc_id_str2id
478  *
479  * SYNOPSIS
480  *
481  *    SilcBool silc_id_str2id(const unsigned char *id, SilcUInt32 id_len,
482  *                            SilcIdType type, void *ret_id,
483  *                            SilcUInt32 ret_id_size);
484  *
485  * DESCRIPTION
486  *
487  *    Converts ID data string to an ID. This can be used to get the
488  *    ID out of data that has been taken for example from packet.  This
489  *    does not allocate any memory.
490  *
491  ***/
492 SilcBool silc_id_str2id(const unsigned char *id, SilcUInt32 id_len,
493 			SilcIdType type, void *ret_id, SilcUInt32 ret_id_size);
494 
495 /****f* silccore/SilcIDAPI/silc_id_str2id2
496  *
497  * SYNOPSIS
498  *
499  *    SilcBool silc_id_str2id2(const unsigned char *id, SilcUInt32 id_len,
500  *                             SilcIdType type, SilcID *ret_id);
501  *
502  * DESCRIPTION
503  *
504  *    Same as silc_id_str2id but returns the ID into SilcID structure in
505  *    `ret_id' pointer.  This does not allocate any memory.
506  *
507  ***/
508 SilcBool silc_id_str2id2(const unsigned char *id, SilcUInt32 id_len,
509 			 SilcIdType type, SilcID *ret_id);
510 
511 /****f* silccore/SilcIDAPI/silc_id_get_len
512  *
513  * SYNOPSIS
514  *
515  *    SilcUInt32 silc_id_get_len(const void *id, SilcIdType type);
516  *
517  * DESCRIPTION
518  *
519  *    Returns the true length of the ID of the type `type'.
520  *
521  ***/
522 SilcUInt32 silc_id_get_len(const void *id, SilcIdType type);
523 
524 /****f* silccore/SilcIDAPI/silc_id_dup
525  *
526  * SYNOPSIS
527  *
528  *    void *silc_id_dup(const void *id, SilcIdType type);
529  *
530  * DESCRIPTION
531  *
532  *    Duplicates the ID of the type `type'. The caller must free the
533  *    duplicated ID.
534  *
535  ***/
536 void *silc_id_dup(const void *id, SilcIdType type);
537 
538 #endif
539