Subversion Repositories HelenOS

Rev

Rev 4075 | Rev 4197 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. /*
  2.  * Copyright (c) 2009 Lukas Mejdrech
  3.  * All rights reserved.
  4.  *
  5.  * Redistribution and use in source and binary forms, with or without
  6.  * modification, are permitted provided that the following conditions
  7.  * are met:
  8.  *
  9.  * - Redistributions of source code must retain the above copyright
  10.  *   notice, this list of conditions and the following disclaimer.
  11.  * - Redistributions in binary form must reproduce the above copyright
  12.  *   notice, this list of conditions and the following disclaimer in the
  13.  *   documentation and/or other materials provided with the distribution.
  14.  * - The name of the author may not be used to endorse or promote products
  15.  *   derived from this software without specific prior written permission.
  16.  *
  17.  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
  18.  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
  19.  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
  20.  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
  21.  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
  22.  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  23.  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  24.  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  25.  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
  26.  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  27.  */
  28.  
  29. /** @addtogroup lo
  30.  *  @{
  31.  */
  32.  
  33. /** @file
  34.  */
  35.  
  36. #include <async.h>
  37. #include <errno.h>
  38. #include <stdio.h>
  39.  
  40. #include <ipc/ipc.h>
  41. #include <ipc/services.h>
  42.  
  43. #include "../../err.h"
  44. #include "../../messages.h"
  45. #include "../../modules.h"
  46.  
  47. #include "../../structures/measured_strings.h"
  48. #include "../../structures/packet/packet_client.h"
  49.  
  50. #include "../netif.h"
  51.  
  52. #define DEFAULT_MTU 1500
  53.  
  54. #define NAME    "lo - loopback interface"
  55.  
  56. netif_globals_t netif_globals;
  57.  
  58. static struct lo_globals{
  59.     measured_string_ref addr;
  60.     int mtu;
  61. } lo_globals;
  62.  
  63. int change_state_message( device_id_t device_id, device_state_t state );
  64. int create( device_id_t device_id, device_ref * device );
  65. int initialize( void );
  66. void    netif_print_name( void );
  67. int probe_auto_message( void );
  68. int probe_message( device_id_t device_id, int irq, int io );
  69. int send_message( device_id_t device_id, packet_t packet );
  70. int start_message( device_id_t device_id );
  71. int stop_message( device_id_t device_id );
  72. measured_string_ref get_addr_message( device_id_t device_id );
  73.  
  74. measured_string_ref get_addr_message( device_id_t device_id ){
  75.     return lo_globals.addr;
  76. }
  77.  
  78. int change_state_message( device_id_t device_id, device_state_t state ){
  79.     ERROR_DECLARE;
  80.  
  81.     device_ref  device;
  82.  
  83.     ERROR_PROPAGATE( find_device( device_id, & device ));
  84.     if( device->state != state ){
  85.         device->state = state;
  86.         nil_message( device, NET_NIL_DEVICE_STATE, device->state, NULL );
  87.         printf( "\nState changed to %s", ( state == NETIF_ACTIVE ) ? "ACTIVE" : "STOPPED" );
  88.     }
  89.     return EOK;
  90. }
  91.  
  92. int create( device_id_t device_id, device_ref * device ){
  93.     ERROR_DECLARE;
  94.  
  95.     if( device_map_count( & netif_globals.device_map ) > 0 ){
  96.         return EXDEV;
  97.     }else{
  98.         * device = ( device_ref ) malloc( sizeof( device_t ));
  99.         if( !( * device )) return ENOMEM;
  100.         ( ** device ).device_id = device_id;
  101.         ( ** device ).nil_phone = -1;
  102.         ( ** device ).specific = NULL;
  103.         null_device_stats( &(( ** device ).stats ));
  104.         ( ** device ).state = NETIF_STOPPED;
  105.         if( ERROR_OCCURRED( device_map_add( & netif_globals.device_map, ( ** device ).device_id, * device ))){
  106.             free( * device );
  107.             * device = NULL;
  108.             return ERROR_CODE;
  109.         }
  110.     }
  111.     return EOK;
  112. }
  113.  
  114. int initialize( void ){
  115.     ipcarg_t    phonehash;
  116.  
  117.     lo_globals.addr = measured_string_create_bulk( "\0\0\0\0\0\0", 0 );
  118.     if( ! lo_globals.addr ) return ENOMEM;
  119.     return REGISTER_ME( SERVICE_LO, & phonehash );
  120. }
  121.  
  122. void netif_print_name( void ){
  123.     printf( NAME );
  124. }
  125.  
  126. int probe_auto_message( void ){
  127. /*  ERROR_DECLARE;
  128.  
  129.     device_ref  device;
  130.  
  131.     ERROR_PROPAGATE( create( arg1, & device ));
  132.     ipc_call_sync_3_3( netif_globals.networking_phone, NET_NET_DEVICE, device->device_id, NULL, NULL, NULL, NULL, NULL );
  133. */  return ENOTSUP;
  134. }
  135.  
  136. int probe_message( device_id_t device_id, int irq, int io ){
  137.     ERROR_DECLARE;
  138.  
  139.     device_ref      device;
  140.     aid_t           message;
  141.     ipc_call_t      answer;
  142.     measured_string_t   configuration[ 1 ] = {{ "MTU", 3 }};
  143.     int         count = 1;
  144.     measured_string_ref settings;
  145.     char *          data;
  146.  
  147.     // create a new device
  148.     ERROR_PROPAGATE( create( device_id, & device ));
  149.     // get configuration
  150.     message = async_send_2( netif_globals.networking_phone, NET_NET_GET_DEVICE_CONF, device->device_id, count, & answer );
  151.     // send names and get settings
  152.     if( ERROR_OCCURRED( measured_strings_send( netif_globals.networking_phone, configuration, count ))
  153.     || ERROR_OCCURRED( measured_strings_return( netif_globals.networking_phone, & settings, & data, count ))){
  154.         async_wait_for( message, NULL );
  155.         return ERROR_CODE;
  156.     }
  157.     // MTU is the first one
  158.     if( settings && ( settings[ 0 ].value )){
  159.         lo_globals.mtu = strtoul( settings[ 0 ].value, NULL, 0 );
  160.     }else{
  161.         lo_globals.mtu = DEFAULT_MTU;
  162.     }
  163.     free( settings );
  164.     free( data );
  165.     // end request
  166.     async_wait_for( message, NULL );
  167.     // print the settings
  168.     printf("\nNew device registered:\n\tid\t= %d\n\tMTU\t= %d", device->device_id, lo_globals.mtu );
  169.     return EOK;
  170. }
  171.  
  172. int send_message( device_id_t device_id, packet_t packet ){
  173.     ERROR_DECLARE;
  174.  
  175.     device_ref  device;
  176.     size_t      length;
  177.     packet_t    next;
  178.  
  179.     ERROR_PROPAGATE( find_device( device_id, & device ));
  180.     if( device->state != NETIF_ACTIVE ) return EPERM;
  181.     next = packet;
  182.     do{
  183.         ++ device->stats.tx_packets;
  184.         ++ device->stats.rx_packets;
  185.         length = packet_get_data_length( next );
  186.         device->stats.tx_bytes += length;
  187.         device->stats.rx_bytes += length;
  188.         next = pq_next( next );
  189.     }while( next );
  190.     nil_message( device, NET_NIL_RECEIVED, packet_get_id( packet ), PACKET_SELF );
  191.     return EOK;
  192. }
  193.  
  194. int start_message( device_id_t device_id ){
  195.     return change_state_message( device_id, NETIF_ACTIVE );
  196. }
  197.  
  198. int stop_message( device_id_t device_id ){
  199.     return change_state_message( device_id, NETIF_STOPPED );
  200. }
  201.  
  202. /** @}
  203.  */
  204.