Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/inetsrv/inetsrv.c

    ra1a101d r9ae6fc7  
    4646#include <stdlib.h>
    4747#include <sys/types.h>
    48 
     48#include <net/socket_codes.h>
    4949#include "addrobj.h"
    5050#include "icmp.h"
    5151#include "icmp_std.h"
     52#include "icmpv6.h"
     53#include "icmpv6_std.h"
    5254#include "inetsrv.h"
    5355#include "inetcfg.h"
    5456#include "inetping.h"
     57#include "inetping6.h"
    5558#include "inet_link.h"
    5659#include "reass.h"
     
    5962#define NAME "inetsrv"
    6063
     64static inet_naddr_t solicited_node_mask = {
     65        .family = AF_INET6,
     66        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0},
     67        .prefix = 104
     68};
     69
     70static inet_addr_t multicast_all_nodes = {
     71        .family = AF_INET,
     72        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
     73};
     74
    6175static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6276
     
    98112        }
    99113       
     114        rc = loc_service_register_with_iface(SERVICE_NAME_INETPING6, &sid,
     115            INET_PORT_PING6);
     116        if (rc != EOK) {
     117                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
     118                return EEXIST;
     119        }
     120       
     121        inet_sroute_t *sroute = inet_sroute_new();
     122        if (sroute == NULL) {
     123                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed creating default route (%d).", rc);
     124                return ENOMEM;
     125        }
     126
     127        inet_naddr(&sroute->dest, 0, 0, 0, 0, 0);
     128        inet_addr(&sroute->router, 10, 0, 2, 2);
     129        sroute->name = str_dup("default");
     130        inet_sroute_add(sroute);
     131
    100132        rc = inet_link_discovery_start();
    101133        if (rc != EOK)
     
    182214
    183215        /* Take source address from the address object */
    184         local->ipv4 = dir.aobj->naddr.ipv4;
     216        inet_naddr_addr(&dir.aobj->naddr, local);
    185217        return EOK;
    186218}
    187219
    188 static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
    189     ipc_call_t *call)
    190 {
     220static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t iid,
     221    ipc_call_t *icall)
     222{
     223        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
     224       
     225        uint8_t tos = IPC_GET_ARG1(*icall);
     226       
     227        ipc_callid_t callid;
     228        size_t size;
     229        if (!async_data_write_receive(&callid, &size)) {
     230                async_answer_0(callid, EREFUSED);
     231                async_answer_0(iid, EREFUSED);
     232                return;
     233        }
     234       
     235        if (size != sizeof(inet_addr_t)) {
     236                async_answer_0(callid, EINVAL);
     237                async_answer_0(iid, EINVAL);
     238                return;
     239        }
     240       
    191241        inet_addr_t remote;
    192         uint8_t tos;
     242        int rc = async_data_write_finalize(callid, &remote, size);
     243        if (rc != EOK) {
     244                async_answer_0(callid, rc);
     245                async_answer_0(iid, rc);
     246        }
     247       
    193248        inet_addr_t local;
    194         int rc;
    195 
    196         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
    197 
    198         remote.ipv4 = IPC_GET_ARG1(*call);
    199         tos = IPC_GET_ARG2(*call);
    200         local.ipv4 = 0;
    201 
    202249        rc = inet_get_srcaddr(&remote, tos, &local);
    203         async_answer_1(callid, rc, local.ipv4);
    204 }
    205 
    206 static void inet_send_srv(inet_client_t *client, ipc_callid_t callid,
    207     ipc_call_t *call)
    208 {
     250        if (rc != EOK) {
     251                async_answer_0(iid, rc);
     252                return;
     253        }
     254       
     255        if (!async_data_read_receive(&callid, &size)) {
     256                async_answer_0(callid, EREFUSED);
     257                async_answer_0(iid, EREFUSED);
     258                return;
     259        }
     260       
     261        if (size != sizeof(inet_addr_t)) {
     262                async_answer_0(callid, EINVAL);
     263                async_answer_0(iid, EINVAL);
     264                return;
     265        }
     266       
     267        rc = async_data_read_finalize(callid, &local, size);
     268        if (rc != EOK) {
     269                async_answer_0(callid, rc);
     270                async_answer_0(iid, rc);
     271                return;
     272        }
     273       
     274        async_answer_0(iid, rc);
     275}
     276
     277static void inet_send_srv(inet_client_t *client, ipc_callid_t iid,
     278    ipc_call_t *icall)
     279{
     280        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
     281       
    209282        inet_dgram_t dgram;
    210         uint8_t ttl;
    211         int df;
    212         int rc;
    213 
    214         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
    215 
    216         dgram.src.ipv4 = IPC_GET_ARG1(*call);
    217         dgram.dest.ipv4 = IPC_GET_ARG2(*call);
    218         dgram.tos = IPC_GET_ARG3(*call);
    219         ttl = IPC_GET_ARG4(*call);
    220         df = IPC_GET_ARG5(*call);
    221 
    222         rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
     283       
     284        dgram.tos = IPC_GET_ARG1(*icall);
     285       
     286        uint8_t ttl = IPC_GET_ARG2(*icall);
     287        int df = IPC_GET_ARG3(*icall);
     288       
     289        ipc_callid_t callid;
     290        size_t size;
     291        if (!async_data_write_receive(&callid, &size)) {
     292                async_answer_0(callid, EREFUSED);
     293                async_answer_0(iid, EREFUSED);
     294                return;
     295        }
     296       
     297        if (size != sizeof(inet_addr_t)) {
     298                async_answer_0(callid, EINVAL);
     299                async_answer_0(iid, EINVAL);
     300                return;
     301        }
     302       
     303        int rc = async_data_write_finalize(callid, &dgram.src, size);
    223304        if (rc != EOK) {
    224305                async_answer_0(callid, rc);
    225                 return;
    226         }
    227 
     306                async_answer_0(iid, rc);
     307        }
     308       
     309        if (!async_data_write_receive(&callid, &size)) {
     310                async_answer_0(callid, EREFUSED);
     311                async_answer_0(iid, EREFUSED);
     312                return;
     313        }
     314       
     315        if (size != sizeof(inet_addr_t)) {
     316                async_answer_0(callid, EINVAL);
     317                async_answer_0(iid, EINVAL);
     318                return;
     319        }
     320       
     321        rc = async_data_write_finalize(callid, &dgram.dest, size);
     322        if (rc != EOK) {
     323                async_answer_0(callid, rc);
     324                async_answer_0(iid, rc);
     325        }
     326       
     327        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0,
     328            &dgram.size);
     329        if (rc != EOK) {
     330                async_answer_0(iid, rc);
     331                return;
     332        }
     333       
    228334        rc = inet_send(client, &dgram, client->protocol, ttl, df);
    229 
     335       
    230336        free(dgram.data);
    231         async_answer_0(callid, rc);
     337        async_answer_0(iid, rc);
    232338}
    233339
     
    327433                inetping_conn(iid, icall, arg);
    328434                break;
     435        case INET_PORT_PING6:
     436                inetping6_conn(iid, icall, arg);
     437                break;
    329438        default:
    330439                async_answer_0(iid, ENOTSUP);
     
    354463{
    355464        async_exch_t *exch = async_exchange_begin(client->sess);
    356 
     465       
    357466        ipc_call_t answer;
    358         aid_t req = async_send_3(exch, INET_EV_RECV, dgram->src.ipv4,
    359             dgram->dest.ipv4, dgram->tos, &answer);
    360         int rc = async_data_write_start(exch, dgram->data, dgram->size);
    361         async_exchange_end(exch);
    362 
    363         if (rc != EOK) {
     467        aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
     468       
     469        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
     470        if (rc != EOK) {
     471                async_exchange_end(exch);
    364472                async_forget(req);
    365473                return rc;
    366474        }
    367 
     475       
     476        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
     477        if (rc != EOK) {
     478                async_exchange_end(exch);
     479                async_forget(req);
     480                return rc;
     481        }
     482       
     483        rc = async_data_write_start(exch, dgram->data, dgram->size);
     484       
     485        async_exchange_end(exch);
     486       
     487        if (rc != EOK) {
     488                async_forget(req);
     489                return rc;
     490        }
     491       
    368492        sysarg_t retval;
    369493        async_wait_for(req, &retval);
    370         if (retval != EOK)
    371                 return retval;
    372 
    373         return EOK;
     494       
     495        return (int) retval;
    374496}
    375497
     
    380502        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_recv_dgram_local()");
    381503
    382         /* ICMP messages are handled internally */
     504        /* ICMP and ICMPv6 messages are handled internally */
    383505        if (proto == IP_PROTO_ICMP)
    384506                return icmp_recv(dgram);
     507       
     508        if (proto == IP_PROTO_ICMPV6)
     509                return icmpv6_recv(dgram);
    385510
    386511        client = inet_client_find(proto);
     
    400525
    401526        addr = inet_addrobj_find(&packet->dest, iaf_addr);
    402         if (addr != NULL) {
     527        if ((addr != NULL) ||
     528            (inet_naddr_compare_mask(&solicited_node_mask, &packet->dest)) ||
     529            (inet_addr_compare(&multicast_all_nodes, &packet->dest))) {
    403530                /* Destined for one of the local addresses */
    404531
Note: See TracChangeset for help on using the changeset viewer.