source: mainline/uspace/srv/inet/pdu.c@ 2ff150e

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

Correct handling of IP protocol field.

  • Property mode set to 100644
File size: 4.1 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 */
51int inet_pdu_encode(inet_packet_t *packet, void **rdata, size_t *rsize)
52{
53 void *data;
54 size_t size;
55 ip_header_t *hdr;
56 size_t hdr_size;
57 size_t data_offs;
58
59 hdr_size = sizeof(ip_header_t);
60 size = hdr_size + packet->size;
61 data_offs = ROUND_UP(hdr_size, 4);
62
63 data = calloc(size, 1);
64 if (data == NULL)
65 return ENOMEM;
66
67 hdr = (ip_header_t *)data;
68 hdr->ver_ihl = (4 << VI_VERSION_l) | (hdr_size / sizeof(uint32_t));
69 hdr->tos = packet->tos;
70 hdr->tot_len = host2uint16_t_be(size);
71 hdr->id = host2uint16_t_be(42);
72 hdr->flags_foff = host2uint16_t_be(packet->df ?
73 BIT_V(uint16_t, FF_FLAG_DF) : 0);
74 hdr->ttl = packet->ttl;
75 hdr->proto = packet->proto;
76 hdr->chksum = 0;
77 hdr->src_addr = host2uint32_t_be(packet->src.ipv4);
78 hdr->dest_addr = host2uint32_t_be(packet->dest.ipv4);
79
80 memcpy((uint8_t *)data + data_offs, packet->data, packet->size);
81
82 *rdata = data;
83 *rsize = size;
84 return EOK;
85}
86
87int inet_pdu_decode(void *data, size_t size, inet_packet_t *packet)
88{
89 ip_header_t *hdr;
90 size_t tot_len;
91 size_t data_offs;
92 uint8_t version;
93 uint16_t ident;
94
95 log_msg(LVL_DEBUG, "inet_pdu_decode()");
96
97 if (size < sizeof(ip_header_t)) {
98 log_msg(LVL_DEBUG, "PDU too short (%zu)", size);
99 return EINVAL;
100 }
101
102 hdr = (ip_header_t *)data;
103
104 version = BIT_RANGE_EXTRACT(uint8_t, VI_VERSION_h, VI_VERSION_l,
105 hdr->ver_ihl);
106 if (version != 4) {
107 log_msg(LVL_DEBUG, "Version (%d) != 4", version);
108 return EINVAL;
109 }
110
111 tot_len = uint16_t_be2host(hdr->tot_len);
112 if (tot_len < sizeof(ip_header_t)) {
113 log_msg(LVL_DEBUG, "Total Length too small (%zu)", tot_len);
114 return EINVAL;
115 }
116
117 if (tot_len > size) {
118 log_msg(LVL_DEBUG, "Total Length = %zu > PDU size = %zu",
119 tot_len, size);
120 return EINVAL;
121 }
122
123 ident = uint16_t_be2host(hdr->id);
124 (void)ident;
125 /* XXX Flags */
126 /* XXX Fragment offset */
127 /* XXX Checksum */
128
129 packet->src.ipv4 = uint32_t_be2host(hdr->src_addr);
130 packet->dest.ipv4 = uint32_t_be2host(hdr->dest_addr);
131 packet->tos = hdr->tos;
132 packet->proto = hdr->proto;
133 packet->ttl = hdr->ttl;
134 packet->df = (uint16_t_be2host(hdr->tos) & BIT_V(uint16_t, FF_FLAG_DF))
135 ? 1 : 0;
136
137 /* XXX IP options */
138 data_offs = sizeof(uint32_t) * BIT_RANGE_EXTRACT(uint8_t, VI_IHL_h,
139 VI_IHL_l, hdr->ver_ihl);
140
141 packet->size = tot_len - data_offs;
142 packet->data = calloc(packet->size, 1);
143 if (packet->data == NULL) {
144 log_msg(LVL_WARN, "Out of memory.");
145 return ENOMEM;
146 }
147
148 memcpy(packet->data, (uint8_t *)data + data_offs, packet->size);
149
150 return EOK;
151}
152
153/** @}
154 */
Note: See TracBrowser for help on using the repository browser.