Changeset e767dbf in mainline for uspace/srv/inet/pdu.c


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.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • 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 */
Note: See TracChangeset for help on using the changeset viewer.