src/internet-stack/sim_interface.h
author Florian Westphal <fw@strlen.de>
Wed Jul 15 18:46:14 2009 +0200 (2009-07-15)
changeset 4685 ae536d9e0d6d
parent 3869 0edba1e055aa
permissions -rw-r--r--
nsc: move nsc glue code from nsc-tcp-l4-protocol to node/nsc-glue.cc.

known problems:
- sim_interface.h is duplicated
- nsc-glue.cc adds hooks in node.cc, "hijacks" incoming packets
- nsc-glue exports NSCs INetStack (instead of wrapping it completely)
- nsc-tcp-l4-protocol and nsc-tcp-socket-impl make calls into nsc-glue
- nsc-tcp-socket-impl should really be "nsc-socket-core" (or something
like that)

needs fixing on nsc side:
- no support for multiple interfaces yet (also not yet supported
on nsc side)
- nsc initialisation still tied to IP (Adding an Interface and assigning the
IP address is a single step; it should be separate)

maybe there is more.

There is a NSC_NEXT define in nsc-glue.h, its main purpose is to flag
the places where the NSC API needs to be adapted to support multiple
interfaces in nsc.
     1 #ifndef __SIM_INTERFACE_H__
     2 #define __SIM_INTERFACE_H__
     3 /*
     4   Network Simulation Cradle
     5   Copyright (C) 2003-2005 Sam Jansen
     6 
     7   This program is free software; you can redistribute it and/or modify it
     8   under the terms of the GNU General Public License as published by the Free
     9   Software Foundation; either version 2 of the License, or (at your option)
    10   any later version.
    11 
    12   This program is distributed in the hope that it will be useful, but WITHOUT
    13   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
    14   FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
    15   more details.
    16 
    17   You should have received a copy of the GNU General Public License along
    18   with this program; if not, write to the Free Software Foundation, Inc., 59
    19   Temple Place, Suite 330, Boston, MA 02111-1307 USA
    20 
    21 */
    22 
    23 #define NSC_VERSION 0x000500
    24 
    25 struct INetStack
    26 {
    27     virtual ~INetStack() {}
    28 
    29     virtual void init(int hz) = 0;
    30     
    31     virtual void if_receive_packet(int if_id, const void *data, unsigned int datalen) = 0;
    32 
    33     /*
    34      * called by NSCs network driver. It invokes ISendCallback->send_callback() to pass
    35      * the packet to the simulator.
    36      */
    37     virtual void if_send_packet(const void *data, unsigned int datalen) = 0;
    38     //virtual void if_send_packet(int if_id, const void *data, unsigned int datalen) = 0;
    39 
    40     /*
    41      * called by network simulator after packet tx was sucessful.
    42      * on Linux, this wakes up the netdev xmit queue.
    43      */
    44     virtual void if_send_finish(int if_id) = 0;
    45 
    46     virtual void if_attach(const char *addr, const char *mask, int mtu) = 0;
    47     virtual void add_default_gateway(const char *addr) = 0;
    48 
    49     /** Purely for debugging/diagnostic purposes. This returns the internal id
    50      * of the stack instance.
    51      */
    52     virtual int get_id() = 0;
    53 
    54     /** Should return a short one-word name of the stack. Eg. Linux 2.4.x ->
    55      * linux24, FreeBSD 5.x -> freebsd5. This can be used to identify output
    56      * from a stack, for example a packet trace file. */
    57     virtual const char *get_name() = 0;
    58 
    59     /** This is used so the simulator can call the stack timer_interrupt function
    60      * the correct amount of times per second. For example, lwip has a hz of 10,
    61      * which it returns here to say that it's timer_interrupt should be called
    62      * 10 times a second. FreeBSD uses 100, as does Linux 2.4, while Linux 2.6
    63      * uses 1000. (This is often configurable in the kernel in question, also.)
    64      */
    65     virtual int get_hz() = 0;
    66 
    67     virtual void timer_interrupt() = 0;
    68     virtual void increment_ticks() = 0;
    69 
    70     virtual void buffer_size(int size) = 0;
    71     
    72     virtual struct INetDatagramSocket *new_udp_socket() { return NULL; }
    73     virtual struct INetStreamSocket *new_tcp_socket() { return NULL; }
    74     virtual struct INetStreamSocket *new_sctp_socket() { return NULL; }
    75 
    76     // The following I've made optional to implement for now. Eases
    77     // integration of new features.
    78     virtual int sysctl(const char *sysctl_name, void *oldval, size_t *oldlenp,
    79         void *newval, size_t newlen)
    80     {
    81         return -1;
    82     }
    83 
    84     // alternate, simpler interface. the stack cradle code is expected
    85     // to convert the string-value to something that the stack can handle.
    86     // The idea here is that this is a front-end to the sysctl(2) call,
    87     // much like the sysctl(8) program.
    88     virtual int sysctl_set(const char *name, const char *value)
    89     {
    90         return -1;
    91     }
    92 
    93     // same as above, cradle code is expected to convert the sysctl value
    94     // into a string.
    95     // returns length of the string in value, i.e. retval > len: 'output truncated'.
    96     virtual int sysctl_get(const char *name, char *value, size_t len)
    97     {
    98         return -1;
    99     }
   100 
   101     // this tells the cradle code to put the name of sysctl number 'idx'
   102     // into name[].
   103     // The idea is that this can be used to get a list of all available sysctls:
   104     // char buf[256]
   105     // for (i=0; sysctl_getnum(i, buf, sizeof(buf)) > 0 ;i++)
   106     //    puts(buf);
   107     // returns -1 if idx is out of range and the length of the sysctl name otherwise.
   108     virtual int sysctl_getnum(size_t idx, char *name, size_t len)
   109     {
   110         return -1;
   111     }
   112 
   113     virtual void show_config()
   114     {
   115         ;
   116     }
   117 
   118     /* Optional functions used to get and set variables for this stack */
   119     virtual bool get_var(const char *var, char *result, int result_len)
   120     {
   121         return false;
   122     }
   123     
   124     virtual bool set_var(const char *var, const char *val)
   125     {
   126         return false;
   127     }
   128 
   129     /** The level of debugging or diagnostic information to print out. This 
   130      * normally means kernel messages printed out during initialisation but
   131      * may also include extra debugging messages that are part of NSC. */
   132     virtual void set_diagnostic(int level) {}
   133 
   134     /** Simple interface to support sending any textual command to a stack 
   135      *
   136      * @returns 0 on success
   137      */
   138     virtual int cmd(const char *) 
   139     {
   140         return 1;
   141     }
   142 };
   143 
   144 struct INetStreamSocket
   145 {
   146     virtual ~INetStreamSocket() {}
   147 
   148     virtual void connect(const char *, int) = 0;
   149     virtual void disconnect() = 0;
   150     virtual void listen(int) = 0;
   151     virtual int accept(INetStreamSocket **) = 0;
   152     virtual int send_data(const void *data, int datalen) = 0;
   153     virtual int read_data(void *buf, int *buflen) = 0;
   154     /* We need to pass the option name in as a string here. The reason for
   155      * this is that different operating systems you compile on will have
   156      * different numbers defined for the constants SO_SNDBUF and so on. */
   157     virtual int setsockopt(char *optname, void *val, size_t valsize) = 0;
   158     virtual void print_state(FILE *) = 0;
   159     virtual bool is_connected() = 0;
   160     virtual bool is_listening() = 0;
   161 
   162     virtual int getpeername(struct sockaddr *sa, size_t *salen) {
   163 	    return -1;
   164     }
   165     virtual int getsockname(struct sockaddr *sa, size_t *salen) {
   166 	    return -1;
   167     }
   168     /* Optional functions used to get and set variables for this TCP
   169      * connection. */
   170     virtual bool get_var(const char *var, char *result, int result_len)
   171     {
   172         return false;
   173     }
   174     
   175     virtual bool set_var(const char *var, const char *val)
   176     {
   177         return false;
   178     }
   179 };
   180 
   181 struct INetDatagramSocket
   182 {
   183     virtual ~INetDatagramSocket() {}
   184 
   185     virtual void set_destination(const char *, int) = 0;
   186     virtual void send_data(const void *data, int datalen) = 0;
   187 };
   188 struct ISendCallback
   189 {
   190     virtual ~ISendCallback() {}
   191 
   192 //  virtual void send_callback(int id, const void *data, unsigned int datalen) = 0;
   193     virtual void send_callback(const void *data, unsigned int datalen) = 0;
   194 };
   195 
   196 struct IInterruptCallback
   197 {
   198     virtual ~IInterruptCallback() {}
   199 
   200     virtual void wakeup() = 0;
   201     virtual void gettime(unsigned int *, unsigned int *) = 0;
   202 };
   203 
   204 typedef int (*FRandom)();
   205 typedef INetStack *(*FCreateStack)(ISendCallback *, IInterruptCallback *, 
   206         FRandom);
   207 
   208 #define CREATE_STACK_FUNC(a,b,c) extern "C" INetStack *nsc_create_stack(\
   209         ISendCallback *a, IInterruptCallback *b, FRandom c)
   210 
   211 #endif