aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/interceptor/virtual_adapter.h
blob: 628b04a68da7fc2b1e3b9b54d585126dd4f2a2d8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
/* Netfilter Driver for IPSec VPN Client
 *
 * Copyright(c)   2012 Samsung Electronics
 *
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

/*
 *
 * Kernel-mode virtual adapter interface.
 *
 * File: virtual_adapter.h
 *
 */


#ifndef VIRTUAL_ADAPTER_H
#define VIRTUAL_ADAPTER_H

#include "interceptor.h"

/* ***************************** Data Types **********************************/

/** Error codes for virtual adapter operations. */
typedef enum {
  /** Success */
  SSH_VIRTUAL_ADAPTER_ERROR_OK              = 0,
  /** Success, status callback will be called again */
  SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE         = 1,
  /** Nonexistent adapter */
  SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT     = 2,
  /** Address configuration error */
  SSH_VIRTUAL_ADAPTER_ERROR_ADDRESS_FAILURE = 3,
  /** Route configuration error */
  SSH_VIRTUAL_ADAPTER_ERROR_ROUTE_FAILURE   = 4,
  /** Parameter configuration error */
  SSH_VIRTUAL_ADAPTER_ERROR_PARAM_FAILURE   = 5,
  /** Memory allocation error */
  SSH_VIRTUAL_ADAPTER_ERROR_OUT_OF_MEMORY   = 6,
  /** Undefined internal error */
  SSH_VIRTUAL_ADAPTER_ERROR_UNKNOWN_ERROR   = 255
} SshVirtualAdapterError;

/** Virtual adapter state. */
typedef enum {
  /** Invalid value */
  SSH_VIRTUAL_ADAPTER_STATE_UNDEFINED        = 0,
  /** Up */
  SSH_VIRTUAL_ADAPTER_STATE_UP               = 1,
  /** Down */
  SSH_VIRTUAL_ADAPTER_STATE_DOWN             = 2,
  /** Keep existing state */
  SSH_VIRTUAL_ADAPTER_STATE_KEEP_OLD         = 3,
} SshVirtualAdapterState;

/** Optional parameters for a virtual adapter. */
struct SshVirtualAdapterParamsRec
{
  /** Virtual adapter mtu. */
  SshUInt32 mtu;

  /** DNS server IP addresses. */
  SshUInt32 dns_ip_count;
  SshIpAddr dns_ip;

  /** WINS server IP addresses. */
  SshUInt32 wins_ip_count;
  SshIpAddr wins_ip;

  /** Windows domain name. */
  char *win_domain;

  /** Netbios node type. */
  SshUInt8 netbios_node_type;
};

typedef struct SshVirtualAdapterParamsRec SshVirtualAdapterParamsStruct;
typedef struct SshVirtualAdapterParamsRec *SshVirtualAdapterParams;

/* ******************* Sending and Receiving Packets *************************/

/** Send packet `pp' to the IP stack like it was received by the
    virtual adapter indexed by `pp->ifnum_in'. The packet `pp' must be a
    plain IP packet (IPv4 or IPv6) or it must be of the same media type
    as the virtual adapter (most probably ethernet). This will free the
    packet `pp'.

    NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_receive()!
*/
void ssh_virtual_adapter_send(SshInterceptor interceptor,
			      SshInterceptorPacket pp);

/** Callback function of this type is called whenever a packet is
    sent out via a virtual adapter. This function must eventually free the
    packet by calling ssh_interceptor_packet_free.

    This function is used for handling only those ARP, neighbor discovery,
    and DHCP packets that are not handled by the generic engine packet
    callback. This function must not be used for passing normal
    IP packets.

    Note that this function may be called asynchronously. */
typedef void (*SshVirtualAdapterPacketCB)(SshInterceptor interceptor,
                                          SshInterceptorPacket pp,
                                          void *adapter_context);

/* **************************** Generic Callbacks ****************************/

