Changes in uspace/lib/net/il/ip_client.c [14f1db0:ccca251] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/il/ip_client.c
r14f1db0 rccca251 27 27 */ 28 28 29 /** @addtogroup ip30 * 29 /** @addtogroup libnet 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * IP client interface implementation. 35 * @see ip_client.h 36 36 */ 37 37 … … 40 40 41 41 #include <ip_client.h> 42 #include <socket_errno.h> 43 #include <packet/packet.h> 44 #include <packet/packet_client.h> 42 #include <packet_client.h> 45 43 #include <ip_header.h> 46 44 47 size_t ip_client_header_length(packet_t packet){ 48 ip_header_ref header; 49 50 header = (ip_header_ref) packet_get_data(packet); 51 if((! header) 52 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 45 #include <net/packet.h> 46 47 /** Returns the IP header length. 48 * 49 * @param[in] packet The packet. 50 * @return The IP header length in bytes. 51 * @return Zero if there is no IP header. 52 */ 53 size_t ip_client_header_length(packet_t *packet) 54 { 55 ip_header_t *header; 56 57 header = (ip_header_t *) packet_get_data(packet); 58 if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t))) 53 59 return 0; 54 } 60 55 61 return IP_HEADER_LENGTH(header); 56 62 } 57 63 58 int ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr * src, socklen_t srclen, struct sockaddr * dest, socklen_t destlen, size_t data_length, void **header, size_t * headerlen){ 59 ipv4_pseudo_header_ref header_in; 60 struct sockaddr_in * address_in; 61 62 if(!(header && headerlen)){ 64 /** Constructs the IPv4 pseudo header. 65 * 66 * @param[in] protocol The transport protocol. 67 * @param[in] src The source address. 68 * @param[in] srclen The source address length. 69 * @param[in] dest The destination address. 70 * @param[in] destlen The destination address length. 71 * @param[in] data_length The data length to be set. 72 * @param[out] header The constructed IPv4 pseudo header. 73 * @param[out] headerlen The length of the IP pseudo header in bytes. 74 * @return EOK on success. 75 * @return EBADMEM if the header and/or the headerlen parameter is 76 * NULL. 77 * @return EINVAL if the source address and/or the destination 78 * address parameter is NULL. 79 * @return EINVAL if the source address length is less than struct 80 * sockaddr length. 81 * @return EINVAL if the source address length differs from the 82 * destination address length. 83 * @return EINVAL if the source address family differs from the 84 * destination family. 85 * @return EAFNOSUPPORT if the address family is not supported. 86 * @return ENOMEM if there is not enough memory left. 87 */ 88 int 89 ip_client_get_pseudo_header(ip_protocol_t protocol, struct sockaddr *src, 90 socklen_t srclen, struct sockaddr *dest, socklen_t destlen, 91 size_t data_length, void **header, size_t *headerlen) 92 { 93 ipv4_pseudo_header_t *header_in; 94 struct sockaddr_in *address_in; 95 96 if (!header || !headerlen) 63 97 return EBADMEM; 64 } 65 if(!(src && dest && (srclen > 0) && ((size_t) srclen >= sizeof(struct sockaddr)) && (srclen == destlen) && (src->sa_family == dest->sa_family))){ 98 99 if (!src || !dest || srclen <= 0 || 100 (((size_t) srclen < sizeof(struct sockaddr))) || 101 (srclen != destlen) || (src->sa_family != dest->sa_family)) { 66 102 return EINVAL; 67 103 } 68 104 69 switch(src->sa_family){ 70 case AF_INET: 71 if(srclen != sizeof(struct sockaddr_in)){ 72 return EINVAL; 73 } 74 *headerlen = sizeof(*header_in); 75 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 76 if(! header_in){ 77 return ENOMEM; 78 } 79 bzero(header_in, * headerlen); 80 address_in = (struct sockaddr_in *) dest; 81 header_in->destination_address = address_in->sin_addr.s_addr; 82 address_in = (struct sockaddr_in *) src; 83 header_in->source_address = address_in->sin_addr.s_addr; 84 header_in->protocol = protocol; 85 header_in->data_length = htons(data_length); 86 *header = header_in; 87 return EOK; 88 // TODO IPv6 89 /* case AF_INET6: 90 if(addrlen != sizeof(struct sockaddr_in6)){ 91 return EINVAL; 92 } 93 address_in6 = (struct sockaddr_in6 *) addr; 94 return EOK; 95 */ default: 96 return EAFNOSUPPORT; 97 } 98 } 99 100 int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){ 101 ip_header_ref header; 102 uint8_t * data; 105 switch (src->sa_family) { 106 case AF_INET: 107 if (srclen != sizeof(struct sockaddr_in)) 108 return EINVAL; 109 110 *headerlen = sizeof(*header_in); 111 header_in = (ipv4_pseudo_header_t *) malloc(*headerlen); 112 if (!header_in) 113 return ENOMEM; 114 115 bzero(header_in, *headerlen); 116 address_in = (struct sockaddr_in *) dest; 117 header_in->destination_address = address_in->sin_addr.s_addr; 118 address_in = (struct sockaddr_in *) src; 119 header_in->source_address = address_in->sin_addr.s_addr; 120 header_in->protocol = protocol; 121 header_in->data_length = htons(data_length); 122 *header = header_in; 123 return EOK; 124 125 // TODO IPv6 126 #if 0 127 case AF_INET6: 128 if (addrlen != sizeof(struct sockaddr_in6)) 129 return EINVAL; 130 131 address_in6 = (struct sockaddr_in6 *) addr; 132 return EOK; 133 #endif 134 135 default: 136 return EAFNOSUPPORT; 137 } 138 } 139 140 /** Prepares the packet to be transfered via IP. 141 * 142 * The IP header is prefixed. 143 * 144 * @param[in,out] packet The packet to be prepared. 145 * @param[in] protocol The transport protocol. 146 * @param[in] ttl The time to live counter. The IPDEFTTL is set if zero. 147 * @param[in] tos The type of service. 148 * @param[in] dont_fragment The value indicating whether fragmentation is 149 * disabled. 150 * @param[in] ipopt_length The prefixed IP options length in bytes. 151 * @return EOK on success. 152 * @return ENOMEM if there is not enough memory left in the packet. 153 */ 154 int 155 ip_client_prepare_packet(packet_t *packet, ip_protocol_t protocol, ip_ttl_t ttl, 156 ip_tos_t tos, int dont_fragment, size_t ipopt_length) 157 { 158 ip_header_t *header; 159 uint8_t *data; 103 160 size_t padding; 104 161 105 // compute the padding if IP options are set 106 // multiple of 4 bytes 162 /* 163 * Compute the padding if IP options are set 164 * multiple of 4 bytes 165 */ 107 166 padding = ipopt_length % 4; 108 if (padding){167 if (padding) { 109 168 padding = 4 - padding; 110 169 ipopt_length += padding; 111 170 } 112 171 113 / / prefix the header172 /* Prefix the header */ 114 173 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 115 if (! data){174 if (!data) 116 175 return ENOMEM; 117 } 118 119 // add the padding 120 while(padding --){ 176 177 /* Add the padding */ 178 while (padding--) 121 179 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 122 } 123 124 // set the header125 header = (ip_header_ref) data;126 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) +ipopt_length);127 header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL;180 181 /* Set the header */ 182 header = (ip_header_t *) data; 183 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + 184 ipopt_length); 185 header->ttl = (ttl ? ttl : IPDEFTTL); 128 186 header->tos = tos; 129 187 header->protocol = protocol; 130 188 131 if (dont_fragment){189 if (dont_fragment) 132 190 header->flags = IPFLAG_DONT_FRAGMENT; 133 } 191 134 192 return EOK; 135 193 } 136 194 137 int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){ 138 ip_header_ref header; 139 140 header = (ip_header_ref) packet_get_data(packet); 141 if((! header) 142 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 195 /** Processes the received IP packet. 196 * 197 * Fills set header fields. 198 * Returns the prefixed IP header length. 199 * 200 * @param[in] packet The received packet. 201 * @param[out] protocol The transport protocol. May be NULL if not desired. 202 * @param[out] ttl The time to live counter. May be NULL if not desired. 203 * @param[out] tos The type of service. May be NULL if not desired. 204 * @param[out] dont_fragment The value indicating whether the fragmentation is 205 * disabled. May be NULL if not desired. 206 * @param[out] ipopt_length The IP options length in bytes. May be NULL if not 207 * desired. 208 * @return The prefixed IP header length in bytes on success. 209 * @return ENOMEM if the packet is too short to contain the IP 210 * header. 211 */ 212 int 213 ip_client_process_packet(packet_t *packet, ip_protocol_t *protocol, 214 ip_ttl_t *ttl, ip_tos_t *tos, int *dont_fragment, size_t *ipopt_length) 215 { 216 ip_header_t *header; 217 218 header = (ip_header_t *) packet_get_data(packet); 219 if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t))) 143 220 return ENOMEM; 144 } 145 146 if(protocol){ 221 222 if (protocol) 147 223 *protocol = header->protocol; 148 } 149 if(ttl){ 224 if (ttl) 150 225 *ttl = header->ttl; 151 } 152 if(tos){ 226 if (tos) 153 227 *tos = header->tos; 154 } 155 if(dont_fragment){ 156 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 157 } 158 if(ipopt_length){ 228 if (dont_fragment) 229 *dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; 230 if (ipopt_length) { 159 231 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 160 232 return sizeof(ip_header_t); 161 } else{233 } else { 162 234 return IP_HEADER_LENGTH(header); 163 235 } 164 236 } 165 237 166 int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length){ 167 ipv4_pseudo_header_ref header_in; 168 169 if(! header){ 238 /** Updates the IPv4 pseudo header data length field. 239 * 240 * @param[in,out] header The IPv4 pseudo header to be updated. 241 * @param[in] headerlen The length of the IP pseudo header in bytes. 242 * @param[in] data_length The data length to be set. 243 * @return EOK on success. 244 * @return EBADMEM if the header parameter is NULL. 245 * @return EINVAL if the headerlen parameter is not IPv4 pseudo 246 * header length. 247 */ 248 int 249 ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, 250 size_t data_length) 251 { 252 ipv4_pseudo_header_t *header_in; 253 254 if (!header) 170 255 return EBADMEM; 171 } 172 173 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 174 header_in = (ipv4_pseudo_header_ref) header; 256 257 if (headerlen == sizeof(ipv4_pseudo_header_t)) { 258 header_in = (ipv4_pseudo_header_t *) header; 175 259 header_in->data_length = htons(data_length); 176 260 return EOK; 177 261 // TODO IPv6 178 } else{262 } else { 179 263 return EINVAL; 180 264 }
Note:
See TracChangeset
for help on using the changeset viewer.