Ignore:
File:
1 edited

Legend:

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

    ra1a101d r1c635d6  
    4646#include <stdlib.h>
    4747#include <sys/types.h>
    48 
     48#include <task.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"
     
    5961#define NAME "inetsrv"
    6062
     63static inet_naddr_t solicited_node_mask = {
     64        .version = ip_v6,
     65        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01, 0xff, 0, 0, 0},
     66        .prefix = 104
     67};
     68
     69static inet_addr_t broadcast4_all_hosts = {
     70        .version = ip_v4,
     71        .addr = 0xffffffff
     72};
     73
     74static inet_addr_t multicast_all_nodes = {
     75        .version = ip_v6,
     76        .addr6 = {0xff, 0x02, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0x01}
     77};
     78
    6179static void inet_client_conn(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6280
     
    97115                return EEXIST;
    98116        }
    99        
    100         rc = inet_link_discovery_start();
    101         if (rc != EOK)
    102                 return EEXIST;
    103117       
    104118        return EOK;
     
    154168{
    155169        inet_dir_t dir;
     170        inet_link_t *ilink;
    156171        int rc;
     172
     173        if (dgram->iplink != 0) {
     174                /* XXX TODO - IPv6 */
     175                log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram directly to iplink %zu",
     176                    dgram->iplink);
     177                /* Send packet directly to the specified IP link */
     178                ilink = inet_link_get_by_id(dgram->iplink);
     179                if (ilink == 0)
     180                        return ENOENT;
     181
     182                if (dgram->src.version != ip_v4 ||
     183                        dgram->dest.version != ip_v4)
     184                        return EINVAL;
     185
     186                return inet_link_send_dgram(ilink, dgram->src.addr,
     187                    dgram->dest.addr, dgram, proto, ttl, df);
     188        }
     189
     190        log_msg(LOG_DEFAULT, LVL_DEBUG, "dgram to be routed");
     191
     192        /* Route packet using source/destination addresses */
    157193
    158194        rc = inet_find_dir(&dgram->src, &dgram->dest, dgram->tos, &dir);
     
    182218
    183219        /* Take source address from the address object */
    184         local->ipv4 = dir.aobj->naddr.ipv4;
     220        if (remote->version == ip_v4 && remote->addr == 0xffffffff) {
     221                /* XXX TODO - IPv6 */
     222                local->version = ip_v4;
     223                local->addr = 0;
     224                return EOK;
     225        }
     226
     227        inet_naddr_addr(&dir.aobj->naddr, local);
    185228        return EOK;
    186229}
    187230
    188 static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t callid,
    189     ipc_call_t *call)
    190 {
     231static void inet_get_srcaddr_srv(inet_client_t *client, ipc_callid_t iid,
     232    ipc_call_t *icall)
     233{
     234        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_get_srcaddr_srv()");
     235       
     236        uint8_t tos = IPC_GET_ARG1(*icall);
     237       
     238        ipc_callid_t callid;
     239        size_t size;
     240        if (!async_data_write_receive(&callid, &size)) {
     241                async_answer_0(callid, EREFUSED);
     242                async_answer_0(iid, EREFUSED);
     243                return;
     244        }
     245       
     246        if (size != sizeof(inet_addr_t)) {
     247                async_answer_0(callid, EINVAL);
     248                async_answer_0(iid, EINVAL);
     249                return;
     250        }
     251       
    191252        inet_addr_t remote;
    192         uint8_t tos;
     253        int rc = async_data_write_finalize(callid, &remote, size);
     254        if (rc != EOK) {
     255                async_answer_0(callid, rc);
     256                async_answer_0(iid, rc);
     257        }
     258       
    193259        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 
    202260        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 {
     261        if (rc != EOK) {
     262                async_answer_0(iid, rc);
     263                return;
     264        }
     265       
     266        if (!async_data_read_receive(&callid, &size)) {
     267                async_answer_0(callid, EREFUSED);
     268                async_answer_0(iid, EREFUSED);
     269                return;
     270        }
     271       
     272        if (size != sizeof(inet_addr_t)) {
     273                async_answer_0(callid, EINVAL);
     274                async_answer_0(iid, EINVAL);
     275                return;
     276        }
     277       
     278        rc = async_data_read_finalize(callid, &local, size);
     279        if (rc != EOK) {
     280                async_answer_0(callid, rc);
     281                async_answer_0(iid, rc);
     282                return;
     283        }
     284       
     285        async_answer_0(iid, rc);
     286}
     287
     288static void inet_send_srv(inet_client_t *client, ipc_callid_t iid,
     289    ipc_call_t *icall)
     290{
     291        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_send_srv()");
     292       
    209293        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);
     294       
     295        dgram.iplink = IPC_GET_ARG1(*icall);
     296        dgram.tos = IPC_GET_ARG2(*icall);
     297       
     298        uint8_t ttl = IPC_GET_ARG3(*icall);
     299        int df = IPC_GET_ARG4(*icall);
     300       
     301        ipc_callid_t callid;
     302        size_t size;
     303        if (!async_data_write_receive(&callid, &size)) {
     304                async_answer_0(callid, EREFUSED);
     305                async_answer_0(iid, EREFUSED);
     306                return;
     307        }
     308       
     309        if (size != sizeof(inet_addr_t)) {
     310                async_answer_0(callid, EINVAL);
     311                async_answer_0(iid, EINVAL);
     312                return;
     313        }
     314       
     315        int rc = async_data_write_finalize(callid, &dgram.src, size);
    223316        if (rc != EOK) {
    224317                async_answer_0(callid, rc);
    225                 return;
    226         }
    227 
     318                async_answer_0(iid, rc);
     319        }
     320       
     321        if (!async_data_write_receive(&callid, &size)) {
     322                async_answer_0(callid, EREFUSED);
     323                async_answer_0(iid, EREFUSED);
     324                return;
     325        }
     326       
     327        if (size != sizeof(inet_addr_t)) {
     328                async_answer_0(callid, EINVAL);
     329                async_answer_0(iid, EINVAL);
     330                return;
     331        }
     332       
     333        rc = async_data_write_finalize(callid, &dgram.dest, size);
     334        if (rc != EOK) {
     335                async_answer_0(callid, rc);
     336                async_answer_0(iid, rc);
     337        }
     338       
     339        rc = async_data_write_accept(&dgram.data, false, 0, 0, 0,
     340            &dgram.size);
     341        if (rc != EOK) {
     342                async_answer_0(iid, rc);
     343                return;
     344        }
     345       
    228346        rc = inet_send(client, &dgram, client->protocol, ttl, df);
    229 
     347       
    230348        free(dgram.data);
    231         async_answer_0(callid, rc);
     349        async_answer_0(iid, rc);
    232350}
    233351
     
    337455        fibril_mutex_lock(&client_list_lock);
    338456
    339         list_foreach(client_list, link) {
    340                 inet_client_t *client = list_get_instance(link, inet_client_t,
    341                     client_list);
    342 
     457        list_foreach(client_list, client_list, inet_client_t, client) {
    343458                if (client->protocol == proto) {
    344459                        fibril_mutex_unlock(&client_list_lock);
     
    354469{
    355470        async_exch_t *exch = async_exchange_begin(client->sess);
    356 
     471       
    357472        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) {
     473        aid_t req = async_send_1(exch, INET_EV_RECV, dgram->tos, &answer);
     474       
     475        int rc = async_data_write_start(exch, &dgram->src, sizeof(inet_addr_t));
     476        if (rc != EOK) {
     477                async_exchange_end(exch);
    364478                async_forget(req);
    365479                return rc;
    366480        }
    367 
     481       
     482        rc = async_data_write_start(exch, &dgram->dest, sizeof(inet_addr_t));
     483        if (rc != EOK) {
     484                async_exchange_end(exch);
     485                async_forget(req);
     486                return rc;
     487        }
     488       
     489        rc = async_data_write_start(exch, dgram->data, dgram->size);
     490       
     491        async_exchange_end(exch);
     492       
     493        if (rc != EOK) {
     494                async_forget(req);
     495                return rc;
     496        }
     497       
    368498        sysarg_t retval;
    369499        async_wait_for(req, &retval);
    370         if (retval != EOK)
    371                 return retval;
    372 
    373         return EOK;
     500       
     501        return (int) retval;
    374502}
    375503
     
    380508        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_recv_dgram_local()");
    381509
    382         /* ICMP messages are handled internally */
     510        /* ICMP and ICMPv6 messages are handled internally */
    383511        if (proto == IP_PROTO_ICMP)
    384512                return icmp_recv(dgram);
     513       
     514        if (proto == IP_PROTO_ICMPV6)
     515                return icmpv6_recv(dgram);
    385516
    386517        client = inet_client_find(proto);
     
    400531
    401532        addr = inet_addrobj_find(&packet->dest, iaf_addr);
    402         if (addr != NULL) {
     533        if ((addr != NULL) ||
     534            (inet_naddr_compare_mask(&solicited_node_mask, &packet->dest)) ||
     535            (inet_addr_compare(&multicast_all_nodes, &packet->dest)) ||
     536            (inet_addr_compare(&broadcast4_all_hosts, &packet->dest))) {
    403537                /* Destined for one of the local addresses */
    404538
Note: See TracChangeset for help on using the changeset viewer.