[ build library {
target = "net",
cFiles = [ "net.c", "netbufs.c", "netif.c", "pbuf.c", "dhcp.c",
- "net_filter.c" ],
+ "net_filter.c", "arp.c" ],
addIncludes = [ "include", "/lib/lwip-2.0.2/src/include/" ],
flounderBindings = [ "net_filter"],
flounderExtraBindings = [ ("net_filter", ["rpcclient"])],
cFiles = [ "test/udp_ping.c" ],
addIncludes = [ "include", "/lib/lwip-2.0.2/src/include/" ],
addLibraries = libDeps [ "net" ]
+ },
+ build application {
+ target = "net_dhcp",
+ cFiles = [ "test/dhcp.c" ],
+ addIncludes = [ "include", "/lib/lwip-2.0.2/src/include/" ],
+ addLibraries = libDeps [ "net" ]
+ },
+ build application {
+ target = "net_arp",
+ cFiles = [ "test/arp.c" ],
+ addIncludes = [ "include", "/lib/lwip-2.0.2/src/include/" ],
+ addLibraries = libDeps [ "net" ]
}
]
* ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
*/
-#define LWIP_ARP_FILTER_NETIF_FN(p, netif, type) arp_filter_netif(p, netif, type)
-#if LWIP_ARP_FILTER_NETIF
- netif = LWIP_ARP_FILTER_NETIF_FN(p, netif, lwip_htons(type));
-#endif /* LWIP_ARP_FILTER_NETIF*/
+#include <barrelfish/barrelfish.h>
-#if 0
- err_t etharp_add_static_entry(const ip4_addr_t *ipaddr, struct eth_addr *ethaddr);
- err_t etharp_remove_static_entry(const ip4_addr_t *ipaddr);
-#endif
-#define ARP_ENTRY "net.arp.%d {mac: %d}"
+#include <lwip/opt.h>
+#include <lwip/netif.h>
+#include <lwip/timeouts.h>
+#include "include/net/netif.h"
-#define ARP_ENTRY_REGEX "r'net\\.arp\\.[0-9]+' { mac: _ }"
+#include <netif/etharp.h>
+
+#include <octopus/octopus.h>
+
+
+#include "networking_internal.h"
+
+///< the debug subsystem
+#define NETDEBUG_SUBSYSTEM "arpd"
+
+
+#define ARP_ENTRY_FIELDS "{mac: %d, ip: %d}"
+#define ARP_ENTRY "net.arp.%d {mac: %lu, ip: %d}"
+
+#define ARP_ENTRY_REGEX "r'net\\.arp\\.[0-9]+' { mac: _, ip: _}"
struct netif *arp_filter_netif(struct pbuf *p, struct netif *netif, uint16_t type)
{
- debug_printf("arp_filter_netif");
-
if (type != ETHTYPE_ARP) {
return netif;
}
+ struct net_state *st = netif->state;
+
+ if (!st->arp_running) {
+ return netif;
+ }
+
+ if (p->len < SIZEOF_ETH_HDR || pbuf_header(p, (s16_t)-SIZEOF_ETH_HDR)) {
+ NETDEBUG("wrong packet size received\n");
+ return netif;
+ }
+
struct etharp_hdr *hdr = (struct etharp_hdr *)p->payload;
+ pbuf_header(p, (s16_t)SIZEOF_ETH_HDR);
+
/* RFC 826 "Packet Reception": */
if ((hdr->hwtype != PP_HTONS(HWTYPE_ETHERNET)) ||
(hdr->hwlen != ETH_HWADDR_LEN) ||
return netif;
}
+ ip_addr_t ip;
+ IPADDR2_COPY(&ip, &hdr->sipaddr);
+
+ uint64_t hwaddr = 0;
+ if (etharp_find_addr(netif, &ip, (struct eth_addr **)&hwaddr,
+ (const ip4_addr_t **)&hwaddr) != -1) {
+ return netif;
+ }
/*
* If already exists, return
*/
- uint64_t hwaddr = 0;
- SMEMCPY(&hwaddr, hdr->shwaddr, sizeof(hdr->shwaddr));
- oct_publish(ARP_ENTRY, hdr->sipaddr, hdr->shwaddr);
+ hwaddr = 0;
+ SMEMCPY(&hwaddr, hdr->shwaddr.addr, sizeof(hdr->shwaddr));
- etharp_add_static_entry(hdr->sipaddr, hdr->shwaddr);
+ NETDEBUG("set " ARP_ENTRY "\n", ip.addr, hwaddr, ip.addr);
+
+ oct_set(ARP_ENTRY, ip.addr, hwaddr, ip.addr);
+
+ etharp_add_static_entry(&ip, &hdr->shwaddr);
return netif;
}
-static void handle_arp_entry(octopus_mode_t mode, const char* record, void* state)
+static errval_t arp_service_start_st(struct net_state *st)
{
+ errval_t err;
+
+ err = oct_init();
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ st->arp_running = true;
- uint64_t ip,hwaddr;
- oct_read(record, ARP_ENTRY, &ip, &hwaddr);
+ return SYS_ERR_OK;
+}
+
+errval_t arp_service_start(void)
+{
+ return arp_service_start_st(get_default_net_state());
+}
+
+static void arp_change_event(octopus_mode_t mode, const char* record, void* st)
+{
+ errval_t err;
+
+ uint64_t ip, hwaddr;
+ err = oct_read(record, "_" ARP_ENTRY_FIELDS, &hwaddr, &ip);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed to read the entrie\n");
+ }
ip_addr_t ipaddr;
ipaddr.addr = (uint32_t)ip;
if (mode & OCT_ON_SET) {
+ NETDEBUG("adding ARP entries: ip=%u, mac=%lx\n", ipaddr.addr, hwaddr);
+
struct eth_addr mac;
SMEMCPY(mac.addr, &hwaddr, sizeof(mac));
etharp_add_static_entry(&ipaddr, &mac);
} else if (mode & OCT_ON_DEL) {
+ NETDEBUG("deleting ARP entries: ip=%u, mac=%lx\n", ipaddr.addr, hwaddr);
etharp_remove_static_entry(&ipaddr);
}
}
-errval_t arp_filter_subscribe(void)
+static errval_t arp_service_subscribe_st(struct net_state *st)
+{
+ NETDEBUG("subscribing to ARP updates..\n");
+
+ errval_t err;
+ err = oct_init();
+ if (err_is_fail(err)) {
+ return err;
+ }
+
+ st->arp_running = false;
+
+ return oct_trigger_existing_and_watch(ARP_ENTRY_REGEX, arp_change_event,
+ st, &st->arp_triggerid);
+}
+
+errval_t arp_service_subscribe(void)
{
struct net_state *st = get_default_net_state();
- subscription_t sub;
- return oct_subscribe(handle_arp_entry, st, &sub, ARP_ENTRY_REGEX);
+ return arp_service_subscribe_st(st);
}
--- /dev/null
+/**
+ * @brief
+ * net.h
+ */
+
+/*
+ * Copyright (c) 2017, ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+
+#ifndef LIB_NET_INCLUDE_NETWORKING_ARP_H_
+#define LIB_NET_INCLUDE_NETWORKING_ARP_H_
+
+
+errval_t arp_service_start(void);
+
+errval_t arp_service_subscribe(void);
+
+#endif /* LIB_NET_INCLUDE_NETWORKING_ARP_H_ */
static errval_t networking_poll_st(struct net_state *st)
{
+ event_dispatch_non_block(get_default_waitset());
if (st->flags & NET_FLAGS_POLLING) {
return net_if_poll(&st->netif);
} else {
if (err_is_fail(err)) {
DEBUG_ERR(err, "failed to start DHCP.\n");
}
+
+ err = arp_service_start();
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed to start the ARP service\n");
+ }
} else {
/* get IP from dhcpd */
err = dhcpd_query(flags);
if (err_is_fail(err)) {
DEBUG_ERR(err, "failed to start DHCP.\n");
}
+
+ err = arp_service_subscribe();
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed to subscribte the ARP service\n");
+ }
}
NETDEBUG("initialization complete.\n");
#include <net/netbufs.h>
#include <net/netif.h>
#include <net/dhcp.h>
+#include <net/arp.h>
#include "debug.h"
bool dhcp_done;
bool dhcp_running;
+ bool arp_running;
+ uint64_t arp_triggerid;
+
struct waitset *waitset;
struct devq *queue;
--- /dev/null
+/**
+ * \file ping.c
+ * \brief
+ */
+
+
+/*
+ * Copyright (c) 2017 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/deferred.h>
+
+#include <lwip/ip.h>
+#include <lwip/udp.h>
+#include <lwip/pbuf.h>
+
+#include <lwip/mem.h>
+#include <lwip/raw.h>
+#include <lwip/icmp.h>
+#include <lwip/netif.h>
+#include <lwip/sys.h>
+#include <lwip/timeouts.h>
+#include <lwip/ip_addr.h>
+#include <lwip/prot/ip4.h>
+
+#include <net/net.h>
+#include <net/arp.h>
+
+#include <octopus/octopus.h>
+#include <octopus/getset.h>
+
+ip_addr_t ip;
+ip_addr_t nm;
+ip_addr_t gw;
+
+uint8_t counter = 0;
+
+static int client_main(int argc, char *argv[])
+{
+ errval_t err;
+
+ debug_printf("ARP client main.\n");
+
+ err = arp_service_subscribe();
+ assert(err_is_ok(err));
+
+ while(1) {
+ event_dispatch(get_default_waitset());
+ }
+}
+
+#define ARP_ENTRY "net.arp.%d {mac: %lu, ip: %d}"
+
+static void timer_callback(void *data)
+{
+ errval_t err;
+
+ if (++counter == 0) {
+ ++counter;
+ }
+
+ IP_ADDR4(&ip, 192,168,1,counter);
+
+
+
+ debug_printf("ARP server timer. set ip to %s\n", ip4addr_ntoa(&ip));
+
+ uint64_t mac = 0xaabbccddeeffUL;
+
+ debug_printf("oct_set net.arp.%d {mac: %lu (%lx)}\n", ip.addr, mac,mac);
+
+ err = oct_set(ARP_ENTRY, ip.addr, mac, ip.addr);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed to set the DHCP record\n");
+ }
+}
+
+static int server_main(int argc, char *argv[])
+{
+ errval_t err;
+
+ debug_printf("ARP server main.\n");
+
+ IP_ADDR4(&ip, 192,168,1,0);
+ IP_ADDR4(&nm, 255,255,255,0);
+ IP_ADDR4(&gw, 192,168,1,0);
+
+ struct periodic_event ptimer;
+
+ /* DHCP fine timer */
+ err = periodic_event_create(&ptimer, get_default_waitset(), (5000 * 1000),
+ MKCLOSURE(timer_callback, NULL));
+ assert(err_is_ok(err));
+
+ while(1) {
+ event_dispatch(get_default_waitset());
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ debug_printf("ARP started.\n");
+
+ oct_init();
+
+ /* parse ip */
+
+ if (argc == 2) {
+ if (strncmp("server", argv[1], strlen("server")) == 0) {
+ return server_main(argc, argv);
+ } else if (strncmp("client", argv[1], strlen("client")) == 0) {
+ return client_main(argc, argv);
+ } else {
+ USER_PANIC("invalid argument supplied: %s\n", argv[1])
+ }
+ }
+
+ return client_main(argc, argv);
+}
+
+
--- /dev/null
+/**
+ * \file ping.c
+ * \brief
+ */
+
+
+/*
+ * Copyright (c) 2017 ETH Zurich.
+ * All rights reserved.
+ *
+ * This file is distributed under the terms in the attached LICENSE file.
+ * If you do not find this file, copies can be found by writing to:
+ * ETH Zurich D-INFK, Universitaetsstrasse 6, CH-8092 Zurich. Attn: Systems Group.
+ */
+
+
+#include <barrelfish/barrelfish.h>
+#include <barrelfish/deferred.h>
+
+#include <lwip/ip.h>
+#include <lwip/udp.h>
+#include <lwip/pbuf.h>
+
+#include <lwip/mem.h>
+#include <lwip/raw.h>
+#include <lwip/icmp.h>
+#include <lwip/netif.h>
+#include <lwip/sys.h>
+#include <lwip/timeouts.h>
+#include <lwip/ip_addr.h>
+#include <lwip/prot/ip4.h>
+
+#include <net/net.h>
+#include <net/dhcp.h>
+
+#include <octopus/octopus.h>
+#include <octopus/getset.h>
+
+ip_addr_t ip;
+ip_addr_t nm;
+ip_addr_t gw;
+
+uint8_t counter = 0;
+
+static int client_main(int argc, char *argv[])
+{
+ errval_t err;
+
+ debug_printf("DHCP client main.\n");
+
+ err = dhcpd_query(0);
+ assert(err_is_ok(err));
+
+ debug_printf("DHCP client query init\n");
+
+ while(1) {
+ event_dispatch(get_default_waitset());
+ }
+}
+
+#define DHCP_RECORD_FIELDS "{ ip: %d, gw: %d, netmask: %d }"
+#define DHCP_RECORD_FORMAT "net.ipconfig " DHCP_RECORD_FIELDS
+
+static void timer_callback(void *data)
+{
+ errval_t err;
+
+ if (++counter == 0) {
+ ++counter;
+ }
+ IP_ADDR4(&ip, 192,168,1,counter);
+
+ debug_printf("DHCP server timer. set ip to %s\n", ip4addr_ntoa(&ip));
+
+ err = oct_set(DHCP_RECORD_FORMAT,ip.addr, gw.addr, nm.addr);
+ if (err_is_fail(err)) {
+ DEBUG_ERR(err, "failed to set the DHCP record\n");
+ }
+}
+
+static int server_main(int argc, char *argv[])
+{
+ errval_t err;
+
+ debug_printf("DHCP server main.\n");
+
+ IP_ADDR4(&ip, 192,168,1,0);
+ IP_ADDR4(&nm, 255,255,255,0);
+ IP_ADDR4(&gw, 192,168,1,0);
+
+ struct periodic_event ptimer;
+
+ /* DHCP fine timer */
+ err = periodic_event_create(&ptimer, get_default_waitset(), (5000 * 1000),
+ MKCLOSURE(timer_callback, NULL));
+ assert(err_is_ok(err));
+
+ while(1) {
+ event_dispatch(get_default_waitset());
+ }
+}
+
+int main(int argc, char *argv[])
+{
+ debug_printf("DHCP started.\n");
+
+ oct_init();
+
+ /* parse ip */
+
+ if (argc == 2) {
+ if (strncmp("server", argv[1], strlen("server")) == 0) {
+ return server_main(argc, argv);
+ } else if (strncmp("client", argv[1], strlen("client")) == 0) {
+ return client_main(argc, argv);
+ } else {
+ USER_PANIC("invalid argument supplied: %s\n", argv[1])
+ }
+ }
+
+ return client_main(argc, argv);
+}
+
+