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

lfn serial ticket/834-toolchain-update topic/msim-upgrade topic/simplify-dev-export
Last change on this file since c8751452 was c8751452, checked in by Martin Decky <martin@…>, 14 years ago

cstyle (no change in functionality)

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