00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00037 #include <errno.h>
00038 #include <mem.h>
00039 #include <unistd.h>
00040 #include <sys/mman.h>
00041
00042 #include <packet_client.h>
00043 #include <packet_remote.h>
00044
00045 #include <net/packet.h>
00046 #include <net/packet_header.h>
00047
00059 int packet_copy_data(packet_t *packet, const void *data, size_t length)
00060 {
00061 if (!packet_is_valid(packet))
00062 return EINVAL;
00063
00064 if (packet->data_start + length >= packet->length)
00065 return ENOMEM;
00066
00067 memcpy((void *) packet + packet->data_start, data, length);
00068 if (packet->data_start + length > packet->data_end)
00069 packet->data_end = packet->data_start + length;
00070
00071 return EOK;
00072 }
00073
00083 void *packet_prefix(packet_t *packet, size_t length)
00084 {
00085 if ((!packet_is_valid(packet)) ||
00086 (packet->data_start - sizeof(packet_t) -
00087 2 * (packet->dest_addr - packet->src_addr) < length)) {
00088 return NULL;
00089 }
00090
00091 packet->data_start -= length;
00092 return (void *) packet + packet->data_start;
00093 }
00094
00104 void *packet_suffix(packet_t *packet, size_t length)
00105 {
00106 if ((!packet_is_valid(packet)) ||
00107 (packet->data_end + length >= packet->length)) {
00108 return NULL;
00109 }
00110
00111 packet->data_end += length;
00112 return (void *) packet + packet->data_end - length;
00113 }
00114
00126 int packet_trim(packet_t *packet, size_t prefix, size_t suffix)
00127 {
00128 if (!packet_is_valid(packet))
00129 return EINVAL;
00130
00131 if (prefix + suffix > PACKET_DATA_LENGTH(packet))
00132 return ENOMEM;
00133
00134 packet->data_start += prefix;
00135 packet->data_end -= suffix;
00136 return EOK;
00137 }
00138
00145 packet_id_t packet_get_id(const packet_t *packet)
00146 {
00147 return packet_is_valid(packet) ? packet->packet_id : 0;
00148 }
00149
00159 int packet_get_addr(const packet_t *packet, uint8_t **src, uint8_t **dest)
00160 {
00161 if (!packet_is_valid(packet))
00162 return EINVAL;
00163 if (!packet->addr_len)
00164 return 0;
00165 if (src)
00166 *src = (void *) packet + packet->src_addr;
00167 if (dest)
00168 *dest = (void *) packet + packet->dest_addr;
00169
00170 return packet->addr_len;
00171 }
00172
00179 size_t packet_get_data_length(const packet_t *packet)
00180 {
00181 if (!packet_is_valid(packet))
00182 return 0;
00183
00184 return PACKET_DATA_LENGTH(packet);
00185 }
00186
00193 void *packet_get_data(const packet_t *packet)
00194 {
00195 if (!packet_is_valid(packet))
00196 return NULL;
00197
00198 return (void *) packet + packet->data_start;
00199 }
00200
00211 int
00212 packet_set_addr(packet_t *packet, const uint8_t *src, const uint8_t *dest,
00213 size_t addr_len)
00214 {
00215 size_t padding;
00216 size_t allocated;
00217
00218 if (!packet_is_valid(packet))
00219 return EINVAL;
00220
00221 allocated = PACKET_MAX_ADDRESS_LENGTH(packet);
00222 if (allocated < addr_len)
00223 return ENOMEM;
00224
00225 padding = allocated - addr_len;
00226 packet->addr_len = addr_len;
00227
00228 if (src) {
00229 memcpy((void *) packet + packet->src_addr, src, addr_len);
00230 if (padding)
00231 bzero((void *) packet + packet->src_addr + addr_len,
00232 padding);
00233 } else {
00234 bzero((void *) packet + packet->src_addr, allocated);
00235 }
00236
00237 if (dest) {
00238 memcpy((void *) packet + packet->dest_addr, dest, addr_len);
00239 if (padding)
00240 bzero((void *) packet + packet->dest_addr + addr_len,
00241 padding);
00242 } else {
00243 bzero((void *) packet + packet->dest_addr, allocated);
00244 }
00245
00246 return EOK;
00247 }
00248
00259 packet_t *packet_get_copy(int phone, packet_t *packet)
00260 {
00261 packet_t *copy;
00262 uint8_t * src = NULL;
00263 uint8_t * dest = NULL;
00264 size_t addrlen;
00265
00266 if (!packet_is_valid(packet))
00267 return NULL;
00268
00269
00270 copy = packet_get_4_remote(phone, PACKET_DATA_LENGTH(packet),
00271 PACKET_MAX_ADDRESS_LENGTH(packet), packet->max_prefix,
00272 PACKET_MIN_SUFFIX(packet));
00273 if (!copy)
00274 return NULL;
00275
00276
00277 addrlen = packet_get_addr(packet, &src, &dest);
00278
00279 if ((packet_copy_data(copy, packet_get_data(packet),
00280 PACKET_DATA_LENGTH(packet)) == EOK) &&
00281
00282 ((addrlen <= 0) ||
00283 (packet_set_addr(copy, src, dest, addrlen) == EOK))) {
00284 copy->order = packet->order;
00285 copy->metric = packet->metric;
00286 return copy;
00287 } else {
00288 pq_release_remote(phone, copy->packet_id);
00289 return NULL;
00290 }
00291 }
00292