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