Changeset 9b9d1c95 in mainline for uspace/lib/net/il/ip_client.c
- Timestamp:
- 2010-10-16T16:36:38Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- c62ae1d6
- Parents:
- af7638e
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/il/ip_client.c
raf7638e r9b9d1c95 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 … … 45 45 #include <net/packet.h> 46 46 47 size_t ip_client_header_length(packet_t packet){ 47 /** Returns the IP header length. 48 * 49 * @param[in] packet The packet. 50 * @returns The IP header length in bytes. 51 * @returns Zero if there is no IP header. 52 */ 53 size_t ip_client_header_length(packet_t packet) 54 { 48 55 ip_header_ref header; 49 56 50 57 header = (ip_header_ref) packet_get_data(packet); 51 if((! header) 52 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 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){ 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 * @returns EOK on success. 75 * @returns EBADMEM if the header and/or the headerlen parameter is 76 * NULL. 77 * @returns EINVAL if the source address and/or the destination 78 * address parameter is NULL. 79 * @returns EINVAL if the source address length is less than struct 80 * sockaddr length. 81 * @returns EINVAL if the source address length differs from the 82 * destination address length. 83 * @returns EINVAL if the source address family differs from the 84 * destination family. 85 * @returns EAFNOSUPPORT if the address family is not supported. 86 * @returns 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 { 59 93 ipv4_pseudo_header_ref header_in; 60 struct sockaddr_in * 61 62 if (!(header && headerlen)){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){ 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_ref) 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 /* case AF_INET6: 127 if (addrlen != sizeof(struct sockaddr_in6)) 128 return EINVAL; 129 130 address_in6 = (struct sockaddr_in6 *) addr; 131 return EOK; 132 */ 133 134 default: 135 return EAFNOSUPPORT; 136 } 137 } 138 139 /** Prepares the packet to be transfered via IP. 140 * 141 * The IP header is prefixed. 142 * 143 * @param[in,out] packet The packet to be prepared. 144 * @param[in] protocol The transport protocol. 145 * @param[in] ttl The time to live counter. The IPDEFTTL is set if zero. 146 * @param[in] tos The type of service. 147 * @param[in] dont_fragment The value indicating whether fragmentation is 148 * disabled. 149 * @param[in] ipopt_length The prefixed IP options length in bytes. 150 * @returns EOK on success. 151 * @returns ENOMEM if there is not enough memory left in the packet. 152 */ 153 int 154 ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, 155 ip_tos_t tos, int dont_fragment, size_t ipopt_length) 156 { 101 157 ip_header_ref header; 102 uint8_t * 158 uint8_t *data; 103 159 size_t padding; 104 160 … … 106 162 // multiple of 4 bytes 107 163 padding = ipopt_length % 4; 108 if (padding){164 if (padding) { 109 165 padding = 4 - padding; 110 166 ipopt_length += padding; … … 113 169 // prefix the header 114 170 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 115 if (! data){171 if (!data) 116 172 return ENOMEM; 117 }118 173 119 174 // add the padding 120 while (padding --){175 while (padding--) 121 176 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 122 }123 177 124 178 // set the header 125 179 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 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + 181 ipopt_length); 182 header->ttl = (ttl ? ttl : IPDEFTTL); 128 183 header->tos = tos; 129 184 header->protocol = protocol; 130 185 131 if (dont_fragment){186 if (dont_fragment) 132 187 header->flags = IPFLAG_DONT_FRAGMENT; 133 } 188 134 189 return EOK; 135 190 } 136 191 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){ 192 /** Processes the received IP packet. 193 * 194 * Fills set header fields. 195 * Returns the prefixed IP header length. 196 * 197 * @param[in] packet The received packet. 198 * @param[out] protocol The transport protocol. May be NULL if not desired. 199 * @param[out] ttl The time to live counter. May be NULL if not desired. 200 * @param[out] tos The type of service. May be NULL if not desired. 201 * @param[out] dont_fragment The value indicating whether the fragmentation is 202 * disabled. May be NULL if not desired. 203 * @param[out] ipopt_length The IP options length in bytes. May be NULL if not 204 * desired. 205 * @returns The prefixed IP header length in bytes on success. 206 * @returns ENOMEM if the packet is too short to contain the IP 207 * header. 208 */ 209 int 210 ip_client_process_packet(packet_t packet, ip_protocol_t *protocol, 211 ip_ttl_t *ttl, ip_tos_t *tos, int *dont_fragment, size_t *ipopt_length) 212 { 138 213 ip_header_ref header; 139 214 140 215 header = (ip_header_ref) packet_get_data(packet); 141 if((! header) 142 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 216 if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t))) 143 217 return ENOMEM; 144 } 145 146 if(protocol){ 218 219 if (protocol) 147 220 *protocol = header->protocol; 148 } 149 if(ttl){ 221 if (ttl) 150 222 *ttl = header->ttl; 151 } 152 if(tos){ 223 if (tos) 153 224 *tos = header->tos; 154 } 155 if(dont_fragment){ 156 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 157 } 158 if(ipopt_length){ 225 if (dont_fragment) 226 *dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; 227 if (ipopt_length) { 159 228 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 160 229 return sizeof(ip_header_t); 161 } else{230 } else { 162 231 return IP_HEADER_LENGTH(header); 163 232 } 164 233 } 165 234 166 int ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, size_t data_length){ 235 /** Updates the IPv4 pseudo header data length field. 236 * 237 * @param[in,out] header The IPv4 pseudo header to be updated. 238 * @param[in] headerlen The length of the IP pseudo header in bytes. 239 * @param[in] data_length The data length to be set. 240 * @returns EOK on success. 241 * @returns EBADMEM if the header parameter is NULL. 242 * @returns EINVAL if the headerlen parameter is not IPv4 pseudo 243 * header length. 244 */ 245 int 246 ip_client_set_pseudo_header_data_length(void *header, size_t headerlen, 247 size_t data_length) 248 { 167 249 ipv4_pseudo_header_ref header_in; 168 250 169 if (! header){251 if (!header) 170 252 return EBADMEM; 171 } 172 173 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 253 254 if (headerlen == sizeof(ipv4_pseudo_header_t)) { 174 255 header_in = (ipv4_pseudo_header_ref) header; 175 256 header_in->data_length = htons(data_length); 176 257 return EOK; 177 258 // TODO IPv6 178 } else{259 } else { 179 260 return EINVAL; 180 261 }
Note:
See TracChangeset
for help on using the changeset viewer.