1 /*
2  * Cisco router simulation platform.
3  * Copyright (c) 2005,2006 Christophe Fillot (cf@utc.fr)
4  *
5  * Network I/O Layer.
6  */
7 
8 #ifndef __NET_IO_H__
9 #define __NET_IO_H__
10 
11 #include <sys/types.h>
12 #include <sys/socket.h>
13 #include <sys/un.h>
14 #include <pthread.h>
15 
16 #include "utils.h"
17 
18 #ifdef LINUX_ETH
19 #include "linux_eth.h"
20 #endif
21 #ifdef GEN_ETH
22 #include "gen_eth.h"
23 #endif
24 
25 /* Maximum packet size */
26 #define NETIO_MAX_PKT_SIZE  32768
27 
28 /* Maximum device length */
29 #define NETIO_DEV_MAXLEN    64
30 
31 enum {
32    NETIO_TYPE_UNIX = 0,
33    NETIO_TYPE_VDE,
34    NETIO_TYPE_TAP,
35    NETIO_TYPE_UDP,
36    NETIO_TYPE_UDP_AUTO,
37    NETIO_TYPE_TCP_CLI,
38    NETIO_TYPE_TCP_SER,
39 #ifdef LINUX_ETH
40    NETIO_TYPE_LINUX_ETH,
41 #endif
42 #ifdef GEN_ETH
43    NETIO_TYPE_GEN_ETH,
44 #endif
45    NETIO_TYPE_FIFO,
46    NETIO_TYPE_NULL,
47    NETIO_TYPE_MAX,
48 };
49 
50 enum {
51    NETIO_FILTER_ACTION_DROP = 0,
52    NETIO_FILTER_ACTION_PASS,
53    NETIO_FILTER_ACTION_ALTER,
54    NETIO_FILTER_ACTION_DUPLICATE,
55 };
56 
57 typedef struct netio_desc netio_desc_t;
58 
59 /* VDE switch definitions */
60 enum vde_request_type { VDE_REQ_NEW_CONTROL };
61 
62 #define VDE_SWITCH_MAGIC   0xfeedface
63 #define VDE_SWITCH_VERSION 3
64 
65 struct vde_request_v3 {
66    m_uint32_t magic;
67    m_uint32_t version;
68    enum vde_request_type type;
69    struct sockaddr_un sock;
70 };
71 
72 /* netio unix descriptor */
73 typedef struct netio_unix_desc netio_unix_desc_t;
74 struct netio_unix_desc {
75    char *local_filename;
76    struct sockaddr_un remote_sock;
77    int fd;
78 };
79 
80 /* netio vde descriptor */
81 typedef struct netio_vde_desc netio_vde_desc_t;
82 struct netio_vde_desc {
83    char *local_filename;
84    struct sockaddr_un remote_sock;
85    int ctrl_fd,data_fd;
86 };
87 
88 /* netio tap descriptor */
89 typedef struct netio_tap_desc netio_tap_desc_t;
90 struct netio_tap_desc {
91    char filename[NETIO_DEV_MAXLEN];
92    int fd;
93 };
94 
95 /* netio udp/tcp descriptor */
96 typedef struct netio_inet_desc netio_inet_desc_t;
97 struct netio_inet_desc {
98    int local_port,remote_port;
99    char *remote_host;
100    int fd;
101 };
102 
103 #ifdef LINUX_ETH
104 /* netio linux raw ethernet descriptor */
105 typedef struct netio_lnxeth_desc netio_lnxeth_desc_t;
106 struct netio_lnxeth_desc {
107    char dev_name[NETIO_DEV_MAXLEN];
108    int dev_id,fd;
109 };
110 #endif
111 
112 #ifdef GEN_ETH
113 /* netio generic raw ethernet descriptor */
114 typedef struct netio_geneth_desc netio_geneth_desc_t;
115 struct netio_geneth_desc {
116    char dev_name[NETIO_DEV_MAXLEN];
117    pcap_t *pcap_dev;
118 };
119 #endif
120 
121 /* FIFO packet */
122 typedef struct netio_fifo_pkt netio_fifo_pkt_t;
123 struct netio_fifo_pkt {
124    netio_fifo_pkt_t *next;
125    size_t pkt_len;
126    char pkt[0];
127 };
128 
129 /* Netio FIFO */
130 typedef struct netio_fifo_desc netio_fifo_desc_t;
131 struct netio_fifo_desc {
132    pthread_cond_t cond;
133    pthread_mutex_t lock,endpoint_lock;
134    netio_fifo_desc_t *endpoint;
135    netio_fifo_pkt_t *head,*last;
136    u_int pkt_count;
137 };
138 
139 /* Packet filter */
140 typedef struct netio_pktfilter netio_pktfilter_t;
141 struct netio_pktfilter {
142    char *name;
143    int  (*setup)(netio_desc_t *nio,void **opt,int argc,char *argv[]);
144    void (*free)(netio_desc_t *nio,void **opt);
145    int  (*pkt_handler)(netio_desc_t *nio,void *pkt,size_t len,void *opt);
146    netio_pktfilter_t *next;
147 };
148 
149 /* Statistics */
150 typedef struct netio_stat netio_stat_t;
151 struct netio_stat {
152    m_uint64_t pkts,bytes;
153 };
154 
155 #define NETIO_BW_SAMPLES     10
156 #define NETIO_BW_SAMPLE_ITV  30
157 
158 /* Generic netio descriptor */
159 struct netio_desc {
160    u_int type;
161    void *dptr;
162    char *name;
163    int debug;
164 
165    /* Frame Relay specific information */
166    m_uint8_t fr_lmi_seq;
167    void *fr_conn_list;
168 
169    /* Ethernet specific information */
170    u_int vlan_port_type;
171    m_uint16_t vlan_id;
172    void *vlan_input_vector;
173    m_uint16_t ethertype;
174 
175    union {
176       netio_unix_desc_t nud;
177       netio_vde_desc_t nvd;
178       netio_tap_desc_t ntd;
179       netio_inet_desc_t nid;
180 #ifdef LINUX_ETH
181       netio_lnxeth_desc_t nled;
182 #endif
183 #ifdef GEN_ETH
184       netio_geneth_desc_t nged;
185 #endif
186       netio_fifo_desc_t nfd;
187    } u;
188 
189    /* Send and receive prototypes */
190    ssize_t (*send)(void *desc,void *pkt,size_t len);
191    ssize_t (*recv)(void *desc,void *pkt,size_t len);
192 
193    /* Configuration saving */
194    void (*save_cfg)(netio_desc_t *nio,FILE *fd);
195 
196    /* Free ressources */
197    void (*free)(void *desc);
198 
199    /* Bandwidth constraint (in Kb/s) */
200    u_int bandwidth;
201    m_uint64_t bw_cnt[NETIO_BW_SAMPLES];
202    m_uint64_t bw_cnt_total;
203    u_int bw_pos;
204    u_int bw_ptask_cnt;
205 
206    /* Packet filters */
207    netio_pktfilter_t *rx_filter,*tx_filter,*both_filter;
208    void *rx_filter_data,*tx_filter_data,*both_filter_data;
209 
210    /* Statistics */
211    m_uint64_t stats_pkts_in,stats_pkts_out;
212    m_uint64_t stats_bytes_in,stats_bytes_out;
213 
214    /* Next pointer (for RX listener) */
215    netio_desc_t *rxl_next;
216 
217    /* Packet data */
218    u_char rx_pkt[NETIO_MAX_PKT_SIZE];
219 };
220 
221 /* RX listener */
222 typedef int (*netio_rx_handler_t)(netio_desc_t *nio,
223                                   u_char *pkt,ssize_t pkt_len,
224                                   void *arg1,void *arg2);
225 
226 struct netio_rx_listener {
227    netio_desc_t *nio;
228    u_int ref_count;
229    volatile int running;
230    netio_rx_handler_t rx_handler;
231    void *arg1,*arg2;
232    pthread_t spec_thread;
233    struct netio_rx_listener *prev,*next;
234 };
235 
236 /* Get NETIO type given a description */
237 int netio_get_type(char *type);
238 
239 /* Show the NETIO types */
240 void netio_show_types(void);
241 
242 /* Create a new NetIO descriptor */
243 netio_desc_t *netio_desc_create_unix(char *nio_name,char *local,char *remote);
244 
245 /* Create a new NetIO descriptor with VDE method */
246 netio_desc_t *netio_desc_create_vde(char *nio_name,char *control,char *local);
247 
248 /* Create a new NetIO descriptor with TAP method */
249 netio_desc_t *netio_desc_create_tap(char *nio_name,char *tap_name);
250 
251 /* Create a new NetIO descriptor with TCP_CLI method */
252 netio_desc_t *netio_desc_create_tcp_cli(char *nio_name,char *addr,char *port);
253 
254 /* Create a new NetIO descriptor with TCP_SER method */
255 netio_desc_t *netio_desc_create_tcp_ser(char *nio_name,char *port);
256 
257 /* Create a new NetIO descriptor with UDP method */
258 netio_desc_t *netio_desc_create_udp(char *nio_name,int local_port,
259                                     char *remote_host,int remote_port);
260 
261 /* Get local port */
262 int netio_udp_auto_get_local_port(netio_desc_t *nio);
263 
264 /* Connect to a remote host/port */
265 int netio_udp_auto_connect(netio_desc_t *nio,char *host,int port);
266 
267 /* Create a new NetIO descriptor with auto UDP method */
268 netio_desc_t *netio_desc_create_udp_auto(char *nio_name,char *local_addr,
269                                          int port_start,int port_end);
270 
271 #ifdef LINUX_ETH
272 /* Create a new NetIO descriptor with raw Ethernet method */
273 netio_desc_t *netio_desc_create_lnxeth(char *nio_name,char *dev_name);
274 #endif
275 
276 #ifdef GEN_ETH
277 /* Create a new NetIO descriptor with generic raw Ethernet method */
278 netio_desc_t *netio_desc_create_geneth(char *nio_name,char *dev_name);
279 #endif
280 
281 /* Establish a cross-connect between two FIFO NetIO */
282 int netio_fifo_crossconnect(netio_desc_t *a,netio_desc_t *b);
283 
284 /* Create a new NetIO descriptor with FIFO method */
285 netio_desc_t *netio_desc_create_fifo(char *nio_name);
286 
287 /* Create a new NetIO descriptor with NULL method */
288 netio_desc_t *netio_desc_create_null(char *nio_name);
289 
290 /* Acquire a reference to NIO from registry (increment reference count) */
291 netio_desc_t *netio_acquire(char *name);
292 
293 /* Release an NIO (decrement reference count) */
294 int netio_release(char *name);
295 
296 /* Delete a NetIO descriptor */
297 int netio_delete(char *name);
298 
299 /* Delete all NetIO descriptors */
300 int netio_delete_all(void);
301 
302 /* Save the configuration of a NetIO descriptor */
303 void netio_save_config(netio_desc_t *nio,FILE *fd);
304 
305 /* Save configurations of all NetIO descriptors */
306 void netio_save_config_all(FILE *fd);
307 
308 /* Send a packet through a NetIO descriptor */
309 ssize_t netio_send(netio_desc_t *nio,void *pkt,size_t len);
310 
311 /* Receive a packet through a NetIO descriptor */
312 ssize_t netio_recv(netio_desc_t *nio,void *pkt,size_t max_len);
313 
314 /* Get a NetIO FD */
315 int netio_get_fd(netio_desc_t *nio);
316 
317 /* Reset NIO statistics */
318 void netio_reset_stats(netio_desc_t *nio);
319 
320 /* Indicate if a NetIO can transmit a packet */
321 int netio_can_transmit(netio_desc_t *nio);
322 
323 /* Update bandwidth counter */
324 void netio_update_bw_stat(netio_desc_t *nio,m_uint64_t bytes);
325 
326 /* Reset NIO bandwidth counter */
327 void netio_clear_bw_stat(netio_desc_t *nio);
328 
329 /* Set the bandwidth constraint */
330 void netio_set_bandwidth(netio_desc_t *nio,u_int bandwidth);
331 
332 /* Enable a RX listener */
333 int netio_rxl_enable(netio_desc_t *nio);
334 
335 /* Add an RX listener in the listener list */
336 int netio_rxl_add(netio_desc_t *nio,netio_rx_handler_t rx_handler,
337                   void *arg1,void *arg2);
338 
339 /* Remove a NIO from the listener list */
340 int netio_rxl_remove(netio_desc_t *nio);
341 
342 /* Initialize the RXL thread */
343 int netio_rxl_init(void);
344 
345 #endif
346