Changeset efedee77 in mainline for uspace/lib/net/tl/tl_common.c
- Timestamp:
- 2010-11-02T22:38:46Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- af894a21
- Parents:
- aab02fb (diff), e06ef614 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/tl/tl_common.c
raab02fb refedee77 27 27 */ 28 28 29 /** @addtogroup net_tl30 * 29 /** @addtogroup libnet 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Transport layer common functions implementation. 35 * @see tl_common.h 36 */ 34 * Transport layer common functions implementation. 35 * @see tl_common.h 36 */ 37 38 #include <tl_common.h> 39 #include <packet_client.h> 40 #include <packet_remote.h> 41 #include <icmp_interface.h> 42 #include <ip_remote.h> 43 #include <ip_interface.h> 44 #include <tl_interface.h> 45 46 #include <net/socket_codes.h> 47 #include <net/in.h> 48 #include <net/in6.h> 49 #include <net/inet.h> 50 #include <net/device.h> 51 #include <net/packet.h> 37 52 38 53 #include <async.h> 39 54 #include <ipc/services.h> 40 41 #include <net_err.h> 42 #include <packet/packet.h> 43 #include <packet/packet_client.h> 44 #include <packet_remote.h> 45 #include <net_device.h> 46 #include <icmp_interface.h> 47 #include <in.h> 48 #include <in6.h> 49 #include <inet.h> 50 #include <ip_local.h> 51 #include <ip_remote.h> 52 #include <socket_codes.h> 53 #include <socket_errno.h> 54 #include <ip_interface.h> 55 #include <tl_interface.h> 56 #include <tl_common.h> 55 #include <errno.h> 56 #include <err.h> 57 57 58 58 DEVICE_MAP_IMPLEMENT(packet_dimensions, packet_dimension_t); 59 59 60 int tl_get_address_port(const struct sockaddr * addr, int addrlen, uint16_t * port){ 61 const struct sockaddr_in * address_in; 62 const struct sockaddr_in6 * address_in6; 63 64 if((addrlen <= 0) || ((size_t) addrlen < sizeof(struct sockaddr))){ 65 return EINVAL; 66 } 67 switch(addr->sa_family){ 68 case AF_INET: 69 if(addrlen != sizeof(struct sockaddr_in)){ 70 return EINVAL; 71 } 72 address_in = (struct sockaddr_in *) addr; 73 *port = ntohs(address_in->sin_port); 74 break; 75 case AF_INET6: 76 if(addrlen != sizeof(struct sockaddr_in6)){ 77 return EINVAL; 78 } 79 address_in6 = (struct sockaddr_in6 *) addr; 80 *port = ntohs(address_in6->sin6_port); 81 break; 82 default: 83 return EAFNOSUPPORT; 84 } 60 /** Gets the address port. 61 * 62 * Supports AF_INET and AF_INET6 address families. 63 * 64 * @param[in,out] addr The address to be updated. 65 * @param[in] addrlen The address length. 66 * @param[out] port The set port. 67 * @returns EOK on success. 68 * @returns EINVAL if the address length does not match the address 69 * family. 70 * @returns EAFNOSUPPORT if the address family is not supported. 71 */ 72 int 73 tl_get_address_port(const struct sockaddr *addr, int addrlen, uint16_t *port) 74 { 75 const struct sockaddr_in *address_in; 76 const struct sockaddr_in6 *address_in6; 77 78 if ((addrlen <= 0) || ((size_t) addrlen < sizeof(struct sockaddr))) 79 return EINVAL; 80 81 switch (addr->sa_family) { 82 case AF_INET: 83 if (addrlen != sizeof(struct sockaddr_in)) 84 return EINVAL; 85 86 address_in = (struct sockaddr_in *) addr; 87 *port = ntohs(address_in->sin_port); 88 break; 89 90 case AF_INET6: 91 if (addrlen != sizeof(struct sockaddr_in6)) 92 return EINVAL; 93 94 address_in6 = (struct sockaddr_in6 *) addr; 95 *port = ntohs(address_in6->sin6_port); 96 break; 97 98 default: 99 return EAFNOSUPPORT; 100 } 101 85 102 return EOK; 86 103 } … … 91 108 * The reply is cached then. 92 109 * 93 * @param[in] ip_phoneThe IP moduel phone for (semi)remote calls.94 * @param[in] 95 * @param[in] device_idThe device identifier.96 * @param[out] packet_dimension 97 * 98 * @return EOK on success.99 * @return EBADMEM if the packet_dimension parameter is NULL.100 * @return ENOMEM if there is not enough memory left.101 * @return EINVAL if the packet_dimensions cache is not valid.102 * @return Other codes as defined for the ip_packet_size_req()function.103 * 104 */ 105 inttl_get_ip_packet_dimension(int ip_phone,110 * @param[in] ip_phone The IP moduel phone for (semi)remote calls. 111 * @param[in] packet_dimensions The packet dimensions cache. 112 * @param[in] device_id The device identifier. 113 * @param[out] packet_dimension The IP packet dimensions. 114 * @return EOK on success. 115 * @return EBADMEM if the packet_dimension parameter is NULL. 116 * @return ENOMEM if there is not enough memory left. 117 * @return EINVAL if the packet_dimensions cache is not valid. 118 * @return Other codes as defined for the ip_packet_size_req() 119 * function. 120 */ 121 int 122 tl_get_ip_packet_dimension(int ip_phone, 106 123 packet_dimensions_ref packet_dimensions, device_id_t device_id, 107 124 packet_dimension_ref *packet_dimension) … … 112 129 return EBADMEM; 113 130 114 *packet_dimension = packet_dimensions_find(packet_dimensions, device_id); 131 *packet_dimension = packet_dimensions_find(packet_dimensions, 132 device_id); 115 133 if (!*packet_dimension) { 116 134 /* Ask for and remember them if not found */ … … 136 154 } 137 155 138 int tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions, device_id_t device_id, size_t content){ 156 /** Updates IP device packet dimensions cache. 157 * 158 * @param[in,out] packet_dimensions The packet dimensions cache. 159 * @param[in] device_id The device identifier. 160 * @param[in] content The new maximum content size. 161 * @returns EOK on success. 162 * @return ENOENT if the packet dimension is not cached. 163 */ 164 int 165 tl_update_ip_packet_dimension(packet_dimensions_ref packet_dimensions, 166 device_id_t device_id, size_t content) 167 { 139 168 packet_dimension_ref packet_dimension; 140 169 141 170 packet_dimension = packet_dimensions_find(packet_dimensions, device_id); 142 if (! packet_dimension){171 if (!packet_dimension) 143 172 return ENOENT; 144 } 173 145 174 packet_dimension->content = content; 146 if(device_id != DEVICE_INVALID_ID){ 147 packet_dimension = packet_dimensions_find(packet_dimensions, DEVICE_INVALID_ID); 148 if(packet_dimension){ 149 if(packet_dimension->content >= content){ 175 176 if (device_id != DEVICE_INVALID_ID) { 177 packet_dimension = packet_dimensions_find(packet_dimensions, 178 DEVICE_INVALID_ID); 179 180 if (packet_dimension) { 181 if (packet_dimension->content >= content) 150 182 packet_dimension->content = content; 151 }else{152 packet_dimensions_exclude(packet_dimensions, DEVICE_INVALID_ID);153 }183 else 184 packet_dimensions_exclude(packet_dimensions, 185 DEVICE_INVALID_ID); 154 186 } 155 187 } 188 156 189 return EOK; 157 190 } 158 191 159 int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port){ 160 struct sockaddr_in * address_in; 161 struct sockaddr_in6 * address_in6; 192 /** Sets the address port. 193 * 194 * Supports AF_INET and AF_INET6 address families. 195 * 196 * @param[in,out] addr The address to be updated. 197 * @param[in] addrlen The address length. 198 * @param[in] port The port to be set. 199 * @returns EOK on success. 200 * @returns EINVAL if the address length does not match the address 201 * family. 202 * @returns EAFNOSUPPORT if the address family is not supported. 203 */ 204 int tl_set_address_port(struct sockaddr * addr, int addrlen, uint16_t port) 205 { 206 struct sockaddr_in *address_in; 207 struct sockaddr_in6 *address_in6; 162 208 size_t length; 163 209 164 if (addrlen < 0){165 return EINVAL; 166 }210 if (addrlen < 0) 211 return EINVAL; 212 167 213 length = (size_t) addrlen; 168 if(length < sizeof(struct sockaddr)){ 169 return EINVAL; 170 } 171 switch(addr->sa_family){ 172 case AF_INET: 173 if(length != sizeof(struct sockaddr_in)){ 214 if (length < sizeof(struct sockaddr)) 215 return EINVAL; 216 217 switch (addr->sa_family) { 218 case AF_INET: 219 if (length != sizeof(struct sockaddr_in)) 220 return EINVAL; 221 address_in = (struct sockaddr_in *) addr; 222 address_in->sin_port = htons(port); 223 return EOK; 224 225 case AF_INET6: 226 if (length != sizeof(struct sockaddr_in6)) 174 227 return EINVAL; 175 } 176 address_in = (struct sockaddr_in *) addr; 177 address_in->sin_port = htons(port); 178 return EOK; 179 case AF_INET6: 180 if(length != sizeof(struct sockaddr_in6)){ 181 return EINVAL; 182 } 183 address_in6 = (struct sockaddr_in6 *) addr; 184 address_in6->sin6_port = htons(port); 185 return EOK; 186 default: 187 return EAFNOSUPPORT; 188 } 189 } 190 191 int tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet, services_t error){ 228 address_in6 = (struct sockaddr_in6 *) addr; 229 address_in6->sin6_port = htons(port); 230 return EOK; 231 232 default: 233 return EAFNOSUPPORT; 234 } 235 } 236 237 /** Prepares the packet for ICMP error notification. 238 * 239 * Keeps the first packet and releases all the others. 240 * Releases all the packets on error. 241 * 242 * @param[in] packet_phone The packet server module phone. 243 * @param[in] icmp_phone The ICMP module phone. 244 * @param[in] packet The packet to be send. 245 * @param[in] error The packet error reporting service. Prefixes the 246 * received packet. 247 * @returns EOK on success. 248 * @returns ENOENT if no packet may be sent. 249 */ 250 int 251 tl_prepare_icmp_packet(int packet_phone, int icmp_phone, packet_t packet, 252 services_t error) 253 { 192 254 packet_t next; 193 uint8_t * 255 uint8_t *src; 194 256 int length; 195 257 … … 200 262 201 263 length = packet_get_addr(packet, &src, NULL); 202 if((length > 0) 203 && (! error) 204 && (icmp_phone >= 0) 205 // set both addresses to the source one (avoids the source address deletion before setting the destination one) 206 && (packet_set_addr(packet, src, src, (size_t) length) == EOK)){ 264 if ((length > 0) && (!error) && (icmp_phone >= 0) && 265 // set both addresses to the source one (avoids the source address 266 // deletion before setting the destination one) 267 (packet_set_addr(packet, src, src, (size_t) length) == EOK)) { 207 268 return EOK; 208 } else{269 } else 209 270 pq_release_remote(packet_phone, packet_get_id(packet)); 210 } 271 211 272 return ENOENT; 212 273 } 213 274 214 int tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix, const packet_dimension_ref dimension, const struct sockaddr * addr, socklen_t addrlen){ 275 /** Receives data from the socket into a packet. 276 * 277 * @param[in] packet_phone The packet server module phone. 278 * @param[out] packet The new created packet. 279 * @param[in] prefix Reserved packet data prefix length. 280 * @param[in] dimension The packet dimension. 281 * @param[in] addr The destination address. 282 * @param[in] addrlen The address length. 283 * @returns Number of bytes received. 284 * @returns EINVAL if the client does not send data. 285 * @returns ENOMEM if there is not enough memory left. 286 * @returns Other error codes as defined for the 287 * async_data_read_finalize() function. 288 */ 289 int 290 tl_socket_read_packet_data(int packet_phone, packet_ref packet, size_t prefix, 291 const packet_dimension_ref dimension, const struct sockaddr *addr, 292 socklen_t addrlen) 293 { 215 294 ERROR_DECLARE; 216 295 … … 219 298 void * data; 220 299 221 if (! dimension){222 return EINVAL; 223 } 300 if (!dimension) 301 return EINVAL; 302 224 303 // get the data length 225 if (! async_data_write_receive(&callid, &length)){226 return EINVAL; 227 } 304 if (!async_data_write_receive(&callid, &length)) 305 return EINVAL; 306 228 307 // get a new packet 229 *packet = packet_get_4_remote(packet_phone, length, dimension->addr_len, prefix + dimension->prefix, dimension->suffix); 230 if(! packet){ 308 *packet = packet_get_4_remote(packet_phone, length, dimension->addr_len, 309 prefix + dimension->prefix, dimension->suffix); 310 if (!packet) 231 311 return ENOMEM; 232 } 312 233 313 // allocate space in the packet 234 314 data = packet_suffix(*packet, length); 235 if (! data){315 if (!data) { 236 316 pq_release_remote(packet_phone, packet_get_id(*packet)); 237 317 return ENOMEM; 238 318 } 319 239 320 // read the data into the packet 240 if(ERROR_OCCURRED(async_data_write_finalize(callid, data, length)) 241 // set the packet destination address 242 || ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr, addrlen))){ 321 if (ERROR_OCCURRED(async_data_write_finalize(callid, data, length)) || 322 // set the packet destination address 323 ERROR_OCCURRED(packet_set_addr(*packet, NULL, (uint8_t *) addr, 324 addrlen))) { 243 325 pq_release_remote(packet_phone, packet_get_id(*packet)); 244 326 return ERROR_CODE; 245 327 } 328 246 329 return (int) length; 247 330 }
Note:
See TracChangeset
for help on using the changeset viewer.