/** A callback function of this type is called to notify about the
   success of a virtual adapter operation.

   - The argument `error' describes whether the operation was successful or
     not. If `error' indicates success, the arguments `adapter_ifnum',
     `adapter_name', and `state' contain information about the virtual adapter.

   - The argument `adapter_ifnum' is an unique interface identifier for the
     virtual adapter.  You can use it configuring additional routes for
     the adapter, and for configuring and destroying the adapter.

   - The argument `adapter_name' contains the name of the created adapter.
     The returned name is the same that identifies the interface in the
     interceptor's interface callback.

   - The argument `adapter_context' is the context attached to the virtual
     adapter in the call to ssh_virtual_adapter_attach.

   Arguments `adapter_ifnum', `adapter_name', `adapter_state', and
   `adapter_context' are valid only for the duration of the callback. */
typedef void (*SshVirtualAdapterStatusCB)(SshVirtualAdapterError error,
                                          SshInterceptorIfnum adapter_ifnum,
                                          const unsigned char *adapter_name,
					  SshVirtualAdapterState adapter_state,
					  void *adapter_context,
                                          void *context);

/* **************************** Attach and Detach ****************************/

/** A callback function of this type is called to notify about detachment
    of a virtual adapter from the engine. The callback is meant only as a
    destructor of the virtual adapter context, and thus should be called
    whenever there is no possibility of `packet_cb' being called again.
    The argument `adapter_context' is the context attached to the virtual
    adapter in the call to ssh_virtual_adapter_attach. */
typedef void (*SshVirtualAdapterDetachCB)(void *adapter_context);

/** Attaches the packet callback and context to a virtual adapter.

   - The argument `packet_cb' specifies a callback function that is
     called when a packet is received from the virtual adapter. The argument
     `adapter_context' is the context for this callback.

   - The optional argument `detach_cb' specifies an engine-level
     destructor for `adapter_context'. It must be called when the
     interceptor is done with virtual adapter, i.e. when the `packet_cb'
     will not be called for this adapter again. Even in case of instant
     failure, the `detach_cb' must be called.

   - The operation completion callback `callback' must be called to notify
     about success or failure of the attachment. In failure cases `callback'
     must be called after `detach_cb'. The argument `context' is the context
     data for this callback.

   NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_attach()!
*/
void ssh_virtual_adapter_attach(SshInterceptor interceptor,
				SshInterceptorIfnum adapter_ifnum,
                                SshVirtualAdapterPacketCB packet_cb,
                                SshVirtualAdapterDetachCB detach_cb,
                                void *adapter_context,
                                SshVirtualAdapterStatusCB callback,
                                void *context);

/** Detach the virtual adapter `adapter_ifnum'. The success of the
    operation is notified by calling the callback function `callback'.

    The detach operation will fail with the error code
    SSH_VIRTUAL_ADAPTER_NONEXISTENT if the virtual adapter was never
    attached. Detaching a virtual adapter must generate an interface callback
    for the interceptor.

    If a detach callback was specified in ssh_virtual_adapter_attach, then
    this `detach_cb' must be called before calling the operation completion
    callback `callback'.

    NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO ssh_virtual_adapter_detach()!
*/
void ssh_virtual_adapter_detach(SshInterceptor interceptor,
				SshInterceptorIfnum adapter_ifnum,
				SshVirtualAdapterStatusCB callback,
				void *context);

/** Detach all configured virtual adapters. This is called when the engine
    is stopped during interceptor is unloading. This function must call
    `detach_cb' for each detached virtual adapter that defines `detach_cb'.

    NOTE: LOCKS MUST NOT BE HELD DURING CALLS TO
    ssh_virtual_adapter_detach_all()! */
void ssh_virtual_adapter_detach_all(SshInterceptor interceptor);

/* *************************** Configuration *********************************/

#ifdef INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE

