Changeset e767dbf in mainline


Ignore:
Timestamp:
2012-02-09T22:57:05Z (12 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
1493811
Parents:
ceba4bed
Message:

Sketch IP PDU encoding and decoding.
Unify IP packet routing.

Location:
uspace/srv/inet
Files:
1 added
7 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/inet/addrobj.c

    rceba4bed re767dbf  
    9090}
    9191
    92 /** Find address object matching address @a addr */
    93 inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr)
     92/** Find address object matching address @a addr.
     93 *
     94 * @param addr  Address
     95 * @oaram find  iaf_net to find network (using mask),
     96 *              iaf_addr to find local address (exact match)
     97 */
     98inet_addrobj_t *inet_addrobj_find(inet_addr_t *addr, inet_addrobj_find_t find)
    9499{
    95100        uint32_t mask;
  • uspace/srv/inet/addrobj.h

    rceba4bed re767dbf  
    4040#include "inet.h"
    4141
     42typedef enum {
     43        /* Find matching network address (using mask) */
     44        iaf_net,
     45        /* Find exact local address (not using mask) */
     46        iaf_addr
     47} inet_addrobj_find_t;
     48
    4249extern inet_addrobj_t *inet_addrobj_new(void);
    4350extern void inet_addrobj_delete(inet_addrobj_t *);
    4451extern void inet_addrobj_add(inet_addrobj_t *);
    4552extern void inet_addrobj_remove(inet_addrobj_t *);
    46 extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *);
     53extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *, inet_addrobj_find_t);
    4754extern int inet_addrobj_send_dgram(inet_addrobj_t *, inet_dgram_t *,
    4855    uint8_t ttl, int df);
  • uspace/srv/inet/inet.c

    rceba4bed re767dbf  
    101101}
    102102
    103 static int inet_send(inet_client_t *client, inet_dgram_t *dgram,
    104     uint8_t ttl, int df)
     103static int inet_route_packet(inet_dgram_t *dgram, uint8_t ttl, int df)
    105104{
    106105        inet_addrobj_t *addr;
    107106
    108         addr = inet_addrobj_find(&dgram->dest);
     107        addr = inet_addrobj_find(&dgram->dest, iaf_net);
    109108        if (addr != NULL) {
    110109                /* Destination is directly accessible */
     
    115114        log_msg(LVL_DEBUG, "inet_send: No route to destination.");
    116115        return ENOENT;
     116}
     117
     118static int inet_send(inet_client_t *client, inet_dgram_t *dgram,
     119    uint8_t ttl, int df)
     120{
     121        return inet_route_packet(dgram, ttl, df);
    117122}
    118123
     
    255260}
    256261
     262int inet_recv_packet(inet_dgram_t *dgram, uint8_t ttl, int df)
     263{
     264        return inet_route_packet(dgram, ttl, df);
     265}
     266
    257267int main(int argc, char *argv[])
    258268{
  • uspace/srv/inet/inet.h

    rceba4bed re767dbf  
    8787
    8888extern int inet_ev_recv(inet_client_t *, inet_dgram_t *);
     89extern int inet_recv_packet(inet_dgram_t *, uint8_t ttl, int df);
    8990
    9091#endif
  • uspace/srv/inet/inet_link.c

    rceba4bed re767dbf  
    5858static FIBRIL_MUTEX_INITIALIZE(inet_discovery_lock);
    5959
    60 static int inet_iplink_recv(iplink_t *ilink, iplink_sdu_t *sdu)
    61 {
     60static int inet_iplink_recv(iplink_t *iplink, iplink_sdu_t *sdu)
     61{
     62        inet_dgram_t dgram;
     63        uint8_t ttl;
     64        int df;
     65        int rc;
     66
    6267        log_msg(LVL_DEBUG, "inet_iplink_recv()");
    63         return EOK;
     68        rc = inet_pdu_decode(sdu->data, sdu->size, &dgram, &ttl, &df);
     69        if (rc != EOK)
     70                return rc;
     71
     72        return inet_recv_packet(&dgram, ttl, df);
    6473}
    6574
     
    211220        sdu.lsrc.ipv4 = lsrc->ipv4;
    212221        sdu.ldest.ipv4 = ldest->ipv4;
    213         rc = inet_pdu_encode(dgram, &sdu.data, &sdu.size);
     222        rc = inet_pdu_encode(dgram, ttl, df, &sdu.data, &sdu.size);
    214223        if (rc != EOK)
    215224                return rc;
  • uspace/srv/inet/pdu.c

    rceba4bed re767dbf  
    3535 */
    3636
     37#include <align.h>
     38#include <bitops.h>
     39#include <byteorder.h>
    3740#include <errno.h>
     41#include <io/log.h>
     42#include <mem.h>
    3843#include <stdlib.h>
    3944
    4045#include "inet.h"
     46#include "inet_std.h"
    4147#include "pdu.h"
    4248
     
    4551 * XXX We should be encoding from packet, not from datagram.
    4652 */
    47 int inet_pdu_encode(inet_dgram_t *dgram, void **rdata, size_t *rsize)
     53int inet_pdu_encode(inet_dgram_t *dgram, uint8_t ttl, int df, void **rdata,
     54    size_t *rsize)
    4855{
    4956        void *data;
    5057        size_t size;
     58        ip_header_t *hdr;
     59        size_t hdr_size;
     60        size_t data_offs;
    5161
    52         size = 20;
     62        hdr_size = sizeof(ip_header_t);
     63        size = hdr_size + dgram->size;
     64        data_offs = ROUND_UP(hdr_size, 4);
     65
    5366        data = calloc(size, 1);
    5467        if (data == NULL)
    5568                return ENOMEM;
    5669
    57         /* XXX Implement */
     70        hdr = (ip_header_t *)data;
     71        hdr->ver_ihl = (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t));
     72        hdr->tos = dgram->tos;
     73        hdr->tot_len = host2uint16_t_be(size);
     74        hdr->id = host2uint16_t_be(42);
     75        hdr->flags_foff = host2uint16_t_be(df ? BIT_V(uint16_t, FF_FLAG_DF) : 0);
     76        hdr->ttl = ttl;
     77        hdr->proto = 0;
     78        hdr->chksum = 0;
     79        hdr->src_addr = host2uint32_t_be(dgram->src.ipv4);
     80        hdr->dest_addr = host2uint32_t_be(dgram->dest.ipv4);
     81
     82        memcpy((uint8_t *)data + data_offs, dgram->data, dgram->size);
    5883
    5984        *rdata = data;
     
    6287}
    6388
     89int inet_pdu_decode(void *data, size_t size, inet_dgram_t *dgram, uint8_t *ttl,
     90    int *df)
     91{
     92        ip_header_t *hdr;
     93        size_t tot_len;
     94        size_t data_offs;
     95        uint8_t version;
     96        uint16_t ident;
     97
     98        log_msg(LVL_DEBUG, "inet_pdu_decode()");
     99
     100        if (size < sizeof(ip_header_t)) {
     101                log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
     102                return EINVAL;
     103        }
     104
     105        hdr = (ip_header_t *)data;
     106
     107        version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, VI_VERSION_l,
     108            hdr->ver_ihl);
     109        if (version != 4) {
     110                log_msg(LVL_DEBUG, "Version (%d) != 4", version);
     111                return EINVAL;
     112        }
     113
     114        tot_len = uint16_t_be2host(hdr->tot_len);
     115        if (tot_len < sizeof(ip_header_t)) {
     116                log_msg(LVL_DEBUG, "Total Length too small (%zu)", tot_len);
     117                return EINVAL;
     118        }
     119
     120        if (tot_len > size) {
     121                log_msg(LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
     122                        tot_len, size);
     123                return EINVAL;
     124        }
     125
     126        ident = uint16_t_be2host(hdr->id);
     127        (void)ident;
     128        /* XXX Flags */
     129        /* XXX Fragment offset */
     130        /* XXX Protocol */
     131        /* XXX Checksum */
     132
     133        dgram->src.ipv4 = uint32_t_be2host(hdr->src_addr);
     134        dgram->dest.ipv4 = uint32_t_be2host(hdr->dest_addr);
     135        dgram->tos = hdr->tos;
     136        *ttl = hdr->ttl;
     137        *df = (uint16_t_be2host(hdr->tos) & BIT_V(uint16_t, FF_FLAG_DF)) ?
     138            1 : 0;
     139
     140        /* XXX IP options */
     141        data_offs = sizeof(uint32_t) * BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h,
     142            VI_IHL_l, hdr->ver_ihl);
     143
     144        dgram->size = tot_len - data_offs;
     145        dgram->data = calloc(dgram->size, 1);
     146        if (dgram->data == NULL) {
     147                log_msg(LVL_WARN, "Out of memory.");
     148                return ENOMEM;
     149        }
     150
     151        memcpy(dgram->data, (uint8_t *)data + data_offs, dgram->size);
     152
     153        return EOK;
     154}
     155
    64156/** @}
    65157 */
  • uspace/srv/inet/pdu.h

    rceba4bed re767dbf  
    4040#include "inet.h"
    4141
    42 extern int inet_pdu_encode(inet_dgram_t *, void **, size_t *);
     42extern int inet_pdu_encode(inet_dgram_t *, uint8_t, int, void **, size_t *);
     43extern int inet_pdu_decode(void *, size_t, inet_dgram_t *, uint8_t *, int *);
    4344
    4445#endif
Note: See TracChangeset for help on using the changeset viewer.