Ignore:
File:
1 edited

Legend:

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

    r4a5a18be r9749e47  
    4646#include <stdlib.h>
    4747#include <sys/types.h>
    48 
    4948#include "addrobj.h"
    5049#include "icmp.h"
    5150#include "icmp_std.h"
     51#include "icmpv6.h"
     52#include "icmpv6_std.h"
    5253#include "inetsrv.h"
    5354#include "inetcfg.h"
     
    5960#define NAME "inetsrv"
    6061
     62static inet_naddr_t solicited_node_mask = {
     63        .version = ip_v6,
     64        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0},
     65        .prefix = 104
     66};
     67
     68static inet_addr_t broadcast4_all_hosts = {
     69        .version = ip_v4,
     70        .addr = 0xffffffff
     71};
     72
     73static inet_addr_t multicast_all_nodes = {
     74        .version = ip_v6,
     75        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
     76};
     77
    6178static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6279
     
    97114                return EEXIST;
    98115        }
    99        
    100         inet_sroute_t *sroute = inet_sroute_new();
    101         if (sroute == NULL) {
    102                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed creating default route (%d).", rc);
    103                 return ENOMEM;
    104         }
    105 
    106         sroute->dest.ipv4 = 0;
    107         sroute->dest.bits = 0;
    108         sroute->router.ipv4 = (10 << 24) | (0 << 16) | (2 << 8) | 2;
    109         sroute->name = str_dup("default");
    110         inet_sroute_add(sroute);
    111 
    112         rc = inet_link_discovery_start();
    113         if (rc != EOK)
    114                 return EEXIST;
    115116       
    116117        return EOK;
     
    166167{
    167168        inet_dir_t dir;
     169        inet_link_t *ilink;
    168170        int rc;
     171
     172        if (dgram->iplink != 0) {
     173                /* XXX TODO - IPv6 */
     174                log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram directly to iplink %zu",
     175                    dgram->iplink);
     176                /* Send packet directly to the specified IP link */
     177                ilink = inet_link_get_by_id(dgram->iplink);
     178                if (ilink == 0)
     179                        return ENOENT;
     180
     181                if (dgram->src.version != ip_v4 ||
     182                        dgram->dest.version != ip_v4)
     183                        return EINVAL;
     184
     185                return inet_link_send_dgram(ilink, dgram->src.addr,
     186                    dgram->dest.addr, dgram, proto, ttl, df);
     187        }
     188
     189        log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed");
     190
     191        /* Route packet using source/destination addresses */
    169192
    170193        rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
     
    194217
    195218        /* Take source address from the address object */
    196         local->ipv4 = dir.aobj->naddr.ipv4;
     219        if (remote->version == ip_v4 && remote->addr == 0xffffffff) {
     220                /* XXX TODO - IPv6 */
     221                local->version = ip_v4;
     222                local->addr = 0;
     223                return EOK;
     224        }
     225
     226        inet_naddr_addr(&dir.aobj->naddr, local);
    197227        return EOK;
    198228}
    199229
    200 static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
    201     ipc_call_t *call)
    202 {
     230static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t iid,
     231    ipc_call_t *icall)
     232{
     233        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
     234       
     235        uint8_t tos = IPC_GET_ARG1(*icall);
     236       
     237        ipc_callid_t callid;
     238        size_t size;
     239        if (!async_data_write_receive(&callid, &size)) {
     240                async_answer_0(callid, EREFUSED);
     241                async_answer_0(iid, EREFUSED);
     242                return;
     243        }
     244       
     245        if (size != sizeof(inet_addr_t)) {
     246                async_answer_0(callid, EINVAL);
     247                async_answer_0(iid, EINVAL);
     248                return;
     249        }
     250       
    203251        inet_addr_t remote;
    204         uint8_t tos;
     252        int rc = async_data_write_finalize(callid, &remote, size);
     253        if (rc != EOK) {
     254                async_answer_0(callid, rc);
     255                async_answer_0(iid, rc);
     256        }
     257       
    205258        inet_addr_t local;
    206         int rc;
    207 
    208         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
    209 
    210         remote.ipv4 = IPC_GET_ARG1(*call);
    211         tos = IPC_GET_ARG2(*call);
    212         local.ipv4 = 0;
    213 
    214259        rc = inet_get_srcaddr(&remote, tos, &local);
    215         async_answer_1(callid, rc, local.ipv4);
    216 }
    217 
    218 static void inet_send_srv(inet_client_t *client, ipc_callid_t callid,
    219     ipc_call_t *call)
    220 {
     260        if (rc != EOK) {
     261                async_answer_0(iid, rc);
     262                return;
     263        }
     264       
     265        if (!async_data_read_receive(&callid, &size)) {
     266                async_answer_0(callid, EREFUSED);
     267                async_answer_0(iid, EREFUSED);
     268                return;
     269        }
     270       
     271        if (size != sizeof(inet_addr_t)) {
     272                async_answer_0(callid, EINVAL);
     273                async_answer_0(iid, EINVAL);
     274                return;
     275        }
     276       
     277        rc = async_data_read_finalize(callid, &local, size);
     278        if (rc != EOK) {
     279                async_answer_0(callid, rc);
     280                async_answer_0(iid, rc);
     281                return;
     282        }
     283       
     284        async_answer_0(iid, rc);
     285}
     286
     287static void inet_send_srv(inet_client_t *client, ipc_callid_t iid,
     288    ipc_call_t *icall)
     289{
     290        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
     291       
    221292        inet_dgram_t dgram;
    222         uint8_t ttl;
    223         int df;
    224         int rc;
    225 
    226         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
    227 
    228         dgram.src.ipv4 = IPC_GET_ARG1(*call);
    229         dgram.dest.ipv4 = IPC_GET_ARG2(*call);
    230         dgram.tos = IPC_GET_ARG3(*call);
    231         ttl = IPC_GET_ARG4(*call);
    232         df = IPC_GET_ARG5(*call);
    233 
    234         rc = async_data_write_accept(&dgram.data, false, 0, 0, 0, &dgram.size);
     293       
     294        dgram.iplink = IPC_GET_ARG1(*icall);
     295        dgram.tos = IPC_GET_ARG2(*icall);
     296       
     297        uint8_t ttl = IPC_GET_ARG3(*icall);
     298        int df = IPC_GET_ARG3(*icall);
     299       
     300        ipc_callid_t callid;
     301        size_t size;
     302        if (!async_data_write_receive(&callid, &size)) {
     303                async_answer_0(callid, EREFUSED);
     304                async_answer_0(iid, EREFUSED);
     305                return;
     306        }
     307       
     308        if (size != sizeof(inet_addr_t)) {
     309                async_answer_0(callid, EINVAL);
     310                async_answer_0(iid, EINVAL);
     311                return;
     312        }
     313       
     314        int rc = async_data_write_finalize(callid, &dgram.src, size);
    235315        if (rc != EOK) {
    236316                async_answer_0(callid, rc);
    237                 return;
    238         }
    239 
     317                async_answer_0(iid, rc);
     318        }
     319       
     320        if (!async_data_write_receive(&callid, &size)) {
     321                async_answer_0(callid, EREFUSED);
     322                async_answer_0(iid, EREFUSED);
     323                return;
     324        }
     325       
     326        if (size != sizeof(inet_addr_t)) {
     327                async_answer_0(callid, EINVAL);
     328                async_answer_0(iid, EINVAL);
     329                return;
     330        }
     331       
     332        rc = async_data_write_finalize(callid, &dgram.dest, size);
     333        if (rc != EOK) {
     334                async_answer_0(callid, rc);
     335                async_answer_0(iid, rc);
     336        }
     337       
     338        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0,
     339            &dgram.size);
     340        if (rc != EOK) {
     341                async_answer_0(iid, rc);
     342                return;
     343        }
     344       
    240345        rc = inet_send(client, &dgram, client->protocol, ttl, df);
    241 
     346       
    242347        free(dgram.data);
    243         async_answer_0(callid, rc);
     348        async_answer_0(iid, rc);
    244349}
    245350
     
    349454        fibril_mutex_lock(&client_list_lock);
    350455
    351         list_foreach(client_list, link) {
    352                 inet_client_t *client = list_get_instance(link, inet_client_t,
    353                     client_list);
    354 
     456        list_foreach(client_list, client_list, inet_client_t, client) {
    355457                if (client->protocol == proto) {
    356458                        fibril_mutex_unlock(&client_list_lock);
     
    366468{
    367469        async_exch_t *exch = async_exchange_begin(client->sess);
    368 
     470       
    369471        ipc_call_t answer;
    370         aid_t req = async_send_3(exch, INET_EV_RECV, dgram->src.ipv4,
    371             dgram->dest.ipv4, dgram->tos, &answer);
    372         int rc = async_data_write_start(exch, dgram->data, dgram->size);
    373         async_exchange_end(exch);
    374 
    375         if (rc != EOK) {
     472        aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
     473       
     474        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
     475        if (rc != EOK) {
     476                async_exchange_end(exch);
    376477                async_forget(req);
    377478                return rc;
    378479        }
    379 
     480       
     481        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
     482        if (rc != EOK) {
     483                async_exchange_end(exch);
     484                async_forget(req);
     485                return rc;
     486        }
     487       
     488        rc = async_data_write_start(exch, dgram->data, dgram->size);
     489       
     490        async_exchange_end(exch);
     491       
     492        if (rc != EOK) {
     493                async_forget(req);
     494                return rc;
     495        }
     496       
    380497        sysarg_t retval;
    381498        async_wait_for(req, &retval);
    382         if (retval != EOK)
    383                 return retval;
    384 
    385         return EOK;
     499       
     500        return (int) retval;
    386501}
    387502
     
    392507        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_recv_dgram_local()");
    393508
    394         /* ICMP messages are handled internally */
     509        /* ICMP and ICMPv6 messages are handled internally */
    395510        if (proto == IP_PROTO_ICMP)
    396511                return icmp_recv(dgram);
     512       
     513        if (proto == IP_PROTO_ICMPV6)
     514                return icmpv6_recv(dgram);
    397515
    398516        client = inet_client_find(proto);
     
    412530
    413531        addr = inet_addrobj_find(&packet->dest, iaf_addr);
    414         if (addr != NULL) {
     532        if ((addr != NULL) ||
     533            (inet_naddr_compare_mask(&solicited_node_mask, &packet->dest)) ||
     534            (inet_addr_compare(&multicast_all_nodes, &packet->dest)) ||
     535            (inet_addr_compare(&broadcast4_all_hosts, &packet->dest))) {
    415536                /* Destined for one of the local addresses */
    416537
Note: See TracChangeset for help on using the changeset viewer.