Changeset 7715994 in mainline for uspace/srv/net/il/ip/ip_client.c


Ignore:
Timestamp:
2010-03-13T12:17:02Z (14 years ago)
Author:
Jiri Svoboda <jiri@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
6ba20a6b
Parents:
d0febca (diff), 2070570 (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.
Message:

Merge mainline changes.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/srv/net/il/ip/ip_client.c

    rd0febca r7715994  
    4848#include "ip_header.h"
    4949
    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;
     50size_t ip_client_header_length(packet_t packet){
     51        ip_header_ref header;
    5452
    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;
    5957        }
    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);
    7059}
    7160
    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;
     61int 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;
    7464
    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;
    7967        }
    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))){
    11269                return EINVAL;
    11370        }
    114 }
    11571
    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){
    12373                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;
    13084                        header_in->destination_address = address_in->sin_addr.s_addr;
    131                         address_in = ( struct sockaddr_in * ) src;
     85                        address_in = (struct sockaddr_in *) src;
    13286                        header_in->source_address = address_in->sin_addr.s_addr;
    13387                        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;
    13690                        return EOK;
    13791                // TODO IPv6
    13892/*              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;
    14197                        return EOK;
    14298*/              default:
     
    145101}
    146102
     103int 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
     140int 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
     169int 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
    147186/** @}
    148187 */
Note: See TracChangeset for help on using the changeset viewer.