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