1/**
2 * \file main.c
3 * \brief
4 */
5
6
7/*
8 * Copyright (c) 2017 ETH Zurich.
9 * All rights reserved.
10 *
11 * This file is distributed under the terms in the attached LICENSE file.
12 * If you do not find this file, copies can be found by writing to:
13 * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
14 */
15
16
17/*
18 * Copyright (c) 2001-2003 Swedish Institute of Computer Science.
19 * All rights reserved.
20 *
21 * Redistribution and use in source and binary forms, with or without modification,
22 * are permitted provided that the following conditions are met:
23 *
24 * 1. Redistributions of source code must retain the above copyright notice,
25 *    this list of conditions and the following disclaimer.
26 * 2. Redistributions in binary form must reproduce the above copyright notice,
27 *    this list of conditions and the following disclaimer in the documentation
28 *    and/or other materials provided with the distribution.
29 * 3. The name of the author may not be used to endorse or promote products
30 *    derived from this software without specific prior written permission.
31 *
32 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
33 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
34 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT
35 * SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT
37 * OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
38 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
39 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING
40 * IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
41 * OF SUCH DAMAGE.
42 *
43 * This file is part of the lwIP TCP/IP stack.
44 *
45 * Author: Adam Dunkels <adam@sics.se>
46 * RT timer modifications by Christiaan Simons
47 */
48
49
50#include <getopt.h>
51#include <string.h>
52
53#include "lwip/init.h"
54
55#include "lwip/debug.h"
56
57#include "lwip/mem.h"
58#include "lwip/memp.h"
59#include "lwip/sys.h"
60#include "lwip/timeouts.h"
61
62#include "lwip/stats.h"
63
64#include "lwip/ip.h"
65#include "lwip/ip4_frag.h"
66#include "lwip/udp.h"
67#include "lwip/tcp.h"
68#include "netif/etharp.h"
69#include "lwip/snmp.h"
70#include "lwip/inet_chksum.h"
71#include "lwip/apps/snmp.h"
72#include "lwip/apps/snmp_mib2.h"
73
74#include "../../src/apps/snmp_private_mib/private_mib.h"
75#include "../../src/apps/udpecho_raw/udpecho_raw.h"
76#include "../../src/apps/tcpecho_raw/tcpecho_raw.h"
77
78/* (manual) host IP configuration */
79static ip4_addr_t ipaddr, netmask, gw;
80
81#if 0
82/* SNMP trap destination cmd option */
83static unsigned char trap_flag;
84static ip_addr_t trap_addr;
85
86static const struct snmp_mib *mibs[] = {
87  &mib2,
88  &mib_private
89};
90#endif
91
92/* nonstatic debug cmd option, exported in lwipopts.h */
93unsigned char debug_flags;
94
95#if LWIP_SNMP
96/* enable == 1, disable == 2 */
97u8_t snmpauthentraps_set = 2;
98#endif
99
100static struct option longopts[] = {
101  /* turn on debugging output (if build with LWIP_DEBUG) */
102  {"debug", no_argument,        NULL, 'd'},
103  /* help */
104  {"help", no_argument, NULL, 'h'},
105  /* gateway address */
106  {"gateway", required_argument, NULL, 'g'},
107  /* ip address */
108  {"ipaddr", required_argument, NULL, 'i'},
109  /* netmask */
110  {"netmask", required_argument, NULL, 'm'},
111  /* ping destination */
112  {"trap_destination", required_argument, NULL, 't'},
113  /* new command line options go here! */
114  {NULL,   0,                 NULL,  0}
115};
116#define NUM_OPTS ((sizeof(longopts) / sizeof(struct option)) - 1)
117
118static void
119usage(void)
120{
121  unsigned char i;
122
123  printf("options:\n");
124  for (i = 0; i < NUM_OPTS; i++) {
125    printf("-%c --%s\n",longopts[i].val, longopts[i].name);
126  }
127}
128
129#include <lwip/pbuf.h>
130#include <lwip/prot/ethernet.h>
131#include <lwip/prot/ip4.h>
132#include <lwip/prot/udp.h>
133
134static void devq_poll(struct netif *netif)
135{
136
137    /* if has foobar packet */
138
139    printf("%s:%u\n", __FUNCTION__, __LINE__);
140
141    /* get the pbuf of packet */
142    struct pbuf *p = NULL;
143
144    p = pbuf_alloc(PBUF_RAW, 2048, PBUF_POOL);
145
146    struct eth_hdr* ethhdr = p->payload;
147    struct ip_hdr *iphdr   = p->payload + SIZEOF_ETH_HDR;
148    struct udp_hdr *udphdr = p->payload  + SIZEOF_ETH_HDR + IP_HLEN;
149
150    memset(ethhdr->dest.addr, 0xaa, sizeof(ethhdr->dest.addr));
151    memset(ethhdr->src.addr, 0xbb, sizeof(ethhdr->src.addr));
152    ethhdr->type = PP_HTONS(ETHTYPE_IP);
153
154    iphdr->_len = lwip_htons(1024);
155    iphdr->_v_hl = (4 << 4) | 5;
156
157
158    IP4_ADDR(&(iphdr->dest), 192,168,0,2);
159    IP4_ADDR(&(iphdr->src), 192,168,0,1);
160
161    iphdr->dest.addr = 0xdeadbeef;
162    iphdr->_proto = IP_PROTO_UDP;
163    iphdr->_chksum = inet_chksum(iphdr, 1024);
164
165    udphdr->dest = PP_HTONS(7);
166    udphdr->src = PP_HTONS(11);
167    udphdr->len = PP_HTONS(1004);
168
169    printf("%s:%u pbuf=%p payload=%p, len=%u, totlen=%u\n", __FUNCTION__, __LINE__,
170            p, p->payload, p->len, p->tot_len);
171
172    /* inet input */
173    netif_input(p, netif);
174}
175
176// 10MBit interface
177#define BFETH_NETSPEED  10000000
178
179/* Define those to better describe your network interface. */
180#define IFNAME0 'e'
181#define IFNAME1 'n'
182
183static err_t devq_send(struct netif *netif, struct pbuf *p)
184{
185    printf("%s:%u pbuf=%p payload=%p, len=%u, totlen=%u\n", __FUNCTION__, __LINE__,
186            p, p->payload, p->len, p->tot_len);
187
188    return ERR_OK;
189}
190
191static err_t devq_netif_init_fn(struct netif *netif)
192{
193    /* maximum transfer unit */
194    netif->mtu = 1500;
195
196    /* device capabilities */
197    netif->flags = // NETIF_FLAG_ETHERNET |
198      NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP;
199
200    /* set MAC hardware address length */
201    netif->hwaddr_len = ETHARP_HWADDR_LEN;
202
203#if LWIP_NETIF_HOSTNAME
204    /* Initialize interface hostname */
205    netif->hostname = "lwip";
206#endif
207
208    netif->name[0] = IFNAME0;
209    netif->name[1] = IFNAME1;
210
211    /*
212     * Initialize the snmp variables and counters inside the struct netif.
213     * The last argument should be replaced with your link speed, in units
214     * of bits per second.
215     */
216    NETIF_INIT_SNMP(netif, snmp_ifType_ethernet_csmacd, BFETH_NETSPEED);
217
218    /* We directly use etharp_output() here to save a function call.
219     * You can instead declare your own function an call etharp_output()
220     * from it if you have to do some checks before sending (e.g. if link
221     * is available...) */
222    netif->output = etharp_output;
223
224    netif->linkoutput = devq_send;
225
226    return ERR_OK;
227}
228
229
230
231int
232main(int argc, char **argv)
233{
234
235    printf("lwip min started\n");
236
237    printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
238
239
240  struct netif netif;
241  int ch;
242  char ip_str[16] = {0}, nm_str[16] = {0}, gw_str[16] = {0};
243
244  /* startup defaults (may be overridden by one or more opts) */
245  IP4_ADDR(&gw, 192,168,0,1);
246  IP4_ADDR(&ipaddr, 192,168,0,2);
247  IP4_ADDR(&netmask, 255,255,255,0);
248
249#if 0
250  trap_flag = 0;
251#endif
252  /* use debug flags defined by debug.h */
253  debug_flags = LWIP_DBG_OFF;
254
255  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
256
257  while ((ch = getopt_long(argc, argv, "dhg:i:m:t:", longopts, NULL)) != -1) {
258    switch (ch) {
259      case 'd':
260        debug_flags |= (LWIP_DBG_ON|LWIP_DBG_TRACE|LWIP_DBG_STATE|LWIP_DBG_FRESH|LWIP_DBG_HALT);
261        break;
262      case 'h':
263        usage();
264        exit(0);
265        break;
266      case 'g':
267        ip4addr_aton(optarg, &gw);
268        break;
269      case 'i':
270        ip4addr_aton(optarg, &ipaddr);
271        break;
272      case 'm':
273        ip4addr_aton(optarg, &netmask);
274        break;
275      case 't':
276#if 0
277        trap_flag = !0;
278        /* @todo: remove this authentraps tweak
279          when we have proper SET & non-volatile mem */
280        snmpauthentraps_set = 1;
281        ipaddr_aton(optarg, &trap_addr);
282        strncpy(ip_str, ipaddr_ntoa(&trap_addr),sizeof(ip_str));
283        printf("SNMP trap destination %s\n", ip_str);
284#endif
285        break;
286      default:
287        usage();
288        break;
289    }
290  }
291
292  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
293
294  argc -= optind;
295  argv += optind;
296
297  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
298
299  strncpy(ip_str, ip4addr_ntoa(&ipaddr), sizeof(ip_str));
300  strncpy(nm_str, ip4addr_ntoa(&netmask), sizeof(nm_str));
301  strncpy(gw_str, ip4addr_ntoa(&gw), sizeof(gw_str));
302  printf("Host at %s mask %s gateway %s\n", ip_str, nm_str, gw_str);
303
304
305#ifdef PERF
306  perf_init("/tmp/minimal.perf");
307#endif /* PERF */
308
309  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
310
311  lwip_init();
312
313  printf("TCP/IP initialized.\n");
314
315  netif_add(&netif, &ipaddr, &netmask, &gw, NULL, devq_netif_init_fn, ethernet_input);
316  netif_set_default(&netif);
317  netif_set_up(&netif);
318
319  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
320
321#if LWIP_IPV6
322  netif_create_ip6_linklocal_address(&netif, 1);
323#endif
324
325  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
326
327#if 0
328  /* initialize our private example MIB */
329  lwip_privmib_init();
330
331  /* snmp_trap_dst_ip_set(0,&trap_addr); */
332  /* snmp_trap_dst_enable(0,trap_flag); */
333
334#if SNMP_LWIP_MIB2
335#if SNMP_USE_NETCONN
336  snmp_threadsync_init(&snmp_mib2_lwip_locks, snmp_mib2_lwip_synchronizer);
337#endif
338  snmp_mib2_set_syscontact_readonly((const u8_t*)"root", NULL);
339  snmp_mib2_set_syslocation_readonly((const u8_t*)"lwIP development PC", NULL);
340  snmp_mib2_set_sysdescr((const u8_t*)"minimal example", NULL);
341#endif /* SNMP_LWIP_MIB2 */
342
343  /* snmp_set_snmpenableauthentraps(&snmpauthentraps_set); */
344  snmp_set_mibs(mibs, LWIP_ARRAYSIZE(mibs));
345  snmp_init();
346#endif /* LWIP_SNMP */
347
348  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
349
350  udpecho_raw_init();
351
352  printf("lwipmin:%s:%u\n", __FUNCTION__, __LINE__);
353
354  tcpecho_raw_init();
355
356
357
358  printf("Applications started.\n");
359
360
361  for(int i = 0; i < 10; i++) {
362    /* poll netif, pass packet to lwIP */
363    devq_poll(&netif);
364
365    sys_check_timeouts();
366  }
367
368  return 0;
369}
370