1 /* -*- Mode:C++; c-file-style:"gnu"; indent-tabs-mode:nil; -*- */
2 /*
3   Network Simulation Cradle
4   Copyright (C) 2003-2005 Sam Jansen
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of the GNU General Public License as published by the Free
8   Software Foundation; either version 2 of the License, or (at your option)
9   any later version.
10 
11   This program is distributed in the hope that it will be useful, but WITHOUT
12   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
14   more details.
15 
16   You should have received a copy of the GNU General Public License along
17   with this program; if not, write to the Free Software Foundation, Inc., 59
18   Temple Place, Suite 330, Boston, MA 02111-1307 USA
19 
20 */
21 
22 #ifndef NSC_SIM_INTERFACE_H
23 #define NSC_SIM_INTERFACE_H
24 
25 #define NSC_VERSION 0x000500
26 
27 /**
28  * \ingroup nsctcp
29  * \brief Struct interface to NSC stack
30  */
31 struct INetStack
32 {
~INetStackINetStack33   virtual ~INetStack() {}
34 
35   /**
36    * \brief Initialize the stack
37    * \param hz timer_interrupt frequency
38    */
39   virtual void init (int hz) = 0;
40 
41   /**
42    * \brief Deliver complete packet to the NSC network stack
43    * \param if_id interface ID
44    * \param data data
45    * \param datalen data length
46    */
47   virtual void if_receive_packet (int if_id, const void *data, int datalen) = 0;
48   /**
49    * \brief Send complete packet to the NSC network stack
50    * \param data data
51    * \param datalen data length
52    */
53   virtual void if_send_packet (const void *data, int datalen) = 0;
54   /**
55    * \brief Signal the completion of send procedure to the NSC network stack
56    * \param if_id interface ID
57    */
58   virtual void if_send_finish (int if_id) = 0;
59 
60   /**
61    * \brief Attach an interface to the stack
62    * \param addr address
63    * \param mask network mask
64    * \param mtu MTU
65    */
66   virtual void if_attach (const char *addr, const char *mask, int mtu) = 0;
67   /**
68    * \brief Add a default gateway to the interface
69    * \param addr gateway address
70    */
71   virtual void add_default_gateway (const char *addr) = 0;
72 
73   /**
74    * \brief Returns the internal id of the stack instance.
75    *
76    * Purely for debugging/diagnostic purposes.
77    * \return internal stack id
78    */
79   virtual int get_id () = 0;
80 
81   /**
82    * \brief Return a short one-word name of the stack
83    *
84    * Should return a short one-word name of the stack. Eg. Linux 2.4.x ->
85    * linux24, FreeBSD 5.x -> freebsd5. This can be used to identify output
86    * from a stack, for example a packet trace file.
87    * \return short one-word name of the stack
88    */
89   virtual const char *get_name () = 0;
90 
91   /**
92    * \brief Get the timer_interrupt frequency
93    *
94    * This is used so the simulator can call the stack timer_interrupt function
95    * the correct amount of times per second. For example, lwip has a hz of 10,
96    * which it returns here to say that it's timer_interrupt should be called
97    * 10 times a second. FreeBSD uses 100, as does Linux 2.4, while Linux 2.6
98    * uses 1000. (This is often configurable in the kernel in question, also.)
99    *
100    * \return frequency
101    */
102   virtual int get_hz () = 0;
103 
104   /**
105    * \brief The stack timer_interrupt function
106    */
107   virtual void timer_interrupt () = 0;
108 
109   /**
110    * \brief Increment the time ticks
111    */
112   virtual void increment_ticks () = 0;
113 
114   /**
115    * \brief Set the buffer size
116    * \param size the buffer size.
117    */
118   virtual void buffer_size (int size) = 0;
119 
120   /**
121    * \brief Create a new UDP socket
122    * \returns A new UDP socket.
123    */
new_udp_socketINetStack124   virtual struct INetDatagramSocket *new_udp_socket () { return NULL; }
125   /**
126    * \brief Create a new TCP socket
127    * \returns A new TCP socket.
128    */
new_tcp_socketINetStack129   virtual struct INetStreamSocket *new_tcp_socket () { return NULL; }
130   /**
131    * \brief Create a new SCTP socket
132    * \returns A new SCTP socket.
133    */
new_sctp_socketINetStack134   virtual struct INetStreamSocket *new_sctp_socket () { return NULL; }
135 
136   // The following I've made optional to implement for now. Eases
137   // integration of new features.
138   /**
139    * \brief use sysctl to modify system parameters
140    * \param sysctl_name name of the parameter to modify
141    * \param oldval old value
142    * \param oldlenp old value length
143    * \param newval new value
144    * \param newlen new value length
145    * \returns The status code.
146    */
sysctlINetStack147   virtual int sysctl (const char *sysctl_name, void *oldval, size_t *oldlenp,
148                       void *newval, size_t newlen)
149   {
150     return -1;
151   }
152 
153   // alternate, simpler interface. the stack cradle code is expected
154   // to convert the string-value to something that the stack can handle.
155   // The idea here is that this is a front-end to the sysctl(2) call,
156   // much like the sysctl(8) program.
157   /**
158    * \brief Set system parameters using sysctl
159    * \param name name of the parameter to modify
160    * \param value new value
161    * \returns
162    */
sysctl_setINetStack163   virtual int sysctl_set (const char *name, const char *value)
164   {
165     return -1;
166   }
167 
168   // same as above, cradle code is expected to convert the sysctl value
169   // into a string.
170   // returns length of the string in value, i.e. retval > len: 'output truncated'.
171   /**
172    * \brief Get system parameters using sysctl
173    * \param name name of the parameter to modify
174    * \param value value
175    * \param len value length
176    * \returns length of the string in value, i.e. retval > len: 'output truncated'.
177    */
sysctl_getINetStack178   virtual int sysctl_get (const char *name, char *value, size_t len)
179   {
180     return -1;
181   }
182 
183   /**
184    * \brief Tell the cradle code to put the name of sysctl number 'idx' into name[].
185    *
186    * The idea is that this can be used to get a list of all available sysctls:
187    * \verbatim
188      char buf[256]
189      for (i=0; sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i++)
190         puts(buf);
191      \endverbatim
192    *
193    * \param idx index
194    * \param name sysctl name
195    * \param len sysctl length
196    * \returns -1 if idx is out of range and the length of the sysctl name otherwise.
197    */
sysctl_getnumINetStack198   virtual int sysctl_getnum (size_t idx, char *name, size_t len)
199   {
200     return -1;
201   }
202 
203   /**
204    * \brief Show the NSC configuration
205    */
show_configINetStack206   virtual void show_config ()
207   {
208     ;
209   }
210 
211   /**
212    * \brief Optional function to get variables for this stack
213    * \param var the variable
214    * \param result the result
215    * \param result_len result length
216    * \returns true on success
217    */
get_varINetStack218   virtual bool get_var (const char *var, char *result, int result_len)
219   {
220     return false;
221   }
222 
223   /**
224    * \brief Optional function to set variables for this stack
225    * \param var the variable
226    * \param val the new value
227    * \returns true on success
228    */
set_varINetStack229   virtual bool set_var (const char *var, const char *val)
230   {
231     return false;
232   }
233 
234   /**
235    * \brief Set the level of debugging or diagnostic information to print out.
236    *
237    * This normally means kernel messages printed out during initialisation but
238    * may also include extra debugging messages that are part of NSC.
239    *
240    * \param level debugging/diagnostic level
241    */
set_diagnosticINetStack242   virtual void set_diagnostic (int level) {}
243 
244   /**
245    * \brief Simple interface to support sending any textual command to a stack
246    *
247    * @returns 0 on success
248    */
cmdINetStack249   virtual int cmd (const char *)
250   {
251     return 1;
252   }
253 };
254 
255 /**
256  * \ingroup nsctcp
257  * \brief Struct interface to NSC Stream (i.e., TCP) Sockets
258  */
259 struct INetStreamSocket
260 {
~INetStreamSocketINetStreamSocket261   virtual ~INetStreamSocket() {}
262 
263   /**
264    * \brief Connect to a remote peer
265    */
266   virtual void connect (const char *, int) = 0;
267   /**
268    * \brief Disconnect from a remote peer
269    */
270   virtual void disconnect () = 0;
271   /**
272    * \brief Put the socket in Listening state on a port
273    */
274   virtual void listen (int) = 0;
275   /**
276    * \brief Accept an incoming connection
277    * \param handler a handler to the INetStreamSocket.
278    * \returns The status code.
279    */
280   virtual int accept (INetStreamSocket **handler) = 0;
281   /**
282    * \brief Send some data
283    * \param data the data
284    * \param datalen data length
285    * \return the number of data sent or -1 on error
286    */
287   virtual int send_data (const void *data, int datalen) = 0;
288   /**
289    * \brief Read some data
290    * \param buf the buffer to store the data
291    * \param buflen buffer length
292    * \return the number of data read or -1 on error
293    */
294   virtual int read_data (void *buf, int *buflen) = 0;
295   /**
296    * \brief Set the socket options
297    *
298    * We need to pass the option name in as a string here. The reason for
299    * this is that different operating systems you compile on will have
300    * different numbers defined for the constants SO_SNDBUF and so on.
301    *
302    * \param optname name of the option
303    * \param val option value
304    * \param valsize size of the option value
305    * \returns
306    */
307   virtual int setsockopt (char *optname, void *val, size_t valsize) = 0;
308   /**
309    * \brief Print the socket state
310    */
311   virtual void print_state (FILE *) = 0;
312   /**
313    * \brief Check the connection state
314    * \returns true if socket is in connected state
315    */
316   virtual bool is_connected () = 0;
317   /**
318    * \brief Check the listening state
319    * \returns true if socket is in listening state
320    */
321   virtual bool is_listening () = 0;
322   /**
323    * \brief Get the peer name
324    *
325    * \note not implemented
326    *
327    * \param sa sockaddr structure to fill
328    * \param salen sockaddr structure length
329    * \returns -1 on error (always returns -1)
330    */
getpeernameINetStreamSocket331   virtual int getpeername (struct sockaddr *sa, size_t *salen) {
332     return -1;
333   }
334   /**
335    * \brief Get the socket local name
336    *
337    * \note not implemented
338    *
339    * \param sa sockaddr structure to fill
340    * \param salen sockaddr structure length
341    * \returns -1 on error (always returns -1)
342    */
getsocknameINetStreamSocket343   virtual int getsockname (struct sockaddr *sa, size_t *salen) {
344     return -1;
345   }
346   /**
347    * \brief Optional function used to get variables for this TCP connection.
348    *
349    * \note not implemented
350    *
351    * \param var variable requested
352    * \param result result result
353    * \param result_len result length
354    * \return always false
355    */
get_varINetStreamSocket356   virtual bool get_var (const char *var, char *result, int result_len)
357   {
358     return false;
359   }
360   /**
361    * \brief Optional function used to set variables for this TCP connection.
362    *
363    * \note not implemented
364    *
365    * \param var variable to set
366    * \param val value to set
367    * \return always false
368    */
set_varINetStreamSocket369   virtual bool set_var (const char *var, const char *val)
370   {
371     return false;
372   }
373 };
374 
375 /**
376  * \ingroup nsctcp
377  * \brief Struct interface to NSC Datagram (i.e., UDP) Sockets
378  */
379 struct INetDatagramSocket
380 {
~INetDatagramSocketINetDatagramSocket381   virtual ~INetDatagramSocket() {}
382 
383   /**
384    * \brief Set the destination address and port
385    */
386   virtual void set_destination (const char *, int) = 0;
387   /**
388    * \brief Send a datagram
389    * \param data the data
390    * \param datalen data length
391    */
392   virtual void send_data (const void *data, int datalen) = 0;
393 };
394 
395 /**
396  * \ingroup nsctcp
397  * \brief Struct interface to NSC send capabilities
398  */
399 struct ISendCallback
400 {
~ISendCallbackISendCallback401   virtual ~ISendCallback() {}
402 
403   /**
404    * \brief Invoked by NSCs 'ethernet driver' to re-inject a packet into ns-3.
405    * \param data the data.
406    * \param datalen the data length.
407    */
408   virtual void send_callback (const void *data, int datalen) = 0;
409 };
410 
411 /**
412  * \ingroup nsctcp
413  * \brief Struct interface to NSC soft interrupt capabilities
414  */
415 struct IInterruptCallback
416 {
~IInterruptCallbackIInterruptCallback417   virtual ~IInterruptCallback() {}
418 
419   /**
420    * \brief Called by the NSC stack whenever something of interest has happened
421    */
422   virtual void wakeup () = 0;
423   /**
424    * \brief Get the actual time
425    */
426   virtual void gettime (unsigned int *, unsigned int *) = 0;
427 };
428 
429 typedef int (*FRandom)();
430 typedef INetStack *(*FCreateStack)(ISendCallback *, IInterruptCallback *,
431                                    FRandom);
432 
433 #define CREATE_STACK_FUNC(a,b,c) extern "C" INetStack *nsc_create_stack ( \
434     ISendCallback *a, IInterruptCallback *b, FRandom c)
435 
436 #endif /* NSC_SIM_INTERFACE_H */
437