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
RevLine 
[21580dd]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
[b69ceea]29/** @addtogroup libnet
30 * @{
[21580dd]31 */
32
33/** @file
[b69ceea]34 * Packet client implementation.
[21580dd]35 */
36
37#include <errno.h>
38#include <mem.h>
39#include <unistd.h>
40#include <sys/mman.h>
[0a866eeb]41#include <packet_client.h>
[b69ceea]42#include <packet_remote.h>
[0a866eeb]43
[c69d327]44#include <net/packet.h>
45#include <net/packet_header.h>
[21580dd]46
[b69ceea]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.
[1bfd3d3]54 * @return EOK on success.
55 * @return EINVAL if the packet is not valid.
56 * @return ENOMEM if there is not enough memory left.
[b69ceea]57 */
[46d4d9f]58int packet_copy_data(packet_t *packet, const void *data, size_t length)
[29fa68b]59{
60 if (!packet_is_valid(packet))
[aadf01e]61 return EINVAL;
[29fa68b]62
63 if (packet->data_start + length >= packet->length)
[aadf01e]64 return ENOMEM;
[29fa68b]65
[aadf01e]66 memcpy((void *) packet + packet->data_start, data, length);
[29fa68b]67 if (packet->data_start + length > packet->data_end)
[21580dd]68 packet->data_end = packet->data_start + length;
[29fa68b]69
[21580dd]70 return EOK;
71}
72
[b69ceea]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.
[1bfd3d3]79 * @return The pointer to the allocated memory.
80 * @return NULL if there is not enough memory left.
[b69ceea]81 */
[46d4d9f]82void *packet_prefix(packet_t *packet, size_t length)
[29fa68b]83{
84 if ((!packet_is_valid(packet)) ||
[46d4d9f]85 (packet->data_start - sizeof(packet_t) -
[29fa68b]86 2 * (packet->dest_addr - packet->src_addr) < length)) {
[aadf01e]87 return NULL;
88 }
[29fa68b]89
[21580dd]90 packet->data_start -= length;
[aadf01e]91 return (void *) packet + packet->data_start;
[21580dd]92}
93
[b69ceea]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.
[1bfd3d3]100 * @return The pointer to the allocated memory.
101 * @return NULL if there is not enough memory left.
[b69ceea]102 */
[46d4d9f]103void *packet_suffix(packet_t *packet, size_t length)
[29fa68b]104{
105 if ((!packet_is_valid(packet)) ||
106 (packet->data_end + length >= packet->length)) {
[aadf01e]107 return NULL;
108 }
[29fa68b]109
[21580dd]110 packet->data_end += length;
[aadf01e]111 return (void *) packet + packet->data_end - length;
[21580dd]112}
113
[b69ceea]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.
[1bfd3d3]121 * @return EOK on success.
122 * @return EINVAL if the packet is not valid.
123 * @return ENOMEM if there is not enough memory left.
[b69ceea]124 */
[46d4d9f]125int packet_trim(packet_t *packet, size_t prefix, size_t suffix)
[29fa68b]126{
127 if (!packet_is_valid(packet))
[aadf01e]128 return EINVAL;
[29fa68b]129
130 if (prefix + suffix > PACKET_DATA_LENGTH(packet))
[aadf01e]131 return ENOMEM;
[29fa68b]132
[21580dd]133 packet->data_start += prefix;
134 packet->data_end -= suffix;
135 return EOK;
136}
137
[b69ceea]138/** Returns the packet identifier.
139 *
140 * @param[in] packet The packet.
[1bfd3d3]141 * @return The packet identifier.
142 * @return Zero if the packet is not valid.
[b69ceea]143 */
[46d4d9f]144packet_id_t packet_get_id(const packet_t *packet)
[29fa68b]145{
[aadf01e]146 return packet_is_valid(packet) ? packet->packet_id : 0;
[21580dd]147}
148
[b69ceea]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.
[1bfd3d3]154 * @return The stored addresses length.
155 * @return Zero if the addresses are not present.
156 * @return EINVAL if the packet is not valid.
[b69ceea]157 */
[46d4d9f]158int packet_get_addr(const packet_t *packet, uint8_t **src, uint8_t **dest)
[29fa68b]159{
160 if (!packet_is_valid(packet))
[aadf01e]161 return EINVAL;
[29fa68b]162 if (!packet->addr_len)
[aadf01e]163 return 0;
[29fa68b]164 if (src)
[aadf01e]165 *src = (void *) packet + packet->src_addr;
[29fa68b]166 if (dest)
[aadf01e]167 *dest = (void *) packet + packet->dest_addr;
[29fa68b]168
[21580dd]169 return packet->addr_len;
170}
171
[b69ceea]172/** Returns the packet content length.
173 *
174 * @param[in] packet The packet.
[1bfd3d3]175 * @return The packet content length in bytes.
176 * @return Zero if the packet is not valid.
[b69ceea]177 */
[46d4d9f]178size_t packet_get_data_length(const packet_t *packet)
[29fa68b]179{
180 if (!packet_is_valid(packet))
[aadf01e]181 return 0;
[29fa68b]182
[aadf01e]183 return PACKET_DATA_LENGTH(packet);
[21580dd]184}
185
[b69ceea]186/** Returns the pointer to the beginning of the packet content.
187 *
188 * @param[in] packet The packet.
[1bfd3d3]189 * @return The pointer to the beginning of the packet content.
190 * @return NULL if the packet is not valid.
[b69ceea]191 */
[46d4d9f]192void *packet_get_data(const packet_t *packet)
[29fa68b]193{
194 if (!packet_is_valid(packet))
[aadf01e]195 return NULL;
[29fa68b]196
[aadf01e]197 return (void *) packet + packet->data_start;
[21580dd]198}
199
[b69ceea]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.
[1bfd3d3]206 * @return EOK on success.
207 * @return EINVAL if the packet is not valid.
208 * @return ENOMEM if there is not enough memory left.
[b69ceea]209 */
[7c8267b]210int
[46d4d9f]211packet_set_addr(packet_t *packet, const uint8_t *src, const uint8_t *dest,
[7c8267b]212 size_t addr_len)
213{
[aadf01e]214 size_t padding;
215 size_t allocated;
[21580dd]216
[7c8267b]217 if (!packet_is_valid(packet))
[aadf01e]218 return EINVAL;
[7c8267b]219
[aadf01e]220 allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
[7c8267b]221 if (allocated < addr_len)
[aadf01e]222 return ENOMEM;
[7c8267b]223
[21580dd]224 padding = allocated - addr_len;
225 packet->addr_len = addr_len;
[7c8267b]226
227 if (src) {
[aadf01e]228 memcpy((void *) packet + packet->src_addr, src, addr_len);
[7c8267b]229 if (padding)
230 bzero((void *) packet + packet->src_addr + addr_len,
231 padding);
232 } else {
[aadf01e]233 bzero((void *) packet + packet->src_addr, allocated);
[21580dd]234 }
[7c8267b]235
236 if (dest) {
[aadf01e]237 memcpy((void *) packet + packet->dest_addr, dest, addr_len);
[7c8267b]238 if (padding)
239 bzero((void *) packet + packet->dest_addr + addr_len,
240 padding);
241 } else {
[aadf01e]242 bzero((void *) packet + packet->dest_addr, allocated);
[21580dd]243 }
[7c8267b]244
[21580dd]245 return EOK;
246}
247
[6b82009]248/** Return the packet copy.
[b69ceea]249 *
[6b82009]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.
[b69ceea]258 *
259 */
[6b82009]260packet_t *packet_get_copy(async_sess_t *sess, packet_t *packet)
[29fa68b]261{
262 if (!packet_is_valid(packet))
[aadf01e]263 return NULL;
[6b82009]264
[28a3e74]265 /* Get a new packet */
[6b82009]266 packet_t *copy = packet_get_4_remote(sess, PACKET_DATA_LENGTH(packet),
[29fa68b]267 PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
268 PACKET_MIN_SUFFIX(packet));
[6b82009]269
[29fa68b]270 if (!copy)
[aadf01e]271 return NULL;
[6b82009]272
[28a3e74]273 /* Get addresses */
[6b82009]274 uint8_t *src = NULL;
275 uint8_t *dest = NULL;
276 size_t addrlen = packet_get_addr(packet, &src, &dest);
277
[28a3e74]278 /* Copy data */
[29fa68b]279 if ((packet_copy_data(copy, packet_get_data(packet),
280 PACKET_DATA_LENGTH(packet)) == EOK) &&
[28a3e74]281 /* Copy addresses if present */
[29fa68b]282 ((addrlen <= 0) ||
283 (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
[21580dd]284 copy->order = packet->order;
285 copy->metric = packet->metric;
286 return copy;
[29fa68b]287 } else {
[6b82009]288 pq_release_remote(sess, copy->packet_id);
[21580dd]289 return NULL;
290 }
291}
292
293/** @}
294 */
Note: See TracBrowser for help on using the repository browser.