Changeset 858fc90 in mainline for uspace/srv/net/il/ip/ip_client.c
- Timestamp:
- 2010-03-15T19:35:25Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 6092b56e
- Parents:
- 92307f1 (diff), 4684368 (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/srv/net/il/ip/ip_client.c
r92307f1 r858fc90 48 48 #include "ip_header.h" 49 49 50 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 ){ 51 ip_header_ref header; 52 uint8_t * data; 53 size_t padding; 50 size_t ip_client_header_length(packet_t packet){ 51 ip_header_ref header; 54 52 55 padding = ipopt_length % 4;56 if( padding ){57 padding = 4 - padding;58 ipopt_length += padding;53 header = (ip_header_ref) packet_get_data(packet); 54 if((! header) 55 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 56 return 0; 59 57 } 60 data = ( uint8_t * ) packet_prefix( packet, sizeof( ip_header_t ) + padding ); 61 if( ! data ) return ENOMEM; 62 while( padding -- ) data[ sizeof( ip_header_t ) + padding ] = IPOPT_NOOP; 63 header = ( ip_header_ref ) data; 64 header->header_length = IP_COMPUTE_HEADER_LENGTH( sizeof( ip_header_t ) + ipopt_length ); 65 header->ttl = ( ttl ? ttl : IPDEFTTL ); //((( ttl ) <= MAXTTL ) ? ttl : MAXTTL ) : IPDEFTTL; 66 header->tos = tos; 67 header->protocol = protocol; 68 if( dont_fragment ) header->flags = IPFLAG_DONT_FRAGMENT; 69 return EOK; 58 return IP_HEADER_LENGTH(header); 70 59 } 71 60 72 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 ){ 73 ip_header_ref header; 61 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, ip_pseudo_header_ref * header, size_t * headerlen){ 62 ipv4_pseudo_header_ref header_in; 63 struct sockaddr_in * address_in; 74 64 75 header = ( ip_header_ref ) packet_get_data( packet ); 76 if(( ! header ) 77 || ( packet_get_data_length( packet ) < sizeof( ip_header_t ))){ 78 return ENOMEM; 65 if(!(header && headerlen)){ 66 return EBADMEM; 79 67 } 80 if( protocol ) * protocol = header->protocol; 81 if( ttl ) * ttl = header->ttl; 82 if( tos ) * tos = header->tos; 83 if( dont_fragment ) * dont_fragment = header->flags & IPFLAG_DONT_FRAGMENT; 84 if( ipopt_length ){ 85 * ipopt_length = IP_HEADER_LENGTH( header ) - sizeof( ip_header_t ); 86 return sizeof( ip_header_t ); 87 }else{ 88 return IP_HEADER_LENGTH( header ); 89 } 90 } 91 92 size_t ip_client_header_length( packet_t packet ){ 93 ip_header_ref header; 94 95 header = ( ip_header_ref ) packet_get_data( packet ); 96 if(( ! header ) 97 || ( packet_get_data_length( packet ) < sizeof( ip_header_t ))){ 98 return 0; 99 } 100 return IP_HEADER_LENGTH( header ); 101 } 102 103 int ip_client_set_pseudo_header_data_length( ip_pseudo_header_ref header, size_t headerlen, size_t data_length ){ 104 ipv4_pseudo_header_ref header_in; 105 106 if( ! header ) return EBADMEM; 107 if( headerlen == sizeof( ipv4_pseudo_header_t )){ 108 header_in = ( ipv4_pseudo_header_ref ) header; 109 header_in->data_length = htons( data_length ); 110 return EOK; 111 }else{ 68 if(!(src && dest && (srclen > 0) && ((size_t) srclen >= sizeof(struct sockaddr)) && (srclen == destlen) && (src->sa_family == dest->sa_family))){ 112 69 return EINVAL; 113 70 } 114 }115 71 116 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, ip_pseudo_header_ref * header, size_t * headerlen ){ 117 ipv4_pseudo_header_ref header_in; 118 struct sockaddr_in * address_in; 119 120 if( !( header && headerlen )) return EBADMEM; 121 if( !( src && dest && ( srclen > 0 ) && (( size_t ) srclen >= sizeof( struct sockaddr )) && ( srclen == destlen ) && ( src->sa_family == dest->sa_family ))) return EINVAL; 122 switch( src->sa_family ){ 72 switch(src->sa_family){ 123 73 case AF_INET: 124 if( srclen != sizeof( struct sockaddr_in )) return EINVAL; 125 * headerlen = sizeof( * header_in ); 126 header_in = ( ipv4_pseudo_header_ref ) malloc( * headerlen ); 127 if( ! header_in ) return ENOMEM; 128 bzero( header_in, * headerlen ); 129 address_in = ( struct sockaddr_in * ) dest; 74 if(srclen != sizeof(struct sockaddr_in)){ 75 return EINVAL; 76 } 77 *headerlen = sizeof(*header_in); 78 header_in = (ipv4_pseudo_header_ref) malloc(*headerlen); 79 if(! header_in){ 80 return ENOMEM; 81 } 82 bzero(header_in, * headerlen); 83 address_in = (struct sockaddr_in *) dest; 130 84 header_in->destination_address = address_in->sin_addr.s_addr; 131 address_in = ( struct sockaddr_in *) src;85 address_in = (struct sockaddr_in *) src; 132 86 header_in->source_address = address_in->sin_addr.s_addr; 133 87 header_in->protocol = protocol; 134 header_in->data_length = htons( data_length);135 * header = ( ip_pseudo_header_ref) header_in;88 header_in->data_length = htons(data_length); 89 *header = (ip_pseudo_header_ref) header_in; 136 90 return EOK; 137 91 // TODO IPv6 138 92 /* case AF_INET6: 139 if( addrlen != sizeof( struct sockaddr_in6 )) return EINVAL; 140 address_in6 = ( struct sockaddr_in6 * ) addr; 93 if(addrlen != sizeof(struct sockaddr_in6)){ 94 return EINVAL; 95 } 96 address_in6 = (struct sockaddr_in6 *) addr; 141 97 return EOK; 142 98 */ default: … … 145 101 } 146 102 103 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){ 104 ip_header_ref header; 105 uint8_t * data; 106 size_t padding; 107 108 // compute the padding if IP options are set 109 // multiple of 4 bytes 110 padding = ipopt_length % 4; 111 if(padding){ 112 padding = 4 - padding; 113 ipopt_length += padding; 114 } 115 116 // prefix the header 117 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 118 if(! data){ 119 return ENOMEM; 120 } 121 122 // add the padding 123 while(padding --){ 124 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 125 } 126 127 // set the header 128 header = (ip_header_ref) data; 129 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length); 130 header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL; 131 header->tos = tos; 132 header->protocol = protocol; 133 134 if(dont_fragment){ 135 header->flags = IPFLAG_DONT_FRAGMENT; 136 } 137 return EOK; 138 } 139 140 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){ 141 ip_header_ref header; 142 143 header = (ip_header_ref) packet_get_data(packet); 144 if((! header) 145 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 146 return ENOMEM; 147 } 148 149 if(protocol){ 150 *protocol = header->protocol; 151 } 152 if(ttl){ 153 *ttl = header->ttl; 154 } 155 if(tos){ 156 *tos = header->tos; 157 } 158 if(dont_fragment){ 159 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 160 } 161 if(ipopt_length){ 162 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 163 return sizeof(ip_header_t); 164 }else{ 165 return IP_HEADER_LENGTH(header); 166 } 167 } 168 169 int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length){ 170 ipv4_pseudo_header_ref header_in; 171 172 if(! header){ 173 return EBADMEM; 174 } 175 176 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 177 header_in = (ipv4_pseudo_header_ref) header; 178 header_in->data_length = htons(data_length); 179 return EOK; 180 // TODO IPv6 181 }else{ 182 return EINVAL; 183 } 184 } 185 147 186 /** @} 148 187 */
Note:
See TracChangeset
for help on using the changeset viewer.