1/* 2 * Copyright (c) 2007-12 ETH Zurich. 3 * All rights reserved. 4 * 5 * This file is distributed under the terms in the attached LICENSE file. 6 * If you do not find this file, copies can be found by writing to: 7 * ETH Zurich D-INFK, Universitaetstrasse 6, CH-8092 Zurich. Attn: Systems Group. 8 */ 9 10#include <barrelfish/barrelfish.h> 11#include <barrelfish/nameservice_client.h> 12#include <barrelfish/net_constants.h> 13#include <if/net_ARP_defs.h> 14 15#include <barrelfish/waitset.h> 16 17// standard libraries 18#include <stdio.h> 19#include <string.h> 20 21#include <lwip/init.h> 22#include <netif/etharp.h> 23 24// local includes 25#include "netd_private.h" 26#include <netd/netd_debug.h> 27 28// ***** Special cases ******** 29// local ip address (your own ip address) (valid request) 30// broadcast ip address (invalid request) 31// multicast IP address (invalid request) 32// 33// 34// 35 36 37// How can I get my own MAC address 38// Where can I find the code which is looking up local MAC address? 39// struct eth_addr *srcaddr = (struct eth_addr *) netif->hwaddr; 40// 41// 42// return etharp_query(netif, ipaddr, q); // q is pbuf 43// lib/lwip/src/netif/etharp.c 44 45// find_entry 46// src/netif/etharp.c 47 48/***************************************************************** 49* Prototypes 50*****************************************************************/ 51 52static errval_t get_ip_info(struct net_ARP_binding *cc, uint32_t iface, 53 errval_t *err, net_ARP_ipv4addr_t *ip, 54 net_ARP_ipv4addr_t *gw, net_ARP_ipv4addr_t *mask); 55static errval_t ARP_resolve_request(struct net_ARP_binding *cc, 56 ipv4addr_t ip, uint32_t iface, bool force, 57 errval_t *err, uint64_t *mac); 58 59// service mappings 60static struct net_ARP_rpc_rx_vtbl rpc_rx_ARP_vtbl = { 61 .ip_info_call = get_ip_info, 62 .ARP_lookup_call = ARP_resolve_request, 63}; 64 65 66/***************************************************************** 67* Dealing with new connections 68*****************************************************************/ 69static errval_t connect_ARP_cb(void *st, struct net_ARP_binding *b) 70{ 71 errval_t err = SYS_ERR_OK; 72 struct netd_state *state = st; 73 NETD_DEBUG("########### new application came in\n"); 74 75 // using the b->st to store session specific data (net_user) 76 struct ARP_user_cl *new_app = malloc(sizeof(struct ARP_user_cl)); 77 78 if (new_app == NULL) { 79 NETD_DEBUG("error: malloc failed...\n"); 80 err = PORT_ERR_NOT_ENOUGH_MEMORY; 81 return err; 82 } 83 84 memset(new_app, 0, sizeof(struct ARP_user_cl)); 85 new_app->state = state; 86 new_app->next = state->registered_user_list; 87 state->registered_user_list = new_app; 88 b->st = (void *) new_app; 89 90 b->rpc_rx_vtbl = rpc_rx_ARP_vtbl; 91 return err; 92} // end function: connect_ARP_cb 93 94 95/***************************************************************** 96* exporting service 97*****************************************************************/ 98 99static void export_ARP_cb(void *st, errval_t err, iref_t iref) 100{ 101 struct netd_state *state = st; 102 103 if (err_is_fail(err)) { 104 DEBUG_ERR(err, "service[%s] export failed", state->ARP_service_name); 105 abort(); // FIXME: Do I need abort after DEBUG_ERR? 106 } 107 108 NETD_DEBUG("service [%s] exported at iref %u\n", state->ARP_service_name, iref); 109 110 // register this iref with the name service 111 err = nameservice_register(state->ARP_service_name, iref); 112 if (err_is_fail(err)) { 113 DEBUG_ERR(err, "nameservice_register failed for [%s]", state->ARP_service_name); 114 abort(); // FIXME: Do I need abort after DEBUG_ERR? 115 } 116 state->ARP_service_exported = true; 117 NETD_DEBUG("service [%s] export successful!\n", state->ARP_service_name); 118} // end function: export_ARP_cb 119 120 121 122// ************************************************************************ 123// ARP lookup interface function 124// ************************************************************************ 125 126static errval_t get_ip_info(struct net_ARP_binding *cc, uint32_t iface, 127 errval_t *err, net_ARP_ipv4addr_t *ip, 128 net_ARP_ipv4addr_t *gw, net_ARP_ipv4addr_t *mask) 129{ 130 printf("####### get IP info called ######\n"); 131 NETD_DEBUG("get_ip_info: client asking for ip over %"PRIu32"\n", iface); 132 struct ARP_user_cl *app = cc->st; 133 struct netd_state *state = app->state; 134 135 *err = SYS_ERR_OK; 136 *ip = state->netif_ptr->ip_addr.addr; 137 *gw = state->netif_ptr->gw.addr; 138 *mask = state->netif_ptr->netmask.addr; 139 NETD_DEBUG("get_ip_info: terminating\n"); 140 return SYS_ERR_OK; 141} 142 143static uint64_t refresh_cache(uint32_t dst_ip_addr) 144{ 145 struct ip_addr dst_ip; 146 struct netif *netif; 147 148 dst_ip.addr = dst_ip_addr; 149 netif = ip_route(&dst_ip); 150 151 NETD_DEBUG("refresh_cache: calling etharp_request\n"); 152 errval_t r = etharp_request(netif, &dst_ip); 153 assert(err_is_ok(r)); 154 155 struct waitset *ws = NULL; 156 ws = get_default_waitset(); 157 while (is_ip_present_in_arp_cache(&dst_ip) == false) { 158// NETD_DEBUG("refresh_arp_cache: event dispatched\n"); 159 r = event_dispatch(ws); 160 if (err_is_fail(r)) { 161 DEBUG_ERR(r, "in event_dispatch"); 162 abort(); 163 } 164 } // end while: till arp not present 165 return find_ip_arp_cache(&dst_ip); 166} 167 168static errval_t ARP_resolve_request(struct net_ARP_binding *cc, 169 ipv4addr_t ip, uint32_t iface, bool force, 170 errval_t *err, uint64_t *mac) 171{ 172 NETD_DEBUG("ARP_resolve_request: client asking ARP lookup for ip %" 173 PRIu32" over iface %"PRIu32"\n", ip, iface); 174 175 *mac = refresh_cache(ip); 176 assert(*mac != 0); 177// assert(!"NYI ARP resolve request"); 178 NETD_DEBUG("ARP_resolve_request: MAC found for ARP request ip %" 179 PRIu32" over iface %"PRIu32" == %"PRIx64"\n", 180 ip, iface, *mac); 181 *err = SYS_ERR_OK; 182 return SYS_ERR_OK; 183} // end function: ARP_resolve_request 184 185 186// Initialzes the ARP lookup service 187int init_ARP_lookup_service(struct netd_state *state, char *dev_name) 188{ 189 errval_t err = SYS_ERR_OK; // default return value 190 191 // sanity check on parameter 192 assert(dev_name != NULL); 193 194 // start the port management service 195 snprintf(state->ARP_service_name, sizeof(state->ARP_service_name), "%s%s", dev_name, 196 NET_ARP_LOOKUP_SUFFIX); 197 state->ARP_service_exported = false; 198 state->registered_user_list = NULL; 199 200 NETD_DEBUG("init_ARP_lookup_service called [%s]\n", state->ARP_service_name); 201 202 // exporting net_ports interface 203 err = net_ARP_export(state, export_ARP_cb, connect_ARP_cb, 204 get_default_waitset(), IDC_EXPORT_FLAGS_DEFAULT); 205 206 if (err_is_fail(err)) { 207 USER_PANIC("net_ARP_export failed!"); 208 return err; 209 } 210 211 // wait till ports export is actually done 212 struct waitset *ws = get_default_waitset(); 213 214 215 while (!state->ARP_service_exported) { 216 err = event_dispatch(ws); 217 if (err_is_fail(err)) { 218 DEBUG_ERR(err, "in event_dispatch for init_ARP_service"); 219 return err; 220 } 221 } // end while: 222 223 return err; 224} // end function: init_ARP_service 225