/** Configures the virtual adapter `adapter_ifnum' with `state', `addresses',
    and `params'. The argument `adapter_ifnum' must be the valid interface
    index of a virtual adapter that has been attached to the engine during
    pm connect.

    The argument `adapter_state' specifies the state to configure for the
    virtual adapter.

    The arguments `num_addresses' and `addresses' specify the IP addresses
    for the virtual adapter. The addresses must specify the netmask. If
    `addresses' is NULL, the address configuration will not be changed.
    Otherwise the existing addresses will be removed from the virtual adapter
    and specified addresses will be added. To clear all addresses from the
    virtual adapter, specify `addresses' as non-NULL and `num_addresses' as 0.

    The argument `params' specifies optional parameters for the virtual
    adapter. If `params' is non-NULL, then the existing params will be cleared
    and the specified params will be set for the virtual adapter.

    Any configured interface addresses must survive interface state changes.

    If the define INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE is not
    defined then the interceptor does not support kernel level virtual
    adapter configure.
*/
void ssh_virtual_adapter_configure(SshInterceptor interceptor,
				   SshInterceptorIfnum adapter_ifnum,
				   SshVirtualAdapterState adapter_state,
				   SshUInt32 num_addresses,
				   SshIpAddr addresses,
				   SshVirtualAdapterParams params,
				   SshVirtualAdapterStatusCB callback,
				   void *context);

#endif /* INTERCEPTOR_IMPLEMENTS_VIRTUAL_ADAPTER_CONFIGURE */

/* *************************** Virtual Adapter Status ************************/

/** This function will call `callback' for virtual adapter `adapter_ifnum'.
    If `adapter_ifnum' equals SSH_INTERCEPTOR_INVALID_IFNUM, then this
    function calls `callback' once for each existing virtual adapter with
    error code SSH_VIRTUAL_ADAPTER_ERROR_OK_MORE, and once with error code
    SSH_VIRTUAL_ADAPTER_ERROR_NONEXISTENT after enumerating all virtual
    adapters. */
void ssh_virtual_adapter_get_status(SshInterceptor interceptor,
				    SshInterceptorIfnum adapter_ifnum,
				    SshVirtualAdapterStatusCB callback,
				    void *context);

/* *************************** Utility functions *****************************/

/** These generic utility functions that are implemented in files
    virtual_adapter_misc.c and virtual_adapter_util.s, and they use the
    virtual adapter API described above. */

/** Initializes engine side virtual adapter contexts and attaches the existing
    virtual adapters to engine. */
SshVirtualAdapterError ssh_virtual_adapter_init(SshInterceptor interceptor);

/** Unitializes engine side virtual adapter contexts and detaches virtual
    adapters from the engine. */
SshVirtualAdapterError ssh_virtual_adapter_uninit(SshInterceptor interceptor);

/** Creates a pseudo Ethernet hardware address for the virtual adapter
    `adapter_ifnum'. The address is formatted in the buffer `buffer' which
    must have space for SSH_ETHERH_ADDRLEN bytes. */
void
ssh_virtual_adapter_interface_ether_address(SshInterceptorIfnum adapter_ifnum,
					    unsigned char *buffer);

/** Create a pseudo Ethernet hardware address for the IP address `ip'.
    The address `ip' can be an IPv4 or an IPv6 address.  The address if
    formatted in the buffer `buffer' which must have space for
    SSH_ETHERH_ADDRLEN bytes. */
void ssh_virtual_adapter_ip_ether_address(SshIpAddr ip, unsigned char *buffer);

/** Encode virtual adapter params `params' to buffer `buffer'. This
    function returns TRUE on success. The caller must ssh_free the allocated
    memory in `data'. */
Boolean
ssh_virtual_adapter_param_encode(SshVirtualAdapterParams params,
				 unsigned char **data, size_t *len);

/** Decode virtual adapter params from table `data' into `params'. This
    function returns TRUE on success. */
Boolean
ssh_virtual_adapter_param_decode(SshVirtualAdapterParams params,
				 const unsigned char *data, size_t len);

#endif /* not VIRTUAL_ADAPTER_H */