source: mainline/uspace/srv/inet/pdu.c@ bd8bfc5a

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since bd8bfc5a was e767dbf, checked in by Jiri Svoboda <jiri@…>, 14 years ago

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

  • Property mode set to 100644
File size: 4.2 KB
Line 
1/*
2 * Copyright (c) 2012 Jiri Svoboda
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 *
9 * - Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * - Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 * - The name of the author may not be used to endorse or promote products
15 * derived from this software without specific prior written permission.
16 *
17 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27 */
28
29/** @addtogroup inet
30 * @{
31 */
32/**
33 * @file
34 * @brief
35 */
36
37#include <align.h>
38#include <bitops.h>
39#include <byteorder.h>
40#include <errno.h>
41#include <io/log.h>
42#include <mem.h>
43#include <stdlib.h>
44
45#include "inet.h"
46#include "inet_std.h"
47#include "pdu.h"
48
49/** Encode Internet PDU.
50 *
51 * XXX We should be encoding from packet, not from datagram.
52 */
53int inet_pdu_encode(inet_dgram_t *dgram, uint8_t ttl, int df, void **rdata,
54 size_t *rsize)
55{
56 void *data;
57 size_t size;
58 ip_header_t *hdr;
59 size_t hdr_size;
60 size_t data_offs;
61
62 hdr_size = sizeof(ip_header_t);
63 size = hdr_size + dgram->size;
64 data_offs = ROUND_UP(hdr_size, 4);
65
66 data = calloc(size, 1);
67 if (data == NULL)
68 return ENOMEM;
69
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);
83
84 *rdata = data;
85 *rsize = size;
86 return EOK;
87}
88
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
156/** @}
157 */
Note: See TracBrowser for help on using the repository browser.