Changeset 0b749a3 in mainline for uspace/lib/net/il/ip_client.c


Ignore:
Timestamp:
2010-11-22T15:39:53Z (13 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
0eddb76, aae339e9
Parents:
9a1d8ab (diff), 8cd1aa5e (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 development/ changes

File:
1 edited

Legend:

Unmodified
Added
Removed
  • uspace/lib/net/il/ip_client.c

    r9a1d8ab r0b749a3  
    2727 */
    2828
    29 /** @addtogroup ip
    30  *  @{
     29/** @addtogroup libnet
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  IP client interface implementation.
    35  *  @see ip_client.h
     34 * IP client interface implementation.
     35 * @see ip_client.h
    3636 */
    3737
     
    4040
    4141#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>
    4543#include <ip_header.h>
    4644
    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 */
     53size_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)))
    5359                return 0;
    54         }
     60
    5561        return IP_HEADER_LENGTH(header);
    5662}
    5763
    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 */
     88int
     89ip_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)
    6397                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)) {
    66102                return EINVAL;
    67103        }
    68104
    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/*      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 * @return              EOK on success.
     151 * @return              ENOMEM if there is not enough memory left in the packet.
     152 */
     153int
     154ip_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;
    103159        size_t padding;
    104160
     
    106162        // multiple of 4 bytes
    107163        padding =  ipopt_length % 4;
    108         if(padding){
     164        if (padding) {
    109165                padding = 4 - padding;
    110166                ipopt_length += padding;
     
    113169        // prefix the header
    114170        data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding);
    115         if(! data){
     171        if (!data)
    116172                return ENOMEM;
    117         }
    118173
    119174        // add the padding
    120         while(padding --){
     175        while (padding--)
    121176                data[sizeof(ip_header_t) + padding] = IPOPT_NOOP;
    122         }
    123177
    124178        // set the header
    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;
     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);
    128183        header->tos = tos;
    129184        header->protocol = protocol;
    130185
    131         if(dont_fragment){
     186        if (dont_fragment)
    132187                header->flags = IPFLAG_DONT_FRAGMENT;
    133         }
     188
    134189        return EOK;
    135190}
    136191
    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))){
     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 */
     209int
     210ip_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;
     214
     215        header = (ip_header_t *) packet_get_data(packet);
     216        if (!header || (packet_get_data_length(packet) < sizeof(ip_header_t)))
    143217                return ENOMEM;
    144         }
    145 
    146         if(protocol){
     218
     219        if (protocol)
    147220                *protocol = header->protocol;
    148         }
    149         if(ttl){
     221        if (ttl)
    150222                *ttl = header->ttl;
    151         }
    152         if(tos){
     223        if (tos)
    153224                *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) {
    159228                *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t);
    160229                return sizeof(ip_header_t);
    161         }else{
     230        } else {
    162231                return IP_HEADER_LENGTH(header);
    163232        }
    164233}
    165234
    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){
     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 */
     245int
     246ip_client_set_pseudo_header_data_length(void *header, size_t headerlen,
     247    size_t data_length)
     248{
     249        ipv4_pseudo_header_t *header_in;
     250
     251        if (!header)
    170252                return EBADMEM;
    171         }
    172 
    173         if(headerlen == sizeof(ipv4_pseudo_header_t)){
    174                 header_in = (ipv4_pseudo_header_ref) header;
     253
     254        if (headerlen == sizeof(ipv4_pseudo_header_t)) {
     255                header_in = (ipv4_pseudo_header_t *) header;
    175256                header_in->data_length = htons(data_length);
    176257                return EOK;
    177258        // TODO IPv6
    178         }else{
     259        } else {
    179260                return EINVAL;
    180261        }
Note: See TracChangeset for help on using the changeset viewer.