Changes in uspace/lib/net/il/ip_client.c [46d4d9f:14f1db0] in mainline
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/lib/net/il/ip_client.c
r46d4d9f r14f1db0 27 27 */ 28 28 29 /** @addtogroup libnet30 * @{29 /** @addtogroup ip 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * IP client interface implementation.35 * @see ip_client.h34 * IP client interface implementation. 35 * @see ip_client.h 36 36 */ 37 37 … … 40 40 41 41 #include <ip_client.h> 42 #include <packet_client.h> 42 #include <socket_errno.h> 43 #include <packet/packet.h> 44 #include <packet/packet_client.h> 43 45 #include <ip_header.h> 44 46 45 #include <net/packet.h> 47 size_t ip_client_header_length(packet_t packet){ 48 ip_header_ref header; 46 49 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))) 50 header = (ip_header_ref) packet_get_data(packet); 51 if((! header) 52 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 59 53 return 0; 60 54 } 61 55 return IP_HEADER_LENGTH(header); 62 56 } 63 57 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; 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; 95 61 96 if (!header || !headerlen)62 if(!(header && headerlen)){ 97 63 return EBADMEM; 98 99 if (!src || !dest || srclen <= 0 || 100 (((size_t) srclen < sizeof(struct sockaddr))) || 101 (srclen != destlen) || (src->sa_family != dest->sa_family)) { 64 } 65 if(!(src && dest && (srclen > 0) && ((size_t) srclen >= sizeof(struct sockaddr)) && (srclen == destlen) && (src->sa_family == dest->sa_family))){ 102 66 return EINVAL; 103 67 } 104 68 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 /* 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; 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; 136 97 } 137 98 } 138 99 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 * @return EOK on success. 151 * @return 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 { 157 ip_header_t *header; 158 uint8_t *data; 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; 159 103 size_t padding; 160 104 … … 162 106 // multiple of 4 bytes 163 107 padding = ipopt_length % 4; 164 if (padding){108 if(padding){ 165 109 padding = 4 - padding; 166 110 ipopt_length += padding; … … 169 113 // prefix the header 170 114 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 171 if (!data)115 if(! data){ 172 116 return ENOMEM; 117 } 173 118 174 119 // add the padding 175 while (padding--)120 while(padding --){ 176 121 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 122 } 177 123 178 124 // set the header 179 header = (ip_header_t *) data; 180 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + 181 ipopt_length); 182 header->ttl = (ttl ? ttl : IPDEFTTL); 125 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; 183 128 header->tos = tos; 184 129 header->protocol = protocol; 185 130 186 if (dont_fragment)131 if(dont_fragment){ 187 132 header->flags = IPFLAG_DONT_FRAGMENT; 188 133 } 189 134 return EOK; 190 135 } 191 136 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 * @return The prefixed IP header length in bytes on success. 206 * @return 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 { 213 ip_header_t *header; 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; 214 139 215 header = (ip_header_t *) packet_get_data(packet); 216 if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t))) 140 header = (ip_header_ref) packet_get_data(packet); 141 if((! header) 142 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 217 143 return ENOMEM; 144 } 218 145 219 if (protocol)146 if(protocol){ 220 147 *protocol = header->protocol; 221 if (ttl) 148 } 149 if(ttl){ 222 150 *ttl = header->ttl; 223 if (tos) 151 } 152 if(tos){ 224 153 *tos = header->tos; 225 if (dont_fragment) 226 *dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; 227 if (ipopt_length) { 154 } 155 if(dont_fragment){ 156 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 157 } 158 if(ipopt_length){ 228 159 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 229 160 return sizeof(ip_header_t); 230 } else{161 }else{ 231 162 return IP_HEADER_LENGTH(header); 232 163 } 233 164 } 234 165 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 * @return EOK on success. 241 * @return EBADMEM if the header parameter is NULL. 242 * @return 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 { 249 ipv4_pseudo_header_t *header_in; 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; 250 168 251 if (!header)169 if(! header){ 252 170 return EBADMEM; 171 } 253 172 254 if (headerlen == sizeof(ipv4_pseudo_header_t)){255 header_in = (ipv4_pseudo_header_ t *) header;173 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 174 header_in = (ipv4_pseudo_header_ref) header; 256 175 header_in->data_length = htons(data_length); 257 176 return EOK; 258 177 // TODO IPv6 259 } else{178 }else{ 260 179 return EINVAL; 261 180 }
Note:
See TracChangeset
for help on using the changeset viewer.