Ignore:
File:
1 edited

Legend:

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

    ra1a101d r7af0cc5  
    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 broadcast4_all_hosts = {
     71        .family = AF_INET,
     72        .addr = 0xffffffff
     73};
     74
     75static inet_addr_t multicast_all_nodes = {
     76        .family = AF_INET6,
     77        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
     78};
     79
    6180static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6281
     
    98117        }
    99118       
    100         rc = inet_link_discovery_start();
    101         if (rc != EOK)
     119        rc = loc_service_register_with_iface(SERVICE_NAME_INETPING6, &sid,
     120            INET_PORT_PING6);
     121        if (rc != EOK) {
     122                log_msg(LOG_DEFAULT, LVL_ERROR, "Failed registering service (%d).", rc);
    102123                return EEXIST;
     124        }
    103125       
    104126        return EOK;
     
    154176{
    155177        inet_dir_t dir;
     178        inet_link_t *ilink;
    156179        int rc;
     180
     181        if (dgram->iplink != 0) {
     182                log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram directly to iplink %zu",
     183                    dgram->iplink);
     184                /* Send packet directly to the specified IP link */
     185                ilink = inet_link_get_by_id(dgram->iplink);
     186                if (ilink == 0)
     187                        return ENOENT;
     188
     189                if (dgram->src.family != AF_INET ||
     190                        dgram->dest.family != AF_INET)
     191                        return EINVAL;
     192
     193                return inet_link_send_dgram(ilink, dgram->src.addr,
     194                    dgram->dest.addr, dgram, proto, ttl, df);
     195        }
     196
     197        log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed");
     198
     199        /* Route packet using source/destination addresses */
    157200
    158201        rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
     
    182225
    183226        /* Take source address from the address object */
    184         local->ipv4 = dir.aobj->naddr.ipv4;
     227        if (remote->family == AF_INET && remote->addr == 0xffffffff) {
     228                local->family = AF_INET;
     229                local->addr = 0;
     230                return EOK;
     231        }
     232        inet_naddr_addr(&dir.aobj->naddr, local);
    185233        return EOK;
    186234}
    187235
    188 static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
    189     ipc_call_t *call)
    190 {
     236static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t iid,
     237    ipc_call_t *icall)
     238{
     239        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
     240       
     241        uint8_t tos = IPC_GET_ARG1(*icall);
     242       
     243        ipc_callid_t callid;
     244        size_t size;
     245        if (!async_data_write_receive(&callid, &size)) {
     246                async_answer_0(callid, EREFUSED);
     247                async_answer_0(iid, EREFUSED);
     248                return;
     249        }
     250       
     251        if (size != sizeof(inet_addr_t)) {
     252                async_answer_0(callid, EINVAL);
     253                async_answer_0(iid, EINVAL);
     254                return;
     255        }
     256       
    191257        inet_addr_t remote;
    192         uint8_t tos;
     258        int rc = async_data_write_finalize(callid, &remote, size);
     259        if (rc != EOK) {
     260                async_answer_0(callid, rc);
     261                async_answer_0(iid, rc);
     262        }
     263       
    193264        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 
    202265        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 {
     266        if (rc != EOK) {
     267                async_answer_0(iid, rc);
     268                return;
     269        }
     270       
     271        if (!async_data_read_receive(&callid, &size)) {
     272                async_answer_0(callid, EREFUSED);
     273                async_answer_0(iid, EREFUSED);
     274                return;
     275        }
     276       
     277        if (size != sizeof(inet_addr_t)) {
     278                async_answer_0(callid, EINVAL);
     279                async_answer_0(iid, EINVAL);
     280                return;
     281        }
     282       
     283        rc = async_data_read_finalize(callid, &local, size);
     284        if (rc != EOK) {
     285                async_answer_0(callid, rc);
     286                async_answer_0(iid, rc);
     287                return;
     288        }
     289       
     290        async_answer_0(iid, rc);
     291}
     292
     293static void inet_send_srv(inet_client_t *client, ipc_callid_t iid,
     294    ipc_call_t *icall)
     295{
     296        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
     297       
    209298        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);
     299       
     300        dgram.iplink = IPC_GET_ARG1(*icall);
     301        dgram.tos = IPC_GET_ARG2(*icall);
     302       
     303        uint8_t ttl = IPC_GET_ARG3(*icall);
     304        int df = IPC_GET_ARG3(*icall);
     305       
     306        ipc_callid_t callid;
     307        size_t size;
     308        if (!async_data_write_receive(&callid, &size)) {
     309                async_answer_0(callid, EREFUSED);
     310                async_answer_0(iid, EREFUSED);
     311                return;
     312        }
     313       
     314        if (size != sizeof(inet_addr_t)) {
     315                async_answer_0(callid, EINVAL);
     316                async_answer_0(iid, EINVAL);
     317                return;
     318        }
     319       
     320        int rc = async_data_write_finalize(callid, &dgram.src, size);
    223321        if (rc != EOK) {
    224322                async_answer_0(callid, rc);
    225                 return;
    226         }
    227 
     323                async_answer_0(iid, rc);
     324        }
     325       
     326        if (!async_data_write_receive(&callid, &size)) {
     327                async_answer_0(callid, EREFUSED);
     328                async_answer_0(iid, EREFUSED);
     329                return;
     330        }
     331       
     332        if (size != sizeof(inet_addr_t)) {
     333                async_answer_0(callid, EINVAL);
     334                async_answer_0(iid, EINVAL);
     335                return;
     336        }
     337       
     338        rc = async_data_write_finalize(callid, &dgram.dest, size);
     339        if (rc != EOK) {
     340                async_answer_0(callid, rc);
     341                async_answer_0(iid, rc);
     342        }
     343       
     344        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0,
     345            &dgram.size);
     346        if (rc != EOK) {
     347                async_answer_0(iid, rc);
     348                return;
     349        }
     350       
    228351        rc = inet_send(client, &dgram, client->protocol, ttl, df);
    229 
     352       
    230353        free(dgram.data);
    231         async_answer_0(callid, rc);
     354        async_answer_0(iid, rc);
    232355}
    233356
     
    327450                inetping_conn(iid, icall, arg);
    328451                break;
     452        case INET_PORT_PING6:
     453                inetping6_conn(iid, icall, arg);
     454                break;
    329455        default:
    330456                async_answer_0(iid, ENOTSUP);
     
    337463        fibril_mutex_lock(&client_list_lock);
    338464
    339         list_foreach(client_list, link) {
    340                 inet_client_t *client = list_get_instance(link, inet_client_t,
    341                     client_list);
    342 
     465        list_foreach(client_list, client_list, inet_client_t, client) {
    343466                if (client->protocol == proto) {
    344467                        fibril_mutex_unlock(&client_list_lock);
     
    354477{
    355478        async_exch_t *exch = async_exchange_begin(client->sess);
    356 
     479       
    357480        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) {
     481        aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
     482       
     483        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
     484        if (rc != EOK) {
     485                async_exchange_end(exch);
    364486                async_forget(req);
    365487                return rc;
    366488        }
    367 
     489       
     490        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
     491        if (rc != EOK) {
     492                async_exchange_end(exch);
     493                async_forget(req);
     494                return rc;
     495        }
     496       
     497        rc = async_data_write_start(exch, dgram->data, dgram->size);
     498       
     499        async_exchange_end(exch);
     500       
     501        if (rc != EOK) {
     502                async_forget(req);
     503                return rc;
     504        }
     505       
    368506        sysarg_t retval;
    369507        async_wait_for(req, &retval);
    370         if (retval != EOK)
    371                 return retval;
    372 
    373         return EOK;
     508       
     509        return (int) retval;
    374510}
    375511
     
    380516        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_recv_dgram_local()");
    381517
    382         /* ICMP messages are handled internally */
     518        /* ICMP and ICMPv6 messages are handled internally */
    383519        if (proto == IP_PROTO_ICMP)
    384520                return icmp_recv(dgram);
     521       
     522        if (proto == IP_PROTO_ICMPV6)
     523                return icmpv6_recv(dgram);
    385524
    386525        client = inet_client_find(proto);
     
    400539
    401540        addr = inet_addrobj_find(&packet->dest, iaf_addr);
    402         if (addr != NULL) {
     541        if ((addr != NULL) ||
     542            (inet_naddr_compare_mask(&solicited_node_mask, &packet->dest)) ||
     543            (inet_addr_compare(&multicast_all_nodes, &packet->dest)) ||
     544            (inet_addr_compare(&broadcast4_all_hosts, &packet->dest))) {
    403545                /* Destined for one of the local addresses */
    404546
Note: See TracChangeset for help on using the changeset viewer.