Ignore:
File:
1 edited

Legend:

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

    r4a5a18be r3aece36  
    4343#include <stdlib.h>
    4444#include <str.h>
    45 
     45#include <net/socket_codes.h>
    4646#include "addrobj.h"
    4747#include "inetsrv.h"
     
    4949#include "pdu.h"
    5050
    51 static int inet_link_open(service_id_t sid);
    52 static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu);
     51static bool first_link = true;
     52static bool first_link6 = true;
     53
     54static int inet_link_open(service_id_t);
     55static int inet_iplink_recv(iplink_t *, iplink_recv_sdu_t *, uint16_t);
    5356
    5457static iplink_ev_ops_t inet_iplink_ev_ops = {
     
    5962static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
    6063
    61 static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu)
    62 {
     64static addr128_t link_local_node_ip =
     65    {0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0xff, 0xfe, 0, 0, 0};
     66
     67static void inet_link_local_node_ip(addr48_t mac_addr,
     68    addr128_t ip_addr)
     69{
     70        memcpy(ip_addr, link_local_node_ip, 16);
     71       
     72        ip_addr[8] = mac_addr[0] ^ 0x02;
     73        ip_addr[9] = mac_addr[1];
     74        ip_addr[10] = mac_addr[2];
     75        ip_addr[13] = mac_addr[3];
     76        ip_addr[14] = mac_addr[4];
     77        ip_addr[15] = mac_addr[5];
     78}
     79
     80static int inet_iplink_recv(iplink_t *iplink, iplink_recv_sdu_t *sdu, uint16_t af)
     81{
     82        log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
     83       
     84        int rc;
    6385        inet_packet_t packet;
    64         int rc;
    65 
    66         log_msg(LOG_DEFAULT, LVL_DEBUG, "inet_iplink_recv()");
    67         rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
     86       
     87        switch (af) {
     88        case AF_INET:
     89                rc = inet_pdu_decode(sdu->data, sdu->size, &packet);
     90                break;
     91        case AF_INET6:
     92                rc = inet_pdu_decode6(sdu->data, sdu->size, &packet);
     93                break;
     94        default:
     95                log_msg(LOG_DEFAULT, LVL_DEBUG, "invalid address family");
     96                return EINVAL;
     97        }
     98       
    6899        if (rc != EOK) {
    69100                log_msg(LOG_DEFAULT, LVL_DEBUG, "failed decoding PDU");
    70101                return rc;
    71102        }
    72 
     103       
    73104        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet()");
    74105        rc = inet_recv_packet(&packet);
    75106        log_msg(LOG_DEFAULT, LVL_DEBUG, "call inet_recv_packet -> %d", rc);
    76107        free(packet.data);
    77 
     108       
    78109        return rc;
    79110}
     
    147178        if (ilink->svc_name != NULL)
    148179                free(ilink->svc_name);
     180       
    149181        free(ilink);
    150182}
     
    153185{
    154186        inet_link_t *ilink;
    155         iplink_addr_t iaddr;
     187        inet_addr_t iaddr;
    156188        int rc;
    157189
     
    189221                goto error;
    190222        }
     223       
     224        /*
     225         * Get the MAC address of the link. If the link has a MAC
     226         * address, we assume that it supports NDP.
     227         */
     228        rc = iplink_get_mac48(ilink->iplink, &ilink->mac);
     229        ilink->mac_valid = (rc == EOK);
    191230
    192231        log_msg(LOG_DEFAULT, LVL_DEBUG, "Opened IP link '%s'", ilink->svc_name);
    193232        list_append(&ilink->link_list, &inet_link_list);
    194233
    195         inet_addrobj_t *addr;
    196 
    197         static int first = 1;
    198         /* XXX For testing: set static IP address 10.0.2.15/24 */
    199         addr = inet_addrobj_new();
    200         if (first) {
    201                 addr->naddr.ipv4 = (127 << 24) + (0 << 16) + (0 << 8) + 1;
    202                 first = 0;
     234        inet_addrobj_t *addr = NULL;
     235       
     236        if (first_link) {
     237                addr = inet_addrobj_new();
     238               
     239                inet_naddr(&addr->naddr, 127, 0, 0, 1, 24);
     240                first_link = false;
    203241        } else {
    204                 addr->naddr.ipv4 = (10 << 24) + (0 << 16) + (2 << 8) + 15;
    205         }
    206         addr->naddr.bits = 24;
    207         addr->ilink = ilink;
    208         addr->name = str_dup("v4a");
    209         rc = inet_addrobj_add(addr);
    210         if (rc != EOK) {
    211                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
    212                 inet_addrobj_delete(addr);
    213                 /* XXX Roll back */
    214                 return rc;
    215         }
    216 
    217         iaddr.ipv4 = addr->naddr.ipv4;
    218         rc = iplink_addr_add(ilink->iplink, &iaddr);
    219         if (rc != EOK) {
    220                 log_msg(LOG_DEFAULT, LVL_ERROR, "Failed setting IP address on internet link.");
    221                 inet_addrobj_remove(addr);
    222                 inet_addrobj_delete(addr);
    223                 /* XXX Roll back */
    224                 return rc;
    225         }
    226 
     242                /*
     243                 * FIXME
     244                 * Setting static IPv4 address for testing purposes:
     245                 * 10.0.2.15/24
     246                 */
     247                addr = inet_addrobj_new();
     248               
     249                inet_naddr(&addr->naddr, 10, 0, 2, 15, 24);
     250        }
     251       
     252        if (addr != NULL) {
     253                addr->ilink = ilink;
     254                addr->name = str_dup("v4a");
     255               
     256                rc = inet_addrobj_add(addr);
     257                if (rc == EOK) {
     258                        inet_naddr_addr(&addr->naddr, &iaddr);
     259                        rc = iplink_addr_add(ilink->iplink, &iaddr);
     260                        if (rc != EOK) {
     261                                log_msg(LOG_DEFAULT, LVL_ERROR,
     262                                    "Failed setting IPv4 address on internet link.");
     263                                inet_addrobj_remove(addr);
     264                                inet_addrobj_delete(addr);
     265                        }
     266                } else {
     267                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv4 address.");
     268                        inet_addrobj_delete(addr);
     269                }
     270        }
     271       
     272        inet_addrobj_t *addr6 = NULL;
     273       
     274        if (first_link6) {
     275                addr6 = inet_addrobj_new();
     276               
     277                inet_naddr6(&addr6->naddr, 0, 0, 0, 0, 0, 0, 0, 1, 128);
     278                first_link6 = false;
     279        } else if (ilink->mac_valid) {
     280                addr6 = inet_addrobj_new();
     281               
     282                addr128_t link_local;
     283                inet_link_local_node_ip(ilink->mac, link_local);
     284               
     285                inet_naddr_set6(link_local, 64, &addr6->naddr);
     286        }
     287       
     288        if (addr6 != NULL) {
     289                addr6->ilink = ilink;
     290                addr6->name = str_dup("v6a");
     291               
     292                rc = inet_addrobj_add(addr6);
     293                if (rc == EOK) {
     294                        inet_naddr_addr(&addr6->naddr, &iaddr);
     295                        rc = iplink_addr_add(ilink->iplink, &iaddr);
     296                        if (rc != EOK) {
     297                                log_msg(LOG_DEFAULT, LVL_ERROR,
     298                                    "Failed setting IPv6 address on internet link.");
     299                                inet_addrobj_remove(addr6);
     300                                inet_addrobj_delete(addr6);
     301                        }
     302                } else {
     303                        log_msg(LOG_DEFAULT, LVL_ERROR, "Failed adding IPv6 address.");
     304                        inet_addrobj_delete(addr6);
     305                }
     306        }
     307       
    227308        return EOK;
    228 
     309       
    229310error:
    230311        if (ilink->iplink != NULL)
    231312                iplink_close(ilink->iplink);
     313       
    232314        inet_link_delete(ilink);
    233315        return rc;
     
    253335}
    254336
    255 /** Send datagram over Internet link */
    256 int inet_link_send_dgram(inet_link_t *ilink, inet_addr_t *lsrc,
    257     inet_addr_t *ldest, inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
    258 {
    259         iplink_sdu_t sdu;
    260         inet_packet_t packet;
    261         int rc;
    262         size_t offs, roffs;
    263 
     337/** Send IPv4 datagram over Internet link */
     338int inet_link_send_dgram(inet_link_t *ilink, addr32_t lsrc, addr32_t ldest,
     339    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
     340{
     341        addr32_t src_v4;
     342        uint16_t src_af = inet_addr_get(&dgram->src, &src_v4, NULL);
     343        if (src_af != AF_INET)
     344                return EINVAL;
     345       
     346        addr32_t dest_v4;
     347        uint16_t dest_af = inet_addr_get(&dgram->dest, &dest_v4, NULL);
     348        if (dest_af != AF_INET)
     349                return EINVAL;
     350       
    264351        /*
    265352         * Fill packet structure. Fragmentation is performed by
    266353         * inet_pdu_encode().
    267354         */
     355       
     356        iplink_sdu_t sdu;
     357       
     358        sdu.src = lsrc;
     359        sdu.dest = ldest;
     360       
     361        inet_packet_t packet;
     362       
    268363        packet.src = dgram->src;
    269364        packet.dest = dgram->dest;
     
    274369        packet.data = dgram->data;
    275370        packet.size = dgram->size;
    276 
    277         sdu.lsrc.ipv4 = lsrc->ipv4;
    278         sdu.ldest.ipv4 = ldest->ipv4;
    279 
    280         offs = 0;
     371       
     372        size_t offs = 0;
     373        int rc;
     374       
    281375        do {
    282376                /* Encode one fragment */
    283                 rc = inet_pdu_encode(&packet, offs, ilink->def_mtu, &sdu.data,
    284                     &sdu.size, &roffs);
     377               
     378                size_t roffs;
     379                rc = inet_pdu_encode(&packet, src_v4, dest_v4, offs, ilink->def_mtu,
     380                    &sdu.data, &sdu.size, &roffs);
    285381                if (rc != EOK)
    286382                        return rc;
    287 
     383               
    288384                /* Send the PDU */
    289385                rc = iplink_send(ilink->iplink, &sdu);
     386               
    290387                free(sdu.data);
    291 
    292388                offs = roffs;
    293389        } while (offs < packet.size);
    294 
     390       
     391        return rc;
     392}
     393
     394/** Send IPv6 datagram over Internet link */
     395int inet_link_send_dgram6(inet_link_t *ilink, addr48_t ldest,
     396    inet_dgram_t *dgram, uint8_t proto, uint8_t ttl, int df)
     397{
     398        addr128_t src_v6;
     399        uint16_t src_af = inet_addr_get(&dgram->src, NULL, &src_v6);
     400        if (src_af != AF_INET6)
     401                return EINVAL;
     402       
     403        addr128_t dest_v6;
     404        uint16_t dest_af = inet_addr_get(&dgram->dest, NULL, &dest_v6);
     405        if (dest_af != AF_INET6)
     406                return EINVAL;
     407       
     408        iplink_sdu6_t sdu6;
     409        addr48(ldest, sdu6.dest);
     410       
     411        /*
     412         * Fill packet structure. Fragmentation is performed by
     413         * inet_pdu_encode6().
     414         */
     415       
     416        inet_packet_t packet;
     417       
     418        packet.src = dgram->src;
     419        packet.dest = dgram->dest;
     420        packet.tos = dgram->tos;
     421        packet.proto = proto;
     422        packet.ttl = ttl;
     423        packet.df = df;
     424        packet.data = dgram->data;
     425        packet.size = dgram->size;
     426       
     427        int rc;
     428        size_t offs = 0;
     429       
     430        do {
     431                /* Encode one fragment */
     432               
     433                size_t roffs;
     434                rc = inet_pdu_encode6(&packet, src_v6, dest_v6, offs, ilink->def_mtu,
     435                    &sdu6.data, &sdu6.size, &roffs);
     436                if (rc != EOK)
     437                        return rc;
     438               
     439                /* Send the PDU */
     440                rc = iplink_send6(ilink->iplink, &sdu6);
     441               
     442                free(sdu6.data);
     443                offs = roffs;
     444        } while (offs < packet.size);
     445       
    295446        return rc;
    296447}
Note: See TracChangeset for help on using the changeset viewer.