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/waitset.h> 12 13// to connect with service 14#include <barrelfish/nameservice_client.h> 15#include <barrelfish/net_constants.h> 16 17#include <if/net_ARP_defs.h> 18#include <if/net_ARP_defs.h> 19 20// standard include files 21#include <stdio.h> 22 23// for netif struct 24#include <netif/bfeth.h> 25#include <netif/etharp.h> 26 27// local include files 28#include "idc_barrelfish.h" 29#include "lwip_barrelfish_debug.h" 30 31// ***************************************************************** 32// local states 33// ***************************************************************** 34static struct net_ARP_binding *net_ARP_binding; 35static bool net_ARP_service_connected = false; 36static struct netif netif; 37 38/**************************************************************** 39* Global states 40*****************************************************************/ 41extern struct waitset *lwip_waitset; 42 43// ***************************************************************** 44// Dealing with new connections 45// ***************************************************************** 46static void net_ARP_bind_cb(void *st, errval_t err, struct net_ARP_binding *b) 47{ 48 if (err_is_fail(err)) { 49 DEBUG_ERR(err, "bind failed for net_ARP"); 50 abort(); 51 } 52 LWIPBF_DEBUG("net_ARP_bind_cb: called\n"); 53 net_ARP_binding = b; 54 net_ARP_rpc_client_init(b); 55 net_ARP_service_connected = true; 56 LWIPBF_DEBUG("net_ARP_bind_cb: net_ARP bind successful!\n"); 57} 58 59static void init_net_ARP_connection(char *service_name) 60{ 61 LWIPBF_DEBUG("init_net_ARP_connection: called\n"); 62 assert(service_name != NULL); 63 LWIPBF_DEBUG("init_net_ARP_connection: connecting to [%s]\n", service_name); 64 65 errval_t err; 66 iref_t iref; 67 68 LWIPBF_DEBUG("init_net_ARP_connection: resolving driver %s\n", service_name); 69 70 err = nameservice_blocking_lookup(service_name, &iref); 71 if (err_is_fail(err)) { 72 DEBUG_ERR(err, "lwip: could not connect to the net_ARP driver.\n" 73 "Terminating.\n"); 74 abort(); 75 } 76 assert(iref != 0); 77 78 LWIPBF_DEBUG("init_net_ARP_connection: connecting\n"); 79 80 err = net_ARP_bind(iref, net_ARP_bind_cb, NULL, lwip_waitset, 81 IDC_BIND_FLAGS_DEFAULT); 82 if (!err_is_ok(err)) { 83 printf("net_ARP_bind_cb failed in init\n"); 84 abort(); 85 } 86 87 LWIPBF_DEBUG("init_net_ARP_connection: terminated\n"); 88} 89 90 91// Connects to the port manager service 92// Blocking call: returns only when connection is done 93// In case of error, it will panic!! 94void idc_connect_ARP_lookup_service(char *service_name) 95{ 96 LWIPBF_DEBUG("idc_c_ARP_lookup_srv: trying to [%s]\n", service_name); 97 98 /* FIXME: decide if this is the best place to connect with net_ARP */ 99 init_net_ARP_connection(service_name); 100 101 // XXX: dispatch on default waitset until bound 102 struct waitset *dws = get_default_waitset(); 103 104 while (!net_ARP_service_connected) { 105 errval_t err = event_dispatch(dws); 106 107 if (err_is_fail(err)) { 108 USER_PANIC_ERR(err, "in event_dispatch while binding ARP_service"); 109 } 110 } 111 LWIPBF_DEBUG("idc_c_ARP_lookup_srv: success [%s]\n", service_name); 112} 113 114 115// ************************************************************************ 116// ARP lookup interface function 117// ************************************************************************ 118 119 120void idc_get_ip_from_ARP_lookup(void) 121{ 122 /* 123 if (is_owner) { 124 assert(!"owner of lwip should never ask for ip through API\n"); 125 abort(); 126 } 127 */ 128 LWIPBF_DEBUG("On the way of getting IP via ARP lookup\n"); 129 130 errval_t err; 131 errval_t remote_err; 132 struct ip_addr ip, gw, nm; 133 uint32_t iface = 0; 134 135 err = net_ARP_binding->rpc_tx_vtbl.ip_info(net_ARP_binding, iface, &remote_err, 136 &ip.addr, &gw.addr, &nm.addr); 137 if (err_is_fail(err)) { 138 USER_PANIC_ERR(err, "error in making ip_info call"); 139 } 140 141 if (err_is_fail(remote_err)) { 142 USER_PANIC_ERR(remote_err, "error in getting ip_info"); 143 } 144 145 LWIPBF_DEBUG("got answer, now setting up things\n"); 146 netif_add(&netif, &ip, &nm, &gw, NULL, bfeth_init, ethernet_input); 147 netif_set_default(&netif); 148 netif_set_up(&netif); 149 150 LWIPBF_DEBUG("client: owner has the IP address %d.%d.%d.%d\n", 151 ip4_addr1(&netif.ip_addr), ip4_addr2(&netif.ip_addr), 152 ip4_addr3(&netif.ip_addr), ip4_addr4(&netif.ip_addr)); 153} 154 155uint64_t idc_ARP_lookup(uint32_t ip) 156{ 157 /* 158 if (is_owner) { 159 assert(!"ARP server should never use this API for ARP lookup\n"); 160 abort(); 161 } 162 */ 163 LWIPBF_DEBUG("idc_ARP_lookup: On the way of ARP lookup\n"); 164 165 errval_t err; 166 errval_t remote_err; 167 uint32_t iface = 0; 168 bool force = false; 169 uint64_t mac = 0; 170 171 err = net_ARP_binding->rpc_tx_vtbl.ARP_lookup(net_ARP_binding, ip, iface, force, 172 &remote_err, &mac); 173 if (err_is_fail(err)) { 174 USER_PANIC_ERR(err, "error in making ARP_lookup call"); 175 } 176 177 if (err_is_fail(remote_err)) { 178 USER_PANIC_ERR(remote_err, "error in ARP lookup process"); 179 } 180 assert(mac != 0); 181 182 LWIPBF_DEBUG("idc_ARP_lookup: got answer\n"); 183 return mac; 184} // end function: idc_ARP_lookup 185