1 /*
2 
3   silccommand.h
4 
5   Author: Pekka Riikonen <priikone@silcnet.org>
6 
7   Copyright (C) 1997 - 2006 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 Command Interface
21  *
22  * DESCRIPTION
23  *
24  * Implementation of the Command Payload. The Command Payload is used to
25  * send commands and also command replies usually between client and
26  * server.
27  *
28  ***/
29 
30 #ifndef SILCCOMMAND_H
31 #define SILCCOMMAND_H
32 
33 /****f* silccore/SilcCommandAPI/SilcCommandCb
34  *
35  * SYNOPSIS
36  *
37  *    typedef void (*SilcCommandCb)(void *context, void *context2);
38  *
39  * DESCRIPTION
40  *
41  *    Command function callback. The actual command function pointer.
42  *    This is generic command callback that the application may choose to
43  *    use with its command routines.  However, none of the generic
44  *    routines depend on this callback so application may freely define
45  *    their own command callback if desired.
46  *
47  ***/
48 typedef void (*SilcCommandCb)(void *context, void *context2);
49 
50 /****s* silccore/SilcCommandAPI/SilcCommandPayload
51  *
52  * NAME
53  *
54  *    typedef struct SilcCommandPayloadStruct *SilcCommandPayload;
55  *
56  * DESCRIPTION
57  *
58  *    This context is the actual Command Payload and is allocated
59  *    by silc_command_payload_parse and given as argument usually to
60  *    all silc_command_payload_* functions.  It is freed by the
61  *    silc_command_payload_free function.
62  *
63  ***/
64 typedef struct SilcCommandPayloadStruct *SilcCommandPayload;
65 
66 /****d* silccore/SilcCommandAPI/SilcCommandFlags
67  *
68  * NAME
69  *
70  *    typedef enum { ... } SilcCommandFlags;
71  *
72  * DESCRIPTION
73  *
74  *    Command flags that set how the commands behave on different
75  *    situations. These can be OR'es together to set multiple flags.
76  *    The application is resoponsible of implementing the behaviour
77  *    of these flags. These are here just to define generic flags.
78  *    The server usually makes use of these flags.
79  *
80  * SOURCE
81  */
82 typedef enum {
83   SILC_CF_NONE           = 0,
84 
85   /* Command may only be used once per (about) 2 seconds. Bursts up
86      to 5 commands are allowed though. */
87   SILC_CF_LAG            = (1L << 1),
88 
89   /* Command may only be used once per (about) 2 seconds. No bursts
90      are allowed at all. */
91   SILC_CF_LAG_STRICT     = (1L << 2),
92 
93   /* Command is available for registered connections (connections
94      whose ID has been created. */
95   SILC_CF_REG            = (1L << 3),
96 
97   /* Command is available only for server operators */
98   SILC_CF_OPER           = (1L << 4),
99 
100   /* Command is available only for SILC (router) operators. If this
101      is set SILC_CF_OPER is not necessary to be set. */
102   SILC_CF_SILC_OPER      = (1L << 5),
103 
104 } SilcCommandFlag;
105 /***/
106 
107 /****d* silccore/SilcCommandAPI/SilcCommand
108  *
109  * NAME
110  *
111  *    typedef SilcUInt8 SilcCommand;
112  *
113  * DESCRIPTION
114  *
115  *    The SilcCommand type definition and the commands. The commands
116  *    listed here are the official SILC Commands and they have client
117  *    and server counterparts.
118  *
119  * SOURCE
120  */
121 typedef SilcUInt8 SilcCommand;
122 
123 /* All SILC commands. These are commands that have client and server
124    counterparts. */
125 #define SILC_COMMAND_NONE               0
126 #define SILC_COMMAND_WHOIS		1
127 #define SILC_COMMAND_WHOWAS		2
128 #define SILC_COMMAND_IDENTIFY           3
129 #define SILC_COMMAND_NICK		4
130 #define SILC_COMMAND_LIST		5
131 #define SILC_COMMAND_TOPIC		6
132 #define SILC_COMMAND_INVITE		7
133 #define SILC_COMMAND_QUIT		8
134 #define SILC_COMMAND_KILL		9
135 #define SILC_COMMAND_INFO		10
136 #define SILC_COMMAND_STATS		11
137 #define SILC_COMMAND_PING		12
138 #define SILC_COMMAND_OPER		13
139 #define SILC_COMMAND_JOIN		14
140 #define SILC_COMMAND_MOTD		15
141 #define SILC_COMMAND_UMODE		16
142 #define SILC_COMMAND_CMODE		17
143 #define SILC_COMMAND_CUMODE		18
144 #define SILC_COMMAND_KICK		19
145 #define SILC_COMMAND_BAN		20
146 #define SILC_COMMAND_DETACH		21
147 #define SILC_COMMAND_WATCH		22
148 #define SILC_COMMAND_SILCOPER	        23
149 #define SILC_COMMAND_LEAVE		24
150 #define SILC_COMMAND_USERS		25
151 #define SILC_COMMAND_GETKEY		26
152 #define SILC_COMMAND_SERVICE		27
153 
154 /* Private range start */
155 #define SILC_COMMAND_PRIVATE            200
156 #define SILC_COMMAND_PRIV_CONNECT       200
157 #define SILC_COMMAND_PRIV_CLOSE         201
158 #define SILC_COMMAND_PRIV_SHUTDOWN      202
159 
160 /* Reserved */
161 #define SILC_COMMAND_RESERVED           255
162 /***/
163 
164 /* Prototypes */
165 
166 /****f* silccore/SilcCommandAPI/silc_command_payload_parse
167  *
168  * SYNOPSIS
169  *
170  *    SilcCommandPayload
171  *    silc_command_payload_parse(const unsigned char *payload,
172  *                               SilcUInt32 payload_len);
173  *
174  * DESCRIPTION
175  *
176  *    Parses command payload returning new command payload structure. The
177  *    `buffer' is the raw payload.
178  *
179  ***/
180 SilcCommandPayload silc_command_payload_parse(const unsigned char *payload,
181 					      SilcUInt32 payload_len);
182 
183 /****f* silccore/SilcCommandAPI/silc_command_payload_encode
184  *
185  * SYNOPSIS
186  *
187  *    SilcBuffer silc_command_payload_encode(SilcCommand cmd,
188  *                                           SilcUInt32 argc,
189  *                                           unsigned char **argv,
190  *                                           SilcUInt32 *argv_lens,
191  *                                           SilcUInt32 *argv_types,
192  *                                           SilcUInt16 ident);
193  *
194  * DESCRIPTION
195  *
196  *     Encodes Command Payload returning it to SilcBuffer.
197  *
198  ***/
199 SilcBuffer silc_command_payload_encode(SilcCommand cmd,
200 				       SilcUInt32 argc,
201 				       unsigned char **argv,
202 				       SilcUInt32 *argv_lens,
203 				       SilcUInt32 *argv_types,
204 				       SilcUInt16 ident);
205 
206 /****f* silccore/SilcCommandAPI/silc_command_payload_encode_payload
207  *
208  * SYNOPSIS
209  *
210  *    SilcBuffer
211  *    silc_command_payload_encode_payload(SilcCommandPayload payload);
212  *
213  * DESCRIPTION
214  *
215  *    Same as silc_command_payload_encode but encodes the buffer from
216  *    SilcCommandPayload structure instead of raw data.
217  *
218  ***/
219 SilcBuffer silc_command_payload_encode_payload(SilcCommandPayload payload);
220 
221 /****f* silccore/SilcCommandAPI/silc_command_payload_encode_va
222  *
223  * SYNOPSIS
224  *
225  *    SilcBuffer silc_command_payload_encode_va(SilcCommand cmd,
226  *                                              SilcUInt16 ident,
227  *                                              SilcUInt32 argc, ...);
228  *
229  * DESCRIPTION
230  *
231  *    Encodes Command payload with variable argument list. The arguments
232  *    must be: SilcUInt32, unsigned char *, unsigned int, ... One
233  *    {SilcUInt32, unsigned char * and unsigned int} forms one argument,
234  *    thus `argc' in case when sending one {SilcUInt32, unsigned char *
235  *    and SilcUInt32} equals one (1) and when sending two of those it
236  *    equals two (2), and so on. This has to be preserved or bad things
237  *    will happen. The variable arguments is: {type, data, data_len}.
238  *
239  ***/
240 SilcBuffer silc_command_payload_encode_va(SilcCommand cmd,
241 					  SilcUInt16 ident,
242 					  SilcUInt32 argc, ...);
243 
244 /****f* silccore/SilcCommandAPI/silc_command_payload_encode_vap
245  *
246  * SYNOPSIS
247  *
248  *    SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
249  *                                               SilcUInt16 ident,
250  *                                               SilcUInt32 argc, va_list ap);
251  *
252  * DESCRIPTION
253  *
254  *    This is equivalent to the silc_command_payload_encode_va except
255  *    takes the va_list as argument.
256  *
257  ***/
258 SilcBuffer silc_command_payload_encode_vap(SilcCommand cmd,
259 					   SilcUInt16 ident,
260 					   SilcUInt32 argc, va_list ap);
261 
262 /****f* silccore/SilcCommandAPI/silc_command_reply_payload_encode_va
263  *
264  * SYNOPSIS
265  *
266  *    SilcBuffer
267  *    silc_command_reply_payload_encode_va(SilcCommand cmd,
268  *                                         SilcStatus status,
269  *                                         SilcStatus error,
270  *                                         SilcUInt16 ident,
271  *                                         SilcUInt32 argc, ...);
272  *
273  * DESCRIPTION
274  *
275  *    Same as silc_command_payload_encode_va except that this is used to
276  *    encode strictly command reply packets.  The `argc' must not count
277  *    `status' and `error' as arguments.  The `status' includes the
278  *    command reply status.  If single reply will be sent then it includes
279  *    SILC_STATUS_OK if error did not occur.  It includes an error value
280  *    if error did occur.  In this case `error' field is ignored.  If
281  *    there will be multiple successful command replies then the `status'
282  *    includes a list value and `error' is ignored.  If there will
283  *    multiple error replies the `status' includes a list value, and
284  *    the `error' includes an error value.  Thus, the `error' value is
285  *    specified only if there will be list of errors.
286  *
287  * NOTES
288  *
289  *    Protocol defines that it is possible to send both list of successful
290  *    and list of error replies at the same time, as long as the error
291  *    replies are sent after the successful replies.
292  *
293  ***/
294 SilcBuffer
295 silc_command_reply_payload_encode_va(SilcCommand cmd,
296 				     SilcStatus status,
297 				     SilcStatus error,
298 				     SilcUInt16 ident,
299 				     SilcUInt32 argc, ...);
300 
301 /****f* silccore/SilcCommandAPI/silc_command_reply_payload_encode_vap
302  *
303  * SYNOPSIS
304  *
305  *    SilcBuffer
306  *    silc_command_reply_payload_encode_vap(SilcCommand cmd,
307  *                                          SilcStatus status,
308  *                                          SilcStatus error,
309  *                                          SilcUInt16 ident, SilcUInt32 argc,
310  *                                          va_list ap);
311  *
312  * DESCRIPTION
313  *
314  *    This is equivalent to the silc_command_reply_payload_encode_va except
315  *    takes the va_list as argument.
316  *
317  ***/
318 SilcBuffer
319 silc_command_reply_payload_encode_vap(SilcCommand cmd,
320 				      SilcStatus status,
321 				      SilcStatus error,
322 				      SilcUInt16 ident, SilcUInt32 argc,
323 				      va_list ap);
324 
325 /****f* silccore/SilcCommandAPI/silc_command_free
326  *
327  * SYNOPSIS
328  *
329  *    void silc_command_payload_free(SilcCommandPayload payload);
330  *
331  * DESCRIPTION
332  *
333  *    Frees the Command Payload and all data in it.
334  *
335  ***/
336 void silc_command_payload_free(SilcCommandPayload payload);
337 
338 /****f* silccore/SilcCommandAPI/silc_command_get
339  *
340  * SYNOPSIS
341  *
342  *    SilcCommand silc_command_get(SilcCommandPayload payload);
343  *
344  * DESCRIPTION
345  *
346  *    Return the command from the payload.
347  *
348  ***/
349 SilcCommand silc_command_get(SilcCommandPayload payload);
350 
351 /****f* silccore/SilcCommandAPI/silc_command_get_args
352  *
353  * SYNOPSIS
354  *
355  *    SilcArgumentPayload silc_command_get_args(SilcCommandPayload payload);
356  *
357  * DESCRIPTION
358  *
359  *    Return the Arguments Payload containing the arguments from the
360  *    Command Payload. The caller must not free it.
361  *
362  ***/
363 SilcArgumentPayload silc_command_get_args(SilcCommandPayload payload);
364 
365 /****f* silccore/SilcCommandAPI/silc_command_get_ident
366  *
367  * SYNOPSIS
368  *
369  *    SilcUInt16 silc_command_get_ident(SilcCommandPayload payload);
370  *
371  * DESCRIPTION
372  *
373  *    Return the command identifier from the payload. The identifier can
374  *    be used to identify which command reply belongs to which command.
375  *    The client sets the identifier to the payload and server must return
376  *    the same identifier in the command reply.
377  *
378  ***/
379 SilcUInt16 silc_command_get_ident(SilcCommandPayload payload);
380 
381 /****f* silccore/SilcCommandAPI/silc_command_get_status
382  *
383  * SYNOPSIS
384  *
385  *    SilcBool silc_command_get_status(SilcCommandPayload payload,
386  *                                 SilcStatus *status,
387  *                                 SilcStatus *error);
388  *
389  * DESCRIPTION
390  *
391  *    This function returns the command reply status into `status' and
392  *    error status, if error occurred into the `error'.  The function
393  *    returns TRUE if command reply status is not error, and FALSE if
394  *    error occurred.  In this case the `error' will include the actual
395  *    error status.  The `status' can be in this case some list value
396  *    which indicates that there will be list of errors.
397  *
398  ***/
399 SilcBool silc_command_get_status(SilcCommandPayload payload,
400 				 SilcStatus *status,
401 				 SilcStatus *error);
402 
403 /****f* silccore/SilcCommandAPI/silc_command_set_ident
404  *
405  * SYNOPSIS
406  *
407  *    void silc_command_set_ident(SilcCommandPayload payload,
408  *                                SilcUInt16 ident);
409  *
410  * DESCRIPTION
411  *
412  *    Function to set identifier to already allocated Command Payload. Command
413  *    payloads are frequentlly resent in SILC and thusly this makes it easy
414  *    to set the identifier without encoding new Command Payload.
415  *
416  ***/
417 void silc_command_set_ident(SilcCommandPayload payload, SilcUInt16 ident);
418 
419 /****f* silccore/SilcCommandAPI/silc_command_set_command
420  *
421  * SYNOPSIS
422  *
423  *    void silc_command_set_command(SilcCommandPayload payload,
424  *                                  SilcCommand command);
425  *
426  * DESCRIPTION
427  *
428  *    Function to set the command to already allocated Command Payload. This
429  *    makes it easy to change the command in the payload without encoding new
430  *    Command Payload.
431  *
432  ***/
433 void silc_command_set_command(SilcCommandPayload payload, SilcCommand command);
434 
435 #endif
436