source: mainline/uspace/lib/net/generic/packet_client.c@ 28a3e74

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

Fix comment style.

  • Property mode set to 100644
File size: 8.2 KB
Line 
1/*
2 * Copyright (c) 2009 Lukas Mejdrech
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 libnet
30 * @{
31 */
32
33/** @file
34 * Packet client implementation.
35 */
36
37#include <errno.h>
38#include <mem.h>
39#include <unistd.h>
40#include <sys/mman.h>
41
42#include <packet_client.h>
43#include <packet_remote.h>
44
45#include <net/packet.h>
46#include <net/packet_header.h>
47
48/** Copies the specified data to the beginning of the actual packet content.
49 *
50 * Pushes the content end if needed.
51 *
52 * @param[in] packet The packet to be filled.
53 * @param[in] data The data to be copied.
54 * @param[in] length The length of the copied data.
55 * @return EOK on success.
56 * @return EINVAL if the packet is not valid.
57 * @return ENOMEM if there is not enough memory left.
58 */
59int packet_copy_data(packet_t *packet, const void *data, size_t length)
60{
61 if (!packet_is_valid(packet))
62 return EINVAL;
63
64 if (packet->data_start + length >= packet->length)
65 return ENOMEM;
66
67 memcpy((void *) packet + packet->data_start, data, length);
68 if (packet->data_start + length > packet->data_end)
69 packet->data_end = packet->data_start + length;
70
71 return EOK;
72}
73
74/** Allocates the specified space right before the actual packet content and
75 * returns its pointer.
76 *
77 * @param[in] packet The packet to be used.
78 * @param[in] length The space length to be allocated at the beginning of the
79 * packet content.
80 * @return The pointer to the allocated memory.
81 * @return NULL if there is not enough memory left.
82 */
83void *packet_prefix(packet_t *packet, size_t length)
84{
85 if ((!packet_is_valid(packet)) ||
86 (packet->data_start - sizeof(packet_t) -
87 2 * (packet->dest_addr - packet->src_addr) < length)) {
88 return NULL;
89 }
90
91 packet->data_start -= length;
92 return (void *) packet + packet->data_start;
93}
94
95/** Allocates the specified space right after the actual packet content and
96 * returns its pointer.
97 *
98 * @param[in] packet The packet to be used.
99 * @param[in] length The space length to be allocated at the end of the
100 * packet content.
101 * @return The pointer to the allocated memory.
102 * @return NULL if there is not enough memory left.
103 */
104void *packet_suffix(packet_t *packet, size_t length)
105{
106 if ((!packet_is_valid(packet)) ||
107 (packet->data_end + length >= packet->length)) {
108 return NULL;
109 }
110
111 packet->data_end += length;
112 return (void *) packet + packet->data_end - length;
113}
114
115/** Trims the actual packet content by the specified prefix and suffix lengths.
116 *
117 * @param[in] packet The packet to be trimmed.
118 * @param[in] prefix The prefix length to be removed from the beginning of
119 * the packet content.
120 * @param[in] suffix The suffix length to be removed from the end of the
121 * packet content.
122 * @return EOK on success.
123 * @return EINVAL if the packet is not valid.
124 * @return ENOMEM if there is not enough memory left.
125 */
126int packet_trim(packet_t *packet, size_t prefix, size_t suffix)
127{
128 if (!packet_is_valid(packet))
129 return EINVAL;
130
131 if (prefix + suffix > PACKET_DATA_LENGTH(packet))
132 return ENOMEM;
133
134 packet->data_start += prefix;
135 packet->data_end -= suffix;
136 return EOK;
137}
138
139/** Returns the packet identifier.
140 *
141 * @param[in] packet The packet.
142 * @return The packet identifier.
143 * @return Zero if the packet is not valid.
144 */
145packet_id_t packet_get_id(const packet_t *packet)
146{
147 return packet_is_valid(packet) ? packet->packet_id : 0;
148}
149
150/** Returns the stored packet addresses and their length.
151 *
152 * @param[in] packet The packet.
153 * @param[out] src The source address. May be NULL if not desired.
154 * @param[out] dest The destination address. May be NULL if not desired.
155 * @return The stored addresses length.
156 * @return Zero if the addresses are not present.
157 * @return EINVAL if the packet is not valid.
158 */
159int packet_get_addr(const packet_t *packet, uint8_t **src, uint8_t **dest)
160{
161 if (!packet_is_valid(packet))
162 return EINVAL;
163 if (!packet->addr_len)
164 return 0;
165 if (src)
166 *src = (void *) packet + packet->src_addr;
167 if (dest)
168 *dest = (void *) packet + packet->dest_addr;
169
170 return packet->addr_len;
171}
172
173/** Returns the packet content length.
174 *
175 * @param[in] packet The packet.
176 * @return The packet content length in bytes.
177 * @return Zero if the packet is not valid.
178 */
179size_t packet_get_data_length(const packet_t *packet)
180{
181 if (!packet_is_valid(packet))
182 return 0;
183
184 return PACKET_DATA_LENGTH(packet);
185}
186
187/** Returns the pointer to the beginning of the packet content.
188 *
189 * @param[in] packet The packet.
190 * @return The pointer to the beginning of the packet content.
191 * @return NULL if the packet is not valid.
192 */
193void *packet_get_data(const packet_t *packet)
194{
195 if (!packet_is_valid(packet))
196 return NULL;
197
198 return (void *) packet + packet->data_start;
199}
200
201/** Sets the packet addresses.
202 *
203 * @param[in] packet The packet.
204 * @param[in] src The new source address. May be NULL.
205 * @param[in] dest The new destination address. May be NULL.
206 * @param[in] addr_len The addresses length.
207 * @return EOK on success.
208 * @return EINVAL if the packet is not valid.
209 * @return ENOMEM if there is not enough memory left.
210 */
211int
212packet_set_addr(packet_t *packet, const uint8_t *src, const uint8_t *dest,
213 size_t addr_len)
214{
215 size_t padding;
216 size_t allocated;
217
218 if (!packet_is_valid(packet))
219 return EINVAL;
220
221 allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
222 if (allocated < addr_len)
223 return ENOMEM;
224
225 padding = allocated - addr_len;
226 packet->addr_len = addr_len;
227
228 if (src) {
229 memcpy((void *) packet + packet->src_addr, src, addr_len);
230 if (padding)
231 bzero((void *) packet + packet->src_addr + addr_len,
232 padding);
233 } else {
234 bzero((void *) packet + packet->src_addr, allocated);
235 }
236
237 if (dest) {
238 memcpy((void *) packet + packet->dest_addr, dest, addr_len);
239 if (padding)
240 bzero((void *) packet + packet->dest_addr + addr_len,
241 padding);
242 } else {
243 bzero((void *) packet + packet->dest_addr, allocated);
244 }
245
246 return EOK;
247}
248
249/** Returns the packet copy.
250 *
251 * Copies the addresses, data, order and metric values.
252 * Does not copy the queue placement.
253 *
254 * @param[in] phone The packet server module phone.
255 * @param[in] packet The original packet.
256 * @return The packet copy.
257 * @return NULL on error.
258 */
259packet_t *packet_get_copy(int phone, packet_t *packet)
260{
261 packet_t *copy;
262 uint8_t * src = NULL;
263 uint8_t * dest = NULL;
264 size_t addrlen;
265
266 if (!packet_is_valid(packet))
267 return NULL;
268
269 /* Get a new packet */
270 copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
271 PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
272 PACKET_MIN_SUFFIX(packet));
273 if (!copy)
274 return NULL;
275
276 /* Get addresses */
277 addrlen = packet_get_addr(packet, &src, &dest);
278 /* Copy data */
279 if ((packet_copy_data(copy, packet_get_data(packet),
280 PACKET_DATA_LENGTH(packet)) == EOK) &&
281 /* Copy addresses if present */
282 ((addrlen <= 0) ||
283 (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
284 copy->order = packet->order;
285 copy->metric = packet->metric;
286 return copy;
287 } else {
288 pq_release_remote(phone, copy->packet_id);
289 return NULL;
290 }
291}
292
293/** @}
294 */
Note: See TracBrowser for help on using the repository browser.