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