Changeset b40bfac in mainline for uspace


Ignore:
Timestamp:
2010-11-08T07:13:25Z (15 years ago)
Author:
Vojtech Horky <vojtechhorky@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
63a1e60
Parents:
d70a463 (diff), 3da12d74 (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

Location:
uspace
Files:
49 edited
4 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    rd70a463 rb40bfac  
    5252        app/usb \
    5353        app/virtusbkbd \
     54        app/netstart \
    5455        app/netecho \
    5556        app/nettest1 \
     
    8990        srv/net/tl/tcp \
    9091        srv/net/net \
    91         srv/net/netstart \
    9292        drv/root
    9393
  • uspace/app/bdsh/exec.c

    rd70a463 rb40bfac  
    4141#include <fcntl.h>
    4242#include <str_error.h>
     43#include <errno.h>
    4344
    4445#include "config.h"
     
    116117        task_exit_t texit;
    117118        char *tmp;
    118         int retval;
     119        int rc, retval;
    119120
    120121        tmp = str_dup(find_command(cmd));
    121122        free(found);
    122123
    123         tid = task_spawn(tmp, (const char **) argv, &retval);
     124        rc = task_spawnv(&tid, tmp, (const char **) argv);
    124125        free(tmp);
    125126
    126         if (tid == 0) {
     127        if (rc != 0) {
    127128                cli_error(CL_EEXEC, "%s: Cannot spawn `%s' (%s)", progname, cmd,
    128                     str_error(retval));
     129                    str_error(rc));
    129130                return 1;
    130131        }
    131132       
    132         task_wait(tid, &texit, &retval);
    133         if (texit != TASK_EXIT_NORMAL) {
     133        rc = task_wait(tid, &texit, &retval);
     134        if (rc != EOK) {
     135                printf("%s: Failed waiting for command (%s)\n", str_error(rc));
     136        } else if (texit != TASK_EXIT_NORMAL) {
    134137                printf("%s: Command failed (unexpectedly terminated)\n", progname);
    135138        } else if (retval != 0) {
    136                 printf("%s: Command failed (%s)\n",
    137                     progname, str_error(retval));
     139                printf("%s: Command failed (exit code %d)\n",
     140                    progname, retval);
    138141        }
    139142
  • uspace/app/getterm/getterm.c

    rd70a463 rb40bfac  
    4141#include <task.h>
    4242#include <str_error.h>
     43#include <errno.h>
    4344#include "version.h"
    4445
     
    7475static task_id_t spawn(const char *fname)
    7576{
    76         const char *args[2];
     77        task_id_t id;
     78        int rc;
    7779       
    78         args[0] = fname;
    79         args[1] = NULL;
    80        
    81         int err;
    82         task_id_t id = task_spawn(fname, args, &err);
    83        
    84         if (id == 0)
     80        rc = task_spawnl(&id, fname, fname, NULL);
     81        if (rc != EOK) {
    8582                printf("%s: Error spawning %s (%s)\n", APP_NAME, fname,
    86                     str_error(err));
     83                    str_error(rc));
     84                return 0;
     85        }
    8786       
    8887        return id;
  • uspace/app/init/init.c

    rd70a463 rb40bfac  
    124124static void spawn(const char *fname)
    125125{
    126         const char *argv[2];
     126        int rc;
    127127        struct stat s;
    128128       
     
    131131       
    132132        printf("%s: Spawning %s\n", NAME, fname);
    133        
    134         argv[0] = fname;
    135         argv[1] = NULL;
    136        
    137         int err;
    138         if (!task_spawn(fname, argv, &err))
     133        rc = task_spawnl(NULL, fname, fname, NULL);
     134        if (rc != EOK) {
    139135                printf("%s: Error spawning %s (%s)\n", NAME, fname,
    140                     str_error(err));
     136                    str_error(rc));
     137        }
    141138}
    142139
    143140static void srv_start(const char *fname)
    144141{
    145         const char *argv[2];
    146142        task_id_t id;
    147143        task_exit_t texit;
     
    153149       
    154150        printf("%s: Starting %s\n", NAME, fname);
    155        
    156         argv[0] = fname;
    157         argv[1] = NULL;
    158        
    159         id = task_spawn(fname, argv, &retval);
     151        rc = task_spawnl(&id, fname, fname, NULL);
    160152        if (!id) {
    161153                printf("%s: Error spawning %s (%s)\n", NAME, fname,
    162                     str_error(retval));
     154                    str_error(rc));
    163155                return;
    164156        }
     
    167159        if (rc != EOK) {
    168160                printf("%s: Error waiting for %s (%s(\n", NAME, fname,
    169                     str_error(retval));
    170                 return;
    171         }
    172        
    173         if ((texit != TASK_EXIT_NORMAL) || (retval != 0)) {
    174                 printf("%s: Server %s failed to start (%s)\n", NAME,
    175                         fname, str_error(retval));
     161                    str_error(rc));
     162                return;
     163        }
     164       
     165        if (texit != TASK_EXIT_NORMAL) {
     166                printf("%s: Server %s failed to start (unexpectedly "
     167                    "terminated)\n", NAME, fname);
     168                return;
     169        }
     170
     171        if (retval != 0) {
     172                printf("%s: Server %s failed to start (exit code %d)\n", NAME,
     173                        fname, retval);
    176174        }
    177175}
     
    179177static void console(const char *dev)
    180178{
    181         const char *argv[3];
    182179        char hid_in[DEVMAP_NAME_MAXLEN];
    183180        int rc;
     
    190187        dev_handle_t handle;
    191188        rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
    192        
    193         if (rc == EOK) {
    194                 argv[0] = SRV_CONSOLE;
    195                 argv[1] = hid_in;
    196                 argv[2] = NULL;
    197                
    198                 if (!task_spawn(SRV_CONSOLE, argv, &rc))
    199                         printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE,
    200                             hid_in, str_error(rc));
    201         } else
     189        if (rc != EOK) {
    202190                printf("%s: Error waiting on %s (%s)\n", NAME, hid_in,
    203191                    str_error(rc));
     192                return;
     193        }
     194       
     195        rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, hid_in, NULL);
     196        if (rc != EOK) {
     197                printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE,
     198                    hid_in, str_error(rc));
     199        }
    204200}
    205201
    206202static void getterm(const char *dev, const char *app)
    207203{
    208         const char *argv[4];
    209204        char term[DEVMAP_NAME_MAXLEN];
    210205        int rc;
     
    217212        dev_handle_t handle;
    218213        rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING);
    219        
    220         if (rc == EOK) {
    221                 argv[0] = APP_GETTERM;
    222                 argv[1] = term;
    223                 argv[2] = app;
    224                 argv[3] = NULL;
    225                
    226                 if (!task_spawn(APP_GETTERM, argv, &rc))
    227                         printf("%s: Error spawning %s %s %s (%s)\n", NAME, APP_GETTERM,
    228                             term, app, str_error(rc));
    229         } else
     214        if (rc != EOK) {
    230215                printf("%s: Error waiting on %s (%s)\n", NAME, term,
    231216                    str_error(rc));
     217                return;
     218        }
     219       
     220        rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, term, app, NULL);
     221        if (rc != EOK) {
     222                printf("%s: Error spawning %s %s %s (%s)\n", NAME,
     223                    APP_GETTERM, term, app, str_error(rc));
     224        }
    232225}
    233226
  • uspace/app/netecho/netecho.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup netecho
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Network echo application.
    35  *  Answers received packets.
     34 * Network echo application.
     35 * Answers received packets.
    3636 */
    3737
     
    4141#include <task.h>
    4242#include <arg_parse.h>
    43 #include <err.h>
    4443
    4544#include <net/in.h>
     
    5150#include "print_error.h"
    5251
    53 /** Network echo module name.
    54  */
     52/** Network echo module name. */
    5553#define NAME    "Network Echo"
    5654
    57 /** Prints the application help.
    58  */
    59 void echo_print_help(void);
    60 
    61 /** Module entry point.
    62  *  Reads command line parameters and starts listenning.
    63  *  @param[in] argc The number of command line parameters.
    64  *  @param[in] argv The command line parameters.
    65  *  @returns EOK on success.
    66  */
    67 int main(int argc, char * argv[]);
    68 
    69 void echo_print_help(void){
     55static void echo_print_help(void)
     56{
    7057        printf(
    7158                "Network Echo aplication\n" \
     
    10188}
    10289
    103 int main(int argc, char * argv[]){
    104         ERROR_DECLARE;
    105 
    106         size_t size                     = 1024;
    107         int verbose                     = 0;
    108         char * reply            = NULL;
    109         sock_type_t type        = SOCK_DGRAM;
    110         int count                       = -1;
    111         int family                      = PF_INET;
    112         uint16_t port           = 7;
    113         int backlog                     = 3;
    114 
    115         socklen_t max_length                            = sizeof(struct sockaddr_in6);
     90int main(int argc, char *argv[])
     91{
     92        size_t size = 1024;
     93        int verbose = 0;
     94        char *reply = NULL;
     95        sock_type_t type = SOCK_DGRAM;
     96        int count = -1;
     97        int family = PF_INET;
     98        uint16_t port = 7;
     99        int backlog = 3;
     100
     101        socklen_t max_length = sizeof(struct sockaddr_in6);
    116102        uint8_t address_data[max_length];
    117         struct sockaddr * address                       = (struct sockaddr *) address_data;
    118         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    119         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     103        struct sockaddr *address = (struct sockaddr *) address_data;
     104        struct sockaddr_in *address_in = (struct sockaddr_in *) address;
     105        struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address;
    120106        socklen_t addrlen;
    121107        char address_string[INET6_ADDRSTRLEN];
    122         uint8_t * address_start;
     108        uint8_t *address_start;
    123109        int socket_id;
    124110        int listening_id;
    125         char * data;
     111        char *data;
    126112        size_t length;
    127113        int index;
    128114        size_t reply_length;
    129115        int value;
     116        int rc;
    130117
    131118        // parse the command line arguments
    132         for(index = 1; index < argc; ++ index){
    133                 if(argv[index][0] == '-'){
    134                         switch(argv[index][1]){
    135                                 case 'b':
    136                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0));
    137                                         break;
    138                                 case 'c':
    139                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0));
    140                                         break;
    141                                 case 'f':
    142                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    143                                         break;
    144                                 case 'h':
     119        for (index = 1; index < argc; ++ index) {
     120                if (argv[index][0] == '-') {
     121                        switch (argv[index][1]) {
     122                        case 'b':
     123                                rc = arg_parse_int(argc, argv, &index, &backlog, 0);
     124                                if (rc != EOK)
     125                                        return rc;
     126                                break;
     127                        case 'c':
     128                                rc = arg_parse_int(argc, argv, &index, &count, 0);
     129                                if (rc != EOK)
     130                                        return rc;
     131                                break;
     132                        case 'f':
     133                                rc = arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family);
     134                                if (rc != EOK)
     135                                        return rc;
     136                                break;
     137                        case 'h':
     138                                echo_print_help();
     139                                return EOK;
     140                                break;
     141                        case 'p':
     142                                rc = arg_parse_int(argc, argv, &index, &value, 0);
     143                                if (rc != EOK)
     144                                        return rc;
     145                                port = (uint16_t) value;
     146                                break;
     147                        case 'r':
     148                                rc = arg_parse_string(argc, argv, &index, &reply, 0);
     149                                if (rc != EOK)
     150                                        return rc;
     151                                break;
     152                        case 's':
     153                                rc = arg_parse_int(argc, argv, &index, &value, 0);
     154                                if (rc != EOK)
     155                                        return rc;
     156                                size = (value >= 0) ? (size_t) value : 0;
     157                                break;
     158                        case 't':
     159                                rc = arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type);
     160                                if (rc != EOK)
     161                                        return rc;
     162                                type = (sock_type_t) value;
     163                                break;
     164                        case 'v':
     165                                verbose = 1;
     166                                break;
     167                        // long options with the double minus sign ('-')
     168                        case '-':
     169                                if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) {
     170                                        rc = arg_parse_int(argc, argv, &index, &backlog, 8);
     171                                        if (rc != EOK)
     172                                                return rc;
     173                                } else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) {
     174                                        rc = arg_parse_int(argc, argv, &index, &count, 8);
     175                                } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) {
     176                                        rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family);
     177                                        if (rc != EOK)
     178                                                return rc;
     179                                } else if (str_lcmp(argv[index] + 2, "help", 5) == 0) {
    145180                                        echo_print_help();
    146181                                        return EOK;
    147                                         break;
    148                                 case 'p':
    149                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
     182                                } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) {
     183                                        rc = arg_parse_int(argc, argv, &index, &value, 7);
     184                                        if (rc != EOK)
     185                                                return rc;
    150186                                        port = (uint16_t) value;
    151                                         break;
    152                                 case 'r':
    153                                         ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0));
    154                                         break;
    155                                 case 's':
    156                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
     187                                } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) {
     188                                        rc = arg_parse_string(argc, argv, &index, &reply, 8);
     189                                        if (rc != EOK)
     190                                                return rc;
     191                                } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) {
     192                                        rc = arg_parse_int(argc, argv, &index, &value, 7);
     193                                        if (rc != EOK)
     194                                                return rc;
    157195                                        size = (value >= 0) ? (size_t) value : 0;
    158                                         break;
    159                                 case 't':
    160                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
     196                                } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) {
     197                                        rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type);
     198                                        if (rc != EOK)
     199                                                return rc;
    161200                                        type = (sock_type_t) value;
    162                                         break;
    163                                 case 'v':
     201                                } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) {
    164202                                        verbose = 1;
    165                                         break;
    166                                 // long options with the double minus sign ('-')
    167                                 case '-':
    168                                         if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){
    169                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8));
    170                                         }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){
    171                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8));
    172                                         }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    173                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    174                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    175                                                 echo_print_help();
    176                                                 return EOK;
    177                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    178                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    179                                                 port = (uint16_t) value;
    180                                         }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){
    181                                                 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8));
    182                                         }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){
    183                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    184                                                 size = (value >= 0) ? (size_t) value : 0;
    185                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    186                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    187                                                 type = (sock_type_t) value;
    188                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    189                                                 verbose = 1;
    190                                         }else{
    191                                                 echo_print_help();
    192                                                 return EINVAL;
    193                                         }
    194                                         break;
    195                                 default:
     203                                } else {
    196204                                        echo_print_help();
    197205                                        return EINVAL;
     206                                }
     207                                break;
     208                        default:
     209                                echo_print_help();
     210                                return EINVAL;
    198211                        }
    199                 }else{
     212                } else {
    200213                        echo_print_help();
    201214                        return EINVAL;
     
    204217
    205218        // check the buffer size
    206         if(size <= 0){
     219        if (size <= 0) {
    207220                fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size);
    208221                size = 1024;
     
    210223        // size plus the terminating null (\0)
    211224        data = (char *) malloc(size + 1);
    212         if(! data){
     225        if (!data) {
    213226                fprintf(stderr, "Failed to allocate receive buffer.\n");
    214227                return ENOMEM;
     
    220233        // prepare the address buffer
    221234        bzero(address_data, max_length);
    222         switch(family){
    223                 case PF_INET:
    224                         address_in->sin_family = AF_INET;
    225                         address_in->sin_port = htons(port);
    226                         addrlen = sizeof(struct sockaddr_in);
    227                         break;
    228                 case PF_INET6:
    229                         address_in6->sin6_family = AF_INET6;
    230                         address_in6->sin6_port = htons(port);
    231                         addrlen = sizeof(struct sockaddr_in6);
    232                         break;
    233                 default:
    234                         fprintf(stderr, "Protocol family is not supported\n");
    235                         return EAFNOSUPPORT;
     235        switch (family) {
     236        case PF_INET:
     237                address_in->sin_family = AF_INET;
     238                address_in->sin_port = htons(port);
     239                addrlen = sizeof(struct sockaddr_in);
     240                break;
     241        case PF_INET6:
     242                address_in6->sin6_family = AF_INET6;
     243                address_in6->sin6_port = htons(port);
     244                addrlen = sizeof(struct sockaddr_in6);
     245                break;
     246        default:
     247                fprintf(stderr, "Protocol family is not supported\n");
     248                return EAFNOSUPPORT;
    236249        }
    237250
    238251        // get a listening socket
    239252        listening_id = socket(family, type, 0);
    240         if(listening_id < 0){
     253        if (listening_id < 0) {
    241254                socket_print_error(stderr, listening_id, "Socket create: ", "\n");
    242255                return listening_id;
     
    244257
    245258        // if the stream socket is used
    246         if(type == SOCK_STREAM){
     259        if (type == SOCK_STREAM) {
    247260                // check the backlog
    248                 if(backlog <= 0){
     261                if (backlog <= 0) {
    249262                        fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size);
    250263                        backlog = 3;
    251264                }
    252265                // set the backlog
    253                 if(ERROR_OCCURRED(listen(listening_id, backlog))){
    254                         socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n");
    255                         return ERROR_CODE;
     266                rc = listen(listening_id, backlog);
     267                if (rc != EOK) {
     268                        socket_print_error(stderr, rc, "Socket listen: ", "\n");
     269                        return rc;
    256270                }
    257271        }
    258272
    259273        // bind the listenning socket
    260         if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){
    261                 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n");
    262                 return ERROR_CODE;
    263         }
    264 
    265         if(verbose){
     274        rc = bind(listening_id, address, addrlen);
     275        if (rc != EOK) {
     276                socket_print_error(stderr, rc, "Socket bind: ", "\n");
     277                return rc;
     278        }
     279
     280        if (verbose)
    266281                printf("Socket %d listenning at %d\n", listening_id, port);
    267         }
    268282
    269283        socket_id = listening_id;
     
    271285        // do count times
    272286        // or indefinitely if set to a negative value
    273         while(count){
     287        while (count) {
    274288
    275289                addrlen = max_length;
    276                 if(type == SOCK_STREAM){
     290                if (type == SOCK_STREAM) {
    277291                        // acceept a socket if the stream socket is used
    278292                        socket_id = accept(listening_id, address, &addrlen);
    279                         if(socket_id <= 0){
     293                        if (socket_id <= 0) {
    280294                                socket_print_error(stderr, socket_id, "Socket accept: ", "\n");
    281                         }else{
    282                                 if(verbose){
     295                        } else {
     296                                if (verbose)
    283297                                        printf("Socket %d accepted\n", socket_id);
    284                                 }
    285298                        }
    286299                }
    287300
    288301                // if the datagram socket is used or the stream socked was accepted
    289                 if(socket_id > 0){
     302                if (socket_id > 0) {
    290303
    291304                        // receive an echo request
    292305                        value = recvfrom(socket_id, data, size, 0, address, &addrlen);
    293                         if(value < 0){
     306                        if (value < 0) {
    294307                                socket_print_error(stderr, value, "Socket receive: ", "\n");
    295                         }else{
     308                        } else {
    296309                                length = (size_t) value;
    297                                 if(verbose){
     310                                if (verbose) {
    298311                                        // print the header
    299312
    300313                                        // get the source port and prepare the address buffer
    301314                                        address_start = NULL;
    302                                         switch(address->sa_family){
    303                                                 case AF_INET:
    304                                                         port = ntohs(address_in->sin_port);
    305                                                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    306                                                         break;
    307                                                 case AF_INET6:
    308                                                         port = ntohs(address_in6->sin6_port);
    309                                                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    310                                                         break;
    311                                                 default:
    312                                                         fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
     315                                        switch (address->sa_family) {
     316                                        case AF_INET:
     317                                                port = ntohs(address_in->sin_port);
     318                                                address_start = (uint8_t *) &address_in->sin_addr.s_addr;
     319                                                break;
     320                                        case AF_INET6:
     321                                                port = ntohs(address_in6->sin6_port);
     322                                                address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
     323                                                break;
     324                                        default:
     325                                                fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family);
    313326                                        }
    314327                                        // parse the source address
    315                                         if(address_start){
    316                                                 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){
    317                                                         fprintf(stderr, "Received address error %d\n", ERROR_CODE);
    318                                                 }else{
     328                                        if (address_start) {
     329                                                rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string));
     330                                                if (rc != EOK) {
     331                                                        fprintf(stderr, "Received address error %d\n", rc);
     332                                                } else {
    319333                                                        data[length] = '\0';
    320334                                                        printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data);
     
    324338
    325339                                // answer the request either with the static reply or the original data
    326                                 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){
    327                                         socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    328                                 }
    329 
     340                                rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen);
     341                                if (rc != EOK)
     342                                        socket_print_error(stderr, rc, "Socket send: ", "\n");
    330343                        }
    331344
    332345                        // close the accepted stream socket
    333                         if(type == SOCK_STREAM){
    334                                 if(ERROR_OCCURRED(closesocket(socket_id))){
    335                                         socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    336                                 }
     346                        if (type == SOCK_STREAM) {
     347                                rc = closesocket(socket_id);
     348                                if (rc != EOK)
     349                                        socket_print_error(stderr, rc, "Close socket: ", "\n");
    337350                        }
    338351
     
    340353
    341354                // decrease the count if positive
    342                 if(count > 0){
    343                         -- count;
    344                         if(verbose){
     355                if (count > 0) {
     356                        count--;
     357                        if (verbose)
    345358                                printf("Waiting for next %d packet(s)\n", count);
    346                         }
    347                 }
    348         }
    349 
    350         if(verbose){
     359                }
     360        }
     361
     362        if (verbose)
    351363                printf("Closing the socket\n");
    352         }
    353364
    354365        // close the listenning socket
    355         if(ERROR_OCCURRED(closesocket(listening_id))){
    356                 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");
    357                 return ERROR_CODE;
    358         }
    359 
    360         if(verbose){
     366        rc = closesocket(listening_id);
     367        if (rc != EOK) {
     368                socket_print_error(stderr, rc, "Close socket: ", "\n");
     369                return rc;
     370        }
     371
     372        if (verbose)
    361373                printf("Exiting\n");
    362         }
    363374
    364375        return EOK;
  • uspace/app/netecho/print_error.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup net_app
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Generic application error printing functions implementation.
     34 * Generic application error printing functions implementation.
    3535 */
     36
     37#include "print_error.h"
    3638
    3739#include <stdio.h>
     
    4042#include <net/icmp_codes.h>
    4143
    42 #include "print_error.h"
     44/** Prints the specific ICMP error description.
     45 *
     46 * @param[in] output The description output stream. May be NULL.
     47 * @param[in] error_code The ICMP error code.
     48 * @param[in] prefix The error description prefix. May be NULL.
     49 * @param[in] suffix The error description suffix. May be NULL.
     50 */
     51void icmp_print_error(FILE *output, int error_code, const char *prefix, const char *suffix)
     52{
     53        if (!output)
     54                return;
     55       
     56        if (prefix)
     57                fprintf(output, "%s", prefix);
     58               
     59        switch (error_code) {
     60        case ICMP_DEST_UNREACH:
     61                fprintf(output, "ICMP Destination Unreachable (%d) error", error_code);
     62                break;
     63        case ICMP_SOURCE_QUENCH:
     64                fprintf(output, "ICMP Source Quench (%d) error", error_code);
     65                break;
     66        case ICMP_REDIRECT:
     67                fprintf(output, "ICMP Redirect (%d) error", error_code);
     68                break;
     69        case ICMP_ALTERNATE_ADDR:
     70                fprintf(output, "ICMP Alternate Host Address (%d) error", error_code);
     71                break;
     72        case ICMP_ROUTER_ADV:
     73                fprintf(output, "ICMP Router Advertisement (%d) error", error_code);
     74                break;
     75        case ICMP_ROUTER_SOL:
     76                fprintf(output, "ICMP Router Solicitation (%d) error", error_code);
     77                break;
     78        case ICMP_TIME_EXCEEDED:
     79                fprintf(output, "ICMP Time Exceeded (%d) error", error_code);
     80                break;
     81        case ICMP_PARAMETERPROB:
     82                fprintf(output, "ICMP Paramenter Problem (%d) error", error_code);
     83                break;
     84        case ICMP_CONVERSION_ERROR:
     85                fprintf(output, "ICMP Datagram Conversion Error (%d) error", error_code);
     86                break;
     87        case ICMP_REDIRECT_MOBILE:
     88                fprintf(output, "ICMP Mobile Host Redirect (%d) error", error_code);
     89                break;
     90        case ICMP_SKIP:
     91                fprintf(output, "ICMP SKIP (%d) error", error_code);
     92                break;
     93        case ICMP_PHOTURIS:
     94                fprintf(output, "ICMP Photuris (%d) error", error_code);
     95                break;
     96        default:
     97                fprintf(output, "Other (%d) error", error_code);
     98        }
    4399
    44 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
    45         if(output){
    46                 if(prefix){
    47                         fprintf(output, "%s", prefix);
    48                 }
    49                 switch(error_code){
    50                         case ICMP_DEST_UNREACH:
    51                                 fprintf(output, "ICMP Destination Unreachable (%d) error", error_code);
    52                                 break;
    53                         case ICMP_SOURCE_QUENCH:
    54                                 fprintf(output, "ICMP Source Quench (%d) error", error_code);
    55                                 break;
    56                         case ICMP_REDIRECT:
    57                                 fprintf(output, "ICMP Redirect (%d) error", error_code);
    58                                 break;
    59                         case ICMP_ALTERNATE_ADDR:
    60                                 fprintf(output, "ICMP Alternate Host Address (%d) error", error_code);
    61                                 break;
    62                         case ICMP_ROUTER_ADV:
    63                                 fprintf(output, "ICMP Router Advertisement (%d) error", error_code);
    64                                 break;
    65                         case ICMP_ROUTER_SOL:
    66                                 fprintf(output, "ICMP Router Solicitation (%d) error", error_code);
    67                                 break;
    68                         case ICMP_TIME_EXCEEDED:
    69                                 fprintf(output, "ICMP Time Exceeded (%d) error", error_code);
    70                                 break;
    71                         case ICMP_PARAMETERPROB:
    72                                 fprintf(output, "ICMP Paramenter Problem (%d) error", error_code);
    73                                 break;
    74                         case ICMP_CONVERSION_ERROR:
    75                                 fprintf(output, "ICMP Datagram Conversion Error (%d) error", error_code);
    76                                 break;
    77                         case ICMP_REDIRECT_MOBILE:
    78                                 fprintf(output, "ICMP Mobile Host Redirect (%d) error", error_code);
    79                                 break;
    80                         case ICMP_SKIP:
    81                                 fprintf(output, "ICMP SKIP (%d) error", error_code);
    82                                 break;
    83                         case ICMP_PHOTURIS:
    84                                 fprintf(output, "ICMP Photuris (%d) error", error_code);
    85                                 break;
    86                         default:
    87                                 fprintf(output, "Other (%d) error", error_code);
    88                 }
    89                 if(suffix){
    90                         fprintf(output, "%s", suffix);
    91                 }
    92         }
     100        if (suffix)
     101                fprintf(output, "%s", suffix);
    93102}
    94103
    95 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
    96         if(IS_ICMP_ERROR(error_code)){
     104/** Prints the error description.
     105 *
     106 * Supports ICMP and socket error codes.
     107 *
     108 * @param[in] output The description output stream. May be NULL.
     109 * @param[in] error_code The error code.
     110 * @param[in] prefix The error description prefix. May be NULL.
     111 * @param[in] suffix The error description suffix. May be NULL.
     112 */
     113void print_error(FILE *output, int error_code, const char *prefix, const char *suffix)
     114{
     115        if (IS_ICMP_ERROR(error_code))
    97116                icmp_print_error(output, error_code, prefix, suffix);
    98         }else if(IS_SOCKET_ERROR(error_code)){
     117        else if(IS_SOCKET_ERROR(error_code))
    99118                socket_print_error(output, error_code, prefix, suffix);
    100         }
    101119}
    102120
    103 void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){
    104         if(output){
    105                 if(prefix){
    106                         fprintf(output, "%s", prefix);
    107                 }
    108                 switch(error_code){
    109                         case ENOTSOCK:
    110                                 fprintf(output, "Not a socket (%d) error", error_code);
    111                                 break;
    112                         case EPROTONOSUPPORT:
    113                                 fprintf(output, "Protocol not supported (%d) error", error_code);
    114                                 break;
    115                         case ESOCKTNOSUPPORT:
    116                                 fprintf(output, "Socket type not supported (%d) error", error_code);
    117                                 break;
    118                         case EPFNOSUPPORT:
    119                                 fprintf(output, "Protocol family not supported (%d) error", error_code);
    120                                 break;
    121                         case EAFNOSUPPORT:
    122                                 fprintf(output, "Address family not supported (%d) error", error_code);
    123                                 break;
    124                         case EADDRINUSE:
    125                                 fprintf(output, "Address already in use (%d) error", error_code);
    126                                 break;
    127                         case ENOTCONN:
    128                                 fprintf(output, "Socket not connected (%d) error", error_code);
    129                                 break;
    130                         case NO_DATA:
    131                                 fprintf(output, "No data (%d) error", error_code);
    132                                 break;
    133                         case EINPROGRESS:
    134                                 fprintf(output, "Another operation in progress (%d) error", error_code);
    135                                 break;
    136                         case EDESTADDRREQ:
    137                                 fprintf(output, "Destination address required (%d) error", error_code);
    138                         case TRY_AGAIN:
    139                                 fprintf(output, "Try again (%d) error", error_code);
    140                         default:
    141                                 fprintf(output, "Other (%d) error", error_code);
    142                 }
    143                 if(suffix){
    144                         fprintf(output, "%s", suffix);
    145                 }
     121/** Prints the specific socket error description.
     122 *
     123 * @param[in] output The description output stream. May be NULL.
     124 * @param[in] error_code The socket error code.
     125 * @param[in] prefix The error description prefix. May be NULL.
     126 * @param[in] suffix The error description suffix. May be NULL.
     127 */
     128void socket_print_error(FILE *output, int error_code, const char *prefix, const char *suffix)
     129{
     130        if (!output)
     131                return;
     132
     133        if (prefix)
     134                fprintf(output, "%s", prefix);
     135
     136        switch (error_code) {
     137        case ENOTSOCK:
     138                fprintf(output, "Not a socket (%d) error", error_code);
     139                break;
     140        case EPROTONOSUPPORT:
     141                fprintf(output, "Protocol not supported (%d) error", error_code);
     142                break;
     143        case ESOCKTNOSUPPORT:
     144                fprintf(output, "Socket type not supported (%d) error", error_code);
     145                break;
     146        case EPFNOSUPPORT:
     147                fprintf(output, "Protocol family not supported (%d) error", error_code);
     148                break;
     149        case EAFNOSUPPORT:
     150                fprintf(output, "Address family not supported (%d) error", error_code);
     151                break;
     152        case EADDRINUSE:
     153                fprintf(output, "Address already in use (%d) error", error_code);
     154                break;
     155        case ENOTCONN:
     156                fprintf(output, "Socket not connected (%d) error", error_code);
     157                break;
     158        case NO_DATA:
     159                fprintf(output, "No data (%d) error", error_code);
     160                break;
     161        case EINPROGRESS:
     162                fprintf(output, "Another operation in progress (%d) error", error_code);
     163                break;
     164        case EDESTADDRREQ:
     165                fprintf(output, "Destination address required (%d) error", error_code);
     166        case TRY_AGAIN:
     167                fprintf(output, "Try again (%d) error", error_code);
     168        default:
     169                fprintf(output, "Other (%d) error", error_code);
    146170        }
     171
     172        if (suffix)
     173                fprintf(output, "%s", suffix);
    147174}
    148175
    149176/** @}
    150177 */
     178
  • uspace/app/netecho/print_error.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup net_app
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Generic application error printing functions.
     34 * Generic application error printing functions.
    3535 */
    3636
    37 #ifndef __NET_APP_PRINT__
    38 #define __NET_APP_PRINT__
     37#ifndef NET_APP_PRINT_
     38#define NET_APP_PRINT_
     39
     40#include <stdio.h>
    3941
    4042/** Returns whether the error code may be an ICMP error code.
    41  *  @param[in] error_code The error code.
    42  *  @returns A value indicating whether the error code may be an ICMP error code.
     43 *
     44 * @param[in] error_code The error code.
     45 * @returns A value indicating whether the error code may be an ICMP error code.
    4346 */
    44 #define IS_ICMP_ERROR(error_code)               ((error_code) > 0)
     47#define IS_ICMP_ERROR(error_code)       ((error_code) > 0)
    4548
    4649/** Returns whether the error code may be socket error code.
    47  *  @param[in] error_code The error code.
    48  *  @returns A value indicating whether the error code may be a socket error code.
     50 *
     51 * @param[in] error_code The error code.
     52 * @returns A value indicating whether the error code may be a socket error code.
    4953 */
    5054#define IS_SOCKET_ERROR(error_code)     ((error_code) < 0)
    5155
    52 /** Prints the specific ICMP error description.
    53  *  @param[in] output The description output stream. May be NULL.
    54  *  @param[in] error_code The ICMP error code.
    55  *  @param[in] prefix The error description prefix. May be NULL.
    56  *  @param[in] suffix The error description suffix. May be NULL.
    57  */
    58 extern void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
    59 
    60 /** Prints the error description.
    61  *  Supports ICMP and socket error codes.
    62  *  @param[in] output The description output stream. May be NULL.
    63  *  @param[in] error_code The error code.
    64  *  @param[in] prefix The error description prefix. May be NULL.
    65  *  @param[in] suffix The error description suffix. May be NULL.
    66  */
    67 extern void print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
    68 
    69 /** Prints the specific socket error description.
    70  *  @param[in] output The description output stream. May be NULL.
    71  *  @param[in] error_code The socket error code.
    72  *  @param[in] prefix The error description prefix. May be NULL.
    73  *  @param[in] suffix The error description suffix. May be NULL.
    74  */
    75 extern void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);
     56extern void icmp_print_error(FILE *, int, const char *, const char *);
     57extern void print_error(FILE *, int, const char *, const char *);
     58extern void socket_print_error(FILE *, int, const char *, const char *);
    7659
    7760#endif
  • uspace/app/netstart/Makefile

    rd70a463 rb40bfac  
    2828#
    2929
    30 USPACE_PREFIX = ../../..
     30USPACE_PREFIX = ../..
    3131LIBS = $(LIBNET_PREFIX)/libnet.a
    3232EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
     
    3535
    3636SOURCES = \
    37         netstart.c \
    38         self_test.c
     37        netstart.c
    3938
    4039include $(USPACE_PREFIX)/Makefile.common
  • uspace/app/netstart/netstart.c

    rd70a463 rb40bfac  
    3232
    3333/** @file
    34  *
    3534 * Start the networking subsystem.
    36  * Perform networking self-test if executed
    37  * with the -s argument.
    38  *
    3935 */
    4036
     
    4541#include <task.h>
    4642#include <str_error.h>
    47 #include <err.h>
    4843#include <ipc/ipc.h>
    4944#include <ipc/services.h>
     
    5247#include <net/modules.h>
    5348
    54 #include "self_test.h"
    55 
    5649/** Start a module.
    5750 *
    58  * @param[in] desc The module description
    59  * @param[in] path The module absolute path.
    60  *
    61  * @returns true on succesful spanwning
    62  * @returns false on failure
    63  *
     51 * @param[in] desc      The module description
     52 * @param[in] path      The module absolute path.
     53 * @returns             True on succesful spanwning.
     54 * @returns             False on failure
    6455 */
    6556static bool spawn(const char *desc, const char *path)
    6657{
     58        int rc;
     59
    6760        printf("%s: Spawning %s (%s)\n", NAME, desc, path);
    68        
    69         const char *argv[2];
    70        
    71         argv[0] = path;
    72         argv[1] = NULL;
    73        
    74         int err;
    75         if (task_spawn(path, argv, &err) == 0) {
     61        rc = task_spawnl(NULL, path, path, NULL);
     62        if (rc != EOK) {
    7663                fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, path,
    77                     str_error(err));
     64                    str_error(rc));
    7865                return false;
    7966        }
     
    8471int main(int argc, char *argv[])
    8572{
    86         ERROR_DECLARE;
    87        
    88         /* Run self-tests */
    89         if ((argc > 1) && (str_cmp(argv[1], "-s") == 0))
    90                 ERROR_PROPAGATE(self_test());
     73        int rc;
    9174       
    9275        if (!spawn("networking service", "/srv/net"))
     
    9679       
    9780        int net_phone = connect_to_service(SERVICE_NETWORKING);
    98         if (ERROR_OCCURRED(ipc_call_sync_0_0(net_phone, NET_NET_STARTUP))) {
    99                 fprintf(stderr, "%s: Startup error %d\n", NAME, ERROR_CODE);
    100                 return ERROR_CODE;
     81        rc = ipc_call_sync_0_0(net_phone, NET_NET_STARTUP);
     82        if (rc != EOK) {
     83                fprintf(stderr, "%s: Startup error %d\n", NAME, rc);
     84                return rc;
    10185        }
    10286       
  • uspace/app/nettest1/nettest.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup nettest
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking test support functions implementation.
     34 * Networking test support functions implementation.
    3535 */
    3636
    3737#include <stdio.h>
    38 #include <err.h>
    39 
    4038#include <net/socket.h>
    4139
     
    4341#include "print_error.h"
    4442
    45 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){
    46         int index;
    47 
    48         if(verbose){
     43
     44/** Creates new sockets.
     45 *
     46 * @param[in] verbose A value indicating whether to print out verbose information.
     47 * @param[out] socket_ids A field to store the socket identifiers.
     48 * @param[in] sockets The number of sockets to create. Should be at most the size of the field.
     49 * @param[in] family The socket address family.
     50 * @param[in] type The socket type.
     51 * @returns EOK on success.
     52 * @returns Other error codes as defined for the socket() function.
     53 */
     54int sockets_create(int verbose, int *socket_ids, int sockets, int family, sock_type_t type)
     55{
     56        int index;
     57
     58        if (verbose)
    4959                printf("Create\t");
    50         }
    51         fflush(stdout);
    52         for(index = 0; index < sockets; ++ index){
     60               
     61        fflush(stdout);
     62       
     63        for (index = 0; index < sockets; index++) {
    5364                socket_ids[index] = socket(family, type, 0);
    54                 if(socket_ids[index] < 0){
     65                if (socket_ids[index] < 0) {
    5566                        printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    5667                        socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n");
    5768                        return socket_ids[index];
    5869                }
    59                 if(verbose){
    60                         print_mark(index);
    61                 }
    62         }
    63         return EOK;
    64 }
    65 
    66 int sockets_close(int verbose, int * socket_ids, int sockets){
    67         ERROR_DECLARE;
    68 
    69         int index;
    70 
    71         if(verbose){
     70                if (verbose)
     71                        print_mark(index);
     72        }
     73       
     74        return EOK;
     75}
     76
     77/** Closes sockets.
     78 *
     79 * @param[in] verbose A value indicating whether to print out verbose information.
     80 * @param[in] socket_ids A field of stored socket identifiers.
     81 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     82 * @returns EOK on success.
     83 * @returns Other error codes as defined for the closesocket() function.
     84 */
     85int sockets_close(int verbose, int *socket_ids, int sockets)
     86{
     87        int index;
     88        int rc;
     89
     90        if (verbose)
    7291                printf("\tClose\t");
    73         }
    74         fflush(stdout);
    75         for(index = 0; index < sockets; ++ index){
    76                 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){
     92
     93        fflush(stdout);
     94       
     95        for (index = 0; index < sockets; index++) {
     96                rc = closesocket(socket_ids[index]);
     97                if (rc != EOK) {
    7798                        printf("Socket %d (%d) error:\n", index, socket_ids[index]);
    78                         socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n");
    79                         return ERROR_CODE;
    80                 }
    81                 if(verbose){
    82                         print_mark(index);
    83                 }
    84         }
    85         return EOK;
    86 }
    87 
    88 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){
    89         ERROR_DECLARE;
    90 
    91         int index;
    92 
    93         if(verbose){
     99                        socket_print_error(stderr, rc, "Socket close: ", "\n");
     100                        return rc;
     101                }
     102                if (verbose)
     103                        print_mark(index);
     104        }
     105       
     106        return EOK;
     107}
     108
     109/** Connects sockets.
     110 *
     111 * @param[in] verbose A value indicating whether to print out verbose information.
     112 * @param[in] socket_ids A field of stored socket identifiers.
     113 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     114 * @param[in] address The destination host address to connect to.
     115 * @param[in] addrlen The length of the destination address in bytes.
     116 * @returns EOK on success.
     117 * @returns Other error codes as defined for the connect() function.
     118 */
     119int sockets_connect(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t addrlen)
     120{
     121        int index;
     122        int rc;
     123
     124        if (verbose)
    94125                printf("\tConnect\t");
    95         }
    96         fflush(stdout);
    97         for(index = 0; index < sockets; ++ index){
    98                 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){
    99                         socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n");
    100                         return ERROR_CODE;
    101                 }
    102                 if(verbose){
    103                         print_mark(index);
    104                 }
    105         }
    106         return EOK;
    107 }
    108 
    109 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){
    110         ERROR_DECLARE;
    111 
     126       
     127        fflush(stdout);
     128       
     129        for (index = 0; index < sockets; index++) {
     130                rc = connect(socket_ids[index], address, addrlen);
     131                if (rc != EOK) {
     132                        socket_print_error(stderr, rc, "Socket connect: ", "\n");
     133                        return rc;
     134                }
     135                if (verbose)
     136                        print_mark(index);
     137        }
     138       
     139        return EOK;
     140}
     141
     142/** Sends data via sockets.
     143 *
     144 * @param[in] verbose A value indicating whether to print out verbose information.
     145 * @param[in] socket_ids A field of stored socket identifiers.
     146 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     147 * @param[in] address The destination host address to send data to.
     148 * @param[in] addrlen The length of the destination address in bytes.
     149 * @param[in] data The data to be sent.
     150 * @param[in] size The data size in bytes.
     151 * @param[in] messages The number of datagrams per socket to be sent.
     152 * @returns EOK on success.
     153 * @returns Other error codes as defined for the sendto() function.
     154 */
     155int sockets_sendto(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t addrlen, char *data, int size, int messages)
     156{
    112157        int index;
    113158        int message;
    114 
    115         if(verbose){
     159        int rc;
     160
     161        if (verbose)
    116162                printf("\tSendto\t");
    117         }
    118         fflush(stdout);
    119         for(index = 0; index < sockets; ++ index){
    120                 for(message = 0; message < messages; ++ message){
    121                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){
    122                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    123                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    124                                 return ERROR_CODE;
    125                         }
    126                 }
    127                 if(verbose){
    128                         print_mark(index);
    129                 }
    130         }
    131         return EOK;
    132 }
    133 
    134 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
     163
     164        fflush(stdout);
     165       
     166        for (index = 0; index < sockets; index++) {
     167                for (message = 0; message < messages; message++) {
     168                        rc = sendto(socket_ids[index], data, size, 0, address, addrlen);
     169                        if (rc != EOK) {
     170                                printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
     171                                socket_print_error(stderr, rc, "Socket send: ", "\n");
     172                                return rc;
     173                        }
     174                }
     175                if (verbose)
     176                        print_mark(index);
     177        }
     178       
     179        return EOK;
     180}
     181
     182/** Receives data via sockets.
     183 *
     184 * @param[in] verbose A value indicating whether to print out verbose information.
     185 * @param[in] socket_ids A field of stored socket identifiers.
     186 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     187 * @param[in] address The source host address of received datagrams.
     188 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
     189 * @param[out] data The received data.
     190 * @param[in] size The maximum data size in bytes.
     191 * @param[in] messages The number of datagrams per socket to be received.
     192 * @returns EOK on success.
     193 * @returns Other error codes as defined for the recvfrom() function.
     194 */
     195int sockets_recvfrom(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t *addrlen, char *data, int size, int messages)
     196{
    135197        int value;
    136198        int index;
    137199        int message;
    138200
    139         if(verbose){
     201        if (verbose)
    140202                printf("\tRecvfrom\t");
    141         }
    142         fflush(stdout);
    143         for(index = 0; index < sockets; ++ index){
    144                 for(message = 0; message < messages; ++ message){
     203       
     204        fflush(stdout);
     205       
     206        for (index = 0; index < sockets; index++) {
     207                for (message = 0; message < messages; message++) {
    145208                        value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    146                         if(value < 0){
     209                        if (value < 0) {
    147210                                printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    148211                                socket_print_error(stderr, value, "Socket receive: ", "\n");
     
    150213                        }
    151214                }
    152                 if(verbose){
    153                         print_mark(index);
    154                 }
    155         }
    156         return EOK;
    157 }
    158 
    159 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){
    160         ERROR_DECLARE;
    161 
     215                if (verbose)
     216                        print_mark(index);
     217        }
     218        return EOK;
     219}
     220
     221/** Sends and receives data via sockets.
     222 *
     223 * Each datagram is sent and a reply read consequently.
     224 * The next datagram is sent after the reply is received.
     225 *
     226 * @param[in] verbose A value indicating whether to print out verbose information.
     227 * @param[in] socket_ids A field of stored socket identifiers.
     228 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
     229 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
     230 * @param[in] addrlen The length of the destination address in bytes.
     231 * @param[in,out] data The data to be sent. The received data are set instead.
     232 * @param[in] size The data size in bytes.
     233 * @param[in] messages The number of datagrams per socket to be received.
     234 * @returns EOK on success.
     235 * @returns Other error codes as defined for the recvfrom() function.
     236 */
     237int sockets_sendto_recvfrom(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t *addrlen, char *data, int size, int messages)
     238{
    162239        int value;
    163240        int index;
    164241        int message;
    165 
    166         if(verbose){
     242        int rc;
     243
     244        if (verbose)
    167245                printf("\tSendto and recvfrom\t");
    168         }
    169         fflush(stdout);
    170         for(index = 0; index < sockets; ++ index){
    171                 for(message = 0; message < messages; ++ message){
    172                         if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){
    173                                 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    174                                 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n");
    175                                 return ERROR_CODE;
     246
     247        fflush(stdout);
     248       
     249        for (index = 0; index < sockets; index++) {
     250                for (message = 0; message < messages; message++) {
     251                        rc = sendto(socket_ids[index], data, size, 0, address, *addrlen);
     252                        if (rc != EOK) {
     253                                printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
     254                                socket_print_error(stderr, rc, "Socket send: ", "\n");
     255                                return rc;
    176256                        }
    177257                        value = recvfrom(socket_ids[index], data, size, 0, address, addrlen);
    178                         if(value < 0){
     258                        if (value < 0) {
    179259                                printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message);
    180260                                socket_print_error(stderr, value, "Socket receive: ", "\n");
     
    182262                        }
    183263                }
    184                 if(verbose){
    185                         print_mark(index);
    186                 }
    187         }
    188         return EOK;
    189 }
    190 
    191 void print_mark(int index){
    192         if((index + 1) % 10){
     264                if (verbose)
     265                        print_mark(index);
     266        }
     267       
     268        return EOK;
     269}
     270
     271/** Prints a mark.
     272 *
     273 * If the index is a multiple of ten, a different mark is printed.
     274 *
     275 * @param[in] index The index of the mark to be printed.
     276 */
     277void print_mark(int index)
     278{
     279        if ((index + 1) % 10)
    193280                printf("*");
    194         }else{
     281        else
    195282                printf("|");
    196         }
    197283        fflush(stdout);
    198284}
  • uspace/app/nettest1/nettest.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup nettest
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking test support functions.
     34 * Networking test support functions.
    3535 */
    3636
    37 #ifndef __NET_TEST__
    38 #define __NET_TEST__
     37#ifndef NET_TEST_
     38#define NET_TEST_
    3939
    4040#include <net/socket.h>
    4141
    42 /** Prints a mark.
    43  *  If the index is a multiple of ten, a different mark is printed.
    44  *  @param[in] index The index of the mark to be printed.
    45  */
    46 extern void print_mark(int index);
    47 
    48 /** Creates new sockets.
    49  *  @param[in] verbose A value indicating whether to print out verbose information.
    50  *  @param[out] socket_ids A field to store the socket identifiers.
    51  *  @param[in] sockets The number of sockets to create. Should be at most the size of the field.
    52  *  @param[in] family The socket address family.
    53  *  @param[in] type The socket type.
    54  *  @returns EOK on success.
    55  *  @returns Other error codes as defined for the socket() function.
    56  */
    57 extern int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type);
    58 
    59 /** Closes sockets.
    60  *  @param[in] verbose A value indicating whether to print out verbose information.
    61  *  @param[in] socket_ids A field of stored socket identifiers.
    62  *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
    63  *  @returns EOK on success.
    64  *  @returns Other error codes as defined for the closesocket() function.
    65  */
    66 extern int sockets_close(int verbose, int * socket_ids, int sockets);
    67 
    68 /** Connects sockets.
    69  *  @param[in] verbose A value indicating whether to print out verbose information.
    70  *  @param[in] socket_ids A field of stored socket identifiers.
    71  *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
    72  *  @param[in] address The destination host address to connect to.
    73  *  @param[in] addrlen The length of the destination address in bytes.
    74  *  @returns EOK on success.
    75  *  @returns Other error codes as defined for the connect() function.
    76  */
    77 extern int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen);
    78 
    79 /** Sends data via sockets.
    80  *  @param[in] verbose A value indicating whether to print out verbose information.
    81  *  @param[in] socket_ids A field of stored socket identifiers.
    82  *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
    83  *  @param[in] address The destination host address to send data to.
    84  *  @param[in] addrlen The length of the destination address in bytes.
    85  *  @param[in] data The data to be sent.
    86  *  @param[in] size The data size in bytes.
    87  *  @param[in] messages The number of datagrams per socket to be sent.
    88  *  @returns EOK on success.
    89  *  @returns Other error codes as defined for the sendto() function.
    90  */
    91 extern int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages);
    92 
    93 /** Receives data via sockets.
    94  *  @param[in] verbose A value indicating whether to print out verbose information.
    95  *  @param[in] socket_ids A field of stored socket identifiers.
    96  *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
    97  *  @param[in] address The source host address of received datagrams.
    98  *  @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead.
    99  *  @param[out] data The received data.
    100  *  @param[in] size The maximum data size in bytes.
    101  *  @param[in] messages The number of datagrams per socket to be received.
    102  *  @returns EOK on success.
    103  *  @returns Other error codes as defined for the recvfrom() function.
    104  */
    105 extern int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
    106 
    107 /** Sends and receives data via sockets.
    108  *  Each datagram is sent and a reply read consequently.
    109  *  The next datagram is sent after the reply is received.
    110  *  @param[in] verbose A value indicating whether to print out verbose information.
    111  *  @param[in] socket_ids A field of stored socket identifiers.
    112  *  @param[in] sockets The number of sockets in the field. Should be at most the size of the field.
    113  *  @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead.
    114  *  @param[in] addrlen The length of the destination address in bytes.
    115  *  @param[in,out] data The data to be sent. The received data are set instead.
    116  *  @param[in] size The data size in bytes.
    117  *  @param[in] messages The number of datagrams per socket to be received.
    118  *  @returns EOK on success.
    119  *  @returns Other error codes as defined for the recvfrom() function.
    120  */
    121 extern int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages);
     42extern void print_mark(int);
     43extern int sockets_create(int, int *, int, int, sock_type_t);
     44extern int sockets_close(int, int *, int);
     45extern int sockets_connect(int, int *, int, struct sockaddr *, socklen_t);
     46extern int sockets_sendto(int, int *, int, struct sockaddr *, socklen_t, char *, int, int);
     47extern int sockets_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int);
     48extern int sockets_sendto_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int);
    12249
    12350#endif
     
    12552/** @}
    12653 */
     54
  • uspace/app/nettest1/nettest1.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup nettest
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking test 1 application - sockets.
    35  */
     34 * Networking test 1 application - sockets.
     35 */
     36
     37#include "nettest.h"
     38#include "print_error.h"
    3639
    3740#include <malloc.h>
     
    4144#include <time.h>
    4245#include <arg_parse.h>
    43 #include <err.h>
    4446
    4547#include <net/in.h>
     
    4951#include <net/socket_parse.h>
    5052
    51 #include "nettest.h"
    52 #include "print_error.h"
    53 
    54 /** Echo module name.
    55  */
     53/** Echo module name. */
    5654#define NAME    "Nettest1"
    5755
    58 /** Packet data pattern.
    59  */
     56/** Packet data pattern. */
    6057#define NETTEST1_TEXT   "Networking test 1 - sockets"
    6158
    62 /** Module entry point.
    63  *  Starts testing.
    64  *  @param[in] argc The number of command line parameters.
    65  *  @param[in] argv The command line parameters.
    66  *  @returns EOK on success.
    67  */
    68 int main(int argc, char * argv[]);
    69 
    70 /** Prints the application help.
    71  */
    72 void nettest1_print_help(void);
    73 
    74 /** Refreshes the data.
    75  *  Fills the data block with the NETTEST1_TEXT pattern.
    76  *  @param[out] data The data block.
    77  *  @param[in] size The data block size in bytes.
    78  */
    79 void nettest1_refresh_data(char * data, size_t size);
    80 
    81 int main(int argc, char * argv[]){
    82         ERROR_DECLARE;
    83 
    84         size_t size                     = 27;
    85         int verbose                     = 0;
    86         sock_type_t type        = SOCK_DGRAM;
    87         int sockets                     = 10;
    88         int messages            = 10;
    89         int family                      = PF_INET;
    90         uint16_t port           = 7;
    91 
    92         socklen_t max_length                            = sizeof(struct sockaddr_in6);
    93         uint8_t address_data[max_length];
    94         struct sockaddr * address                       = (struct sockaddr *) address_data;
    95         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    96         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
    97         socklen_t addrlen;
    98 //      char address_string[INET6_ADDRSTRLEN];
    99         uint8_t * address_start;
    100 
    101         int * socket_ids;
    102         char * data;
     59static int family = PF_INET;
     60static sock_type_t type = SOCK_DGRAM;
     61static char *data;
     62static size_t size = 27;
     63static int verbose = 0;
     64
     65static struct sockaddr *address;
     66static socklen_t addrlen;
     67
     68static int sockets;
     69static int messages;
     70static uint16_t port;
     71
     72static void nettest1_print_help(void)
     73{
     74        printf(
     75            "Network Networking test 1 aplication - sockets\n"
     76            "Usage: echo [options] numeric_address\n"
     77            "Where options are:\n"
     78            "-f protocol_family | --family=protocol_family\n"
     79            "\tThe listenning socket protocol family. Only the PF_INET and "
     80            "PF_INET6 are supported.\n"
     81            "\n"
     82            "-h | --help\n"
     83            "\tShow this application help.\n"
     84            "\n"
     85            "-m count | --messages=count\n"
     86            "\tThe number of messages to send and receive per socket. The "
     87            "default is 10.\n"
     88            "\n"
     89            "-n sockets | --sockets=count\n"
     90            "\tThe number of sockets to use. The default is 10.\n"
     91            "\n"
     92            "-p port_number | --port=port_number\n"
     93            "\tThe port number the application should send messages to. The "
     94            "default is 7.\n"
     95            "\n"
     96            "-s packet_size | --size=packet_size\n"
     97            "\tThe packet data size the application sends. The default is "
     98            "28 bytes.\n"
     99            "\n"
     100            "-v | --verbose\n"
     101            "\tShow all output messages.\n");
     102}
     103
     104/** Parse one command-line option.
     105 *
     106 * @param argc          Number of all command-line arguments.
     107 * @param argv          All command-line arguments.
     108 * @param index         Current argument index (in, out).
     109 */
     110static int nettest1_parse_opt(int argc, char *argv[], int *index)
     111{
    103112        int value;
     113        int rc;
     114
     115        switch (argv[*index][1]) {
     116        /*
     117         * Short options with only one letter
     118         */
     119        case 'f':
     120                rc = arg_parse_name_int(argc, argv, index, &family, 0, socket_parse_protocol_family);
     121                if (rc != EOK)
     122                        return rc;
     123                break;
     124        case 'h':
     125                nettest1_print_help();
     126                return EOK;
     127        case 'm':
     128                rc = arg_parse_int(argc, argv, index, &messages, 0);
     129                if (rc != EOK)
     130                        return rc;
     131                break;
     132        case 'n':
     133                rc = arg_parse_int(argc, argv, index, &sockets, 0);
     134                if (rc != EOK)
     135                        return rc;
     136                break;
     137        case 'p':
     138                rc = arg_parse_int(argc, argv, index, &value, 0);
     139                if (rc != EOK)
     140                        return rc;
     141                port = (uint16_t) value;
     142                break;
     143        case 's':
     144                rc = arg_parse_int(argc, argv, index, &value, 0);
     145                if (rc != EOK)
     146                        return rc;
     147                size = (value >= 0) ? (size_t) value : 0;
     148                break;
     149        case 't':
     150                rc = arg_parse_name_int(argc, argv, index, &value, 0, socket_parse_socket_type);
     151                if (rc != EOK)
     152                        return rc;
     153                type = (sock_type_t) value;
     154                break;
     155        case 'v':
     156                verbose = 1;
     157                break;
     158        /*
     159         * Long options with double dash ('-')
     160         */
     161        case '-':
     162                if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
     163                        rc = arg_parse_name_int(argc, argv, index, &family, 9,
     164                            socket_parse_protocol_family);
     165                        if (rc != EOK)
     166                                return rc;
     167                } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
     168                        nettest1_print_help();
     169                        return EOK;
     170                } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) {
     171                        rc = arg_parse_int(argc, argv, index, &messages, 8);
     172                        if (rc != EOK)
     173                                return rc;
     174                } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) {
     175                        rc = arg_parse_int(argc, argv, index, &sockets, 8);
     176                        if (rc != EOK)
     177                                return rc;
     178                } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
     179                        rc = arg_parse_int(argc, argv, index, &value, 7);
     180                        if (rc != EOK)
     181                                return rc;
     182                        port = (uint16_t) value;
     183                } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
     184                        rc = arg_parse_name_int(argc, argv, index, &value, 7,
     185                            socket_parse_socket_type);
     186                        if (rc != EOK)
     187                                return rc;
     188                        type = (sock_type_t) value;
     189                } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
     190                        verbose = 1;
     191                } else {
     192                        nettest1_print_help();
     193                        return EINVAL;
     194                }
     195                break;
     196        default:
     197                nettest1_print_help();
     198                return EINVAL;
     199        }
     200
     201        return EOK;
     202}
     203
     204/** Fill buffer with the NETTEST1_TEXT pattern.
     205 *
     206 * @param buffer        Data buffer.
     207 * @param size          Buffer size in bytes.
     208 */
     209static void nettest1_fill_buffer(char *buffer, size_t size)
     210{
     211        size_t length;
     212
     213        length = 0;
     214        while (size > length + sizeof(NETTEST1_TEXT) - 1) {
     215                memcpy(buffer + length, NETTEST1_TEXT,
     216                    sizeof(NETTEST1_TEXT) - 1);
     217                length += sizeof(NETTEST1_TEXT) - 1;
     218        }
     219
     220        memcpy(buffer + length, NETTEST1_TEXT, size - length);
     221        buffer[size] = '\0';
     222}
     223
     224static int nettest1_test(int *socket_ids, int nsockets, int nmessages)
     225{
     226        int rc;
     227
     228        if (verbose)
     229                printf("%d sockets, %d messages\n", nsockets, nmessages);
     230
     231        rc = sockets_create(verbose, socket_ids, nsockets, family, type);
     232        if (rc != EOK)
     233                return rc;
     234
     235        if (type == SOCK_STREAM) {
     236                rc = sockets_connect(verbose, socket_ids, nsockets, address,
     237                    addrlen);
     238                if (rc != EOK)
     239                        return rc;
     240        }
     241
     242        rc = sockets_sendto_recvfrom(verbose, socket_ids, nsockets, address,
     243            &addrlen, data, size, nmessages);
     244        if (rc != EOK)
     245                return rc;
     246
     247        rc = sockets_close(verbose, socket_ids, nsockets);
     248        if (rc != EOK)
     249                return rc;
     250
     251        if (verbose)
     252                printf("\tOK\n");
     253
     254        /****/
     255
     256        rc = sockets_create(verbose, socket_ids, nsockets, family, type);
     257        if (rc != EOK)
     258                return rc;
     259
     260        if (type == SOCK_STREAM) {
     261                rc = sockets_connect(verbose, socket_ids, nsockets, address,
     262                    addrlen);
     263                if (rc != EOK)
     264                        return rc;
     265        }
     266
     267        rc = sockets_sendto(verbose, socket_ids, nsockets, address, addrlen,
     268            data, size, nmessages);
     269        if (rc != EOK)
     270                return rc;
     271
     272        rc = sockets_recvfrom(verbose, socket_ids, nsockets, address, &addrlen,
     273            data, size, nmessages);
     274        if (rc != EOK)
     275                return rc;
     276
     277        rc = sockets_close(verbose, socket_ids, nsockets);
     278        if (rc != EOK)
     279                return rc;
     280
     281        if (verbose)
     282                printf("\tOK\n");
     283
     284        return EOK;
     285}
     286
     287int main(int argc, char *argv[])
     288{
     289
     290        socklen_t max_length;
     291        uint8_t *address_data[sizeof(struct sockaddr_in6)];
     292        struct sockaddr_in *address_in;
     293        struct sockaddr_in6 *address_in6;
     294        uint8_t *address_start;
     295
     296        int *socket_ids;
    104297        int index;
    105298        struct timeval time_before;
    106299        struct timeval time_after;
    107300
    108         // parse the command line arguments
    109         // stop before the last argument if it does not start with the minus sign ('-')
    110         for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
    111                 // options should start with the minus sign ('-')
    112                 if(argv[index][0] == '-'){
    113                         switch(argv[index][1]){
    114                                 // short options with only one letter
    115                                 case 'f':
    116                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    117                                         break;
    118                                 case 'h':
    119                                         nettest1_print_help();
    120                                         return EOK;
    121                                         break;
    122                                 case 'm':
    123                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
    124                                         break;
    125                                 case 'n':
    126                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
    127                                         break;
    128                                 case 'p':
    129                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    130                                         port = (uint16_t) value;
    131                                         break;
    132                                 case 's':
    133                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    134                                         size = (value >= 0) ? (size_t) value : 0;
    135                                         break;
    136                                 case 't':
    137                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    138                                         type = (sock_type_t) value;
    139                                         break;
    140                                 case 'v':
    141                                         verbose = 1;
    142                                         break;
    143                                 // long options with the double minus sign ('-')
    144                                 case '-':
    145                                         if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    146                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    147                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    148                                                 nettest1_print_help();
    149                                                 return EOK;
    150                                         }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    151                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
    152                                         }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    153                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
    154                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    155                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    156                                                 port = (uint16_t) value;
    157                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    158                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    159                                                 type = (sock_type_t) value;
    160                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    161                                                 verbose = 1;
    162                                         }else{
    163                                                 nettest1_print_help();
    164                                                 return EINVAL;
    165                                         }
    166                                         break;
    167                                 default:
    168                                         nettest1_print_help();
    169                                         return EINVAL;
    170                         }
    171                 }else{
     301        int rc;
     302
     303        max_length = sizeof(address_data);
     304        address = (struct sockaddr *) address_data;
     305        address_in = (struct sockaddr_in *) address;
     306        address_in6 = (struct sockaddr_in6 *) address;
     307
     308        sockets = 10;
     309        messages = 10;
     310        port = 7;
     311
     312        /*
     313         * Parse the command line arguments. Stop before the last argument
     314         * if it does not start with dash ('-')
     315         */
     316        for (index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); index++) {
     317                /* Options should start with dash ('-') */
     318                if (argv[index][0] == '-') {
     319                        rc = nettest1_parse_opt(argc, argv, &index);
     320                        if (rc != EOK)
     321                                return rc;
     322                } else {
    172323                        nettest1_print_help();
    173324                        return EINVAL;
     
    175326        }
    176327
    177         // if not before the last argument containing the address
    178         if(index >= argc){
     328        /* If not before the last argument containing the address */
     329        if (index >= argc) {
    179330                printf("Command line error: missing address\n");
    180331                nettest1_print_help();
     
    182333        }
    183334
    184         // prepare the address buffer
     335        /* Prepare the address buffer */
    185336        bzero(address_data, max_length);
    186         switch(family){
    187                 case PF_INET:
    188                         address_in->sin_family = AF_INET;
    189                         address_in->sin_port = htons(port);
    190                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    191                         addrlen = sizeof(struct sockaddr_in);
    192                         break;
    193                 case PF_INET6:
    194                         address_in6->sin6_family = AF_INET6;
    195                         address_in6->sin6_port = htons(port);
    196                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    197                         addrlen = sizeof(struct sockaddr_in6);
    198                         break;
    199                 default:
    200                         fprintf(stderr, "Address family is not supported\n");
    201                         return EAFNOSUPPORT;
    202         }
    203 
    204         // parse the last argument which should contain the address
    205         if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    206                 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
    207                 return ERROR_CODE;
    208         }
    209 
    210         // check the buffer size
    211         if(size <= 0){
    212                 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
     337
     338        switch (family) {
     339        case PF_INET:
     340                address_in->sin_family = AF_INET;
     341                address_in->sin_port = htons(port);
     342                address_start = (uint8_t *) &address_in->sin_addr.s_addr;
     343                addrlen = sizeof(struct sockaddr_in);
     344                break;
     345        case PF_INET6:
     346                address_in6->sin6_family = AF_INET6;
     347                address_in6->sin6_port = htons(port);
     348                address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
     349                addrlen = sizeof(struct sockaddr_in6);
     350                break;
     351        default:
     352                fprintf(stderr, "Address family is not supported\n");
     353                return EAFNOSUPPORT;
     354        }
     355
     356        /* Parse the last argument which should contain the address */
     357        rc = inet_pton(family, argv[argc - 1], address_start);
     358        if (rc != EOK) {
     359                fprintf(stderr, "Address parse error %d\n", rc);
     360                return rc;
     361        }
     362
     363        /* Check data buffer size */
     364        if (size <= 0) {
     365                fprintf(stderr, "Data buffer size too small (%d). Using 1024 "
     366                    "bytes instead.\n", size);
    213367                size = 1024;
    214368        }
    215369
    216         // prepare the buffer
    217         // size plus the terminating null (\0)
     370        /*
     371         * Prepare data buffer. Allocate size bytes plus one for the
     372         * trailing null character.
     373         */
    218374        data = (char *) malloc(size + 1);
    219         if(! data){
     375        if (!data) {
    220376                fprintf(stderr, "Failed to allocate data buffer.\n");
    221377                return ENOMEM;
    222378        }
    223         nettest1_refresh_data(data, size);
    224 
    225         // check the socket count
    226         if(sockets <= 0){
    227                 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
     379        nettest1_fill_buffer(data, size);
     380
     381        /* Check socket count */
     382        if (sockets <= 0) {
     383                fprintf(stderr, "Socket count too small (%d). Using "
     384                    "2 instead.\n", sockets);
    228385                sockets = 2;
    229386        }
    230387
    231         // prepare the socket buffer
    232         // count plus the terminating null (\0)
     388        /*
     389         * Prepare socket buffer. Allocate count fields plus the terminating
     390         * null (\0).
     391         */
    233392        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    234         if(! socket_ids){
     393        if (!socket_ids) {
    235394                fprintf(stderr, "Failed to allocate receive buffer.\n");
    236395                return ENOMEM;
     
    238397        socket_ids[sockets] = NULL;
    239398
    240         if(verbose){
     399        if (verbose)
    241400                printf("Starting tests\n");
    242         }
    243 
    244         if(verbose){
    245                 printf("1 socket, 1 message\n");
    246         }
    247 
    248         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    249                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    250                 return ERROR_CODE;
    251         }
    252 
    253         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
    254         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
    255         if(verbose){
    256                 printf("\tOK\n");
    257         }
    258 
    259         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
    260         if(type == SOCK_STREAM){
    261                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
    262         }
    263         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1));
    264         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
    265         if(verbose){
    266                 printf("\tOK\n");
    267         }
    268 
    269         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
    270         if(type == SOCK_STREAM){
    271                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
    272         }
    273         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, 1));
    274         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1));
    275         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
    276         if(verbose){
    277                 printf("\tOK\n");
    278         }
    279 
    280         if(verbose){
    281                 printf("1 socket, %d messages\n", messages);
    282         }
    283 
    284         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
    285         if(type == SOCK_STREAM){
    286                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
    287         }
    288         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages));
    289         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
    290         if(verbose){
    291                 printf("\tOK\n");
    292         }
    293 
    294         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type));
    295         if(type == SOCK_STREAM){
    296                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen));
    297         }
    298         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, messages));
    299         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages));
    300         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1));
    301         if(verbose){
    302                 printf("\tOK\n");
    303         }
    304 
    305         if(verbose){
    306                 printf("%d sockets, 1 message\n", sockets);
    307         }
    308 
    309         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    310         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    311         if(verbose){
    312                 printf("\tOK\n");
    313         }
    314 
    315         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    316         if(type == SOCK_STREAM){
    317                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    318         }
    319         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1));
    320         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    321         if(verbose){
    322                 printf("\tOK\n");
    323         }
    324 
    325         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    326         if(type == SOCK_STREAM){
    327                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    328         }
    329         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, 1));
    330         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1));
    331         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    332         if(verbose){
    333                 printf("\tOK\n");
    334         }
    335 
    336         if(verbose){
    337                 printf("%d sockets, %d messages\n", sockets, messages);
    338         }
    339 
    340         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    341         if(type == SOCK_STREAM){
    342                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    343         }
    344         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    345         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    346         if(verbose){
    347                 printf("\tOK\n");
    348         }
    349 
    350         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    351         if(type == SOCK_STREAM){
    352                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    353         }
    354         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages));
    355         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    356         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    357 
    358         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    359                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    360                 return ERROR_CODE;
    361         }
    362 
    363         if(verbose){
    364                 printf("\tOK\n");
    365         }
    366 
    367         printf("Tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    368 
    369         if(verbose){
     401
     402        rc = gettimeofday(&time_before, NULL);
     403        if (rc != EOK) {
     404                fprintf(stderr, "Get time of day error %d\n", rc);
     405                return rc;
     406        }
     407
     408        nettest1_test(socket_ids,       1,        1);
     409        nettest1_test(socket_ids,       1, messages);
     410        nettest1_test(socket_ids, sockets,        1);
     411        nettest1_test(socket_ids, sockets, messages);
     412
     413        rc = gettimeofday(&time_after, NULL);
     414        if (rc != EOK) {
     415                fprintf(stderr, "Get time of day error %d\n", rc);
     416                return rc;
     417        }
     418
     419        printf("Tested in %d microseconds\n", tv_sub(&time_after,
     420            &time_before));
     421
     422        if (verbose)
    370423                printf("Exiting\n");
    371         }
    372424
    373425        return EOK;
    374426}
    375427
    376 void nettest1_print_help(void){
    377         printf(
    378                 "Network Networking test 1 aplication - sockets\n" \
    379                 "Usage: echo [options] numeric_address\n" \
    380                 "Where options are:\n" \
    381                 "-f protocol_family | --family=protocol_family\n" \
    382                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    383                 "\n" \
    384                 "-h | --help\n" \
    385                 "\tShow this application help.\n"
    386                 "\n" \
    387                 "-m count | --messages=count\n" \
    388                 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
    389                 "\n" \
    390                 "-n sockets | --sockets=count\n" \
    391                 "\tThe number of sockets to use. The default is 10.\n" \
    392                 "\n" \
    393                 "-p port_number | --port=port_number\n" \
    394                 "\tThe port number the application should send messages to. The default is 7.\n" \
    395                 "\n" \
    396                 "-s packet_size | --size=packet_size\n" \
    397                 "\tThe packet data size the application sends. The default is 28 bytes.\n" \
    398                 "\n" \
    399                 "-v | --verbose\n" \
    400                 "\tShow all output messages.\n"
    401         );
    402 }
    403 
    404 void nettest1_refresh_data(char * data, size_t size){
    405         size_t length;
    406 
    407         // fill the data
    408         length = 0;
    409         while(size > length + sizeof(NETTEST1_TEXT) - 1){
    410                 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);
    411                 length += sizeof(NETTEST1_TEXT) - 1;
    412         }
    413         memcpy(data + length, NETTEST1_TEXT, size - length);
    414         data[size] = '\0';
    415 }
    416428
    417429/** @}
  • uspace/app/nettest2/nettest2.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup nettest
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Networking test 2 application - transfer.
    35  */
     34 * Networking test 2 application - transfer.
     35 */
     36
     37#include "nettest.h"
     38#include "print_error.h"
    3639
    3740#include <malloc.h>
     
    4144#include <time.h>
    4245#include <arg_parse.h>
    43 #include <err.h>
     46#include <bool.h>
    4447
    4548#include <net/in.h>
     
    4952#include <net/socket_parse.h>
    5053
    51 #include "nettest.h"
    52 #include "print_error.h"
    53 
    54 /** Echo module name.
    55  */
     54/** Echo module name. */
    5655#define NAME    "Nettest2"
    5756
    58 /** Packet data pattern.
    59  */
     57/** Packet data pattern. */
    6058#define NETTEST2_TEXT   "Networking test 2 - transfer"
    6159
    62 /** Module entry point.
    63  *  Starts testing.
    64  *  @param[in] argc The number of command line parameters.
    65  *  @param[in] argv The command line parameters.
    66  *  @returns EOK on success.
    67  */
    68 int main(int argc, char * argv[]);
    69 
    70 /** Prints the application help.
    71  */
    72 void nettest2_print_help(void);
    73 
    74 /** Refreshes the data.
    75  *  Fills the data block with the NETTEST1_TEXT pattern.
    76  *  @param[out] data The data block.
    77  *  @param[in] size The data block size in bytes.
    78  */
    79 void nettest2_refresh_data(char * data, size_t size);
    80 
    81 int main(int argc, char * argv[]){
    82         ERROR_DECLARE;
    83 
    84         size_t size                     = 28;
    85         int verbose                     = 0;
    86         sock_type_t type        = SOCK_DGRAM;
    87         int sockets                     = 10;
    88         int messages            = 10;
    89         int family                      = PF_INET;
    90         uint16_t port           = 7;
    91 
    92         socklen_t max_length                            = sizeof(struct sockaddr_in6);
    93         uint8_t address_data[max_length];
    94         struct sockaddr * address                       = (struct sockaddr *) address_data;
    95         struct sockaddr_in * address_in         = (struct sockaddr_in *) address;
    96         struct sockaddr_in6 * address_in6       = (struct sockaddr_in6 *) address;
     60static size_t size;
     61static bool verbose;
     62static sock_type_t type;
     63static int sockets;
     64static int messages;
     65static int family;
     66static uint16_t port;
     67
     68static void nettest2_print_help(void)
     69{
     70        printf(
     71            "Network Networking test 2 aplication - UDP transfer\n"
     72            "Usage: echo [options] address\n"
     73            "Where options are:\n"
     74            "-f protocol_family | --family=protocol_family\n"
     75            "\tThe listenning socket protocol family. Only the PF_INET and "
     76            "PF_INET6 are supported.\n"
     77            "\n"
     78            "-h | --help\n"
     79            "\tShow this application help.\n"
     80            "\n"
     81            "-m count | --messages=count\n"
     82            "\tThe number of messages to send and receive per socket. The "
     83            "default is 10.\n"
     84            "\n"
     85            "-n sockets | --sockets=count\n"
     86            "\tThe number of sockets to use. The default is 10.\n"
     87            "\n"
     88            "-p port_number | --port=port_number\n"
     89            "\tThe port number the application should send messages to. The "
     90            "default is 7.\n"
     91            "\n"
     92            "-s packet_size | --size=packet_size\n"
     93            "\tThe packet data size the application sends. The default is 29 "
     94            "bytes.\n"
     95            "\n"
     96            "-v | --verbose\n"
     97            "\tShow all output messages.\n");
     98}
     99
     100/** Fill buffer with the NETTEST2_TEXT pattern.
     101 *
     102 * @param buffer        Data buffer.
     103 * @param size          Buffer size in bytes.
     104 */
     105static void nettest2_fill_buffer(char *buffer, size_t size)
     106{
     107        size_t length;
     108
     109        length = 0;
     110        while (size > length + sizeof(NETTEST2_TEXT) - 1) {
     111                memcpy(buffer + length, NETTEST2_TEXT,
     112                    sizeof(NETTEST2_TEXT) - 1);
     113                length += sizeof(NETTEST2_TEXT) - 1;
     114        }
     115
     116        memcpy(buffer + length, NETTEST2_TEXT, size - length);
     117        buffer[size] = '\0';
     118}
     119
     120/** Parse one command-line option.
     121 *
     122 * @param argc          Number of all command-line arguments.
     123 * @param argv          All command-line arguments.
     124 * @param index         Current argument index (in, out).
     125 */
     126static int nettest2_parse_opt(int argc, char *argv[], int *index)
     127{
     128        int value;
     129        int rc;
     130
     131        switch (argv[*index][1]) {
     132        /*
     133         * Short options with only one letter
     134         */
     135        case 'f':
     136                rc = arg_parse_name_int(argc, argv, index, &family, 0,
     137                    socket_parse_protocol_family);
     138                if (rc != EOK)
     139                        return rc;
     140                break;
     141        case 'h':
     142                nettest2_print_help();
     143                return EOK;
     144                break;
     145        case 'm':
     146                rc = arg_parse_int(argc, argv, index, &messages, 0);
     147                if (rc != EOK)
     148                        return rc;
     149                break;
     150        case 'n':
     151                rc = arg_parse_int(argc, argv, index, &sockets, 0);
     152                if (rc != EOK)
     153                        return rc;
     154                break;
     155        case 'p':
     156                rc = arg_parse_int(argc, argv, index, &value, 0);
     157                if (rc != EOK)
     158                        return rc;
     159                port = (uint16_t) value;
     160                break;
     161        case 's':
     162                rc = arg_parse_int(argc, argv, index, &value, 0);
     163                if (rc != EOK)
     164                        return rc;
     165                size = (value >= 0) ? (size_t) value : 0;
     166                break;
     167        case 't':
     168                rc = arg_parse_name_int(argc, argv, index, &value, 0,
     169                    socket_parse_socket_type);
     170                if (rc != EOK)
     171                        return rc;
     172                type = (sock_type_t) value;
     173                break;
     174        case 'v':
     175                verbose = true;
     176                break;
     177        /*
     178         * Long options with double dash ('-')
     179         */
     180        case '-':
     181                if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) {
     182                        rc = arg_parse_name_int(argc, argv, index, &family, 9,
     183                            socket_parse_protocol_family);
     184                        if (rc != EOK)
     185                                return rc;
     186                } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) {
     187                        nettest2_print_help();
     188                        return EOK;
     189                } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) {
     190                        rc = arg_parse_int(argc, argv, index, &messages, 8);
     191                        if (rc != EOK)
     192                                return rc;
     193                } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) {
     194                        rc = arg_parse_int(argc, argv, index, &sockets, 8);
     195                        if (rc != EOK)
     196                                return rc;
     197                } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) {
     198                        rc = arg_parse_int(argc, argv, index, &value, 7);
     199                        if (rc != EOK)
     200                                return rc;
     201                        port = (uint16_t) value;
     202                } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) {
     203                        rc = arg_parse_name_int(argc, argv, index, &value, 7,
     204                            socket_parse_socket_type);
     205                        if (rc != EOK)
     206                                return rc;
     207                        type = (sock_type_t) value;
     208                } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) {
     209                        verbose = 1;
     210                } else {
     211                        nettest2_print_help();
     212                        return EINVAL;
     213                }
     214                break;
     215        default:
     216                nettest2_print_help();
     217                return EINVAL;
     218        }
     219
     220        return EOK;
     221}
     222
     223int main(int argc, char *argv[])
     224{
     225        socklen_t max_length;
     226        uint8_t address_data[sizeof(struct sockaddr_in6)];
     227        struct sockaddr *address;
     228        struct sockaddr_in *address_in;
     229        struct sockaddr_in6 *address_in6;
    97230        socklen_t addrlen;
    98 //      char address_string[INET6_ADDRSTRLEN];
    99         uint8_t * address_start;
    100 
    101         int * socket_ids;
    102         char * data;
    103         int value;
     231        uint8_t *address_start;
     232
     233        int *socket_ids;
     234        char *data;
    104235        int index;
    105236        struct timeval time_before;
    106237        struct timeval time_after;
    107238
    108         // parse the command line arguments
    109         // stop before the last argument if it does not start with the minus sign ('-')
    110         for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){
    111                 // options should start with the minus sign ('-')
    112                 if(argv[index][0] == '-'){
    113                         switch(argv[index][1]){
    114                                 // short options with only one letter
    115                                 case 'f':
    116                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family));
    117                                         break;
    118                                 case 'h':
    119                                         nettest2_print_help();
    120                                         return EOK;
    121                                         break;
    122                                 case 'm':
    123                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0));
    124                                         break;
    125                                 case 'n':
    126                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0));
    127                                         break;
    128                                 case 'p':
    129                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    130                                         port = (uint16_t) value;
    131                                         break;
    132                                 case 's':
    133                                         ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0));
    134                                         size = (value >= 0) ? (size_t) value : 0;
    135                                         break;
    136                                 case 't':
    137                                         ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type));
    138                                         type = (sock_type_t) value;
    139                                         break;
    140                                 case 'v':
    141                                         verbose = 1;
    142                                         break;
    143                                 // long options with the double minus sign ('-')
    144                                 case '-':
    145                                         if(str_lcmp(argv[index] + 2, "family=", 7) == 0){
    146                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family));
    147                                         }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){
    148                                                 nettest2_print_help();
    149                                                 return EOK;
    150                                         }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){
    151                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8));
    152                                         }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){
    153                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8));
    154                                         }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){
    155                                                 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7));
    156                                                 port = (uint16_t) value;
    157                                         }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){
    158                                                 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type));
    159                                                 type = (sock_type_t) value;
    160                                         }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){
    161                                                 verbose = 1;
    162                                         }else{
    163                                                 nettest2_print_help();
    164                                                 return EINVAL;
    165                                         }
    166                                         break;
    167                                 default:
    168                                         nettest2_print_help();
    169                                         return EINVAL;
    170                         }
    171                 }else{
     239        int rc;
     240
     241        size = 28;
     242        verbose = false;
     243        type = SOCK_DGRAM;
     244        sockets = 10;
     245        messages = 10;
     246        family = PF_INET;
     247        port = 7;
     248
     249        max_length = sizeof(address_data);
     250        address = (struct sockaddr *) address_data;
     251        address_in = (struct sockaddr_in *) address;
     252        address_in6 = (struct sockaddr_in6 *) address;
     253
     254        /*
     255         * Parse the command line arguments.
     256         *
     257         * Stop before the last argument if it does not start with dash ('-')
     258         */
     259        for (index = 1; (index < argc - 1) || ((index == argc - 1) &&
     260            (argv[index][0] == '-')); ++index) {
     261
     262                /* Options should start with dash ('-') */
     263                if (argv[index][0] == '-') {
     264                        rc = nettest2_parse_opt(argc, argv, &index);
     265                        if (rc != EOK)
     266                                return rc;
     267                } else {
    172268                        nettest2_print_help();
    173269                        return EINVAL;
     
    175271        }
    176272
    177         // if not before the last argument containing the address
    178         if(index >= argc){
     273        /* If not before the last argument containing the address */
     274        if (index >= argc) {
    179275                printf("Command line error: missing address\n");
    180276                nettest2_print_help();
     
    182278        }
    183279
    184         // prepare the address buffer
     280        /* Prepare the address buffer */
    185281        bzero(address_data, max_length);
    186         switch(family){
    187                 case PF_INET:
    188                         address_in->sin_family = AF_INET;
    189                         address_in->sin_port = htons(port);
    190                         address_start = (uint8_t *) &address_in->sin_addr.s_addr;
    191                         addrlen = sizeof(struct sockaddr_in);
    192                         break;
    193                 case PF_INET6:
    194                         address_in6->sin6_family = AF_INET6;
    195                         address_in6->sin6_port = htons(port);
    196                         address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
    197                         addrlen = sizeof(struct sockaddr_in6);
    198                         break;
    199                 default:
    200                         fprintf(stderr, "Address family is not supported\n");
    201                         return EAFNOSUPPORT;
    202         }
    203 
    204         // parse the last argument which should contain the address
    205         if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){
    206                 fprintf(stderr, "Address parse error %d\n", ERROR_CODE);
    207                 return ERROR_CODE;
    208         }
    209 
    210         // check the buffer size
    211         if(size <= 0){
    212                 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size);
     282
     283        switch (family) {
     284        case PF_INET:
     285                address_in->sin_family = AF_INET;
     286                address_in->sin_port = htons(port);
     287                address_start = (uint8_t *) &address_in->sin_addr.s_addr;
     288                addrlen = sizeof(struct sockaddr_in);
     289                break;
     290        case PF_INET6:
     291                address_in6->sin6_family = AF_INET6;
     292                address_in6->sin6_port = htons(port);
     293                address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr;
     294                addrlen = sizeof(struct sockaddr_in6);
     295                break;
     296        default:
     297                fprintf(stderr, "Address family is not supported\n");
     298                return EAFNOSUPPORT;
     299        }
     300
     301        /* Parse the last argument which should contain the address. */
     302        rc = inet_pton(family, argv[argc - 1], address_start);
     303        if (rc != EOK) {
     304                fprintf(stderr, "Address parse error %d\n", rc);
     305                return rc;
     306        }
     307
     308        /* Check data buffer size. */
     309        if (size <= 0) {
     310                fprintf(stderr, "Data buffer size too small (%d). Using 1024 "
     311                    "bytes instead.\n", size);
    213312                size = 1024;
    214313        }
    215314
    216         // prepare the buffer
    217         // size plus terminating null (\0)
     315        /*
     316         * Prepare the buffer. Allocate size bytes plus one for terminating
     317         * null character.
     318         */
    218319        data = (char *) malloc(size + 1);
    219         if(! data){
     320        if (!data) {
    220321                fprintf(stderr, "Failed to allocate data buffer.\n");
    221322                return ENOMEM;
    222323        }
    223         nettest2_refresh_data(data, size);
    224 
    225         // check the socket count
    226         if(sockets <= 0){
    227                 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets);
     324
     325        /* Fill buffer with a pattern. */
     326        nettest2_fill_buffer(data, size);
     327
     328        /* Check socket count. */
     329        if (sockets <= 0) {
     330                fprintf(stderr, "Socket count too small (%d). Using "
     331                    "2 instead.\n", sockets);
    228332                sockets = 2;
    229333        }
    230334
    231         // prepare the socket buffer
    232         // count plus the terminating null (\0)
     335        /*
     336         * Prepare the socket buffer.
     337         * Allocate count entries plus the terminating null (\0)
     338         */
    233339        socket_ids = (int *) malloc(sizeof(int) * (sockets + 1));
    234         if(! socket_ids){
     340        if (!socket_ids) {
    235341                fprintf(stderr, "Failed to allocate receive buffer.\n");
    236342                return ENOMEM;
     
    238344        socket_ids[sockets] = NULL;
    239345
    240         if(verbose){
     346        if (verbose)
    241347                printf("Starting tests\n");
    242         }
    243 
    244         ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type));
    245 
    246         if(type == SOCK_STREAM){
    247                 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen));
    248         }
    249 
    250         if(verbose){
     348
     349        rc = sockets_create(verbose, socket_ids, sockets, family, type);
     350        if (rc != EOK)
     351                return rc;
     352
     353        if (type == SOCK_STREAM) {
     354                rc = sockets_connect(verbose, socket_ids, sockets,
     355                    address, addrlen);
     356                if (rc != EOK)
     357                        return rc;
     358        }
     359
     360        if (verbose)
    251361                printf("\n");
    252         }
    253 
    254         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    255                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    256                 return ERROR_CODE;
    257         }
    258 
    259         ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    260 
    261         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    262                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    263                 return ERROR_CODE;
    264         }
    265 
    266         if(verbose){
     362
     363        rc = gettimeofday(&time_before, NULL);
     364        if (rc != EOK) {
     365                fprintf(stderr, "Get time of day error %d\n", rc);
     366                return rc;
     367        }
     368
     369        rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address,
     370            &addrlen, data, size, messages);
     371        if (rc != EOK)
     372                return rc;
     373
     374        rc = gettimeofday(&time_after, NULL);
     375        if (rc != EOK) {
     376                fprintf(stderr, "Get time of day error %d\n", rc);
     377                return rc;
     378        }
     379
     380        if (verbose)
    267381                printf("\tOK\n");
    268         }
    269 
    270         printf("sendto + recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    271 
    272         if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){
    273                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    274                 return ERROR_CODE;
    275         }
    276 
    277         ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages));
    278         ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages));
    279 
    280         if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){
    281                 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE);
    282                 return ERROR_CODE;
    283         }
    284 
    285         if(verbose){
     382
     383        printf("sendto + recvfrom tested in %d microseconds\n",
     384            tv_sub(&time_after, &time_before));
     385
     386        rc = gettimeofday(&time_before, NULL);
     387        if (rc != EOK) {
     388                fprintf(stderr, "Get time of day error %d\n", rc);
     389                return rc;
     390        }
     391
     392        rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen,
     393            data, size, messages);
     394        if (rc != EOK)
     395                return rc;
     396
     397        rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen,
     398            data, size, messages);
     399        if (rc != EOK)
     400                return rc;
     401
     402        rc = gettimeofday(&time_after, NULL);
     403        if (rc != EOK) {
     404                fprintf(stderr, "Get time of day error %d\n", rc);
     405                return rc;
     406        }
     407
     408        if (verbose)
    286409                printf("\tOK\n");
    287         }
    288 
    289         printf("sendto, recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before));
    290 
    291         ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets));
    292 
    293         if(verbose){
     410
     411        printf("sendto, recvfrom tested in %d microseconds\n",
     412            tv_sub(&time_after, &time_before));
     413
     414        rc = sockets_close(verbose, socket_ids, sockets);
     415        if (rc != EOK)
     416                return rc;
     417
     418        if (verbose)
    294419                printf("\nExiting\n");
    295         }
    296420
    297421        return EOK;
    298422}
    299423
    300 void nettest2_print_help(void){
    301         printf(
    302                 "Network Networking test 2 aplication - UDP transfer\n" \
    303                 "Usage: echo [options] numeric_address\n" \
    304                 "Where options are:\n" \
    305                 "-f protocol_family | --family=protocol_family\n" \
    306                 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"
    307                 "\n" \
    308                 "-h | --help\n" \
    309                 "\tShow this application help.\n"
    310                 "\n" \
    311                 "-m count | --messages=count\n" \
    312                 "\tThe number of messages to send and receive per socket. The default is 10.\n" \
    313                 "\n" \
    314                 "-n sockets | --sockets=count\n" \
    315                 "\tThe number of sockets to use. The default is 10.\n" \
    316                 "\n" \
    317                 "-p port_number | --port=port_number\n" \
    318                 "\tThe port number the application should send messages to. The default is 7.\n" \
    319                 "\n" \
    320                 "-s packet_size | --size=packet_size\n" \
    321                 "\tThe packet data size the application sends. The default is 29 bytes.\n" \
    322                 "\n" \
    323                 "-v | --verbose\n" \
    324                 "\tShow all output messages.\n"
    325         );
    326 }
    327 
    328 void nettest2_refresh_data(char * data, size_t size){
    329         size_t length;
    330 
    331         // fill the data
    332         length = 0;
    333         while(size > length + sizeof(NETTEST2_TEXT) - 1){
    334                 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);
    335                 length += sizeof(NETTEST2_TEXT) - 1;
    336         }
    337         memcpy(data + length, NETTEST2_TEXT, size - length);
    338         data[size] = '\0';
    339 }
    340 
    341424/** @}
    342425 */
  • uspace/app/redir/redir.c

    rd70a463 rb40bfac  
    4343#include <task.h>
    4444#include <str_error.h>
     45#include <errno.h>
    4546
    4647#define NAME  "redir"
     
    7677static task_id_t spawn(int argc, char *argv[])
    7778{
    78         const char **args = (const char **) calloc(argc + 1, sizeof(char *));
     79        const char **args;
     80        task_id_t id;
     81        int rc;
     82
     83        args = (const char **) calloc(argc + 1, sizeof(char *));
    7984        if (!args) {
    8085                printf("No memory available\n");
     
    8893        args[argc] = NULL;
    8994       
    90         int err;
    91         task_id_t id = task_spawn(argv[0], args, &err);
     95        rc = task_spawnv(&id, argv[0], args);
    9296       
    9397        free(args);
    9498       
    95         if (id == 0)
     99        if (rc != EOK) {
    96100                printf("%s: Error spawning %s (%s)\n", NAME, argv[0],
    97                     str_error(err));
     101                    str_error(rc));
     102        }
    98103       
    99104        return id;
  • uspace/app/sbi/src/os/helenos.c

    rd70a463 rb40bfac  
    249249        task_id_t tid;
    250250        task_exit_t texit;
    251         int retval;
    252 
    253         tid = task_spawn(cmd[0], (char const * const *) cmd, &retval);
    254         if (tid == 0) {
     251        int rc, retval;
     252
     253        rc = task_spawnv(&tid, cmd[0], (char const * const *) cmd);
     254        if (rc != EOK) {
    255255                printf("Error: Failed spawning '%s' (%s).\n", cmd[0],
    256                     str_error(retval));
     256                    str_error(rc));
    257257                exit(1);
    258258        }
    259259
    260260        /* XXX Handle exit status and return value. */
    261         task_wait(tid, &texit, &retval);
     261        rc = task_wait(tid, &texit, &retval);
     262        (void) rc;
    262263
    263264        return EOK;
  • uspace/lib/c/generic/fibril_synch.c

    rd70a463 rb40bfac  
    5858}
    5959
    60 static bool check_for_deadlock(fibril_owner_info_t *oi)
    61 {
    62         while (oi && oi->owned_by) {
    63                 if (oi->owned_by == (fibril_t *) fibril_get_id())
    64                         return true;
    65                 oi = oi->owned_by->waits_for;
    66         }
    67 
    68         return false;
    69 }
    70 
    7160static void print_deadlock(fibril_owner_info_t *oi)
    7261{
     
    8978                oi = oi->owned_by->waits_for;
    9079        }
    91 
    92         abort();
    93 }
     80}
     81
     82
     83static void check_for_deadlock(fibril_owner_info_t *oi)
     84{
     85        while (oi && oi->owned_by) {
     86                if (oi->owned_by == (fibril_t *) fibril_get_id()) {
     87                        print_deadlock(oi);
     88                        abort();
     89                }
     90                oi = oi->owned_by->waits_for;
     91        }
     92}
     93
    9494
    9595void fibril_mutex_initialize(fibril_mutex_t *fm)
     
    113113                link_initialize(&wdata.wu_event.link);
    114114                list_append(&wdata.wu_event.link, &fm->waiters);
    115 
    116                 if (check_for_deadlock(&fm->oi))
    117                         print_deadlock(&fm->oi);
     115                check_for_deadlock(&fm->oi);
    118116                f->waits_for = &fm->oi;
    119 
    120117                fibril_switch(FIBRIL_TO_MANAGER);
    121118        } else {
     
    183180void fibril_rwlock_read_lock(fibril_rwlock_t *frw)
    184181{
     182        fibril_t *f = (fibril_t *) fibril_get_id();
     183       
    185184        futex_down(&async_futex);
    186185        if (frw->writers) {
    187                 fibril_t *f = (fibril_t *) fibril_get_id();
    188186                awaiter_t wdata;
    189187
     
    194192                f->flags &= ~FIBRIL_WRITER;
    195193                list_append(&wdata.wu_event.link, &frw->waiters);
     194                check_for_deadlock(&frw->oi);
     195                f->waits_for = &frw->oi;
    196196                fibril_switch(FIBRIL_TO_MANAGER);
    197197        } else {
    198                 frw->readers++;
     198                /* Consider the first reader the owner. */
     199                if (frw->readers++ == 0)
     200                        frw->oi.owned_by = f;
    199201                futex_up(&async_futex);
    200202        }
     
    203205void fibril_rwlock_write_lock(fibril_rwlock_t *frw)
    204206{
     207        fibril_t *f = (fibril_t *) fibril_get_id();
     208       
    205209        futex_down(&async_futex);
    206210        if (frw->writers || frw->readers) {
    207                 fibril_t *f = (fibril_t *) fibril_get_id();
    208211                awaiter_t wdata;
    209212
     
    214217                f->flags |= FIBRIL_WRITER;
    215218                list_append(&wdata.wu_event.link, &frw->waiters);
     219                check_for_deadlock(&frw->oi);
     220                f->waits_for = &frw->oi;
    216221                fibril_switch(FIBRIL_TO_MANAGER);
    217222        } else {
     223                frw->oi.owned_by = f;
    218224                frw->writers++;
    219225                futex_up(&async_futex);
     
    226232        assert(frw->readers || (frw->writers == 1));
    227233        if (frw->readers) {
    228                 if (--frw->readers)
     234                if (--frw->readers) {
     235                        if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) {
     236                                /*
     237                                 * If this reader firbril was considered the
     238                                 * owner of this rwlock, clear the ownership
     239                                 * information even if there are still more
     240                                 * readers.
     241                                 *
     242                                 * This is the limitation of the detection
     243                                 * mechanism rooted in the fact that tracking
     244                                 * all readers would require dynamically
     245                                 * allocated memory for keeping linkage info.
     246                                 */
     247                                frw->oi.owned_by = NULL;
     248                        }
    229249                        goto out;
     250                }
    230251        } else {
    231252                frw->writers--;
     
    233254       
    234255        assert(!frw->readers && !frw->writers);
     256       
     257        frw->oi.owned_by = NULL;
    235258       
    236259        while (!list_empty(&frw->waiters)) {
     
    241264                wdp = list_get_instance(tmp, awaiter_t, wu_event.link);
    242265                f = (fibril_t *) wdp->fid;
     266               
     267                f->waits_for = NULL;
    243268               
    244269                if (f->flags & FIBRIL_WRITER) {
     
    250275                        fibril_add_ready(wdp->fid);
    251276                        frw->writers++;
     277                        frw->oi.owned_by = f;
    252278                        optimize_execution_power();
    253279                        break;
     
    257283                        list_remove(&wdp->wu_event.link);
    258284                        fibril_add_ready(wdp->fid);
    259                         frw->readers++;
     285                        if (frw->readers++ == 0) {
     286                                /* Consider the first reader the owner. */
     287                                frw->oi.owned_by = f;
     288                        }
    260289                        optimize_execution_power();
    261290                }
  • uspace/lib/c/generic/task.c

    rd70a463 rb40bfac  
    3939#include <errno.h>
    4040#include <loader/loader.h>
     41#include <stdarg.h>
    4142#include <str.h>
    4243#include <ipc/ns.h>
     
    6869 *
    6970 * This is really just a convenience wrapper over the more complicated
    70  * loader API.
    71  *
    72  * @param path Pathname of the binary to execute.
    73  * @param argv Command-line arguments.
    74  * @param err  If not NULL, the error value is stored here.
    75  *
    76  * @return ID of the newly created task or zero on error.
    77  *
    78  */
    79 task_id_t task_spawn(const char *path, const char *const args[], int *err)
    80 {
     71 * loader API. Arguments are passed as a null-terminated array of strings.
     72 *
     73 * @param id    If not NULL, the ID of the task is stored here on success.
     74 * @param path  Pathname of the binary to execute.
     75 * @param argv  Command-line arguments.
     76 *
     77 * @return      Zero on success or negative error code.
     78 */
     79int task_spawnv(task_id_t *id, const char *path, const char *const args[])
     80{
     81        loader_t *ldr;
     82        task_id_t task_id;
     83        int rc;
     84
    8185        /* Connect to a program loader. */
    82         loader_t *ldr = loader_connect();
    83         if (ldr == NULL) {
    84                 if (err != NULL)
    85                         *err = EREFUSED;
    86                
    87                 return 0;
    88         }
     86        ldr = loader_connect();
     87        if (ldr == NULL)
     88                return EREFUSED;
    8989       
    9090        /* Get task ID. */
    91         task_id_t task_id;
    92         int rc = loader_get_task_id(ldr, &task_id);
     91        rc = loader_get_task_id(ldr, &task_id);
    9392        if (rc != EOK)
    9493                goto error;
     
    149148        free(ldr);
    150149       
    151         if (err != NULL)
    152                 *err = EOK;
    153        
    154         return task_id;
     150        if (id != NULL)
     151                *id = task_id;
     152       
     153        return EOK;
    155154       
    156155error:
     
    158157        loader_abort(ldr);
    159158        free(ldr);
    160        
    161         if (err != NULL)
    162                 *err = rc;
    163        
    164         return 0;
     159        return rc;
     160}
     161
     162/** Create a new task by running an executable from the filesystem.
     163 *
     164 * This is really just a convenience wrapper over the more complicated
     165 * loader API. Arguments are passed as a null-terminated list of arguments.
     166 *
     167 * @param id    If not NULL, the ID of the task is stored here on success.
     168 * @param path  Pathname of the binary to execute.
     169 * @param ...   Command-line arguments.
     170 *
     171 * @return      Zero on success or negative error code.
     172 */
     173int task_spawnl(task_id_t *task_id, const char *path, ...)
     174{
     175        va_list ap;
     176        int rc, cnt;
     177        const char *arg;
     178        const char **arglist;
     179
     180        /* Count the number of arguments. */
     181        cnt = 0;
     182        va_start(ap, path);
     183        do {
     184                arg = va_arg(ap, const char *);
     185                cnt++;
     186        } while (arg != NULL);
     187        va_end(ap);
     188
     189        /* Allocate argument list. */
     190        arglist = malloc(cnt * sizeof(const char *));
     191        if (arglist == NULL)
     192                return ENOMEM;
     193
     194        /* Fill in arguments. */
     195        cnt = 0;
     196        va_start(ap, path);
     197        do {
     198                arg = va_arg(ap, const char *);
     199                arglist[cnt++] = arg;
     200        } while (arg != NULL);
     201        va_end(ap);
     202
     203        /* Spawn task. */
     204        rc = task_spawnv(task_id, path, arglist);
     205
     206        /* Free argument list. */
     207        free(arglist);
     208        return rc;
    165209}
    166210
  • uspace/lib/c/include/ipc/services.h

    rd70a463 rb40bfac  
    3939
    4040typedef enum {
    41         SERVICE_LOAD = 1,
     41        SERVICE_NONE = 0,
     42        SERVICE_LOAD,
    4243        SERVICE_PCI,
    4344        SERVICE_VIDEO,
  • uspace/lib/c/include/task.h

    rd70a463 rb40bfac  
    4848extern int task_set_name(const char *);
    4949extern task_id_t task_spawn(const char *, const char *const[], int *);
     50extern int task_spawnv(task_id_t *, const char *path, const char *const []);
     51extern int task_spawnl(task_id_t *, const char *path, ...);
     52
    5053extern int task_wait(task_id_t id, task_exit_t *, int *);
    5154extern int task_retval(int);
  • uspace/lib/net/adt/module_map.c

    rd70a463 rb40bfac  
    132132task_id_t spawn(const char *fname)
    133133{
    134         const char *argv[2];
    135         task_id_t res;
     134        task_id_t id;
     135        int rc;
    136136       
    137         argv[0] = fname;
    138         argv[1] = NULL;
    139         res = task_spawn(fname, argv, NULL);
     137        rc = task_spawnl(&id, fname, fname, NULL);
     138        if (rc != EOK)
     139                return 0;
    140140       
    141         return res;
     141        return id;
    142142}
    143143
  • uspace/lib/net/include/tl_local.h

    rd70a463 rb40bfac  
    3737#include <async.h>
    3838
     39/** Starts the TL module.
     40 *
     41 * Initializes the client connection serving function, initializes the module,
     42 * registers the module service and starts the async manager, processing IPC
     43 * messages in an infinite loop.
     44 *
     45 * @param[in] client_connection The client connection processing function. The
     46 *                      module skeleton propagates its own one.
     47 * @returns             EOK on successful module termination.
     48 * @returns             Other error codes as defined for the module initialize
     49 *                      function.
     50 * @returns             Other error codes as defined for the REGISTER_ME() macro
     51 *                      function.
     52 */
    3953extern int tl_module_message_standalone(ipc_callid_t, ipc_call_t *,
    4054    ipc_call_t *, int *);
     55
     56
     57/** Processes the TL module message.
     58 *
     59 * @param[in] callid    The message identifier.
     60 * @param[in] call      The message parameters.
     61 * @param[out] answer   The message answer parameters.
     62 * @param[out] answer_count The last parameter for the actual answer in the
     63 *                      answer parameter.
     64 * @returns             EOK on success.
     65 * @returns             Other error codes as defined for the module's message
     66 *                      standalone function.
     67 */
    4168extern int tl_module_start_standalone(async_client_conn_t);
    4269
  • uspace/lib/packet/generic/packet_server.c

    rd70a463 rb40bfac  
    212212       
    213213        for (index = 0; index < FREE_QUEUES_COUNT; index++) {
    214                 if (length > ps_globals.sizes[index])
     214                if ((length > ps_globals.sizes[index]) &&
     215                    (index < FREE_QUEUES_COUNT - 1))
    215216                        continue;
    216217               
  • uspace/srv/devman/devman.c

    rd70a463 rb40bfac  
    3737#include <ipc/devman.h>
    3838#include <devmap.h>
     39#include <str_error.h>
    3940
    4041#include "devman.h"
     
    446447bool start_driver(driver_t *drv)
    447448{
     449        int rc;
     450
    448451        printf(NAME ": start_driver '%s'\n", drv->name);
    449452       
    450         const char *argv[2];
    451        
    452         argv[0] = drv->name;
    453         argv[1] = NULL;
    454        
    455         int err;
    456         if (task_spawn(drv->binary_path, argv, &err) == 0) {
    457                 printf(NAME ": error spawning %s, errno = %d\n",
    458                     drv->name, err);
     453        rc = task_spawnl(NULL, drv->binary_path, drv->binary_path, NULL);
     454        if (rc != EOK) {
     455                printf(NAME ": error spawning %s (%s)\n",
     456                    drv->name, str_error(rc));
    459457                return false;
    460458        }
  • uspace/srv/net/il/arp/arp.c

    rd70a463 rb40bfac  
    5555#include <ipc/il.h>
    5656#include <byteorder.h>
    57 #include <err.h>
     57#include <errno.h>
    5858
    5959#include <net/modules.h>
     
    179179    measured_string_ref address)
    180180{
    181         ERROR_DECLARE;
     181        int rc;
    182182
    183183        *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t));
    184184        if (!*proto)
    185185                return ENOMEM;
     186       
    186187        (*proto)->service = service;
    187188        (*proto)->addr = address;
    188189        (*proto)->addr_data = address->value;
    189         if (ERROR_OCCURRED(arp_addr_initialize(&(*proto)->addresses))) {
     190       
     191        rc = arp_addr_initialize(&(*proto)->addresses);
     192        if (rc != EOK) {
    190193                free(*proto);
    191                 return ERROR_CODE;
    192         }
     194                return rc;
     195        }
     196       
    193197        return EOK;
    194198}
     
    214218    services_t protocol, measured_string_ref address)
    215219{
    216         ERROR_DECLARE;
    217 
    218220        arp_device_ref device;
    219221        arp_proto_ref proto;
     222        hw_type_t hardware;
    220223        int index;
    221         hw_type_t hardware;
     224        int rc;
    222225
    223226        fibril_rwlock_write_lock(&arp_globals.lock);
     
    237240                        proto->addr_data = address->value;
    238241                } else {
    239                         if (ERROR_OCCURRED(arp_proto_create(&proto, protocol,
    240                             address))) {
     242                        rc = arp_proto_create(&proto, protocol, address);
     243                        if (rc != EOK) {
    241244                                fibril_rwlock_write_unlock(&arp_globals.lock);
    242                                 return ERROR_CODE;
     245                                return rc;
    243246                        }
    244247                        index = arp_protos_add(&device->protos, proto->service,
     
    265268                device->hardware = hardware;
    266269                device->device_id = device_id;
    267                 if (ERROR_OCCURRED(arp_protos_initialize(&device->protos)) ||
    268                     ERROR_OCCURRED(arp_proto_create(&proto, protocol,
    269                     address))) {
     270                rc = arp_protos_initialize(&device->protos);
     271                if (rc != EOK) {
    270272                        fibril_rwlock_write_unlock(&arp_globals.lock);
    271273                        free(device);
    272                         return ERROR_CODE;
     274                        return rc;
     275                }
     276                rc = arp_proto_create(&proto, protocol, address);
     277                if (rc != EOK) {
     278                        fibril_rwlock_write_unlock(&arp_globals.lock);
     279                        free(device);
     280                        return rc;
    273281                }
    274282                index = arp_protos_add(&device->protos, proto->service, proto);
     
    293301               
    294302                // get packet dimensions
    295                 if (ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id,
    296                     &device->packet_dimension))) {
     303                rc = nil_packet_size_req(device->phone, device_id,
     304                    &device->packet_dimension);
     305                if (rc != EOK) {
    297306                        fibril_rwlock_write_unlock(&arp_globals.lock);
    298307                        arp_protos_destroy(&device->protos);
    299308                        free(device);
    300                         return ERROR_CODE;
     309                        return rc;
    301310                }
    302311               
    303312                // get hardware address
    304                 if (ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id,
    305                     &device->addr, &device->addr_data))) {
     313                rc = nil_get_addr_req(device->phone, device_id, &device->addr,
     314                    &device->addr_data);
     315                if (rc != EOK) {
    306316                        fibril_rwlock_write_unlock(&arp_globals.lock);
    307317                        arp_protos_destroy(&device->protos);
    308318                        free(device);
    309                         return ERROR_CODE;
     319                        return rc;
    310320                }
    311321               
    312322                // get broadcast address
    313                 if (ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone,
    314                     device_id, &device->broadcast_addr,
    315                     &device->broadcast_data))) {
     323                rc = nil_get_broadcast_addr_req(device->phone, device_id,
     324                    &device->broadcast_addr, &device->broadcast_data);
     325                if (rc != EOK) {
    316326                        fibril_rwlock_write_unlock(&arp_globals.lock);
    317327                        free(device->addr);
     
    319329                        arp_protos_destroy(&device->protos);
    320330                        free(device);
    321                         return ERROR_CODE;
    322                 }
    323                
    324                 if (ERROR_OCCURRED(arp_cache_add(&arp_globals.cache,
    325                     device->device_id, device))) {
     331                        return rc;
     332                }
     333               
     334                rc = arp_cache_add(&arp_globals.cache, device->device_id,
     335                    device);
     336                if (rc != EOK) {
    326337                        fibril_rwlock_write_unlock(&arp_globals.lock);
    327338                        free(device->addr);
     
    331342                        arp_protos_destroy(&device->protos);
    332343                        free(device);
    333                         return ERROR_CODE;
     344                        return rc;
    334345                }
    335346                printf("%s: Device registered (id: %d, type: 0x%x, service: %d,"
     
    351362int arp_initialize(async_client_conn_t client_connection)
    352363{
    353         ERROR_DECLARE;
     364        int rc;
    354365
    355366        fibril_rwlock_initialize(&arp_globals.lock);
    356367        fibril_rwlock_write_lock(&arp_globals.lock);
    357368        arp_globals.client_connection = client_connection;
    358         ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));
     369        rc = arp_cache_initialize(&arp_globals.cache);
    359370        fibril_rwlock_write_unlock(&arp_globals.lock);
    360         return EOK;
     371       
     372        return rc;
    361373}
    362374
     
    406418static int arp_receive_message(device_id_t device_id, packet_t packet)
    407419{
    408         ERROR_DECLARE;
    409 
    410420        size_t length;
    411421        arp_header_ref header;
     
    417427        uint8_t *des_hw;
    418428        uint8_t *des_proto;
     429        int rc;
    419430
    420431        length = packet_get_data_length(packet);
     
    467478                                return ENOMEM;
    468479
    469                         ERROR_PROPAGATE(arp_addr_add(&proto->addresses,
    470                             (char *) src_proto, CONVERT_SIZE(uint8_t, char,
    471                             header->protocol_length), hw_source));
     480                        rc = arp_addr_add(&proto->addresses, (char *) src_proto,
     481                            CONVERT_SIZE(uint8_t, char,
     482                            header->protocol_length), hw_source);
     483                        if (rc != EOK)
     484                                return rc;
    472485                }
    473486                if (ntohs(header->operation) == ARPOP_REQUEST) {
     
    480493                        memcpy(des_hw, hw_source->value,
    481494                            header->hardware_length);
    482                         ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw,
    483                             header->hardware_length));
     495                       
     496                        rc = packet_set_addr(packet, src_hw, des_hw,
     497                            header->hardware_length);
     498                        if (rc != EOK)
     499                                return rc;
     500                       
    484501                        nil_send_msg(device->phone, device_id, packet,
    485502                            SERVICE_ARP);
     
    596613    ipc_call_t *answer, int *answer_count)
    597614{
    598         ERROR_DECLARE;
    599        
    600615        measured_string_ref address;
    601616        measured_string_ref translation;
     
    603618        packet_t packet;
    604619        packet_t next;
     620        int rc;
    605621       
    606622        *answer_count = 0;
     
    610626       
    611627        case NET_ARP_DEVICE:
    612                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
    613                 if (ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call),
    614                     IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))) {
     628                rc = measured_strings_receive(&address, &data, 1);
     629                if (rc != EOK)
     630                        return rc;
     631               
     632                rc = arp_device_message(IPC_GET_DEVICE(call),
     633                    IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address);
     634                if (rc != EOK) {
    615635                        free(address);
    616636                        free(data);
    617637                }
    618                 return ERROR_CODE;
     638                return rc;
    619639       
    620640        case NET_ARP_TRANSLATE:
    621                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     641                rc = measured_strings_receive(&address, &data, 1);
     642                if (rc != EOK)
     643                        return rc;
     644               
    622645                fibril_rwlock_read_lock(&arp_globals.lock);
    623646                translation = arp_translate_message(IPC_GET_DEVICE(call),
     
    629652                        return ENOENT;
    630653                }
    631                 ERROR_CODE = measured_strings_reply(translation, 1);
     654                rc = measured_strings_reply(translation, 1);
    632655                fibril_rwlock_read_unlock(&arp_globals.lock);
    633                 return ERROR_CODE;
     656                return rc;
    634657
    635658        case NET_ARP_CLEAR_DEVICE:
     
    637660
    638661        case NET_ARP_CLEAR_ADDRESS:
    639                 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1));
     662                rc = measured_strings_receive(&address, &data, 1);
     663                if (rc != EOK)
     664                        return rc;
     665               
    640666                arp_clear_address_req(0, IPC_GET_DEVICE(call),
    641667                    IPC_GET_SERVICE(call), address);
     
    652678       
    653679        case NET_IL_RECEIVED:
    654                 if (ERROR_NONE(packet_translate_remote(arp_globals.net_phone,
    655                     &packet, IPC_GET_PACKET(call)))) {
    656                         fibril_rwlock_read_lock(&arp_globals.lock);
    657                         do {
    658                                 next = pq_detach(packet);
    659                                 ERROR_CODE =
    660                                     arp_receive_message(IPC_GET_DEVICE(call),
    661                                     packet);
    662                                 if (ERROR_CODE != 1) {
    663                                         pq_release_remote(arp_globals.net_phone,
    664                                             packet_get_id(packet));
    665                                 }
    666                                 packet = next;
    667                         } while (packet);
    668                         fibril_rwlock_read_unlock(&arp_globals.lock);
    669                 }
    670                 return ERROR_CODE;
     680                rc = packet_translate_remote(arp_globals.net_phone, &packet,
     681                    IPC_GET_PACKET(call));
     682                if (rc != EOK)
     683                        return rc;
     684               
     685                fibril_rwlock_read_lock(&arp_globals.lock);
     686                do {
     687                        next = pq_detach(packet);
     688                        rc = arp_receive_message(IPC_GET_DEVICE(call), packet);
     689                        if (rc != 1) {
     690                                pq_release_remote(arp_globals.net_phone,
     691                                    packet_get_id(packet));
     692                        }
     693                        packet = next;
     694                } while (packet);
     695                fibril_rwlock_read_unlock(&arp_globals.lock);
     696               
     697                return EOK;
    671698       
    672699        case NET_IL_MTU_CHANGED:
     
    727754int main(int argc, char *argv[])
    728755{
    729         ERROR_DECLARE;
     756        int rc;
    730757       
    731758        /* Start the module */
    732         ERROR_PROPAGATE(il_module_start_standalone(il_client_connection));
    733         return EOK;
     759        rc = il_module_start_standalone(il_client_connection);
     760        return rc;
    734761}
    735762
  • uspace/srv/net/il/arp/arp_module.c

    rd70a463 rb40bfac  
    4141#include <async.h>
    4242#include <stdio.h>
    43 #include <err.h>
     43#include <errno.h>
    4444
    4545#include <ipc/ipc.h>
     
    6666int il_module_start_standalone(async_client_conn_t client_connection)
    6767{
    68         ERROR_DECLARE;
     68        ipcarg_t phonehash;
     69        int rc;
    6970       
    7071        async_set_client_connection(client_connection);
    7172        arp_globals.net_phone = net_connect_module();
    72         ERROR_PROPAGATE(pm_init());
    7373       
    74         ipcarg_t phonehash;
    75         if (ERROR_OCCURRED(arp_initialize(client_connection)) ||
    76             ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))) {
    77                 pm_destroy();
    78                 return ERROR_CODE;
    79         }
     74        rc = pm_init();
     75        if (rc != EOK)
     76                return rc;
     77       
     78        rc = arp_initialize(client_connection);
     79        if (rc != EOK)
     80                goto out;
     81       
     82        rc = REGISTER_ME(SERVICE_ARP, &phonehash);
     83        if (rc != EOK)
     84                goto out;
    8085       
    8186        async_manager();
    82        
     87
     88out:
    8389        pm_destroy();
    84         return EOK;
     90        return rc;
    8591}
    8692
  • uspace/srv/net/il/ip/ip.c

    rd70a463 rb40bfac  
    4141#include <async.h>
    4242#include <errno.h>
    43 #include <err.h>
    4443#include <fibril_synch.h>
    4544#include <stdio.h>
     
    254253int ip_initialize(async_client_conn_t client_connection)
    255254{
    256         ERROR_DECLARE;
     255        int rc;
    257256
    258257        fibril_rwlock_initialize(&ip_globals.lock);
     
    265264        ip_globals.gateway.gateway.s_addr = 0;
    266265        ip_globals.gateway.netif = NULL;
    267         ERROR_PROPAGATE(ip_netifs_initialize(&ip_globals.netifs));
    268         ERROR_PROPAGATE(ip_protos_initialize(&ip_globals.protos));
    269266        ip_globals.client_connection = client_connection;
    270         ERROR_PROPAGATE(modules_initialize(&ip_globals.modules));
    271         ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME,
    272             ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module));
     267       
     268        rc = ip_netifs_initialize(&ip_globals.netifs);
     269        if (rc != EOK)
     270                goto out;
     271        rc = ip_protos_initialize(&ip_globals.protos);
     272        if (rc != EOK)
     273                goto out;
     274        rc = modules_initialize(&ip_globals.modules);
     275        if (rc != EOK)
     276                goto out;
     277        rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME,
     278            SERVICE_ARP, 0, arp_connect_module);
     279
     280out:
    273281        fibril_rwlock_write_unlock(&ip_globals.lock);
    274282
    275         return EOK;
     283        return rc;
    276284}
    277285
     
    302310static int ip_netif_initialize(ip_netif_ref ip_netif)
    303311{
    304         ERROR_DECLARE;
    305 
    306312        measured_string_t names[] = {
    307313                {
     
    342348        char *data;
    343349        measured_string_t address;
    344         int index;
    345350        ip_route_ref route;
    346351        in_addr_t gateway;
     352        int index;
     353        int rc;
    347354
    348355        ip_netif->arp = NULL;
     
    354361
    355362        // get configuration
    356         ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone,
    357             ip_netif->device_id, &configuration, count, &data));
     363        rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id,
     364            &configuration, count, &data);
     365        if (rc != EOK)
     366                return rc;
     367       
    358368        if (configuration) {
    359369                if (configuration[0].value)
     
    383393                                return index;
    384394                        }
    385                         if (ERROR_OCCURRED(inet_pton(AF_INET,
    386                             configuration[2].value,
    387                             (uint8_t *) &route->address.s_addr)) ||
    388                             ERROR_OCCURRED(inet_pton(AF_INET,
    389                             configuration[3].value,
    390                             (uint8_t *) &route->netmask.s_addr)) ||
     395                       
     396                        if ((inet_pton(AF_INET, configuration[2].value,
     397                            (uint8_t *) &route->address.s_addr) != EOK) ||
     398                            (inet_pton(AF_INET, configuration[3].value,
     399                            (uint8_t *) &route->netmask.s_addr) != EOK) ||
    391400                            (inet_pton(AF_INET, configuration[4].value,
    392401                            (uint8_t *) &gateway.s_addr) == EINVAL) ||
     
    434443                        address.value = (char *) &route->address.s_addr;
    435444                        address.length = CONVERT_SIZE(in_addr_t, char, 1);
    436                         ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone,
     445                       
     446                        rc = arp_device_req(ip_netif->arp->phone,
    437447                            ip_netif->device_id, SERVICE_IP, ip_netif->service,
    438                             &address));
     448                            &address);
     449                        if (rc != EOK)
     450                                return rc;
    439451                } else {
    440452                        ip_netif->arp = 0;
     
    443455
    444456        // get packet dimensions
    445         ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone,
    446             ip_netif->device_id, &ip_netif->packet_dimension));
     457        rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id,
     458            &ip_netif->packet_dimension);
     459        if (rc != EOK)
     460                return rc;
     461       
    447462        if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) {
    448463                printf("Maximum transmission unit %d bytes is too small, at "
     
    610625    measured_string_ref destination)
    611626{
    612         ERROR_DECLARE;
    613 
    614627        size_t length;
    615628        ip_header_ref header;
     
    617630        ip_header_ref middle_header;
    618631        packet_t next;
     632        int rc;
    619633
    620634        length = packet_get_data_length(packet);
     
    624638        header = (ip_header_ref) packet_get_data(packet);
    625639        if (destination) {
    626                 ERROR_PROPAGATE(packet_set_addr(packet, NULL,
    627                     (uint8_t *) destination->value,
    628                     CONVERT_SIZE(char, uint8_t, destination->length)));
     640                rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value,
     641                    CONVERT_SIZE(char, uint8_t, destination->length));
    629642        } else {
    630                 ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0));
    631         }
     643                rc = packet_set_addr(packet, NULL, NULL, 0);
     644        }
     645        if (rc != EOK)
     646                return rc;
     647       
    632648        header->version = IPV4;
    633649        header->fragment_offset_high = 0;
     
    669685                            IP_HEADER_CHECKSUM(middle_header);
    670686                        if (destination) {
    671                                 if (ERROR_OCCURRED(packet_set_addr(next, NULL,
     687                                rc = packet_set_addr(next, NULL,
    672688                                    (uint8_t *) destination->value,
    673689                                    CONVERT_SIZE(char, uint8_t,
    674                                     destination->length)))) {
     690                                    destination->length));
     691                                if (rc != EOK) {
    675692                                        free(last_header);
    676                                         return ERROR_CODE;
     693                                        return rc;
    677694                                }
    678695                        }
     
    699716                    IP_HEADER_CHECKSUM(middle_header);
    700717                if (destination) {
    701                         if (ERROR_OCCURRED(packet_set_addr(next, NULL,
     718                        rc = packet_set_addr(next, NULL,
    702719                            (uint8_t *) destination->value,
    703                             CONVERT_SIZE(char, uint8_t,
    704                             destination->length)))) {
     720                            CONVERT_SIZE(char, uint8_t, destination->length));
     721                        if (rc != EOK) {
    705722                                free(last_header);
    706                                 return ERROR_CODE;
    707                             }
     723                                return rc;
     724                        }
    708725                }
    709726                length += packet_get_data_length(next);
     
    741758    const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen)
    742759{
    743         ERROR_DECLARE;
    744 
    745760        void *data;
    746761        size_t offset;
     762        int rc;
    747763
    748764        data = packet_suffix(new_packet, length);
     
    752768        memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length,
    753769            length);
    754         ERROR_PROPAGATE(packet_trim(packet, 0, length));
     770       
     771        rc = packet_trim(packet, 0, length);
     772        if (rc != EOK)
     773                return rc;
     774       
    755775        header->total_length = htons(IP_TOTAL_LENGTH(header) - length);
    756776        new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length);
     
    761781            IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset);
    762782        new_header->header_checksum = IP_HEADER_CHECKSUM(new_header);
    763         ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src,
    764             (const uint8_t *) dest, addrlen));
     783       
     784        rc = packet_set_addr(new_packet, (const uint8_t *) src,
     785            (const uint8_t *) dest, addrlen);
     786        if (rc != EOK)
     787                return rc;
    765788
    766789        return pq_insert_after(packet, new_packet);
     
    796819    socklen_t addr_len)
    797820{
    798         ERROR_DECLARE;
    799 
    800821        packet_t new_packet;
    801822        ip_header_ref header;
     
    806827        socklen_t addrlen;
    807828        int result;
     829        int rc;
    808830
    809831        result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest);
     
    839861
    840862        // trim the unused space
    841         if (ERROR_OCCURRED(packet_trim(new_packet, 0,
    842             IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)))) {
    843                 return ip_release_and_return(packet, ERROR_CODE);
    844         }
     863        rc = packet_trim(new_packet, 0,
     864            IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header));
     865        if (rc != EOK)
     866                return ip_release_and_return(packet, rc);
    845867
    846868        // biggest multiple of 8 lower than content
    847869        // TODO even fragmentation?
    848870        length = length & ~0x7;
    849         if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header,
    850             last_header,
     871       
     872        rc = ip_fragment_packet_data(packet, new_packet, header, last_header,
    851873            ((IP_HEADER_DATA_LENGTH(header) -
    852874            ((length - IP_HEADER_LENGTH(header)) & ~0x7)) %
    853             ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)), src, dest,
    854             addrlen))) {
    855                 return ip_release_and_return(packet, ERROR_CODE);
    856         }
     875            ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)),
     876            src, dest, addrlen);
     877        if (rc != EOK)
     878                return ip_release_and_return(packet, rc);
    857879
    858880        // mark the first as fragmented
     
    872894                        return ip_release_and_return(packet, ENOMEM);
    873895
    874                 if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet,
    875                     header, middle_header,
    876                     (length - IP_HEADER_LENGTH(middle_header)) & ~0x7, src,
    877                     dest, addrlen))) {
    878                         return ip_release_and_return(packet, ERROR_CODE);
    879                 }
     896                rc = ip_fragment_packet_data(packet, new_packet, header,
     897                    middle_header,
     898                    (length - IP_HEADER_LENGTH(middle_header)) & ~0x7,
     899                    src, dest, addrlen);
     900                if (rc != EOK)
     901                        return ip_release_and_return(packet, rc);
    880902        }
    881903
     
    974996    in_addr_t *src, in_addr_t dest, services_t error)
    975997{
    976         ERROR_DECLARE;
    977 
    978998        measured_string_t destination;
    979999        measured_string_ref translation;
    9801000        char *data;
    9811001        int phone;
     1002        int rc;
    9821003
    9831004        // get destination hardware address
     
    9871008                destination.length = CONVERT_SIZE(dest.s_addr, char, 1);
    9881009
    989                 if (ERROR_OCCURRED(arp_translate_req(netif->arp->phone,
    990                     netif->device_id, SERVICE_IP, &destination, &translation,
    991                     &data))) {
     1010                rc = arp_translate_req(netif->arp->phone, netif->device_id,
     1011                    SERVICE_IP, &destination, &translation, &data);
     1012                if (rc != EOK) {
    9921013                        pq_release_remote(ip_globals.net_phone,
    9931014                            packet_get_id(packet));
    994                         return ERROR_CODE;
     1015                        return rc;
    9951016                }
    9961017
     
    10141035        }
    10151036
    1016         if (ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))) {
     1037        rc = ip_prepare_packet(src, dest, packet, translation);
     1038        if (rc != EOK) {
    10171039                pq_release_remote(ip_globals.net_phone, packet_get_id(packet));
    10181040        } else {
     
    10321054        }
    10331055
    1034         return ERROR_CODE;
     1056        return rc;
    10351057}
    10361058
     
    11581180ip_device_req_local(int il_phone, device_id_t device_id, services_t netif)
    11591181{
    1160         ERROR_DECLARE;
    1161 
    11621182        ip_netif_ref ip_netif;
    11631183        ip_route_ref route;
    11641184        int index;
     1185        int rc;
    11651186
    11661187        ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t));
     
    11681189                return ENOMEM;
    11691190
    1170         if (ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))) {
     1191        rc = ip_routes_initialize(&ip_netif->routes);
     1192        if (rc != EOK) {
    11711193                free(ip_netif);
    1172                 return ERROR_CODE;
     1194                return rc;
    11731195        }
    11741196
     
    11781200
    11791201        fibril_rwlock_write_lock(&ip_globals.netifs_lock);
    1180         if (ERROR_OCCURRED(ip_netif_initialize(ip_netif))) {
     1202
     1203        rc = ip_netif_initialize(ip_netif);
     1204        if (rc != EOK) {
    11811205                fibril_rwlock_write_unlock(&ip_globals.netifs_lock);
    11821206                ip_routes_destroy(&ip_netif->routes);
    11831207                free(ip_netif);
    1184                 return ERROR_CODE;
     1208                return rc;
    11851209        }
    11861210        if (ip_netif->arp)
     
    12261250    services_t sender, services_t error)
    12271251{
    1228         ERROR_DECLARE;
    1229 
    12301252        int addrlen;
    12311253        ip_netif_ref netif;
     
    12361258        in_addr_t *src;
    12371259        int phone;
     1260        int rc;
    12381261
    12391262        // addresses in the host byte order
     
    13231346        }
    13241347
    1325         ERROR_CODE = ip_send_route(packet, netif, route, src, *dest, error);
     1348        rc = ip_send_route(packet, netif, route, src, *dest, error);
    13261349        fibril_rwlock_read_unlock(&ip_globals.netifs_lock);
    13271350
    1328         return ERROR_CODE;
     1351        return rc;
    13291352}
    13301353
     
    14311454    services_t error)
    14321455{
    1433         ERROR_DECLARE;
    1434 
    14351456        ip_proto_ref proto;
    14361457        int phone;
     
    14421463        struct sockaddr_in dest_in;
    14431464        socklen_t addrlen;
     1465        int rc;
    14441466
    14451467        if ((header->flags & IPFLAG_MORE_FRAGMENTS) ||
     
    14671489        }
    14681490
    1469         if (ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src,
    1470             (uint8_t *) dest, addrlen))) {
    1471                 return ip_release_and_return(packet, ERROR_CODE);
    1472         }
     1491        rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest,
     1492            addrlen);
     1493        if (rc != EOK)
     1494                return ip_release_and_return(packet, rc);
    14731495
    14741496        // trim padding if present
    14751497        if (!error &&
    14761498            (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) {
    1477                 if (ERROR_OCCURRED(packet_trim(packet, 0,
    1478                     packet_get_data_length(packet) - IP_TOTAL_LENGTH(header))))
    1479                         return ip_release_and_return(packet, ERROR_CODE);
     1499                rc = packet_trim(packet, 0,
     1500                    packet_get_data_length(packet) - IP_TOTAL_LENGTH(header));
     1501                if (rc != EOK)
     1502                        return ip_release_and_return(packet, rc);
    14801503        }
    14811504
     
    14981521                received_msg = proto->received_msg;
    14991522                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    1500                 ERROR_CODE = received_msg(device_id, packet, service, error);
     1523                rc = received_msg(device_id, packet, service, error);
    15011524        } else {
    1502                 ERROR_CODE = tl_received_msg(proto->phone, device_id, packet,
     1525                rc = tl_received_msg(proto->phone, device_id, packet,
    15031526                    proto->service, error);
    15041527                fibril_rwlock_read_unlock(&ip_globals.protos_lock);
    15051528        }
    15061529
    1507         return ERROR_CODE;
     1530        return rc;
    15081531}
    15091532
     
    15321555ip_process_packet(device_id_t device_id, packet_t packet)
    15331556{
    1534         ERROR_DECLARE;
    1535 
    15361557        ip_header_ref header;
    15371558        in_addr_t dest;
     
    15411562        struct sockaddr_in addr_in;
    15421563        socklen_t addrlen;
     1564        int rc;
    15431565
    15441566        header = (ip_header_ref) packet_get_data(packet);
     
    15851607        }
    15861608
    1587         ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr,
    1588             addrlen));
     1609        rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen);
     1610        if (rc != EOK)
     1611                return rc;
    15891612
    15901613        route = ip_find_route(dest);
     
    18671890    int *answer_count)
    18681891{
    1869         ERROR_DECLARE;
    1870        
    18711892        packet_t packet;
    18721893        struct sockaddr *addr;
     
    18781899        size_t headerlen;
    18791900        device_id_t device_id;
     1901        int rc;
    18801902       
    18811903        *answer_count = 0;
     
    18931915       
    18941916        case NET_IL_SEND:
    1895                 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone,
    1896                     &packet, IPC_GET_PACKET(call)));
     1917                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1918                    IPC_GET_PACKET(call));
     1919                if (rc != EOK)
     1920                        return rc;
    18971921                return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0,
    18981922                    IPC_GET_ERROR(call));
     
    19031927       
    19041928        case NET_IL_RECEIVED:
    1905                 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone,
    1906                     &packet, IPC_GET_PACKET(call)));
     1929                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1930                    IPC_GET_PACKET(call));
     1931                if (rc != EOK)
     1932                        return rc;
    19071933                return ip_receive_message(IPC_GET_DEVICE(call), packet);
    19081934       
    19091935        case NET_IP_RECEIVED_ERROR:
    1910                 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone,
    1911                     &packet, IPC_GET_PACKET(call)));
     1936                rc = packet_translate_remote(ip_globals.net_phone, &packet,
     1937                    IPC_GET_PACKET(call));
     1938                if (rc != EOK)
     1939                        return rc;
    19121940                return ip_received_error_msg_local(0, IPC_GET_DEVICE(call),
    19131941                    packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call));
     
    19231951
    19241952        case NET_IP_GET_ROUTE:
    1925                 ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen));
    1926                 ERROR_PROPAGATE(ip_get_route_req_local(0, IP_GET_PROTOCOL(call),
    1927                     addr, (socklen_t) addrlen, &device_id, &header,
    1928                     &headerlen));
     1953                rc = data_receive((void **) &addr, &addrlen);
     1954                if (rc != EOK)
     1955                        return rc;
     1956               
     1957                rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr,
     1958                    (socklen_t) addrlen, &device_id, &header, &headerlen);
     1959                if (rc != EOK)
     1960                        return rc;
     1961               
    19291962                IPC_SET_DEVICE(answer, device_id);
    19301963                IP_SET_HEADERLEN(answer, headerlen);
    19311964               
    19321965                *answer_count = 2;
    1933                        
    1934                 if (ERROR_NONE(data_reply(&headerlen, sizeof(headerlen))))
    1935                         ERROR_CODE = data_reply(header, headerlen);
     1966               
     1967                rc = data_reply(&headerlen, sizeof(headerlen));
     1968                if (rc == EOK)
     1969                        rc = data_reply(header, headerlen);
    19361970                       
    19371971                free(header);
    1938                 return ERROR_CODE;
     1972                return rc;
    19391973       
    19401974        case NET_IL_PACKET_SPACE:
    1941                 ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call),
    1942                     &addrlen, &prefix, &content, &suffix));
     1975                rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen,
     1976                    &prefix, &content, &suffix);
     1977                if (rc != EOK)
     1978                        return rc;
     1979               
    19431980                IPC_SET_ADDR(answer, addrlen);
    19441981                IPC_SET_PREFIX(answer, prefix);
     
    20052042int main(int argc, char *argv[])
    20062043{
    2007         ERROR_DECLARE;
     2044        int rc;
    20082045       
    20092046        /* Start the module */
    2010         ERROR_PROPAGATE(il_module_start_standalone(il_client_connection));
    2011         return EOK;
     2047        rc = il_module_start_standalone(il_client_connection);
     2048        return rc;
    20122049}
    20132050
  • uspace/srv/net/il/ip/ip_module.c

    rd70a463 rb40bfac  
    4444#include <ipc/ipc.h>
    4545#include <ipc/services.h>
    46 #include <err.h>
     46#include <errno.h>
    4747
    4848#include <net/modules.h>
     
    6666int il_module_start_standalone(async_client_conn_t client_connection)
    6767{
    68         ERROR_DECLARE;
     68        ipcarg_t phonehash;
     69        int rc;
    6970       
    7071        async_set_client_connection(client_connection);
    7172        ip_globals.net_phone = net_connect_module();
    72         ERROR_PROPAGATE(pm_init());
     73
     74        rc = pm_init();
     75        if (rc != EOK)
     76                return rc;
    7377       
    74         ipcarg_t phonehash;
    75         if (ERROR_OCCURRED(ip_initialize(client_connection)) ||
    76             ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))) {
    77                 pm_destroy();
    78                 return ERROR_CODE;
    79         }
     78        rc = ip_initialize(client_connection);
     79        if (rc != EOK)
     80                goto out;
     81       
     82        rc = REGISTER_ME(SERVICE_IP, &phonehash);
     83        if (rc != EOK)
     84                goto out;
    8085       
    8186        async_manager();
    82        
     87
     88out:
    8389        pm_destroy();
    84         return EOK;
     90        return rc;
    8591}
    8692
  • uspace/srv/net/net/net.c

    rd70a463 rb40bfac  
    3636 */
    3737
     38#include "net.h"
     39
    3840#include <async.h>
    3941#include <ctype.h>
     
    5254
    5355#include <net/modules.h>
     56#include <net/packet.h>
     57#include <net/device.h>
     58
    5459#include <adt/char_map.h>
    5560#include <adt/generic_char_map.h>
    5661#include <adt/measured_strings.h>
    5762#include <adt/module_map.h>
    58 #include <net/packet.h>
     63
    5964#include <netif_remote.h>
    60 #include <net/device.h>
    6165#include <nil_interface.h>
    6266#include <net_interface.h>
    6367#include <ip_interface.h>
    6468
    65 #include "net.h"
    66 
    67 /** Networking module name.
    68  *
    69  */
     69/** Networking module name. */
    7070#define NAME  "net"
    7171
    72 /** File read buffer size.
    73  *
    74  */
     72/** File read buffer size. */
    7573#define BUFFER_SIZE  256
    7674
    77 /** Networking module global data.
    78  *
    79  */
     75/** Networking module global data. */
    8076net_globals_t net_globals;
    8177
     
    10096        measured_string_ref setting =
    10197            measured_string_create_bulk(value, 0);
    102        
    10398        if (!setting)
    10499                return ENOMEM;
     
    206201        unsigned int line_number = 0;
    207202        size_t index = 0;
    208         while ((!ferror(cfg)) && (!feof(cfg))) {
     203        while (!ferror(cfg) && !feof(cfg)) {
    209204                int read = fgetc(cfg);
    210205                if ((read > 0) && (read != '\n') && (read != '\r')) {
     
    326321        ipcarg_t phonehash;
    327322       
    328         if (ERROR_OCCURRED(net_initialize(client_connection))
    329             || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){
     323        if (ERROR_OCCURRED(net_initialize(client_connection)) ||
     324            ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))) {
    330325                pm_destroy();
    331326                return ERROR_CODE;
     
    379374    size_t count, char **data)
    380375{
    381         if (!(configuration && (count > 0)))
     376        if (!configuration || (count <= 0))
    382377                return EINVAL;
    383378       
     
    482477        /* Inter-network layer startup */
    483478        switch (netif->il->service) {
    484                 case SERVICE_IP:
    485                         ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id,
    486                             internet_service));
    487                         break;
    488                 default:
    489                         return ENOENT;
     479        case SERVICE_IP:
     480                ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id,
     481                    internet_service));
     482                break;
     483        default:
     484                return ENOENT;
    490485        }
    491486       
     
    511506        ERROR_DECLARE;
    512507       
    513         const char *conf_files[] = {"lo", "ne2k"};
     508        const char *conf_files[] = {
     509                "lo",
     510                "ne2k"
     511        };
    514512        size_t count = sizeof(conf_files) / sizeof(char *);
    515513       
     
    603601        *answer_count = 0;
    604602        switch (IPC_GET_METHOD(*call)) {
    605                 case IPC_M_PHONE_HUNGUP:
    606                         return EOK;
    607                 case NET_NET_GET_DEVICE_CONF:
    608                         ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
    609                             IPC_GET_COUNT(call)));
    610                         net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings,
    611                             IPC_GET_COUNT(call), NULL);
    612                        
    613                         /* Strings should not contain received data anymore */
    614                         free(data);
    615                        
    616                         ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
    617                         free(strings);
    618                         return ERROR_CODE;
    619                 case NET_NET_GET_CONF:
    620                         ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
    621                             IPC_GET_COUNT(call)));
    622                         net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL);
    623                        
    624                         /* Strings should not contain received data anymore */
    625                         free(data);
    626                        
    627                         ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
    628                         free(strings);
    629                         return ERROR_CODE;
    630                 case NET_NET_STARTUP:
    631                         return startup();
     603        case IPC_M_PHONE_HUNGUP:
     604                return EOK;
     605        case NET_NET_GET_DEVICE_CONF:
     606                ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
     607                    IPC_GET_COUNT(call)));
     608                net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings,
     609                    IPC_GET_COUNT(call), NULL);
     610               
     611                /* Strings should not contain received data anymore */
     612                free(data);
     613               
     614                ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
     615                free(strings);
     616                return ERROR_CODE;
     617        case NET_NET_GET_CONF:
     618                ERROR_PROPAGATE(measured_strings_receive(&strings, &data,
     619                    IPC_GET_COUNT(call)));
     620                net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL);
     621               
     622                /* Strings should not contain received data anymore */
     623                free(data);
     624               
     625                ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call));
     626                free(strings);
     627                return ERROR_CODE;
     628        case NET_NET_STARTUP:
     629                return startup();
    632630        }
    633631        return ENOTSUP;
     
    661659                int res = net_module_message(callid, &call, &answer, &answer_count);
    662660               
    663                 /* End if said to either by the message or the processing result */
     661                /* End if told to either by the message or the processing result */
    664662                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
    665663                        return;
  • uspace/srv/net/net/net.h

    rd70a463 rb40bfac  
    3636 */
    3737
    38 #ifndef __NET_NET_H__
    39 #define __NET_NET_H__
     38#ifndef NET_NET_H_
     39#define NET_NET_H_
    4040
    4141#include <ipc/ipc.h>
  • uspace/srv/net/net/net_standalone.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup net
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  Wrapper for the standalone networking module.
     34 * Wrapper for the standalone networking module.
    3535 */
    3636
     37#include "net.h"
     38
    3739#include <str.h>
    38 
     40#include <adt/measured_strings.h>
     41#include <adt/module_map.h>
    3942#include <ipc/ipc.h>
    4043#include <ipc/net.h>
    4144
    4245#include <ip_interface.h>
    43 #include <adt/measured_strings.h>
    44 #include <adt/module_map.h>
    4546#include <packet_server.h>
    4647
    47 #include "net.h"
    48 
    49 /** Networking module global data.
    50  */
     48/** Networking module global data. */
    5149extern net_globals_t net_globals;
    5250
     
    6058 *
    6159 */
    62 int net_initialize_build(async_client_conn_t client_connection){
     60int net_initialize_build(async_client_conn_t client_connection)
     61{
    6362        ERROR_DECLARE;
    6463       
  • uspace/srv/net/netif/lo/lo.c

    rd70a463 rb40bfac  
    3737#include <async.h>
    3838#include <errno.h>
    39 #include <err.h>
    4039#include <stdio.h>
    4140#include <str.h>
     
    8382int netif_get_device_stats(device_id_t device_id, device_stats_ref stats)
    8483{
    85         ERROR_DECLARE;
    86 
    8784        netif_device_t *device;
     85        int rc;
    8886
    8987        if (!stats)
    9088                return EBADMEM;
    91         ERROR_PROPAGATE(find_device(device_id, &device));
     89        rc = find_device(device_id, &device);
     90        if (rc != EOK)
     91                return rc;
    9292        memcpy(stats, (device_stats_ref) device->specific,
    9393            sizeof(device_stats_t));
     
    164164int netif_probe_message(device_id_t device_id, int irq, uintptr_t io)
    165165{
    166         ERROR_DECLARE;
    167 
    168166        netif_device_t *device;
     167        int rc;
    169168
    170169        // create a new device
    171         ERROR_PROPAGATE(create(device_id, &device));
     170        rc = create(device_id, &device);
     171        if (rc != EOK)
     172                return rc;
    172173        // print the settings
    173174        printf("%s: Device created (id: %d)\n", NAME, device->device_id);
     
    177178int netif_send_message(device_id_t device_id, packet_t packet, services_t sender)
    178179{
    179         ERROR_DECLARE;
    180 
    181180        netif_device_t *device;
    182181        size_t length;
    183182        packet_t next;
    184183        int phone;
    185 
    186         ERROR_PROPAGATE(find_device(device_id, &device));
     184        int rc;
     185
     186        rc = find_device(device_id, &device);
     187        if (rc != EOK)
     188                return EOK;
    187189        if (device->state != NETIF_ACTIVE) {
    188190                netif_pq_release(packet_get_id(packet));
     
    259261int main(int argc, char *argv[])
    260262{
    261         ERROR_DECLARE;
     263        int rc;
    262264       
    263265        /* Start the module */
    264         ERROR_PROPAGATE(netif_module_start(netif_client_connection));
    265         return EOK;
     266        rc = netif_module_start(netif_client_connection);
     267        return rc;
    266268}
    267269
  • uspace/srv/net/nil/eth/eth.c

    rd70a463 rb40bfac  
    4242#include <byteorder.h>
    4343#include <str.h>
    44 #include <err.h>
     44#include <errno.h>
    4545
    4646#include <ipc/ipc.h>
     
    196196int nil_initialize(int net_phone)
    197197{
    198         ERROR_DECLARE;
     198        int rc;
    199199
    200200        fibril_rwlock_initialize(&eth_globals.devices_lock);
     
    208208            CONVERT_SIZE(uint8_t, char, ETH_ADDR));
    209209        if (!eth_globals.broadcast_addr) {
    210                 ERROR_CODE = ENOMEM;
     210                rc = ENOMEM;
    211211                goto out;
    212212        }
    213         if (ERROR_OCCURRED(eth_devices_initialize(&eth_globals.devices))) {
     213        rc = eth_devices_initialize(&eth_globals.devices);
     214        if (rc != EOK) {
    214215                free(eth_globals.broadcast_addr);
    215216                goto out;
    216217        }
    217         if (ERROR_OCCURRED(eth_protos_initialize(&eth_globals.protos))) {
     218        rc = eth_protos_initialize(&eth_globals.protos);
     219        if (rc != EOK) {
    218220                free(eth_globals.broadcast_addr);
    219221                eth_devices_destroy(&eth_globals.devices);
     
    223225        fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    224226       
    225         return ERROR_CODE;
     227        return rc;
    226228}
    227229
     
    234236static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall)
    235237{
    236         ERROR_DECLARE;
    237 
    238238        packet_t packet;
     239        int rc;
    239240
    240241        while (true) {
     
    246247                        break;
    247248                case NET_NIL_RECEIVED:
    248                         if (ERROR_NONE(packet_translate_remote(
    249                             eth_globals.net_phone, &packet,
    250                             IPC_GET_PACKET(icall)))) {
    251                                 ERROR_CODE = nil_received_msg_local(0,
     249                        rc = packet_translate_remote(eth_globals.net_phone,
     250                            &packet, IPC_GET_PACKET(icall));
     251                        if (rc == EOK) {
     252                                rc = nil_received_msg_local(0,
    252253                                    IPC_GET_DEVICE(icall), packet, 0);
    253254                        }
    254                         ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
     255                        ipc_answer_0(iid, (ipcarg_t) rc);
    255256                        break;
    256257                default:
     
    282283eth_device_message(device_id_t device_id, services_t service, size_t mtu)
    283284{
    284         ERROR_DECLARE;
    285 
    286285        eth_device_ref device;
    287286        int index;
     
    300299        char *data;
    301300        eth_proto_ref proto;
     301        int rc;
    302302
    303303        fibril_rwlock_write_lock(&eth_globals.devices_lock);
     
    351351
    352352        configuration = &names[0];
    353         if (ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone,
    354             device->device_id, &configuration, count, &data))) {
     353        rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id,
     354            &configuration, count, &data);
     355        if (rc != EOK) {
    355356                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    356357                free(device);
    357                 return ERROR_CODE;
     358                return rc;
    358359        }
    359360        if (configuration) {
     
    387388       
    388389        // get hardware address
    389         if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id,
    390             &device->addr, &device->addr_data))) {
     390        rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
     391            &device->addr_data);
     392        if (rc != EOK) {
    391393                fibril_rwlock_write_unlock(&eth_globals.devices_lock);
    392394                free(device);
    393                 return ERROR_CODE;
     395                return rc;
    394396        }
    395397       
     
    429431static eth_proto_ref eth_process_packet(int flags, packet_t packet)
    430432{
    431         ERROR_DECLARE;
    432 
    433433        eth_header_snap_ref header;
    434434        size_t length;
     
    437437        size_t suffix;
    438438        eth_fcs_ref fcs;
    439         uint8_t * data;
     439        uint8_t *data;
     440        int rc;
    440441
    441442        length = packet_get_data_length(packet);
     
    488489       
    489490        if (IS_DUMMY(flags)) {
    490                 if ((~compute_crc32(~0U, data, length * 8)) != ntohl(*fcs))
     491                if (~compute_crc32(~0U, data, length * 8) != ntohl(*fcs))
    491492                        return NULL;
    492493                suffix += sizeof(eth_fcs_t);
    493494        }
    494495       
    495         if (ERROR_OCCURRED(packet_set_addr(packet,
    496             header->header.source_address, header->header.destination_address,
    497             ETH_ADDR)) || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))) {
     496        rc = packet_set_addr(packet, header->header.source_address,
     497            header->header.destination_address, ETH_ADDR);
     498        if (rc != EOK)
    498499                return NULL;
    499         }
     500
     501        rc = packet_trim(packet, prefix, suffix);
     502        if (rc != EOK)
     503                return NULL;
    500504       
    501505        return eth_protos_find(&eth_globals.protos, type);
     
    781785eth_send_message(device_id_t device_id, packet_t packet, services_t sender)
    782786{
    783         ERROR_DECLARE;
    784 
    785787        eth_device_ref device;
    786788        packet_t next;
    787789        packet_t tmp;
    788790        int ethertype;
     791        int rc;
    789792
    790793        ethertype = htons(protocol_map(SERVICE_ETHERNET, sender));
     
    804807        next = packet;
    805808        do {
    806                 if (ERROR_OCCURRED(eth_prepare_packet(device->flags, next,
    807                     (uint8_t *) device->addr->value, ethertype, device->mtu))) {
     809                rc = eth_prepare_packet(device->flags, next,
     810                    (uint8_t *) device->addr->value, ethertype, device->mtu);
     811                if (rc != EOK) {
    808812                        // release invalid packet
    809813                        tmp = pq_detach(next);
     
    832836    ipc_call_t *answer, int *answer_count)
    833837{
    834         ERROR_DECLARE;
    835        
    836838        measured_string_ref address;
    837839        packet_t packet;
     
    840842        size_t suffix;
    841843        size_t content;
     844        int rc;
    842845       
    843846        *answer_count = 0;
     
    850853                    IPC_GET_SERVICE(call), IPC_GET_MTU(call));
    851854        case NET_NIL_SEND:
    852                 ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone,
    853                     &packet, IPC_GET_PACKET(call)));
     855                rc = packet_translate_remote(eth_globals.net_phone, &packet,
     856                    IPC_GET_PACKET(call));
     857                if (rc != EOK)
     858                        return rc;
    854859                return eth_send_message(IPC_GET_DEVICE(call), packet,
    855860                    IPC_GET_SERVICE(call));
    856861        case NET_NIL_PACKET_SPACE:
    857                 ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call),
    858                     &addrlen, &prefix, &content, &suffix));
     862                rc = eth_packet_space_message(IPC_GET_DEVICE(call), &addrlen,
     863                    &prefix, &content, &suffix);
     864                if (rc != EOK)
     865                        return rc;
    859866                IPC_SET_ADDR(answer, addrlen);
    860867                IPC_SET_PREFIX(answer, prefix);
     
    864871                return EOK;
    865872        case NET_NIL_ADDR:
    866                 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
    867                     ETH_LOCAL_ADDR, &address));
     873                rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR,
     874                    &address);
     875                if (rc != EOK)
     876                        return rc;
    868877                return measured_strings_reply(address, 1);
    869878        case NET_NIL_BROADCAST_ADDR:
    870                 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call),
    871                     ETH_BROADCAST_ADDR, &address));
     879                rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR,
     880                    &address);
     881                if (rc != EOK)
     882                        return EOK;
    872883                return measured_strings_reply(address, 1);
    873884        case IPC_M_CONNECT_TO_ME:
     
    923934int main(int argc, char *argv[])
    924935{
    925         ERROR_DECLARE;
     936        int rc;
    926937       
    927938        /* Start the module */
    928         ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));
    929         return EOK;
     939        rc = nil_module_start_standalone(nil_client_connection);
     940        return rc;
    930941}
    931942
  • uspace/srv/net/nil/eth/eth_module.c

    rd70a463 rb40bfac  
    4040#include <async.h>
    4141#include <stdio.h>
    42 #include <err.h>
     42#include <errno.h>
    4343
    4444#include <ipc/ipc.h>
     
    5252int nil_module_start_standalone(async_client_conn_t client_connection)
    5353{
    54         ERROR_DECLARE;
     54        ipcarg_t phonehash;
     55        int rc;
    5556       
    5657        async_set_client_connection(client_connection);
    5758        int net_phone = net_connect_module();
    58         ERROR_PROPAGATE(pm_init());
     59
     60        rc = pm_init();
     61        if (rc != EOK)
     62                return rc;
    5963       
    60         ipcarg_t phonehash;
    61         if (ERROR_OCCURRED(nil_initialize(net_phone)) ||
    62             ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))) {
    63                 pm_destroy();
    64                 return ERROR_CODE;
    65         }
     64        rc = nil_initialize(net_phone);
     65        if (rc != EOK)
     66                goto out;
     67
     68        rc = REGISTER_ME(SERVICE_ETHERNET, &phonehash);
     69        if (rc != EOK)
     70                goto out;
    6671       
    6772        async_manager();
    68        
     73
     74out:
    6975        pm_destroy();
    70         return EOK;
     76        return rc;
    7177}
    7278
  • uspace/srv/net/nil/nildummy/nildummy.c

    rd70a463 rb40bfac  
    4141#include <stdio.h>
    4242#include <str.h>
    43 #include <err.h>
    4443#include <ipc/ipc.h>
    4544#include <ipc/net.h>
     
    8281int nil_initialize(int net_phone)
    8382{
    84         ERROR_DECLARE;
     83        int rc;
    8584       
    8685        fibril_rwlock_initialize(&nildummy_globals.devices_lock);
     
    9190        nildummy_globals.net_phone = net_phone;
    9291        nildummy_globals.proto.phone = 0;
    93         ERROR_CODE = nildummy_devices_initialize(&nildummy_globals.devices);
     92        rc = nildummy_devices_initialize(&nildummy_globals.devices);
    9493       
    9594        fibril_rwlock_write_unlock(&nildummy_globals.protos_lock);
    9695        fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    9796       
    98         return ERROR_CODE;
     97        return rc;
    9998}
    10099
     
    107106static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall)
    108107{
    109         ERROR_DECLARE;
    110 
    111108        packet_t packet;
     109        int rc;
    112110
    113111        while (true) {
    114112                switch (IPC_GET_METHOD(*icall)) {
    115113                case NET_NIL_DEVICE_STATE:
    116                         ERROR_CODE = nil_device_state_msg_local(0,
     114                        rc = nil_device_state_msg_local(0,
    117115                            IPC_GET_DEVICE(icall), IPC_GET_STATE(icall));
    118                         ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
     116                        ipc_answer_0(iid, (ipcarg_t) rc);
    119117                        break;
    120118               
    121119                case NET_NIL_RECEIVED:
    122                         if (ERROR_NONE(packet_translate_remote(
    123                             nildummy_globals.net_phone, &packet,
    124                             IPC_GET_PACKET(icall)))) {
    125                                 ERROR_CODE = nil_received_msg_local(0,
     120                        rc = packet_translate_remote(nildummy_globals.net_phone,
     121                            &packet, IPC_GET_PACKET(icall));
     122                        if (rc == EOK) {
     123                                rc = nil_received_msg_local(0,
    126124                                    IPC_GET_DEVICE(icall), packet, 0);
    127125                        }
    128                         ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);
     126                        ipc_answer_0(iid, (ipcarg_t) rc);
    129127                        break;
    130128               
     
    155153nildummy_device_message(device_id_t device_id, services_t service, size_t mtu)
    156154{
    157         ERROR_DECLARE;
    158 
    159155        nildummy_device_ref device;
    160156        int index;
     157        int rc;
    161158
    162159        fibril_rwlock_write_lock(&nildummy_globals.devices_lock);
     
    216213       
    217214        // get hardware address
    218         if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id,
    219             &device->addr, &device->addr_data))) {
     215        rc = netif_get_addr_req(device->phone, device->device_id, &device->addr,
     216            &device->addr_data);
     217        if (rc != EOK) {
    220218                fibril_rwlock_write_unlock(&nildummy_globals.devices_lock);
    221219                free(device);
    222                 return ERROR_CODE;
     220                return rc;
    223221        }
    224222       
     
    380378    ipc_call_t *answer, int *answer_count)
    381379{
    382         ERROR_DECLARE;
    383        
    384380        measured_string_ref address;
    385381        packet_t packet;
     
    388384        size_t suffix;
    389385        size_t content;
     386        int rc;
    390387       
    391388        *answer_count = 0;
     
    399396       
    400397        case NET_NIL_SEND:
    401                 ERROR_PROPAGATE(packet_translate_remote(
    402                     nildummy_globals.net_phone, &packet, IPC_GET_PACKET(call)));
     398                rc = packet_translate_remote(nildummy_globals.net_phone,
     399                    &packet, IPC_GET_PACKET(call));
     400                if (rc != EOK)
     401                        return rc;
    403402                return nildummy_send_message(IPC_GET_DEVICE(call), packet,
    404403                    IPC_GET_SERVICE(call));
    405404       
    406405        case NET_NIL_PACKET_SPACE:
    407                 ERROR_PROPAGATE(nildummy_packet_space_message(
    408                     IPC_GET_DEVICE(call), &addrlen, &prefix, &content,
    409                     &suffix));
     406                rc = nildummy_packet_space_message(IPC_GET_DEVICE(call),
     407                    &addrlen, &prefix, &content, &suffix);
     408                if (rc != EOK)
     409                        return rc;
    410410                IPC_SET_ADDR(answer, addrlen);
    411411                IPC_SET_PREFIX(answer, prefix);
     
    416416       
    417417        case NET_NIL_ADDR:
    418                 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    419                     &address));
     418                rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
     419                if (rc != EOK)
     420                        return rc;
    420421                return measured_strings_reply(address, 1);
    421422       
    422423        case NET_NIL_BROADCAST_ADDR:
    423                 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call),
    424                     &address));
     424                rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address);
     425                if (rc != EOK)
     426                        return rc;
    425427                return measured_strings_reply(address, 1);
    426428       
     
    476478int main(int argc, char *argv[])
    477479{
    478         ERROR_DECLARE;
     480        int rc;
    479481       
    480482        /* Start the module */
    481         ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));
    482         return EOK;
     483        rc = nil_module_start_standalone(nil_client_connection);
     484        return rc;
    483485}
    484486
  • uspace/srv/net/nil/nildummy/nildummy.h

    rd70a463 rb40bfac  
    6262 * @see nildummy_proto
    6363 */
    64 typedef struct nildummy_proto   nildummy_proto_t;
     64typedef struct nildummy_proto nildummy_proto_t;
    6565
    6666/** Type definition of the dummy nil protocol specific data pointer.
     
    100100
    101101/** Dummy nil global data. */
    102 struct  nildummy_globals {
     102struct nildummy_globals {
    103103        /** Networking module phone. */
    104104        int net_phone;
  • uspace/srv/net/nil/nildummy/nildummy_module.c

    rd70a463 rb40bfac  
    3838#include <async.h>
    3939#include <stdio.h>
    40 #include <err.h>
     40#include <errno.h>
    4141
    4242#include <ipc/ipc.h>
     
    5252int nil_module_start_standalone(async_client_conn_t client_connection)
    5353{
    54         ERROR_DECLARE;
     54        ipcarg_t phonehash;
     55        int rc;
    5556       
    5657        async_set_client_connection(client_connection);
    5758        int net_phone = net_connect_module();
    58         ERROR_PROPAGATE(pm_init());
    5959       
    60         ipcarg_t phonehash;
    61         if (ERROR_OCCURRED(nil_initialize(net_phone)) ||
    62             ERROR_OCCURRED(REGISTER_ME(SERVICE_NILDUMMY, &phonehash))) {
    63                 pm_destroy();
    64                 return ERROR_CODE;
    65         }
     60        rc = pm_init();
     61        if (rc != EOK)
     62                return rc;
     63       
     64       
     65        rc = nil_initialize(net_phone);
     66        if (rc != EOK)
     67                goto out;
     68       
     69        rc = REGISTER_ME(SERVICE_NILDUMMY, &phonehash);
     70        if (rc != EOK)
     71                goto out;
    6672       
    6773        async_manager();
    68        
     74
     75out:
    6976        pm_destroy();
    70         return EOK;
     77        return rc;
    7178}
    7279
  • uspace/srv/net/tl/icmp/icmp.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup icmp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  ICMP module implementation.
    35  *  @see icmp.h
    36  */
     34 * ICMP module implementation.
     35 * @see icmp.h
     36 */
     37
     38#include "icmp.h"
     39#include "icmp_module.h"
    3740
    3841#include <async.h>
     
    5154#include <byteorder.h>
    5255#include <errno.h>
    53 #include <err.h>
    5456
    5557#include <net/socket_codes.h>
    5658#include <net/ip_protocols.h>
    5759#include <net/inet.h>
    58 
    5960#include <net/modules.h>
     61#include <net/icmp_api.h>
     62#include <net/icmp_codes.h>
     63#include <net/icmp_common.h>
     64
    6065#include <packet_client.h>
    6166#include <packet_remote.h>
    6267#include <net_checksum.h>
    63 #include <net/icmp_api.h>
    6468#include <icmp_client.h>
    65 #include <net/icmp_codes.h>
    66 #include <net/icmp_common.h>
    6769#include <icmp_interface.h>
    6870#include <il_interface.h>
     
    7476#include <icmp_header.h>
    7577
    76 #include "icmp.h"
    77 #include "icmp_module.h"
    78 
    79 /** ICMP module name.
    80  */
     78/** ICMP module name. */
    8179#define NAME    "ICMP protocol"
    8280
    83 /** Default ICMP error reporting.
    84  */
     81/** Default ICMP error reporting. */
    8582#define NET_DEFAULT_ICMP_ERROR_REPORTING        true
    8683
    87 /** Default ICMP echo replying.
    88  */
     84/** Default ICMP echo replying. */
    8985#define NET_DEFAULT_ICMP_ECHO_REPLYING          true
    9086
    91 /** Original datagram length in bytes transfered to the error notification message.
     87/** Original datagram length in bytes transfered to the error notification
     88 * message.
    9289 */
    9390#define ICMP_KEEP_LENGTH        8
    9491
    95 /** Free identifier numbers pool start.
    96  */
     92/** Free identifier numbers pool start. */
    9793#define ICMP_FREE_IDS_START     1
    9894
    99 /** Free identifier numbers pool end.
    100  */
     95/** Free identifier numbers pool end. */
    10196#define ICMP_FREE_IDS_END       UINT16_MAX
    10297
    10398/** Computes the ICMP datagram checksum.
    104  *  @param[in,out] header The ICMP datagram header.
    105  *  @param[in] length The total datagram length.
    106  *  @returns The computed checksum.
    107  */
    108 #define ICMP_CHECKSUM(header, length)           htons(ip_checksum((uint8_t *) (header), (length)))
    109 
    110 /** An echo request datagrams pattern.
    111  */
    112 #define ICMP_ECHO_TEXT                                  "Hello from HelenOS."
     99 *
     100 * @param[in,out] header The ICMP datagram header.
     101 * @param[in] length    The total datagram length.
     102 * @returns             The computed checksum.
     103 */
     104#define ICMP_CHECKSUM(header, length) \
     105        htons(ip_checksum((uint8_t *) (header), (length)))
     106
     107/** An echo request datagrams pattern. */
     108#define ICMP_ECHO_TEXT          "Hello from HelenOS."
    113109
    114110/** Computes an ICMP reply data key.
    115  *  @param[in] id The message identifier.
    116  *  @param[in] sequence The message sequence number.
    117  *  @returns The computed ICMP reply data key.
    118  */
    119 #define ICMP_GET_REPLY_KEY(id, sequence)        (((id) << 16) | (sequence &0xFFFF))
    120 
    121 /** Processes the received ICMP packet.
    122  *  Is used as an entry point from the underlying IP module.
    123  *  Releases the packet on error.
    124  *  @param device_id The device identifier. Ignored parameter.
    125  *  @param[in,out] packet The received packet.
    126  *  @param receiver The target service. Ignored parameter.
    127  *  @param[in] error The packet error reporting service. Prefixes the received packet.
    128  *  @returns EOK on success.
    129  *  @returns Other error codes as defined for the icmp_process_packet() function.
    130  */
    131 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error);
    132 
    133 /** Processes the received ICMP packet.
    134  *  Notifies the destination socket application.
    135  *  @param[in,out] packet The received packet.
    136  *  @param[in] error The packet error reporting service. Prefixes the received packet.
    137  *  @returns EOK on success.
    138  *  @returns EINVAL if the packet is not valid.
    139  *  @returns EINVAL if the stored packet address is not the an_addr_t.
    140  *  @returns EINVAL if the packet does not contain any data.
    141  *  @returns NO_DATA if the packet content is shorter than the user datagram header.
    142  *  @returns ENOMEM if there is not enough memory left.
    143  *  @returns EADDRNOTAVAIL if the destination socket does not exist.
    144  *  @returns Other error codes as defined for the ip_client_process_packet() function.
    145  */
    146 int icmp_process_packet(packet_t packet, services_t error);
    147 
    148 /** Processes the client messages.
    149  *  Remembers the assigned identifier and sequence numbers.
    150  *  Runs until the client module disconnects.
    151  *  @param[in] callid The message identifier.
    152  *  @param[in] call The message parameters.
    153  *  @returns EOK.
    154  *  @see icmp_interface.h
    155  *  @see icmp_api.h
    156  */
    157 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
    158 
    159 /** Processes the generic client messages.
    160  *  @param[in] call The message parameters.
    161  *  @returns EOK on success.
    162  *  @returns ENOTSUP if the message is not known.
    163  *  @returns Other error codes as defined for the packet_translate() function.
    164  *  @returns Other error codes as defined for the icmp_destination_unreachable_msg() function.
    165  *  @returns Other error codes as defined for the icmp_source_quench_msg() function.
    166  *  @returns Other error codes as defined for the icmp_time_exceeded_msg() function.
    167  *  @returns Other error codes as defined for the icmp_parameter_problem_msg() function.
    168  *  @see icmp_interface.h
    169  */
    170 int icmp_process_message(ipc_call_t * call);
     111 *
     112 * @param[in] id        The message identifier.
     113 * @param[in] sequence  The message sequence number.
     114 * @returns             The computed ICMP reply data key.
     115 */
     116#define ICMP_GET_REPLY_KEY(id, sequence) \
     117        (((id) << 16) | (sequence & 0xFFFF))
     118
     119
     120/** ICMP global data. */
     121icmp_globals_t  icmp_globals;
     122
     123INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t);
     124INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t);
    171125
    172126/** Releases the packet and returns the result.
    173  *  @param[in] packet The packet queue to be released.
    174  *  @param[in] result The result to be returned.
    175  *  @returns The result parameter.
    176  */
    177 int icmp_release_and_return(packet_t packet, int result);
     127 *
     128 * @param[in] packet    The packet queue to be released.
     129 * @param[in] result    The result to be returned.
     130 * @returns             The result parameter.
     131 */
     132static int icmp_release_and_return(packet_t packet, int result)
     133{
     134        pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
     135        return result;
     136}
     137
     138/** Sends the ICMP message.
     139 *
     140 * Sets the message type and code and computes the checksum.
     141 * Error messages are sent only if allowed in the configuration.
     142 * Releases the packet on errors.
     143 *
     144 * @param[in] type      The message type.
     145 * @param[in] code      The message code.
     146 * @param[in] packet    The message packet to be sent.
     147 * @param[in] header    The ICMP header.
     148 * @param[in] error     The error service to be announced. Should be
     149 *                      SERVICE_ICMP or zero.
     150 * @param[in] ttl       The time to live.
     151 * @param[in] tos       The type of service.
     152 * @param[in] dont_fragment The value indicating whether the datagram must not
     153 *                      be fragmented. Is used as a MTU discovery.
     154 * @returns             EOK on success.
     155 * @returns             EPERM if the error message is not allowed.
     156 */
     157static int
     158icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet,
     159    icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos,
     160    int dont_fragment)
     161{
     162        int rc;
     163
     164        // do not send an error if disabled
     165        if (error && !icmp_globals.error_reporting)
     166                return icmp_release_and_return(packet, EPERM);
     167
     168        header->type = type;
     169        header->code = code;
     170        header->checksum = 0;
     171        header->checksum = ICMP_CHECKSUM(header,
     172            packet_get_data_length(packet));
     173       
     174        rc = ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos,
     175            dont_fragment, 0);
     176        if (rc != EOK)
     177                return icmp_release_and_return(packet, rc);
     178
     179        return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP,
     180            error);
     181}
     182
     183/** Prepares the ICMP error packet.
     184 *
     185 * Truncates the original packet if longer than ICMP_KEEP_LENGTH bytes.
     186 * Prefixes and returns the ICMP header.
     187 *
     188 * @param[in,out] packet The original packet.
     189 * @returns The prefixed ICMP header.
     190 * @returns NULL on errors.
     191 */
     192static icmp_header_ref icmp_prepare_packet(packet_t packet)
     193{
     194        icmp_header_ref header;
     195        size_t header_length;
     196        size_t total_length;
     197
     198        total_length = packet_get_data_length(packet);
     199        if (total_length <= 0)
     200                return NULL;
     201
     202        header_length = ip_client_header_length(packet);
     203        if (header_length <= 0)
     204                return NULL;
     205
     206        // truncate if longer than 64 bits (without the IP header)
     207        if ((total_length > header_length + ICMP_KEEP_LENGTH) &&
     208            (packet_trim(packet, 0,
     209            total_length - header_length - ICMP_KEEP_LENGTH) != EOK)) {
     210                return NULL;
     211        }
     212
     213        header = PACKET_PREFIX(packet, icmp_header_t);
     214        if (!header)
     215                return NULL;
     216
     217        bzero(header, sizeof(*header));
     218        return header;
     219}
    178220
    179221/** Requests an echo message.
    180  *  Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout.
    181  *  Blocks the caller until the reply or the timeout occurs.
    182  *  @param[in] id The message identifier.
    183  *  @param[in] sequence The message sequence parameter.
    184  *  @param[in] size The message data length in bytes.
    185  *  @param[in] timeout The timeout in miliseconds.
    186  *  @param[in] ttl The time to live.
    187  *  @param[in] tos The type of service.
    188  *  @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery.
    189  *  @param[in] addr The target host address.
    190  *  @param[in] addrlen The torget host address length.
    191  *  @returns ICMP_ECHO on success.
    192  *  @returns ETIMEOUT if the reply has not arrived before the timeout.
    193  *  @returns ICMP type of the received error notification.
    194  *  @returns EINVAL if the addrlen parameter is less or equal to zero (<=0).
    195  *  @returns ENOMEM if there is not enough memory left.
    196  *  @returns EPARTY if there was an internal error.
    197  */
    198 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen);
    199 
    200 /** Prepares the ICMP error packet.
    201  *  Truncates the original packet if longer than ICMP_KEEP_LENGTH bytes.
    202  *  Prefixes and returns the ICMP header.
    203  *  @param[in,out] packet The original packet.
    204  *  @returns The prefixed ICMP header.
    205  *  @returns NULL on errors.
    206  */
    207 icmp_header_ref icmp_prepare_packet(packet_t packet);
    208 
    209 /** Sends the ICMP message.
    210  *  Sets the message type and code and computes the checksum.
    211  *  Error messages are sent only if allowed in the configuration.
    212  *  Releases the packet on errors.
    213  *  @param[in] type The message type.
    214  *  @param[in] code The message code.
    215  *  @param[in] packet The message packet to be sent.
    216  *  @param[in] header The ICMP header.
    217  *  @param[in] error The error service to be announced. Should be SERVICE_ICMP or zero (0).
    218  *  @param[in] ttl The time to live.
    219  *  @param[in] tos The type of service.
    220  *  @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery.
    221  *  @returns EOK on success.
    222  *  @returns EPERM if the error message is not allowed.
    223  */
    224 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment);
    225 
    226 /** Tries to set the pending reply result as the received message type.
    227  *  If the reply data is not present, the reply timed out and the other fibril
    228  *  is already awake.
    229  *  Releases the packet.
    230  *  @param[in] packet The received reply message.
    231  *  @param[in] header The ICMP message header.
    232  *  @param[in] type The received reply message type.
    233  *  @param[in] code The received reply message code.
    234  *  @returns EOK.
    235  */
    236 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code);
    237 
    238 /** Assigns a new identifier for the connection.
    239  *  Fills the echo data parameter with the assigned values.
    240  *  @param[in,out] echo_data The echo data to be bound.
    241  *  @returns Index of the inserted echo data.
    242  *  @returns EBADMEM if the echo_data parameter is NULL.
    243  *  @returns ENOTCONN if no free identifier have been found.
    244  */
    245 int icmp_bind_free_id(icmp_echo_ref echo_data);
    246 
    247 /** ICMP global data.
    248  */
    249 icmp_globals_t  icmp_globals;
    250 
    251 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t);
    252 
    253 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t);
    254 
    255 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
    256         icmp_echo_ref echo_data;
    257         int res;
    258 
    259         fibril_rwlock_write_lock(&icmp_globals.lock);
    260         // use the phone as the echo data index
    261         echo_data = icmp_echo_data_find(&icmp_globals.echo_data, icmp_phone);
    262         if(! echo_data){
    263                 res = ENOENT;
    264         }else{
    265                 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen);
    266                 if(echo_data->sequence_number < UINT16_MAX){
    267                         ++ echo_data->sequence_number;
    268                 }else{
    269                         echo_data->sequence_number = 0;
    270                 }
    271         }
    272         fibril_rwlock_write_unlock(&icmp_globals.lock);
    273         return res;
    274 }
    275 
    276 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){
    277         ERROR_DECLARE;
    278 
     222 *
     223 * Sends a packet with specified parameters to the target host and waits for
     224 * the reply upto the given timeout.
     225 * Blocks the caller until the reply or the timeout occurs.
     226 *
     227 * @param[in] id        The message identifier.
     228 * @param[in] sequence  The message sequence parameter.
     229 * @param[in] size      The message data length in bytes.
     230 * @param[in] timeout   The timeout in miliseconds.
     231 * @param[in] ttl       The time to live.
     232 * @param[in] tos       The type of service.
     233 * @param[in] dont_fragment The value indicating whether the datagram must not
     234 *                      be fragmented. Is used as a MTU discovery.
     235 * @param[in] addr      The target host address.
     236 * @param[in] addrlen   The torget host address length.
     237 * @returns             ICMP_ECHO on success.
     238 * @returns             ETIMEOUT if the reply has not arrived before the
     239 *                      timeout.
     240 * @returns             ICMP type of the received error notification.
     241 * @returns             EINVAL if the addrlen parameter is less or equal to
     242 *                      zero.
     243 * @returns             ENOMEM if there is not enough memory left.
     244 * @returns             EPARTY if there was an internal error.
     245 */
     246static int
     247icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size,
     248    mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment,
     249    const struct sockaddr * addr, socklen_t addrlen)
     250{
    279251        icmp_header_ref header;
    280252        packet_t packet;
    281253        size_t length;
    282         uint8_t * data;
     254        uint8_t *data;
    283255        icmp_reply_ref reply;
    284256        int reply_key;
    285         int result;
    286257        int index;
    287 
    288         if(addrlen <= 0){
     258        int rc;
     259
     260        if (addrlen <= 0)
    289261                return EINVAL;
    290         }
     262
    291263        length = (size_t) addrlen;
    292264        // TODO do not ask all the time
    293         ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension));
    294         packet = packet_get_4_remote(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix);
    295         if(! packet){
     265        rc = ip_packet_size_req(icmp_globals.ip_phone, -1,
     266            &icmp_globals.packet_dimension);
     267        if (rc != EOK)
     268                return rc;
     269
     270        packet = packet_get_4_remote(icmp_globals.net_phone, size,
     271            icmp_globals.packet_dimension.addr_len,
     272            ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix,
     273            icmp_globals.packet_dimension.suffix);
     274        if (!packet)
    296275                return ENOMEM;
    297         }
    298276
    299277        // prepare the requesting packet
    300278        // set the destination address
    301         if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (const uint8_t *) addr, length))){
    302                 return icmp_release_and_return(packet, ERROR_CODE);
    303         }
     279        rc = packet_set_addr(packet, NULL, (const uint8_t *) addr, length);
     280        if (rc != EOK)
     281                return icmp_release_and_return(packet, rc);
     282
    304283        // allocate space in the packet
    305284        data = (uint8_t *) packet_suffix(packet, size);
    306         if(! data){
     285        if (!data)
    307286                return icmp_release_and_return(packet, ENOMEM);
    308         }
     287
    309288        // fill the data
    310289        length = 0;
    311         while(size > length + sizeof(ICMP_ECHO_TEXT)){
     290        while (size > length + sizeof(ICMP_ECHO_TEXT)) {
    312291                memcpy(data + length, ICMP_ECHO_TEXT, sizeof(ICMP_ECHO_TEXT));
    313292                length += sizeof(ICMP_ECHO_TEXT);
    314293        }
    315294        memcpy(data + length, ICMP_ECHO_TEXT, size - length);
     295
    316296        // prefix the header
    317297        header = PACKET_PREFIX(packet, icmp_header_t);
    318         if(! header){
     298        if (!header)
    319299                return icmp_release_and_return(packet, ENOMEM);
    320         }
     300
    321301        bzero(header, sizeof(*header));
    322302        header->un.echo.identifier = id;
     
    325305        // prepare the reply structure
    326306        reply = malloc(sizeof(*reply));
    327         if(! reply){
     307        if (!reply)
    328308                return icmp_release_and_return(packet, ENOMEM);
    329         }
     309
    330310        fibril_mutex_initialize(&reply->mutex);
    331311        fibril_mutex_lock(&reply->mutex);
    332312        fibril_condvar_initialize(&reply->condvar);
    333         reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number);
     313        reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier,
     314            header->un.echo.sequence_number);
    334315        index = icmp_replies_add(&icmp_globals.replies, reply_key, reply);
    335         if(index < 0){
     316        if (index < 0) {
    336317                free(reply);
    337318                return icmp_release_and_return(packet, index);
     
    342323
    343324        // send the request
    344         icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment);
     325        icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos,
     326            dont_fragment);
    345327
    346328        // wait for the reply
    347329        // timeout in microseconds
    348         if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){
    349                 result = ERROR_CODE;
    350         }else{
    351                 // read the result
    352                 result = reply->result;
    353         }
     330        rc = fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex,
     331            timeout * 1000);
     332        if (rc == EOK)
     333                rc = reply->result;
    354334
    355335        // drop the reply mutex before locking the globals again
     
    359339        // destroy the reply structure
    360340        icmp_replies_exclude_index(&icmp_globals.replies, index);
    361         return result;
    362 }
    363 
    364 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){
     341
     342        return rc;
     343}
     344
     345static int
     346icmp_destination_unreachable_msg_local(int icmp_phone, icmp_code_t code,
     347    icmp_param_t mtu, packet_t packet)
     348{
    365349        icmp_header_ref header;
    366350
    367351        header = icmp_prepare_packet(packet);
    368         if(! header){
     352        if (!header)
    369353                return icmp_release_and_return(packet, ENOMEM);
    370         }
    371         if(mtu){
     354
     355        if (mtu)
    372356                header->un.frag.mtu = mtu;
    373         }
    374         return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    375 }
    376 
    377 int icmp_source_quench_msg(int icmp_phone, packet_t packet){
     357
     358        return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header,
     359            SERVICE_ICMP, 0, 0, 0);
     360}
     361
     362static int icmp_source_quench_msg_local(int icmp_phone, packet_t packet)
     363{
    378364        icmp_header_ref header;
    379365
    380366        header = icmp_prepare_packet(packet);
    381         if(! header){
     367        if (!header)
    382368                return icmp_release_and_return(packet, ENOMEM);
    383         }
    384         return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0);
    385 }
    386 
    387 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){
     369
     370        return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header,
     371            SERVICE_ICMP, 0, 0, 0);
     372}
     373
     374static int
     375icmp_time_exceeded_msg_local(int icmp_phone, icmp_code_t code, packet_t packet)
     376{
    388377        icmp_header_ref header;
    389378
    390379        header = icmp_prepare_packet(packet);
    391         if(! header){
     380        if (!header)
    392381                return icmp_release_and_return(packet, ENOMEM);
    393         }
    394         return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    395 }
    396 
    397 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){
     382
     383        return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header,
     384            SERVICE_ICMP, 0, 0, 0);
     385}
     386
     387static int
     388icmp_parameter_problem_msg_local(int icmp_phone, icmp_code_t code,
     389    icmp_param_t pointer, packet_t packet)
     390{
    398391        icmp_header_ref header;
    399392
    400393        header = icmp_prepare_packet(packet);
    401         if(! header){
     394        if (!header)
    402395                return icmp_release_and_return(packet, ENOMEM);
    403         }
     396
    404397        header->un.param.pointer = pointer;
    405         return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0);
    406 }
    407 
    408 icmp_header_ref icmp_prepare_packet(packet_t packet){
    409         icmp_header_ref header;
    410         size_t header_length;
    411         size_t total_length;
    412 
    413         total_length = packet_get_data_length(packet);
    414         if(total_length <= 0){
    415                 return NULL;
    416         }
    417         header_length = ip_client_header_length(packet);
    418         if(header_length <= 0){
    419                 return NULL;
    420         }
    421         // truncate if longer than 64 bits (without the IP header)
    422         if((total_length > header_length + ICMP_KEEP_LENGTH)
    423                 && (packet_trim(packet, 0, total_length - header_length - ICMP_KEEP_LENGTH) != EOK)){
    424                 return NULL;
    425         }
    426         header = PACKET_PREFIX(packet, icmp_header_t);
    427         if(! header){
    428                 return NULL;
    429         }
    430         bzero(header, sizeof(*header));
    431         return header;
    432 }
    433 
    434 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){
    435         ERROR_DECLARE;
    436 
    437         // do not send an error if disabled
    438         if(error && (! icmp_globals.error_reporting)){
    439                 return icmp_release_and_return(packet, EPERM);
    440         }
    441         header->type = type;
    442         header->code = code;
    443         header->checksum = 0;
    444         header->checksum = ICMP_CHECKSUM(header, packet_get_data_length(packet));
    445         if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0))){
    446                 return icmp_release_and_return(packet, ERROR_CODE);
    447         }
    448         return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error);
    449 }
    450 
    451 int icmp_initialize(async_client_conn_t client_connection){
    452         ERROR_DECLARE;
    453 
    454         measured_string_t names[] = {{str_dup("ICMP_ERROR_REPORTING"), 20}, {str_dup("ICMP_ECHO_REPLYING"), 18}};
     398        return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header,
     399            SERVICE_ICMP, 0, 0, 0);
     400}
     401
     402/** Initializes the ICMP module.
     403 *
     404 * @param[in] client_connection The client connection processing function. The
     405 *                      module skeleton propagates its own one.
     406 * @returns             EOK on success.
     407 * @returns             ENOMEM if there is not enough memory left.
     408 */
     409int icmp_initialize(async_client_conn_t client_connection)
     410{
     411        measured_string_t names[] = {
     412                {
     413                        (char *) "ICMP_ERROR_REPORTING",
     414                        20
     415                },
     416                {
     417                        (char *) "ICMP_ECHO_REPLYING",
     418                        18
     419                }
     420        };
    455421        measured_string_ref configuration;
    456422        size_t count = sizeof(names) / sizeof(measured_string_t);
    457         char * data;
     423        char *data;
     424        int rc;
    458425
    459426        fibril_rwlock_initialize(&icmp_globals.lock);
     
    461428        icmp_replies_initialize(&icmp_globals.replies);
    462429        icmp_echo_data_initialize(&icmp_globals.echo_data);
    463         icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection);
    464         if(icmp_globals.ip_phone < 0){
     430       
     431        icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP,
     432            SERVICE_ICMP, client_connection);
     433        if (icmp_globals.ip_phone < 0) {
     434                fibril_rwlock_write_unlock(&icmp_globals.lock);
    465435                return icmp_globals.ip_phone;
    466436        }
    467         ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension));
     437       
     438        rc = ip_packet_size_req(icmp_globals.ip_phone, -1,
     439            &icmp_globals.packet_dimension);
     440        if (rc != EOK) {
     441                fibril_rwlock_write_unlock(&icmp_globals.lock);
     442                return rc;
     443        }
     444
    468445        icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE;
    469446        icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE;
    470         // get configuration
     447
    471448        icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING;
    472449        icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING;
     450
     451        // get configuration
    473452        configuration = &names[0];
    474         ERROR_PROPAGATE(net_get_conf_req(icmp_globals.net_phone, &configuration, count, &data));
    475         if(configuration){
    476                 if(configuration[0].value){
    477                         icmp_globals.error_reporting = (configuration[0].value[0] == 'y');
     453        rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count,
     454            &data);
     455        if (rc != EOK) {
     456                fibril_rwlock_write_unlock(&icmp_globals.lock);
     457                return rc;
     458        }
     459       
     460        if (configuration) {
     461                if (configuration[0].value) {
     462                        icmp_globals.error_reporting =
     463                            (configuration[0].value[0] == 'y');
    478464                }
    479                 if(configuration[1].value){
    480                         icmp_globals.echo_replying = (configuration[1].value[0] == 'y');
     465                if (configuration[1].value) {
     466                        icmp_globals.echo_replying =
     467                            (configuration[1].value[0] == 'y');
    481468                }
    482469                net_free_settings(configuration, data);
    483470        }
     471
    484472        fibril_rwlock_write_unlock(&icmp_globals.lock);
    485473        return EOK;
    486474}
    487475
    488 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){
    489         ERROR_DECLARE;
    490 
    491         if(ERROR_OCCURRED(icmp_process_packet(packet, error))){
    492                 return icmp_release_and_return(packet, ERROR_CODE);
    493         }
    494 
    495         return EOK;
    496 }
    497 
    498 int icmp_process_packet(packet_t packet, services_t error){
    499         ERROR_DECLARE;
    500 
     476/** Tries to set the pending reply result as the received message type.
     477 *
     478 * If the reply data is not present, the reply timed out and the other fibril
     479 * is already awake.
     480 * Releases the packet.
     481 *
     482 * @param[in] packet    The received reply message.
     483 * @param[in] header    The ICMP message header.
     484 * @param[in] type      The received reply message type.
     485 * @param[in] code      The received reply message code.
     486 */
     487static void
     488icmp_process_echo_reply(packet_t packet, icmp_header_ref header,
     489    icmp_type_t type, icmp_code_t code)
     490{
     491        int reply_key;
     492        icmp_reply_ref reply;
     493
     494        // compute the reply key
     495        reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier,
     496            header->un.echo.sequence_number);
     497        pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
     498
     499        fibril_rwlock_write_lock(&icmp_globals.lock);
     500        // find the pending reply
     501        reply = icmp_replies_find(&icmp_globals.replies, reply_key);
     502        if (reply) {
     503                reply->result = type;
     504                fibril_condvar_signal(&reply->condvar);
     505        }
     506        fibril_rwlock_write_unlock(&icmp_globals.lock);
     507}
     508
     509/** Processes the received ICMP packet.
     510 *
     511 * Notifies the destination socket application.
     512 *
     513 * @param[in,out] packet The received packet.
     514 * @param[in] error     The packet error reporting service. Prefixes the
     515 *                      received packet.
     516 * @returns             EOK on success.
     517 * @returns             EINVAL if the packet is not valid.
     518 * @returns             EINVAL if the stored packet address is not the an_addr_t.
     519 * @returns             EINVAL if the packet does not contain any data.
     520 * @returns             NO_DATA if the packet content is shorter than the user
     521 *                      datagram header.
     522 * @returns             ENOMEM if there is not enough memory left.
     523 * @returns             EADDRNOTAVAIL if the destination socket does not exist.
     524 * @returns             Other error codes as defined for the
     525 *                      ip_client_process_packet() function.
     526 */
     527static int icmp_process_packet(packet_t packet, services_t error)
     528{
    501529        size_t length;
    502         uint8_t * src;
     530        uint8_t *src;
    503531        int addrlen;
    504532        int result;
    505         void * data;
     533        void *data;
    506534        icmp_header_ref header;
    507535        icmp_type_t type;
    508536        icmp_code_t code;
    509 
    510         if(error){
    511                 switch(error){
    512                         case SERVICE_ICMP:
    513                                 // process error
    514                                 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL);
    515                                 if(result < 0){
    516                                         return result;
    517                                 }
    518                                 length = (size_t) result;
    519                                 // remove the error header
    520                                 ERROR_PROPAGATE(packet_trim(packet, length, 0));
    521                                 break;
    522                         default:
    523                                 return ENOTSUP;
    524                 }
    525         }
     537        int rc;
     538
     539        switch (error) {
     540        case SERVICE_NONE:
     541                break;
     542        case SERVICE_ICMP:
     543                // process error
     544                result = icmp_client_process_packet(packet, &type, &code, NULL,
     545                    NULL);
     546                if (result < 0)
     547                        return result;
     548                length = (size_t) result;
     549                // remove the error header
     550                rc = packet_trim(packet, length, 0);
     551                if (rc != EOK)
     552                        return rc;
     553                break;
     554        default:
     555                return ENOTSUP;
     556        }
     557
    526558        // get rid of the ip header
    527559        length = ip_client_header_length(packet);
    528         ERROR_PROPAGATE(packet_trim(packet, length, 0));
     560        rc = packet_trim(packet, length, 0);
     561        if (rc != EOK)
     562                return rc;
    529563
    530564        length = packet_get_data_length(packet);
    531         if(length <= 0){
     565        if (length <= 0)
    532566                return EINVAL;
    533         }
    534         if(length < ICMP_HEADER_SIZE){
     567
     568        if (length < ICMP_HEADER_SIZE)
    535569                return EINVAL;
    536         }
     570
    537571        data = packet_get_data(packet);
    538         if(! data){
     572        if (!data)
    539573                return EINVAL;
    540         }
     574
    541575        // get icmp header
    542576        header = (icmp_header_ref) data;
    543         // checksum
    544         if(header->checksum){
    545                 while(ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO){
     577
     578        if (header->checksum) {
     579                while (ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO) {
    546580                        // set the original message type on error notification
    547581                        // type swap observed in Qemu
    548                         if(error){
    549                                 switch(header->type){
    550                                         case ICMP_ECHOREPLY:
    551                                                 header->type = ICMP_ECHO;
    552                                                 continue;
     582                        if (error) {
     583                                switch (header->type) {
     584                                case ICMP_ECHOREPLY:
     585                                        header->type = ICMP_ECHO;
     586                                        continue;
    553587                                }
    554588                        }
     
    556590                }
    557591        }
    558         switch(header->type){
    559                 case ICMP_ECHOREPLY:
    560                         if(error){
    561                                 return icmp_process_echo_reply(packet, header, type, code);
    562                         }else{
    563                                 return icmp_process_echo_reply(packet, header, ICMP_ECHO, 0);
     592
     593        switch (header->type) {
     594        case ICMP_ECHOREPLY:
     595                if (error)
     596                        icmp_process_echo_reply(packet, header, type, code);
     597                else
     598                        icmp_process_echo_reply(packet, header, ICMP_ECHO, 0);
     599
     600                return EOK;
     601
     602        case ICMP_ECHO:
     603                if (error) {
     604                        icmp_process_echo_reply(packet, header, type, code);
     605                        return EOK;
     606                }
     607               
     608                // do not send a reply if disabled
     609                if (icmp_globals.echo_replying) {
     610                        addrlen = packet_get_addr(packet, &src, NULL);
     611
     612                        // set both addresses to the source one (avoids the
     613                        // source address deletion before setting the
     614                        // destination one)
     615                        if ((addrlen > 0) && (packet_set_addr(packet, src, src,
     616                            (size_t) addrlen) == EOK)) {
     617                                // send the reply
     618                                icmp_send_packet(ICMP_ECHOREPLY, 0, packet,
     619                                    header, 0, 0, 0, 0);
     620                                return EOK;
    564621                        }
    565                 case ICMP_ECHO:
    566                         if(error){
    567                                 return icmp_process_echo_reply(packet, header, type, code);
    568                         // do not send a reply if disabled
    569                         }else if(icmp_globals.echo_replying){
    570                                 addrlen = packet_get_addr(packet, &src, NULL);
    571                                 if((addrlen > 0)
    572                                 // set both addresses to the source one (avoids the source address deletion before setting the destination one)
    573                                         && (packet_set_addr(packet, src, src, (size_t) addrlen) == EOK)){
    574                                         // send the reply
    575                                         icmp_send_packet(ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0);
    576                                         return EOK;
    577                                 }else{
    578                                         return EINVAL;
     622
     623                        return EINVAL;
     624                }
     625
     626                return EPERM;
     627
     628        case ICMP_DEST_UNREACH:
     629        case ICMP_SOURCE_QUENCH:
     630        case ICMP_REDIRECT:
     631        case ICMP_ALTERNATE_ADDR:
     632        case ICMP_ROUTER_ADV:
     633        case ICMP_ROUTER_SOL:
     634        case ICMP_TIME_EXCEEDED:
     635        case ICMP_PARAMETERPROB:
     636        case ICMP_CONVERSION_ERROR:
     637        case ICMP_REDIRECT_MOBILE:
     638        case ICMP_SKIP:
     639        case ICMP_PHOTURIS:
     640                ip_received_error_msg(icmp_globals.ip_phone, -1, packet,
     641                    SERVICE_IP, SERVICE_ICMP);
     642                return EOK;
     643
     644        default:
     645                return ENOTSUP;
     646        }
     647}
     648
     649/** Processes the received ICMP packet.
     650 *
     651 * Is used as an entry point from the underlying IP module.
     652 * Releases the packet on error.
     653 *
     654 * @param device_id     The device identifier. Ignored parameter.
     655 * @param[in,out] packet The received packet.
     656 * @param receiver      The target service. Ignored parameter.
     657 * @param[in] error     The packet error reporting service. Prefixes the
     658 *                      received packet.
     659 * @returns             EOK on success.
     660 * @returns             Other error codes as defined for the
     661 *                      icmp_process_packet() function.
     662 */
     663static int
     664icmp_received_msg_local(device_id_t device_id, packet_t packet,
     665    services_t receiver, services_t error)
     666{
     667        int rc;
     668
     669        rc = icmp_process_packet(packet, error);
     670        if (rc != EOK)
     671                return icmp_release_and_return(packet, rc);
     672
     673        return EOK;
     674}
     675
     676/** Processes the generic client messages.
     677 *
     678 * @param[in] call      The message parameters.
     679 * @returns             EOK on success.
     680 * @returns             ENOTSUP if the message is not known.
     681 * @returns             Other error codes as defined for the packet_translate()
     682 *                      function.
     683 * @returns             Other error codes as defined for the
     684 *                      icmp_destination_unreachable_msg_local() function.
     685 * @returns             Other error codes as defined for the
     686 *                      icmp_source_quench_msg_local() function.
     687 * @returns             Other error codes as defined for the
     688 *                      icmp_time_exceeded_msg_local() function.
     689 * @returns             Other error codes as defined for the
     690 *                      icmp_parameter_problem_msg_local() function.
     691 *
     692 * @see icmp_interface.h
     693 */
     694static int icmp_process_message(ipc_call_t *call)
     695{
     696        packet_t packet;
     697        int rc;
     698
     699        switch (IPC_GET_METHOD(*call)) {
     700        case NET_ICMP_DEST_UNREACH:
     701                rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     702                    IPC_GET_PACKET(call));
     703                if (rc != EOK)
     704                        return rc;
     705                return icmp_destination_unreachable_msg_local(0,
     706                    ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet);
     707        case NET_ICMP_SOURCE_QUENCH:
     708                rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     709                    IPC_GET_PACKET(call));
     710                if (rc != EOK)
     711                        return rc;
     712                return icmp_source_quench_msg_local(0, packet);
     713        case NET_ICMP_TIME_EXCEEDED:
     714                rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     715                    IPC_GET_PACKET(call));
     716                if (rc != EOK)
     717                        return rc;
     718                return icmp_time_exceeded_msg_local(0, ICMP_GET_CODE(call),
     719                    packet);
     720        case NET_ICMP_PARAMETERPROB:
     721                rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     722                    IPC_GET_PACKET(call));
     723                if (rc != EOK)
     724                        return rc;
     725                return icmp_parameter_problem_msg_local(0, ICMP_GET_CODE(call),
     726                    ICMP_GET_POINTER(call), packet);
     727        default:
     728                return ENOTSUP;
     729        }
     730}
     731
     732/** Assigns a new identifier for the connection.
     733 *
     734 * Fills the echo data parameter with the assigned values.
     735 *
     736 * @param[in,out] echo_data The echo data to be bound.
     737 * @returns             Index of the inserted echo data.
     738 * @returns             EBADMEM if the echo_data parameter is NULL.
     739 * @returns             ENOTCONN if no free identifier have been found.
     740 */
     741static int icmp_bind_free_id(icmp_echo_ref echo_data)
     742{
     743        icmp_param_t index;
     744
     745        if (!echo_data)
     746                return EBADMEM;
     747
     748        // from the last used one
     749        index = icmp_globals.last_used_id;
     750        do {
     751                index++;
     752                // til the range end
     753                if (index >= ICMP_FREE_IDS_END) {
     754                        // start from the range beginning
     755                        index = ICMP_FREE_IDS_START - 1;
     756                        do {
     757                                index++;
     758                                // til the last used one
     759                                if (index >= icmp_globals.last_used_id) {
     760                                        // none found
     761                                        return ENOTCONN;
    579762                                }
    580                         }else{
    581                                 return EPERM;
    582                         }
    583                 case ICMP_DEST_UNREACH:
    584                 case ICMP_SOURCE_QUENCH:
    585                 case ICMP_REDIRECT:
    586                 case ICMP_ALTERNATE_ADDR:
    587                 case ICMP_ROUTER_ADV:
    588                 case ICMP_ROUTER_SOL:
    589                 case ICMP_TIME_EXCEEDED:
    590                 case ICMP_PARAMETERPROB:
    591                 case ICMP_CONVERSION_ERROR:
    592                 case ICMP_REDIRECT_MOBILE:
    593                 case ICMP_SKIP:
    594                 case ICMP_PHOTURIS:
    595                         ip_received_error_msg(icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP);
    596                         return EOK;
    597                 default:
    598                         return ENOTSUP;
    599         }
    600 }
    601 
    602 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){
    603         int reply_key;
    604         icmp_reply_ref reply;
    605 
    606         // compute the reply key
    607         reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number);
    608         pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
    609         // lock the globals
    610         fibril_rwlock_write_lock(&icmp_globals.lock);
    611         // find the pending reply
    612         reply = icmp_replies_find(&icmp_globals.replies, reply_key);
    613         if(reply){
    614                 // set the result
    615                 reply->result = type;
    616                 // notify the waiting fibril
    617                 fibril_condvar_signal(&reply->condvar);
    618         }
    619         fibril_rwlock_write_unlock(&icmp_globals.lock);
    620         return EOK;
    621 }
    622 
    623 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
    624         ERROR_DECLARE;
    625 
    626         packet_t packet;
    627 
    628         *answer_count = 0;
    629         switch(IPC_GET_METHOD(*call)){
    630                 case NET_TL_RECEIVED:
    631                         if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    632                                 ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call));
    633                         }
    634                         return ERROR_CODE;
    635                 case NET_ICMP_INIT:
    636                         return icmp_process_client_messages(callid, * call);
    637                 default:
    638                         return icmp_process_message(call);
    639         }
    640         return ENOTSUP;
    641 }
    642 
    643 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call){
    644         ERROR_DECLARE;
    645 
     763                        } while(icmp_echo_data_find(&icmp_globals.echo_data,
     764                            index) != NULL);
     765
     766                        // found, break immediately
     767                        break;
     768                }
     769        } while (icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);
     770
     771        echo_data->identifier = index;
     772        echo_data->sequence_number = 0;
     773
     774        return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data);
     775}
     776
     777/** Processes the client messages.
     778 *
     779 * Remembers the assigned identifier and sequence numbers.
     780 * Runs until the client module disconnects.
     781 *
     782 * @param[in] callid    The message identifier.
     783 * @param[in] call      The message parameters.
     784 * @returns EOK.
     785 *
     786 * @see icmp_interface.h
     787 * @see icmp_api.h
     788 */
     789static int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
     790{
    646791        bool keep_on_going = true;
    647 //      fibril_rwlock_t                 lock;
    648792        ipc_call_t answer;
    649793        int answer_count;
    650794        size_t length;
    651         struct sockaddr * addr;
     795        struct sockaddr *addr;
    652796        ipc_callid_t data_callid;
    653797        icmp_echo_ref echo_data;
    654         int res;
     798        int rc = EOK;
    655799
    656800        /*
     
    658802         *  - Answer the first NET_ICMP_INIT call.
    659803         */
    660         res = EOK;
    661804        answer_count = 0;
    662805
    663 //      fibril_rwlock_initialize(&lock);
    664 
    665806        echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data));
    666         if(! echo_data){
     807        if (!echo_data)
    667808                return ENOMEM;
    668         }
    669809
    670810        // assign a new identifier
    671811        fibril_rwlock_write_lock(&icmp_globals.lock);
    672         res = icmp_bind_free_id(echo_data);
     812        rc = icmp_bind_free_id(echo_data);
    673813        fibril_rwlock_write_unlock(&icmp_globals.lock);
    674         if(res < 0){
     814        if (rc < 0) {
    675815                free(echo_data);
    676                 return res;
    677         }
    678 
    679         while(keep_on_going){
    680 
     816                return rc;
     817        }
     818
     819        while (keep_on_going) {
    681820                // answer the call
    682                 answer_call(callid, res, &answer, answer_count);
     821                answer_call(callid, rc, &answer, answer_count);
    683822
    684823                // refresh data
     
    689828
    690829                // process the call
    691                 switch(IPC_GET_METHOD(call)){
    692                         case IPC_M_PHONE_HUNGUP:
    693                                 keep_on_going = false;
    694                                 res = EHANGUP;
     830                switch (IPC_GET_METHOD(call)) {
     831                case IPC_M_PHONE_HUNGUP:
     832                        keep_on_going = false;
     833                        rc = EHANGUP;
     834                        break;
     835               
     836                case NET_ICMP_ECHO:
     837                        if (!async_data_write_receive(&data_callid, &length)) {
     838                                rc = EINVAL;
    695839                                break;
    696                         case NET_ICMP_ECHO:
    697 //                              fibril_rwlock_write_lock(&lock);
    698                                 if(! async_data_write_receive(&data_callid, &length)){
    699                                         res = EINVAL;
    700                                 }else{
    701                                         addr = malloc(length);
    702                                         if(! addr){
    703                                                 res = ENOMEM;
    704                                         }else{
    705                                                 if(! ERROR_OCCURRED(async_data_write_finalize(data_callid, addr, length))){
    706                                                         fibril_rwlock_write_lock(&icmp_globals.lock);
    707                                                         res = icmp_echo(echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE(call), ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), addr, (socklen_t) length);
    708                                                         fibril_rwlock_write_unlock(&icmp_globals.lock);
    709                                                         free(addr);
    710                                                         if(echo_data->sequence_number < UINT16_MAX){
    711                                                                 ++ echo_data->sequence_number;
    712                                                         }else{
    713                                                                 echo_data->sequence_number = 0;
    714                                                         }
    715                                                 }else{
    716                                                         res = ERROR_CODE;
    717                                                 }
    718                                         }
    719                                 }
    720 //                              fibril_rwlock_write_unlock(&lock);
     840                        }
     841                       
     842                        addr = malloc(length);
     843                        if (!addr) {
     844                                rc = ENOMEM;
    721845                                break;
    722                         default:
    723                                 res = icmp_process_message(&call);
     846                        }
     847                       
     848                        rc = async_data_write_finalize(data_callid, addr,
     849                            length);
     850                        if (rc != EOK) {
     851                                free(addr);
     852                                break;
     853                        }
     854
     855                        fibril_rwlock_write_lock(&icmp_globals.lock);
     856                        rc = icmp_echo(echo_data->identifier,
     857                            echo_data->sequence_number, ICMP_GET_SIZE(call),
     858                            ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call),
     859                            ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call),
     860                            addr, (socklen_t) length);
     861                        fibril_rwlock_write_unlock(&icmp_globals.lock);
     862
     863                        free(addr);
     864
     865                        if (echo_data->sequence_number < UINT16_MAX)
     866                                echo_data->sequence_number++;
     867                        else
     868                                echo_data->sequence_number = 0;
     869
     870                        break;
     871
     872                default:
     873                        rc = icmp_process_message(&call);
    724874                }
     875
    725876        }
    726877
     
    729880        icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier);
    730881        fibril_rwlock_write_unlock(&icmp_globals.lock);
    731         return res;
    732 }
    733 
    734 int icmp_process_message(ipc_call_t * call){
    735         ERROR_DECLARE;
    736 
     882
     883        return rc;
     884}
     885
     886/** Processes the ICMP message.
     887 *
     888 * @param[in] callid    The message identifier.
     889 * @param[in] call      The message parameters.
     890 * @param[out] answer   The message answer parameters.
     891 * @param[out] answer_count The last parameter for the actual answer in the
     892 *                      answer parameter.
     893 * @returns             EOK on success.
     894 * @returns             ENOTSUP if the message is not known.
     895 *
     896 * @see icmp_interface.h
     897 * @see IS_NET_ICMP_MESSAGE()
     898 */
     899int
     900icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     901    ipc_call_t *answer, int *answer_count)
     902{
    737903        packet_t packet;
    738 
    739         switch(IPC_GET_METHOD(*call)){
    740                 case NET_ICMP_DEST_UNREACH:
    741                         if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    742                                 ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet);
    743                         }
    744                         return ERROR_CODE;
    745                 case NET_ICMP_SOURCE_QUENCH:
    746                         if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    747                                 ERROR_CODE = icmp_source_quench_msg(0, packet);
    748                         }
    749                         return ERROR_CODE;
    750                 case NET_ICMP_TIME_EXCEEDED:
    751                         if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    752                                 ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet);
    753                         }
    754                         return ERROR_CODE;
    755                 case NET_ICMP_PARAMETERPROB:
    756                         if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){
    757                                 ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet);
    758                         }
    759                         return ERROR_CODE;
    760                 default:
    761                         return ENOTSUP;
    762         }
    763 }
    764 
    765 int icmp_release_and_return(packet_t packet, int result){
    766         pq_release_remote(icmp_globals.net_phone, packet_get_id(packet));
    767         return result;
    768 }
    769 
    770 int icmp_bind_free_id(icmp_echo_ref echo_data){
    771         icmp_param_t index;
    772 
    773         if(! echo_data){
    774                 return EBADMEM;
    775         }
    776         // from the last used one
    777         index = icmp_globals.last_used_id;
    778         do{
    779                 ++ index;
    780                 // til the range end
    781                 if(index >= ICMP_FREE_IDS_END){
    782                         // start from the range beginning
    783                         index = ICMP_FREE_IDS_START - 1;
    784                         do{
    785                                 ++ index;
    786                                 // til the last used one
    787                                 if(index >= icmp_globals.last_used_id){
    788                                         // none found
    789                                         return ENOTCONN;
    790                                 }
    791                         }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);
    792                         // found, break immediately
    793                         break;
    794                 }
    795         }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);
    796         echo_data->identifier = index;
    797         echo_data->sequence_number = 0;
    798         return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data);
    799 }
     904        int rc;
     905
     906        *answer_count = 0;
     907        switch (IPC_GET_METHOD(*call)) {
     908        case NET_TL_RECEIVED:
     909                rc = packet_translate_remote(icmp_globals.net_phone, &packet,
     910                    IPC_GET_PACKET(call));
     911                if (rc != EOK)
     912                        return rc;
     913                return icmp_received_msg_local(IPC_GET_DEVICE(call), packet,
     914                    SERVICE_ICMP, IPC_GET_ERROR(call));
     915       
     916        case NET_ICMP_INIT:
     917                return icmp_process_client_messages(callid, * call);
     918       
     919        default:
     920                return icmp_process_message(call);
     921        }
     922
     923        return ENOTSUP;
     924}
     925
    800926
    801927/** Default thread for new connections.
    802928 *
    803  *  @param[in] iid The initial message identifier.
    804  *  @param[in] icall The initial message call structure.
    805  *
    806  */
    807 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     929 * @param[in] iid The initial message identifier.
     930 * @param[in] icall The initial message call structure.
     931 *
     932 */
     933static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall)
    808934{
    809935        /*
     
    813939        ipc_answer_0(iid, EOK);
    814940       
    815         while(true) {
     941        while (true) {
    816942                ipc_call_t answer;
    817943                int answer_count;
     
    828954                    &answer_count);
    829955               
    830                 /* End if said to either by the message or the processing result */
    831                 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP))
     956                /*
     957                 * End if told to either by the message or the processing
     958                 * result.
     959                 */
     960                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     961                    (res == EHANGUP))
    832962                        return;
    833963               
     
    839969/** Starts the module.
    840970 *
    841  *  @param argc The count of the command line arguments. Ignored parameter.
    842  *  @param argv The command line parameters. Ignored parameter.
    843  *
    844  *  @returns EOK on success.
    845  *  @returns Other error codes as defined for each specific module start function.
    846  *
     971 * @returns             EOK on success.
     972 * @returns             Other error codes as defined for each specific module
     973 *                      start function.
    847974 */
    848975int main(int argc, char *argv[])
    849976{
    850         ERROR_DECLARE;
     977        int rc;
    851978       
    852979        /* Start the module */
    853         if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
    854                 return ERROR_CODE;
    855        
    856         return EOK;
     980        rc = tl_module_start_standalone(tl_client_connection);
     981        return rc;
    857982}
    858983
    859984/** @}
    860985 */
     986
  • uspace/srv/net/tl/icmp/icmp.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup icmp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  ICMP module.
     34 * ICMP module.
    3535 */
    3636
    37 #ifndef __NET_ICMP_H__
    38 #define __NET_ICMP_H__
     37#ifndef NET_ICMP_H_
     38#define NET_ICMP_H_
    3939
    4040#include <fibril_synch.h>
    4141
    4242#include <net/icmp_codes.h>
     43#include <net/packet.h>
    4344#include <adt/int_map.h>
    4445#include <icmp_header.h>
    4546
    4647/** Type definition of the ICMP reply data.
    47  *  @see icmp_reply
     48 * @see icmp_reply
    4849 */
    49 typedef struct icmp_reply       icmp_reply_t;
     50typedef struct icmp_reply icmp_reply_t;
    5051
    5152/** Type definition of the ICMP reply data pointer.
    52  *  @see icmp_reply
     53 * @see icmp_reply
    5354 */
    54 typedef icmp_reply_t *  icmp_reply_ref;
     55typedef icmp_reply_t *icmp_reply_ref;
    5556
    5657/** Type definition of the ICMP global data.
    57  *  @see icmp_globals
     58 * @see icmp_globals
    5859 */
    59 typedef struct icmp_globals     icmp_globals_t;
     60typedef struct icmp_globals icmp_globals_t;
    6061
    6162/** Pending replies map.
    62  *  Maps message identifiers to the pending replies.
    63  *  Sending fibril waits for its associated reply event.
    64  *  Receiving fibril sets the associated reply with the return value and signals the event.
     63 *
     64 * Maps message identifiers to the pending replies.
     65 * Sending fibril waits for its associated reply event.
     66 * Receiving fibril sets the associated reply with the return value and signals
     67 * the event.
    6568 */
    6669INT_MAP_DECLARE(icmp_replies, icmp_reply_t);
    6770
    6871/** Echo specific data map.
    69  *  The identifier is used in the future semi-remote calls instead of the ICMP phone.
     72 *
     73 * The identifier is used in the future semi-remote calls instead of the ICMP
     74 * phone.
    7075 */
    7176INT_MAP_DECLARE(icmp_echo_data, icmp_echo_t);
    7277
    73 /** ICMP reply data.
    74  */
    75 struct icmp_reply{
    76         /** Reply result.
    77          */
     78/** ICMP reply data. */
     79struct icmp_reply {
     80        /** Reply result. */
    7881        int result;
    79         /** Safety lock.
    80          */
     82        /** Safety lock. */
    8183        fibril_mutex_t mutex;
    82         /** Received or timeouted reply signaling.
    83          */
     84        /** Received or timeouted reply signaling. */
    8485        fibril_condvar_t condvar;
    8586};
    8687
    87 /** ICMP global data.
    88  */
    89 struct  icmp_globals{
    90         /** IP module phone.
    91          */
     88/** ICMP global data. */
     89struct icmp_globals {
     90        /** IP module phone. */
    9291        int ip_phone;
    93         /** Packet dimension.
    94          */
     92        /** Packet dimension. */
    9593        packet_dimension_t packet_dimension;
    96         /** Networking module phone.
    97          */
     94        /** Networking module phone. */
    9895        int net_phone;
    99         /** Indicates whether ICMP error reporting is enabled.
    100          */
     96        /** Indicates whether ICMP error reporting is enabled. */
    10197        int error_reporting;
    102         /** Indicates whether ICMP echo replying (ping) is enabled.
    103          */
     98        /** Indicates whether ICMP echo replying (ping) is enabled. */
    10499        int echo_replying;
    105         /** The last used identifier number.
    106          */
     100        /** The last used identifier number. */
    107101        icmp_param_t last_used_id;
    108         /** The budled modules assigned echo specific data.
    109          */
     102        /** The budled modules assigned echo specific data. */
    110103        icmp_echo_data_t echo_data;
    111         /** Echo timeout locks.
    112          */
     104        /** Echo timeout locks. */
    113105        icmp_replies_t replies;
    114         /** Safety lock.
    115          */
     106        /** Safety lock. */
    116107        fibril_rwlock_t lock;
    117108};
     
    121112/** @}
    122113 */
    123 
  • uspace/srv/net/tl/icmp/icmp_module.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup icmp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  ICMP standalone module implementation.
    35  *  Contains skeleton module functions mapping.
    36  *  The functions are used by the module skeleton as module specific entry points.
    37  *  @see module.c
     34 * ICMP standalone module implementation.
     35 * Contains skeleton module functions mapping.
     36 * The functions are used by the module skeleton as module specific entry points.
     37 * @see module.c
    3838 */
     39
     40#include "icmp.h"
     41#include "icmp_module.h"
    3942
    4043#include <async.h>
    4144#include <stdio.h>
    42 #include <err.h>
     45#include <errno.h>
    4346#include <ipc/ipc.h>
    4447#include <ipc/services.h>
     
    4750#include <net/packet.h>
    4851#include <net_interface.h>
     52
    4953#include <tl_local.h>
    5054
    51 #include "icmp.h"
    52 #include "icmp_module.h"
     55/** ICMP module global data. */
     56extern icmp_globals_t icmp_globals;
    5357
    54 /** ICMP module global data.
    55  */
    56 extern icmp_globals_t   icmp_globals;
    57 
    58 /** Starts the ICMP module.
    59  *  Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.
    60  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    61  *  @returns EOK on successful module termination.
    62  *  @returns Other error codes as defined for the arp_initialize() function.
    63  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
    64  */
    65 int tl_module_start_standalone(async_client_conn_t client_connection){
    66         ERROR_DECLARE;
    67 
     58int tl_module_start_standalone(async_client_conn_t client_connection)
     59{
    6860        ipcarg_t phonehash;
     61        int rc;
    6962
    7063        async_set_client_connection(client_connection);
    7164        icmp_globals.net_phone = net_connect_module();
    72         if(icmp_globals.net_phone < 0){
     65        if (icmp_globals.net_phone < 0)
    7366                return icmp_globals.net_phone;
    74         }
    75         ERROR_PROPAGATE(pm_init());
    76         if(ERROR_OCCURRED(icmp_initialize(client_connection))
    77                 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ICMP, &phonehash))){
    78                 pm_destroy();
    79                 return ERROR_CODE;
    80         }
     67
     68        rc = pm_init();
     69        if (rc != EOK)
     70                return rc;
     71       
     72        rc = icmp_initialize(client_connection);
     73        if (rc != EOK)
     74                goto out;
     75
     76        rc = REGISTER_ME(SERVICE_ICMP, &phonehash);
     77        if (rc != EOK)
     78                goto out;
    8179
    8280        async_manager();
    8381
     82out:
    8483        pm_destroy();
    85         return EOK;
     84        return rc;
    8685}
    8786
    88 /** Processes the ICMP message.
    89  *  @param[in] callid The message identifier.
    90  *  @param[in] call The message parameters.
    91  *  @param[out] answer The message answer parameters.
    92  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    93  *  @returns EOK on success.
    94  *  @returns Other error codes as defined for the icmp_message() function.
    95  */
    96 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     87int
     88tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     89    ipc_call_t *answer, int *answer_count)
     90{
    9791        return icmp_message_standalone(callid, call, answer, answer_count);
    9892}
  • uspace/srv/net/tl/icmp/icmp_module.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup icmp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  ICMP module functions.
    35  *  The functions are used as ICMP module entry points.
     34 * ICMP module functions.
     35 * The functions are used as ICMP module entry points.
    3636 */
    3737
    38 #ifndef __NET_ICMP_MODULE_H__
    39 #define __NET_ICMP_MODULE_H__
     38#ifndef NET_ICMP_MODULE_H_
     39#define NET_ICMP_MODULE_H_
    4040
    4141#include <async.h>
    4242#include <ipc/ipc.h>
    4343
    44 /** Initializes the ICMP module.
    45  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    46  *  @returns EOK on success.
    47  *  @returns ENOMEM if there is not enough memory left.
    48  */
    49 int icmp_initialize(async_client_conn_t client_connection);
    50 
    51 /** Processes the ICMP message.
    52  *  @param[in] callid The message identifier.
    53  *  @param[in] call The message parameters.
    54  *  @param[out] answer The message answer parameters.
    55  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    56  *  @returns EOK on success.
    57  *  @returns ENOTSUP if the message is not known.
    58  *  @see icmp_interface.h
    59  *  @see IS_NET_ICMP_MESSAGE()
    60  */
    61 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
     44extern int icmp_initialize(async_client_conn_t);
     45extern int icmp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
     46    int *);
    6247
    6348#endif
  • uspace/srv/net/tl/tcp/tcp.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP module implementation.
    35  *  @see tcp.h
     34 * TCP module implementation.
     35 * @see tcp.h
    3636 */
     37
     38#include "tcp.h"
     39#include "tcp_header.h"
     40#include "tcp_module.h"
    3741
    3842#include <assert.h>
     
    4347#include <stdio.h>
    4448#include <errno.h>
    45 #include <err.h>
    4649
    4750#include <ipc/ipc.h>
     
    7275#include <tl_interface.h>
    7376
    74 #include "tcp.h"
    75 #include "tcp_header.h"
    76 #include "tcp_module.h"
    77 
    7877/** TCP module name. */
    7978#define NAME    "TCP protocol"
     
    110109
    111110/** Returns a value indicating whether the value is in the interval respecting
    112  *  the possible overflow.
     111 * the possible overflow.
    113112 *
    114  *  The high end and/or the value may overflow, be lower than the low value.
    115  *  @param[in] lower The last value before the interval.
    116  *  @param[in] value The value to be checked.
    117  *  @param[in] higher_equal The last value in the interval.
     113 * The high end and/or the value may overflow, be lower than the low value.
     114 *
     115 * @param[in] lower     The last value before the interval.
     116 * @param[in] value     The value to be checked.
     117 * @param[in] higher_equal The last value in the interval.
    118118 */
    119119#define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \
     
    165165};
    166166
    167 /** Releases the packet and returns the result.
    168  *  @param[in] packet The packet queue to be released.
    169  *  @param[in] result The result to be returned.
    170  *  @return The result parameter.
    171  */
    172 int tcp_release_and_return(packet_t packet, int result);
    173 
    174 void tcp_prepare_operation_header(socket_core_ref socket,
    175     tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize,
    176     int finalize);
    177 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t),
    178     socket_core_ref socket, tcp_socket_data_ref socket_data,
    179     size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout,
    180     int globals_read_only);
    181 void tcp_free_socket_data(socket_core_ref socket);
    182 
    183 int tcp_timeout(void *data);
    184 
    185 int tcp_release_after_timeout(void *data);
    186 
    187 int tcp_process_packet(device_id_t device_id, packet_t packet,
    188     services_t error);
    189 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets,
    190     struct sockaddr *addr, socklen_t addrlen);
    191 int tcp_queue_prepare_packet(socket_core_ref socket,
    192     tcp_socket_data_ref socket_data, packet_t packet, size_t data_length);
    193 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data,
    194     packet_t packet, size_t data_length);
    195 packet_t tcp_get_packets_to_send(socket_core_ref socket,
    196     tcp_socket_data_ref socket_data);
    197 void tcp_send_packets(device_id_t device_id, packet_t packet);
    198 
    199 void tcp_process_acknowledgement(socket_core_ref socket,
    200     tcp_socket_data_ref socket_data, tcp_header_ref header);
    201 packet_t tcp_send_prepare_packet(socket_core_ref socket,
    202     tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
    203     size_t sequence_number);
    204 packet_t tcp_prepare_copy(socket_core_ref socket,
    205     tcp_socket_data_ref socket_data, packet_t packet, size_t data_length,
    206     size_t sequence_number);
    207 void tcp_retransmit_packet(socket_core_ref socket,
    208     tcp_socket_data_ref socket_data, size_t sequence_number);
    209 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
    210     tcp_socket_data_ref socket_data, int synchronize, int finalize);
    211 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data);
    212 
    213 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data);
    214 
    215 int tcp_process_listen(socket_core_ref listening_socket,
    216     tcp_socket_data_ref listening_socket_data, tcp_header_ref header,
    217     packet_t packet, struct sockaddr *src, struct sockaddr *dest,
    218     size_t addrlen);
    219 int tcp_process_syn_sent(socket_core_ref socket,
    220     tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
    221 int tcp_process_syn_received(socket_core_ref socket,
    222     tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet);
    223 int tcp_process_established(socket_core_ref socket,
    224     tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet,
    225     int fragments, size_t total_length);
    226 int tcp_queue_received_packet(socket_core_ref socket,
    227     tcp_socket_data_ref socket_data, packet_t packet, int fragments,
    228     size_t total_length);
    229 
    230 int tcp_received_msg(device_id_t device_id, packet_t packet,
    231     services_t receiver, services_t error);
    232 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
    233 
    234 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id,
    235     int backlog);
    236 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id,
    237     struct sockaddr *addr, socklen_t addrlen);
    238 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id,
    239     int flags, size_t * addrlen);
    240 int tcp_send_message(socket_cores_ref local_sockets, int socket_id,
    241     int fragments, size_t * data_fragment_size, int flags);
    242 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
    243     int new_socket_id, size_t * data_fragment_size, size_t * addrlen);
    244 int tcp_close_message(socket_cores_ref local_sockets, int socket_id);
     167static int tcp_release_and_return(packet_t, int);
     168static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref,
     169    tcp_header_ref, int synchronize, int);
     170static int tcp_prepare_timeout(int (*)(void *), socket_core_ref,
     171    tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int);
     172static void tcp_free_socket_data(socket_core_ref);
     173
     174static int tcp_timeout(void *);
     175
     176static int tcp_release_after_timeout(void *);
     177
     178static int tcp_process_packet(device_id_t, packet_t, services_t);
     179static int tcp_connect_core(socket_core_ref, socket_cores_ref,
     180    struct sockaddr *, socklen_t);
     181static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref,
     182    packet_t, size_t);
     183static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t,
     184    size_t);
     185static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref);
     186static void tcp_send_packets(device_id_t, packet_t);
     187
     188static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref,
     189    tcp_header_ref);
     190static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref,
     191    packet_t, size_t, size_t);
     192static packet_t tcp_prepare_copy(socket_core_ref, tcp_socket_data_ref, packet_t,
     193    size_t, size_t);
     194/* static */ void tcp_retransmit_packet(socket_core_ref, tcp_socket_data_ref,
     195    size_t);
     196static int tcp_create_notification_packet(packet_t *, socket_core_ref,
     197    tcp_socket_data_ref, int, int);
     198static void tcp_refresh_socket_data(tcp_socket_data_ref);
     199
     200static void tcp_initialize_socket_data(tcp_socket_data_ref);
     201
     202static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref,
     203    tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t);
     204static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref,
     205    tcp_header_ref, packet_t);
     206static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref,
     207    tcp_header_ref, packet_t);
     208static int tcp_process_established(socket_core_ref, tcp_socket_data_ref,
     209    tcp_header_ref, packet_t, int, size_t);
     210static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref,
     211    packet_t, int, size_t);
     212
     213static int tcp_received_msg(device_id_t, packet_t, services_t, services_t);
     214static int tcp_process_client_messages(ipc_callid_t, ipc_call_t);
     215
     216static int tcp_listen_message(socket_cores_ref, int, int);
     217static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *,
     218    socklen_t);
     219static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *);
     220static int tcp_send_message(socket_cores_ref, int, int, size_t *, int);
     221static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *);
     222static int tcp_close_message(socket_cores_ref, int);
    245223
    246224/** TCP global data. */
    247225tcp_globals_t tcp_globals;
    248226
     227/** Initializes the TCP module.
     228 *
     229 * @param[in] client_connection The client connection processing function. The
     230 *                      module skeleton propagates its own one.
     231 * @returns             EOK on success.
     232 * @returns             ENOMEM if there is not enough memory left.
     233 */
    249234int tcp_initialize(async_client_conn_t client_connection)
    250235{
    251         ERROR_DECLARE;
     236        int rc;
    252237
    253238        assert(client_connection);
     
    260245        tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP,
    261246            SERVICE_TCP, client_connection);
    262         if (tcp_globals.ip_phone < 0)
     247        if (tcp_globals.ip_phone < 0) {
     248                fibril_rwlock_write_unlock(&tcp_globals.lock);
    263249                return tcp_globals.ip_phone;
     250        }
    264251       
    265         ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets));
    266         if (ERROR_OCCURRED(packet_dimensions_initialize(
    267             &tcp_globals.dimensions))) {
     252        rc = socket_ports_initialize(&tcp_globals.sockets);
     253        if (rc != EOK)
     254                goto out;
     255
     256        rc = packet_dimensions_initialize(&tcp_globals.dimensions);
     257        if (rc != EOK) {
    268258                socket_ports_destroy(&tcp_globals.sockets);
    269                 return ERROR_CODE;
     259                goto out;
    270260        }
    271261
    272262        tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1;
     263
     264out:
    273265        fibril_rwlock_write_unlock(&tcp_globals.lock);
    274 
    275         return EOK;
     266        return rc;
    276267}
    277268
     
    280271    services_t error)
    281272{
    282         ERROR_DECLARE;
     273        int rc;
    283274
    284275        if (receiver != SERVICE_TCP)
     
    286277
    287278        fibril_rwlock_write_lock(&tcp_globals.lock);
    288         if (ERROR_OCCURRED(tcp_process_packet(device_id, packet, error)))
     279        rc = tcp_process_packet(device_id, packet, error);
     280        if (rc != EOK)
    289281                fibril_rwlock_write_unlock(&tcp_globals.lock);
    290282
    291         printf("receive %d \n", ERROR_CODE);
    292 
    293         return ERROR_CODE;
     283        printf("receive %d \n", rc);
     284
     285        return rc;
    294286}
    295287
    296288int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    297289{
    298         ERROR_DECLARE;
    299 
    300290        size_t length;
    301291        size_t offset;
     
    313303        struct sockaddr *dest;
    314304        size_t addrlen;
    315 
    316         if (error) {
    317                 switch (error) {
    318                 case SERVICE_ICMP:
    319                         // process error
    320                         result = icmp_client_process_packet(packet, &type,
    321                             &code, NULL, NULL);
    322                         if (result < 0)
    323                                 return tcp_release_and_return(packet, result);
    324 
    325                         length = (size_t) result;
    326                         if (ERROR_OCCURRED(packet_trim(packet, length, 0))) {
    327                                 return tcp_release_and_return(packet,
    328                                     ERROR_CODE);
    329                         }
    330                         break;
    331 
    332                 default:
    333                         return tcp_release_and_return(packet, ENOTSUP);
    334                 }
     305        int rc;
     306
     307        switch (error) {
     308        case SERVICE_NONE:
     309                break;
     310        case SERVICE_ICMP:
     311                // process error
     312                result = icmp_client_process_packet(packet, &type, &code, NULL,
     313                    NULL);
     314                if (result < 0)
     315                        return tcp_release_and_return(packet, result);
     316
     317                length = (size_t) result;
     318                rc = packet_trim(packet, length, 0);
     319                if (rc != EOK)
     320                        return tcp_release_and_return(packet, rc);
     321                break;
     322        default:
     323                return tcp_release_and_return(packet, ENOTSUP);
    335324        }
    336325
     
    350339
    351340        // trim all but TCP header
    352         if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
    353                 return tcp_release_and_return(packet, ERROR_CODE);
     341        rc = packet_trim(packet, offset, 0);
     342        if (rc != EOK)
     343                return tcp_release_and_return(packet, rc);
    354344
    355345        // get tcp header
     
    367357        addrlen = (size_t) result;
    368358
    369         if (ERROR_OCCURRED(tl_set_address_port(src, addrlen,
    370             ntohs(header->source_port))))
    371                 return tcp_release_and_return(packet, ERROR_CODE);
     359        rc = tl_set_address_port(src, addrlen, ntohs(header->source_port));
     360        if (rc != EOK)
     361                return tcp_release_and_return(packet, rc);
    372362       
    373363        // find the destination socket
     
    379369                    ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING,
    380370                    0);
    381                 if (!socket) {
    382                         if (tl_prepare_icmp_packet(tcp_globals.net_phone,
    383                             tcp_globals.icmp_phone, packet, error) == EOK) {
    384                                 icmp_destination_unreachable_msg(
    385                                     tcp_globals.icmp_phone, ICMP_PORT_UNREACH,
    386                                     0, packet);
    387                         }
    388                         return EADDRNOTAVAIL;
    389                 }
    390         }
     371        }
     372        if (!socket) {
     373                if (tl_prepare_icmp_packet(tcp_globals.net_phone,
     374                    tcp_globals.icmp_phone, packet, error) == EOK) {
     375                        icmp_destination_unreachable_msg(tcp_globals.icmp_phone,
     376                            ICMP_PORT_UNREACH, 0, packet);
     377                }
     378                return EADDRNOTAVAIL;
     379        }
     380
    391381        printf("socket id %d\n", socket->socket_id);
    392382        socket_data = (tcp_socket_data_ref) socket->specific_data;
     
    402392        total_length = 0;
    403393        do {
    404                 ++fragments;
     394                fragments++;
    405395                length = packet_get_data_length(next_packet);
    406396                if (length <= 0)
     
    421411
    422412        if (error)
    423                 goto error;
     413                goto has_error_service;
    424414       
    425415        if (socket_data->state == TCP_SOCKET_LISTEN) {
    426 
    427416                if (socket_data->pseudo_header) {
    428417                        free(socket_data->pseudo_header);
     
    431420                }
    432421
    433                 if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src,
    434                     addrlen, dest, addrlen, total_length,
    435                     &socket_data->pseudo_header, &socket_data->headerlen))) {
     422                rc = ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen,
     423                    dest, addrlen, total_length, &socket_data->pseudo_header,
     424                    &socket_data->headerlen);
     425                if (rc != EOK) {
    436426                        fibril_rwlock_write_unlock(socket_data->local_lock);
    437                         return tcp_release_and_return(packet, ERROR_CODE);
    438                 }
    439 
    440         } else if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
    441             socket_data->pseudo_header, socket_data->headerlen,
    442             total_length))) {
    443                 fibril_rwlock_write_unlock(socket_data->local_lock);
    444                 return tcp_release_and_return(packet, ERROR_CODE);
     427                        return tcp_release_and_return(packet, rc);
     428                }
     429        } else {
     430                rc = ip_client_set_pseudo_header_data_length(
     431                    socket_data->pseudo_header, socket_data->headerlen,
     432                    total_length);
     433                if (rc != EOK) {
     434                        fibril_rwlock_write_unlock(socket_data->local_lock);
     435                        return tcp_release_and_return(packet, rc);
     436                }
    445437        }
    446438       
     
    452444                fibril_rwlock_write_unlock(socket_data->local_lock);
    453445
    454                 if (ERROR_NONE(tl_prepare_icmp_packet(tcp_globals.net_phone,
    455                     tcp_globals.icmp_phone, packet, error))) {
     446                rc = tl_prepare_icmp_packet(tcp_globals.net_phone,
     447                    tcp_globals.icmp_phone, packet, error);
     448                if (rc == EOK) {
    456449                        // checksum error ICMP
    457450                        icmp_parameter_problem_msg(tcp_globals.icmp_phone,
     
    464457        }
    465458
    466 error:
     459has_error_service:
    467460        fibril_rwlock_read_unlock(&tcp_globals.lock);
    468461
     
    470463        switch (socket_data->state) {
    471464        case TCP_SOCKET_LISTEN:
    472                 ERROR_CODE = tcp_process_listen(socket, socket_data, header,
    473                     packet, src, dest, addrlen);
     465                rc = tcp_process_listen(socket, socket_data, header, packet,
     466                    src, dest, addrlen);
    474467                break;
    475468        case TCP_SOCKET_SYN_RECEIVED:
    476                 ERROR_CODE = tcp_process_syn_received(socket, socket_data,
    477                     header, packet);
     469                rc = tcp_process_syn_received(socket, socket_data, header,
     470                    packet);
    478471                break;
    479472        case TCP_SOCKET_SYN_SENT:
    480                 ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header,
    481                     packet);
     473                rc = tcp_process_syn_sent(socket, socket_data, header, packet);
    482474                break;
    483475        case TCP_SOCKET_FIN_WAIT_1:
     
    490482                // ack releasing the socket gets processed later
    491483        case TCP_SOCKET_ESTABLISHED:
    492                 ERROR_CODE = tcp_process_established(socket, socket_data,
    493                     header, packet, fragments, total_length);
     484                rc = tcp_process_established(socket, socket_data, header,
     485                    packet, fragments, total_length);
    494486                break;
    495487        default:
     
    497489        }
    498490
    499         if (ERROR_CODE != EOK) {
    500                 printf("process %d\n", ERROR_CODE);
     491        if (rc != EOK) {
    501492                fibril_rwlock_write_unlock(socket_data->local_lock);
     493                printf("process %d\n", rc);
    502494        }
    503495
     
    507499int
    508500tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data,
    509     tcp_header_ref header, packet_t packet, int fragments,
    510     size_t total_length)
    511 {
    512         ERROR_DECLARE;
    513 
     501    tcp_header_ref header, packet_t packet, int fragments, size_t total_length)
     502{
    514503        packet_t next_packet;
    515504        packet_t tmp_packet;
     
    520509        size_t offset;
    521510        uint32_t new_sequence_number;
     511        int rc;
    522512
    523513        assert(socket);
     
    560550                }
    561551
    562                 if ((offset > 0) && (ERROR_OCCURRED(packet_trim(packet,
    563                     offset, 0))))
    564                         return tcp_release_and_return(packet, ERROR_CODE);
     552                if (offset > 0) {
     553                        rc = packet_trim(packet, offset, 0);
     554                        if (rc != EOK)
     555                                return tcp_release_and_return(packet, rc);
     556                }
    565557
    566558                assert(new_sequence_number == socket_data->next_incoming);
     
    594586                        if (length <= offset)
    595587                                next_packet = pq_next(next_packet);
    596                         else if (ERROR_OCCURRED(packet_trim(next_packet, 0,
    597                             length - offset)))
    598                                 return tcp_release_and_return(packet,
    599                                     ERROR_CODE);
     588                        else {
     589                                rc = packet_trim(next_packet, 0,
     590                                    length - offset));
     591                                if (rc != EOK)
     592                                        return tcp_release_and_return(packet,
     593                                            rc);
     594                        }
    600595                        offset -= length;
    601596                        total_length -= length - offset;
     
    622617                // remove the header
    623618                total_length -= TCP_HEADER_LENGTH(header);
    624                 if (ERROR_OCCURRED(packet_trim(packet,
    625                     TCP_HEADER_LENGTH(header), 0)))
    626                         return tcp_release_and_return(packet, ERROR_CODE);
     619                rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
     620                if (rc != EOK)
     621                        return tcp_release_and_return(packet, rc);
    627622
    628623                if (total_length) {
    629                         ERROR_PROPAGATE(tcp_queue_received_packet(socket,
    630                             socket_data, packet, fragments, total_length));
     624                        rc = tcp_queue_received_packet(socket, socket_data,
     625                            packet, fragments, total_length);
     626                        if (rc != EOK)
     627                                return rc;
    631628                } else {
    632629                        total_length = 1;
     
    636633                packet = socket_data->incoming;
    637634                while (packet) {
    638 
    639                         if (ERROR_OCCURRED(pq_get_order(socket_data->incoming,
    640                             &order, NULL))) {
     635                        rc = pq_get_order(socket_data->incoming, &order, NULL);
     636                        if (rc != EOK) {
    641637                                // remove the corrupted packet
    642638                                next_packet = pq_detach(packet);
     
    675671                                    socket_data->next_incoming) {
    676672                                        // queue received data
    677                                         ERROR_PROPAGATE(
    678                                             tcp_queue_received_packet(socket,
     673                                        rc = tcp_queue_received_packet(socket,
    679674                                            socket_data, packet, 1,
    680                                             packet_get_data_length(packet)));
     675                                            packet_get_data_length(packet));
     676                                        if (rc != EOK)
     677                                                return rc;
    681678                                        socket_data->next_incoming =
    682679                                            new_sequence_number;
     
    684681                                        continue;
    685682                                        // at least partly following data?
    686                                 } else if (IS_IN_INTERVAL_OVERFLOW(
    687                                     sequence_number, socket_data->next_incoming,
    688                                     new_sequence_number)) {
     683                                }
     684                                if (IS_IN_INTERVAL_OVERFLOW(sequence_number,
     685                                    socket_data->next_incoming, new_sequence_number)) {
    689686                                        if (socket_data->next_incoming <
    690687                                            new_sequence_number) {
     
    696693                                                    new_sequence_number;
    697694                                        }
    698                                         if (ERROR_NONE(packet_trim(packet,
    699                                             length, 0))) {
     695                                        rc = packet_trim(packet,length, 0);
     696                                        if (rc == EOK) {
    700697                                                // queue received data
    701                                                 ERROR_PROPAGATE(
    702                                                     tcp_queue_received_packet(
     698                                                rc = tcp_queue_received_packet(
    703699                                                    socket, socket_data, packet,
    704700                                                    1, packet_get_data_length(
    705                                                     packet)));
     701                                                    packet));
     702                                                if (rc != EOK)
     703                                                        return rc;
    706704                                                socket_data->next_incoming =
    707705                                                    new_sequence_number;
     
    728726                // remove the header
    729727                total_length -= TCP_HEADER_LENGTH(header);
    730                 if (ERROR_OCCURRED(packet_trim(packet,
    731                     TCP_HEADER_LENGTH(header), 0)))
    732                         return tcp_release_and_return(packet, ERROR_CODE);
     728                rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0);
     729                if (rc != EOK)
     730                        return tcp_release_and_return(packet, rc);
    733731
    734732                next_packet = pq_detach(packet);
    735733                length = packet_get_data_length(packet);
    736                 if (ERROR_OCCURRED(pq_add(&socket_data->incoming, packet,
    737                     new_sequence_number, length))) {
     734                rc = pq_add(&socket_data->incoming, packet, new_sequence_number,
     735                    length);
     736                if (rc != EOK) {
    738737                        // remove the corrupted packets
    739738                        pq_release_remote(tcp_globals.net_phone,
     
    746745                                tmp_packet = pq_detach(next_packet);
    747746                                length = packet_get_data_length(next_packet);
    748                                 if (ERROR_OCCURRED(pq_set_order(next_packet,
    749                                     new_sequence_number, length)) ||
    750                                     ERROR_OCCURRED(pq_insert_after(packet,
    751                                     next_packet))) {
     747
     748                                rc = pq_set_order(next_packet,
     749                                    new_sequence_number, length);
     750                                if (rc != EOK) {
     751                                        pq_release_remote(tcp_globals.net_phone,
     752                                            packet_get_id(next_packet));
     753                                }
     754                                rc = pq_insert_after(packet, next_packet);
     755                                if (rc != EOK) {
    752756                                        pq_release_remote(tcp_globals.net_phone,
    753757                                            packet_get_id(next_packet));
     
    781785        if (!packet) {
    782786                // create the notification packet
    783                 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
    784                     socket_data, 0, 0));
    785                 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data,
    786                     packet, 1));
     787                rc = tcp_create_notification_packet(&packet, socket,
     788                    socket_data, 0, 0);
     789                if (rc != EOK)
     790                        return rc;
     791                rc = tcp_queue_prepare_packet(socket, socket_data, packet, 1);
     792                if (rc != EOK)
     793                        return rc;
    787794                packet = tcp_send_prepare_packet(socket, socket_data, packet, 1,
    788795                    socket_data->last_outgoing + 1);
     
    802809    size_t total_length)
    803810{
    804         ERROR_DECLARE;
    805 
    806811        packet_dimension_ref packet_dimension;
     812        int rc;
    807813
    808814        assert(socket);
     
    814820
    815821        // queue the received packet
    816         if (ERROR_OCCURRED(dyn_fifo_push(&socket->received,
    817             packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) ||
    818             ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
    819             &tcp_globals.dimensions, socket_data->device_id,
    820             &packet_dimension))) {
    821                 return tcp_release_and_return(packet, ERROR_CODE);
    822         }
     822        rc = dyn_fifo_push(&socket->received, packet_get_id(packet),
     823            SOCKET_MAX_RECEIVED_SIZE);
     824        if (rc != EOK)
     825                return tcp_release_and_return(packet, rc);
     826        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
     827            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
     828        if (rc != EOK)
     829                return tcp_release_and_return(packet, rc);
    823830
    824831        // decrease the window size
     
    839846    tcp_header_ref header, packet_t packet)
    840847{
    841         ERROR_DECLARE;
    842 
    843848        packet_t next_packet;
     849        int rc;
    844850
    845851        assert(socket);
     
    863869        }
    864870        // trim if longer than the header
    865         if ((packet_get_data_length(packet) > sizeof(*header)) &&
    866             ERROR_OCCURRED(packet_trim(packet, 0,
    867             packet_get_data_length(packet) - sizeof(*header)))) {
    868                 return tcp_release_and_return(packet, ERROR_CODE);
     871        if (packet_get_data_length(packet) > sizeof(*header)) {
     872                rc = packet_trim(packet, 0,
     873                    packet_get_data_length(packet) - sizeof(*header));
     874                if (rc != EOK)
     875                        return tcp_release_and_return(packet, rc);
    869876        }
    870877        tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
     
    895902    size_t addrlen)
    896903{
    897         ERROR_DECLARE;
    898 
    899904        packet_t next_packet;
    900905        socket_core_ref socket;
     
    903908        int listening_socket_id = listening_socket->socket_id;
    904909        int listening_port = listening_socket->port;
     910        int rc;
    905911
    906912        assert(listening_socket);
     
    932938        memcpy(socket_data->addr, src, socket_data->addrlen);
    933939        socket_data->dest_port = ntohs(header->source_port);
    934         if (ERROR_OCCURRED(tl_set_address_port(socket_data->addr,
    935             socket_data->addrlen, socket_data->dest_port))) {
     940        rc = tl_set_address_port(socket_data->addr, socket_data->addrlen,
     941            socket_data->dest_port);
     942        if (rc != EOK) {
    936943                free(socket_data->addr);
    937944                free(socket_data);
    938                 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    939                 return ERROR_CODE;
     945                return tcp_release_and_return(packet, rc);
    940946        }
    941947
    942948        // create a socket
    943949        socket_id = -1;
    944         if (ERROR_OCCURRED(socket_create(socket_data->local_sockets,
    945             listening_socket->phone, socket_data, &socket_id))) {
     950        rc = socket_create(socket_data->local_sockets, listening_socket->phone,
     951            socket_data, &socket_id);
     952        if (rc != EOK) {
    946953                free(socket_data->addr);
    947954                free(socket_data);
    948                 return tcp_release_and_return(packet, ERROR_CODE);
     955                return tcp_release_and_return(packet, rc);
    949956        }
    950957
     
    961968        listening_socket = socket_port_find(&tcp_globals.sockets,
    962969            listening_port, SOCKET_MAP_KEY_LISTENING, 0);
    963         if ((!listening_socket) ||
     970        if (!listening_socket ||
    964971            (listening_socket->socket_id != listening_socket_id)) {
    965972                fibril_rwlock_write_unlock(&tcp_globals.lock);
     
    983990        assert(socket_data);
    984991
    985         ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port,
    986             socket, (const char *) socket_data->addr, socket_data->addrlen);
     992        rc = socket_port_add(&tcp_globals.sockets, listening_port, socket,
     993            (const char *) socket_data->addr, socket_data->addrlen);
    987994        assert(socket == socket_port_find(&tcp_globals.sockets, listening_port,
    988995            (const char *) socket_data->addr, socket_data->addrlen));
    989996
    990 //      ERROR_CODE = socket_bind_free_port(&tcp_globals.sockets, socket,
     997//      rc = socket_bind_free_port(&tcp_globals.sockets, socket,
    991998//          TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    992999//          tcp_globals.last_used_port);
    9931000//      tcp_globals.last_used_port = socket->port;
    9941001        fibril_rwlock_write_unlock(&tcp_globals.lock);
    995         if (ERROR_CODE != EOK) {
     1002        if (rc != EOK) {
    9961003                socket_destroy(tcp_globals.net_phone, socket->socket_id,
    9971004                    socket_data->local_sockets, &tcp_globals.sockets,
    9981005                    tcp_free_socket_data);
    999                 return tcp_release_and_return(packet, ERROR_CODE);
     1006                return tcp_release_and_return(packet, rc);
    10001007        }
    10011008
     
    10111018
    10121019        // trim if longer than the header
    1013         if ((packet_get_data_length(packet) > sizeof(*header)) &&
    1014             ERROR_OCCURRED(packet_trim(packet, 0,
    1015             packet_get_data_length(packet) - sizeof(*header)))) {
     1020        if (packet_get_data_length(packet) > sizeof(*header)) {
     1021                rc = packet_trim(packet, 0,
     1022                    packet_get_data_length(packet) - sizeof(*header));
     1023                if (rc != EOK) {
     1024                        socket_destroy(tcp_globals.net_phone, socket->socket_id,
     1025                            socket_data->local_sockets, &tcp_globals.sockets,
     1026                            tcp_free_socket_data);
     1027                        return tcp_release_and_return(packet, rc);
     1028                }
     1029        }
     1030
     1031        tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
     1032
     1033        rc = tcp_queue_packet(socket, socket_data, packet, 1);
     1034        if (rc != EOK) {
    10161035                socket_destroy(tcp_globals.net_phone, socket->socket_id,
    10171036                    socket_data->local_sockets, &tcp_globals.sockets,
    10181037                    tcp_free_socket_data);
    1019                 return tcp_release_and_return(packet, ERROR_CODE);
    1020         }
    1021 
    1022         tcp_prepare_operation_header(socket, socket_data, header, 1, 0);
    1023 
    1024         if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))) {
    1025                 socket_destroy(tcp_globals.net_phone, socket->socket_id,
    1026                     socket_data->local_sockets, &tcp_globals.sockets,
    1027                     tcp_free_socket_data);
    1028                 return ERROR_CODE;
     1038                return rc;
    10291039        }
    10301040
     
    10501060    tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet)
    10511061{
    1052         ERROR_DECLARE;
    1053 
    10541062        socket_core_ref listening_socket;
    10551063        tcp_socket_data_ref listening_socket_data;
     1064        int rc;
    10561065
    10571066        assert(socket);
     
    10781087
    10791088                // queue the received packet
    1080                 if (ERROR_NONE(dyn_fifo_push(&listening_socket->accepted,
    1081                     (-1 * socket->socket_id),
    1082                     listening_socket_data->backlog))) {
    1083 
     1089                rc = dyn_fifo_push(&listening_socket->accepted,
     1090                    (-1 * socket->socket_id), listening_socket_data->backlog);
     1091                if (rc == EOK) {
    10841092                        // notify the destination socket
    10851093                        async_msg_5(socket->phone, NET_SOCKET_ACCEPTED,
     
    10961104
    10971105        // create the notification packet
    1098         ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
    1099             socket_data, 0, 1));
     1106        rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1);
     1107        if (rc != EOK)
     1108                return rc;
    11001109
    11011110        // send the packet
    1102         ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
     1111        rc = tcp_queue_packet(socket, socket_data, packet, 1);
     1112        if (rc != EOK)
     1113                return rc;
    11031114
    11041115        // flush packets
     
    11911202        if (number == socket_data->expected) {
    11921203                // increase the counter
    1193                 ++socket_data->expected_count;
     1204                socket_data->expected_count++;
    11941205                if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) {
    11951206                        socket_data->expected_count = 1;
     
    12001211}
    12011212
    1202 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
    1203     ipc_call_t * answer, int *answer_count)
    1204 {
    1205         ERROR_DECLARE;
    1206 
     1213/** Processes the TCP message.
     1214 *
     1215 * @param[in] callid    The message identifier.
     1216 * @param[in] call      The message parameters.
     1217 * @param[out] answer   The message answer parameters.
     1218 * @param[out] answer_count The last parameter for the actual answer in the
     1219 *                      answer parameter.
     1220 * @returns             EOK on success.
     1221 * @returns             ENOTSUP if the message is not known.
     1222 *
     1223 * @see tcp_interface.h
     1224 * @see IS_NET_TCP_MESSAGE()
     1225 */
     1226int
     1227tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     1228    ipc_call_t *answer, int *answer_count)
     1229{
    12071230        packet_t packet;
     1231        int rc;
    12081232
    12091233        assert(call);
     
    12141238        switch (IPC_GET_METHOD(*call)) {
    12151239        case NET_TL_RECEIVED:
    1216                 //fibril_rwlock_read_lock(&tcp_globals.lock);
    1217                 if (ERROR_NONE(packet_translate_remote(tcp_globals.net_phone,
    1218                     &packet, IPC_GET_PACKET(call)))) {
    1219                         ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call),
    1220                             packet, SERVICE_TCP, IPC_GET_ERROR(call));
    1221                 }
    1222                 //fibril_rwlock_read_unlock(&tcp_globals.lock);
    1223                 return ERROR_CODE;
    1224 
     1240//              fibril_rwlock_read_lock(&tcp_globals.lock);
     1241                rc = packet_translate_remote(tcp_globals.net_phone, &packet,
     1242                    IPC_GET_PACKET(call));
     1243                if (rc != EOK) {
     1244//                      fibril_rwlock_read_unlock(&tcp_globals.lock);
     1245                        return rc;
     1246                }
     1247                rc = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP,
     1248                    IPC_GET_ERROR(call));
     1249//              fibril_rwlock_read_unlock(&tcp_globals.lock);
     1250                return rc;
    12251251        case IPC_M_CONNECT_TO_ME:
    12261252                return tcp_process_client_messages(callid, *call);
     
    15211547        socket = socket_port_find(&tcp_globals.sockets, timeout->port,
    15221548            timeout->key, timeout->key_length);
    1523         if (!(socket && (socket->socket_id == timeout->socket_id)))
     1549        if (!socket || (socket->socket_id != timeout->socket_id))
    15241550                goto out;
    15251551       
     
    15321558        if (timeout->sequence_number) {
    15331559                // increase the timeout counter;
    1534                 ++socket_data->timeout_count;
     1560                socket_data->timeout_count++;
    15351561                if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) {
    15361562                        // TODO release as connection lost
     
    16671693    struct sockaddr *addr, socklen_t addrlen)
    16681694{
    1669         ERROR_DECLARE;
    1670 
    16711695        socket_core_ref socket;
     1696        int rc;
    16721697
    16731698        assert(local_sockets);
     
    16801705                return ENOTSOCK;
    16811706       
    1682         if (ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr,
    1683             addrlen))) {
     1707        rc = tcp_connect_core(socket, local_sockets, addr, addrlen);
     1708        if (rc != EOK) {
    16841709                tcp_free_socket_data(socket);
    16851710                // unbind if bound
     
    16901715                }
    16911716        }
    1692         return ERROR_CODE;
     1717        return rc;
    16931718}
    16941719
     
    16971722    struct sockaddr *addr, socklen_t addrlen)
    16981723{
    1699         ERROR_DECLARE;
    1700 
    17011724        tcp_socket_data_ref socket_data;
    17021725        packet_t packet;
     1726        int rc;
    17031727
    17041728        assert(socket);
     
    17161740
    17171741        // get the destination port
    1718         ERROR_PROPAGATE(tl_get_address_port(addr, addrlen,
    1719             &socket_data->dest_port));
     1742        rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port);
     1743        if (rc != EOK)
     1744                return rc;
     1745       
    17201746        if (socket->port <= 0) {
    17211747                // try to find a free port
    1722                 ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets,
    1723                     socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
    1724                     tcp_globals.last_used_port));
     1748                rc = socket_bind_free_port(&tcp_globals.sockets, socket,
     1749                    TCP_FREE_PORTS_START, TCP_FREE_PORTS_END,
     1750                    tcp_globals.last_used_port);
     1751                if (rc != EOK)
     1752                        return rc;
    17251753                // set the next port as the search starting port number
    17261754                tcp_globals.last_used_port = socket->port;
    17271755        }
    17281756
    1729         ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
     1757        rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,
    17301758            addr, addrlen, &socket_data->device_id,
    1731             &socket_data->pseudo_header, &socket_data->headerlen));
     1759            &socket_data->pseudo_header, &socket_data->headerlen);
     1760        if (rc != EOK)
     1761                return rc;
    17321762
    17331763        // create the notification packet
    1734         ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
    1735             socket_data, 1, 0));
     1764        rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0);
     1765        if (rc != EOK)
     1766                return rc;
    17361767
    17371768        // unlock the globals and wait for an operation
     
    17411772        socket_data->addrlen = addrlen;
    17421773        // send the packet
    1743         if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) ||
    1744             ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data,
    1745             0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) {
    1746 
     1774
     1775        if (((rc = tcp_queue_packet(socket, socket_data, packet, 1)) != EOK) ||
     1776            ((rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0,
     1777            TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false)) !=
     1778            EOK)) {
    17471779                socket_data->addr = NULL;
    17481780                socket_data->addrlen = 0;
    17491781                fibril_rwlock_write_lock(&tcp_globals.lock);
    1750 
    17511782        } else {
    1752 
    17531783                packet = tcp_get_packets_to_send(socket, socket_data);
    17541784                if (packet) {
     
    17621792                        fibril_condvar_wait(&socket_data->operation.condvar,
    17631793                            &socket_data->operation.mutex);
    1764                         ERROR_CODE = socket_data->operation.result;
    1765                         if (ERROR_CODE != EOK) {
     1794                        rc = socket_data->operation.result;
     1795                        if (rc != EOK) {
    17661796                                socket_data->addr = NULL;
    17671797                                socket_data->addrlen = 0;
     
    17701800                        socket_data->addr = NULL;
    17711801                        socket_data->addrlen = 0;
    1772                         ERROR_CODE = EINTR;
     1802                        rc = EINTR;
    17731803                }
    17741804        }
     
    17771807
    17781808        // return the result
    1779         return ERROR_CODE;
     1809        return rc;
    17801810}
    17811811
     
    17841814    tcp_socket_data_ref socket_data, packet_t packet, size_t data_length)
    17851815{
    1786         ERROR_DECLARE;
    1787 
    17881816        tcp_header_ref header;
     1817        int rc;
    17891818
    17901819        assert(socket);
     
    18011830        header->sequence_number = htonl(socket_data->next_outgoing);
    18021831
    1803         if (ERROR_OCCURRED(packet_set_addr(packet, NULL,
    1804             (uint8_t *) socket_data->addr, socket_data->addrlen)))
     1832        rc = packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr,
     1833            socket_data->addrlen);
     1834        if (rc != EOK)
    18051835                return tcp_release_and_return(packet, EINVAL);
    18061836
     
    18161846    packet_t packet, size_t data_length)
    18171847{
    1818         ERROR_DECLARE;
     1848        int rc;
    18191849
    18201850        assert(socket);
     
    18221852        assert(socket->specific_data == socket_data);
    18231853
    1824         ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet,
    1825             data_length));
    1826 
    1827         if (ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet,
    1828             socket_data->next_outgoing, data_length)))
    1829                 return tcp_release_and_return(packet, ERROR_CODE);
     1854        rc = tcp_queue_prepare_packet(socket, socket_data, packet, data_length);
     1855        if (rc != EOK)
     1856                return rc;
     1857
     1858        rc = pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing,
     1859            data_length);
     1860        if (rc != EOK)
     1861                return tcp_release_and_return(packet, rc);
    18301862
    18311863        socket_data->next_outgoing += data_length;
     
    18361868tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data)
    18371869{
    1838         ERROR_DECLARE;
    1839 
    18401870        packet_t packet;
    18411871        packet_t copy;
     
    18431873        packet_t previous = NULL;
    18441874        size_t data_length;
     1875        int rc;
    18451876
    18461877        assert(socket);
     
    18671898                if (!sending) {
    18681899                        sending = copy;
    1869                 } else if (ERROR_OCCURRED(pq_insert_after(previous, copy))) {
    1870                         pq_release_remote(tcp_globals.net_phone,
    1871                             packet_get_id(copy));
    1872                         return sending;
     1900                } else {
     1901                        rc = pq_insert_after(previous, copy);
     1902                        if (rc != EOK) {
     1903                                pq_release_remote(tcp_globals.net_phone,
     1904                                    packet_get_id(copy));
     1905                                return sending;
     1906                        }
    18731907                }
    18741908
     
    18761910                packet = pq_next(packet);
    18771911                // overflow occurred ?
    1878                 if ((!packet) &&
     1912                if (!packet &&
    18791913                    (socket_data->last_outgoing > socket_data->next_outgoing)) {
    18801914                        printf("gpts overflow\n");
     
    18921926    packet_t packet, size_t data_length, size_t sequence_number)
    18931927{
    1894         ERROR_DECLARE;
    1895 
    18961928        tcp_header_ref header;
    18971929        uint32_t checksum;
     1930        int rc;
    18981931
    18991932        assert(socket);
     
    19021935
    19031936        // adjust the pseudo header
    1904         if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
    1905             socket_data->pseudo_header, socket_data->headerlen,
    1906             packet_get_data_length(packet)))) {
     1937        rc = ip_client_set_pseudo_header_data_length(socket_data->pseudo_header,
     1938            socket_data->headerlen, packet_get_data_length(packet));
     1939        if (rc != EOK) {
    19071940                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    19081941                return NULL;
     
    19291962        checksum = compute_checksum(0, socket_data->pseudo_header,
    19301963            socket_data->headerlen);
    1931         checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet),
     1964        checksum = compute_checksum(checksum,
     1965            (uint8_t *) packet_get_data(packet),
    19321966            packet_get_data_length(packet));
    19331967        header->checksum = htons(flip_checksum(compact_checksum(checksum)));
    19341968
    19351969        // prepare the packet
    1936         if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0,
    1937             0, 0)) || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket,
    1938             socket_data, sequence_number, socket_data->state,
    1939             socket_data->timeout, true))) {
     1970        rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0);
     1971        if (rc != EOK) {
     1972                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
     1973                return NULL;
     1974        }
     1975        rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data,
     1976            sequence_number, socket_data->state, socket_data->timeout, true);
     1977        if (rc != EOK) {
    19401978                pq_release_remote(tcp_globals.net_phone, packet_get_id(packet));
    19411979                return NULL;
     
    20442082int
    20452083tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    2046     size_t * addrlen)
    2047 {
    2048         ERROR_DECLARE;
    2049 
     2084    size_t *addrlen)
     2085{
    20502086        socket_core_ref socket;
    20512087        tcp_socket_data_ref socket_data;
     
    20532089        packet_t packet;
    20542090        size_t length;
     2091        int rc;
    20552092
    20562093        assert(local_sockets);
     
    20742111        // send the source address if desired
    20752112        if (addrlen) {
    2076                 ERROR_PROPAGATE(data_reply(socket_data->addr,
    2077                     socket_data->addrlen));
     2113                rc = data_reply(socket_data->addr, socket_data->addrlen);
     2114                if (rc != EOK)
     2115                        return rc;
    20782116                *addrlen = socket_data->addrlen;
    20792117        }
     
    20842122                return NO_DATA;
    20852123
    2086         ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet,
    2087             packet_id));
     2124        rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id);
     2125        if (rc != EOK)
     2126                return rc;
    20882127
    20892128        // reply the packets
    2090         ERROR_PROPAGATE(socket_reply_packets(packet, &length));
     2129        rc = socket_reply_packets(packet, &length);
     2130        if (rc != EOK)
     2131                return rc;
    20912132
    20922133        // release the packet
     
    20992140int
    21002141tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments,
    2101     size_t * data_fragment_size, int flags)
    2102 {
    2103         ERROR_DECLARE;
    2104 
     2142    size_t *data_fragment_size, int flags)
     2143{
    21052144        socket_core_ref socket;
    21062145        tcp_socket_data_ref socket_data;
     
    21112150        int index;
    21122151        int result;
     2152        int rc;
    21132153
    21142154        assert(local_sockets);
     
    21312171                return ENOTCONN;
    21322172
    2133         ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
    2134            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension));
     2173        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
     2174            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
     2175        if (rc != EOK)
     2176                return rc;
    21352177
    21362178        *data_fragment_size =
     
    21382180            packet_dimension->content : socket_data->data_fragment_size);
    21392181
    2140         for (index = 0; index < fragments; ++index) {
     2182        for (index = 0; index < fragments; index++) {
    21412183                // read the data fragment
    21422184                result = tl_socket_read_packet_data(tcp_globals.net_phone,
     
    21532195
    21542196                tcp_prepare_operation_header(socket, socket_data, header, 0, 0);
    2155                 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet,
    2156                     0));
     2197                rc = tcp_queue_packet(socket, socket_data, packet, 0);
     2198                if (rc != EOK)
     2199                        return rc;
    21572200        }
    21582201
     
    21732216tcp_close_message(socket_cores_ref local_sockets, int socket_id)
    21742217{
    2175         ERROR_DECLARE;
    2176 
    21772218        socket_core_ref socket;
    21782219        tcp_socket_data_ref socket_data;
    21792220        packet_t packet;
     2221        int rc;
    21802222
    21812223        // find the socket
     
    22022244        default:
    22032245                // just destroy
    2204                 if (ERROR_NONE(socket_destroy(tcp_globals.net_phone, socket_id,
     2246                rc = socket_destroy(tcp_globals.net_phone, socket_id,
    22052247                    local_sockets, &tcp_globals.sockets,
    2206                     tcp_free_socket_data))) {
     2248                    tcp_free_socket_data);
     2249                if (rc == EOK) {
    22072250                        fibril_rwlock_write_unlock(socket_data->local_lock);
    22082251                        fibril_rwlock_write_unlock(&tcp_globals.lock);
    22092252                }
    2210                 return ERROR_CODE;
     2253                return rc;
    22112254        }
    22122255
     
    22152258
    22162259        // create the notification packet
    2217         ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket,
    2218             socket_data, 0, 1));
     2260        rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1);
     2261        if (rc != EOK)
     2262                return rc;
    22192263
    22202264        // send the packet
    2221         ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1));
     2265        rc = tcp_queue_packet(socket, socket_data, packet, 1);
     2266        if (rc != EOK)
     2267                return rc;
    22222268
    22232269        // flush packets
     
    22352281
    22362282int
    2237 tcp_create_notification_packet(packet_t * packet, socket_core_ref socket,
     2283tcp_create_notification_packet(packet_t *packet, socket_core_ref socket,
    22382284    tcp_socket_data_ref socket_data, int synchronize, int finalize)
    22392285{
    2240         ERROR_DECLARE;
    2241 
    22422286        packet_dimension_ref packet_dimension;
    22432287        tcp_header_ref header;
     2288        int rc;
    22442289
    22452290        assert(packet);
    22462291
    22472292        // get the device packet dimension
    2248         ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone,
    2249             &tcp_globals.dimensions, socket_data->device_id,
    2250             &packet_dimension));
     2293        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
     2294            &tcp_globals.dimensions, socket_data->device_id, &packet_dimension);
     2295        if (rc != EOK)
     2296                return rc;
    22512297
    22522298        // get a new packet
     
    22712317int
    22722318tcp_accept_message(socket_cores_ref local_sockets, int socket_id,
    2273     int new_socket_id, size_t * data_fragment_size, size_t * addrlen)
    2274 {
    2275         ERROR_DECLARE;
    2276 
     2319    int new_socket_id, size_t *data_fragment_size, size_t *addrlen)
     2320{
    22772321        socket_core_ref accepted;
    22782322        socket_core_ref socket;
    22792323        tcp_socket_data_ref socket_data;
    22802324        packet_dimension_ref packet_dimension;
     2325        int rc;
    22812326
    22822327        assert(local_sockets);
     
    23122357                // TODO can it be in another state?
    23132358                if (socket_data->state == TCP_SOCKET_ESTABLISHED) {
    2314                         ERROR_PROPAGATE(data_reply(socket_data->addr,
    2315                             socket_data->addrlen));
    2316                         ERROR_PROPAGATE(tl_get_ip_packet_dimension(
    2317                             tcp_globals.ip_phone, &tcp_globals.dimensions,
    2318                             socket_data->device_id, &packet_dimension));
     2359                        rc = data_reply(socket_data->addr,
     2360                            socket_data->addrlen);
     2361                        if (rc != EOK)
     2362                                return rc;
     2363                        rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone,
     2364                            &tcp_globals.dimensions, socket_data->device_id,
     2365                            &packet_dimension);
     2366                        if (rc != EOK)
     2367                                return rc;
    23192368                        *addrlen = socket_data->addrlen;
    23202369
     
    23262375       
    23272376                        if (new_socket_id > 0) {
    2328                                 ERROR_PROPAGATE(socket_cores_update(
    2329                                     local_sockets, accepted->socket_id,
    2330                                     new_socket_id));
     2377                                rc = socket_cores_update(local_sockets,
     2378                                    accepted->socket_id, new_socket_id);
     2379                                if (rc != EOK)
     2380                                        return rc;
    23312381                                accepted->socket_id = new_socket_id;
    23322382                        }
     
    23732423}
    23742424
     2425/** Releases the packet and returns the result.
     2426 *
     2427 * @param[in] packet    The packet queue to be released.
     2428 * @param[in] result    The result to be returned.
     2429 * @return              The result parameter.
     2430 */
    23752431int tcp_release_and_return(packet_t packet, int result)
    23762432{
     
    23812437/** Default thread for new connections.
    23822438 *
    2383  *  @param[in] iid The initial message identifier.
    2384  *  @param[in] icall The initial message call structure.
     2439 * @param[in] iid       The initial message identifier.
     2440 * @param[in] icall     The initial message call structure.
    23852441 *
    23862442 */
     
    23972453                int answer_count;
    23982454
    2399                 /*
    2400                    Clear the answer structure
    2401                  */
     2455                /* Clear the answer structure */
    24022456                refresh_answer(&answer, &answer_count);
    24032457
    2404                 /*
    2405                    Fetch the next message
    2406                  */
     2458                /* Fetch the next message */
    24072459                ipc_call_t call;
    24082460                ipc_callid_t callid = async_get_call(&call);
    24092461
    2410                 /*
    2411                    Process the message
    2412                  */
     2462                /* Process the message */
    24132463                int res = tl_module_message_standalone(callid, &call, &answer,
    24142464                    &answer_count);
    24152465
    24162466                /*
    2417                    End if said to either by the message or the processing result
     2467                 * End if told to either by the message or the processing
     2468                 * result.
    24182469                 */
    24192470                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    24302481/** Starts the module.
    24312482 *
    2432  *  @param argc The count of the command line arguments. Ignored parameter.
    2433  *  @param argv The command line parameters. Ignored parameter.
    2434  *
    2435  *  @returns EOK on success.
    2436  *  @returns Other error codes as defined for each specific module start function.
    2437  *
     2483 * @returns             EOK on success.
     2484 * @returns             Other error codes as defined for each specific module
     2485 *                      start function.
    24382486 */
    24392487int
    24402488main(int argc, char *argv[])
    24412489{
    2442         ERROR_DECLARE;
    2443 
    2444         /*
    2445            Start the module
    2446          */
    2447         if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
    2448                 return ERROR_CODE;
    2449 
    2450         return EOK;
     2490        int rc;
     2491
     2492        rc = tl_module_start_standalone(tl_client_connection);
     2493        return rc;
    24512494}
    24522495
  • uspace/srv/net/tl/tcp/tcp.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP module.
    35  */
    36 
    37 #ifndef __NET_TCP_H__
    38 #define __NET_TCP_H__
     34 * TCP module.
     35 */
     36
     37#ifndef NET_TCP_H_
     38#define NET_TCP_H_
    3939
    4040#include <fibril_synch.h>
     
    4646
    4747/** Type definition of the TCP global data.
    48  *  @see tcp_globals
    49  */
    50 typedef struct tcp_globals      tcp_globals_t;
     48 * @see tcp_globals
     49 */
     50typedef struct tcp_globals tcp_globals_t;
    5151
    5252/** Type definition of the TCP socket specific data.
    53  *  @see tcp_socket_data
    54  */
    55 typedef struct tcp_socket_data  tcp_socket_data_t;
     53 * @see tcp_socket_data
     54 */
     55typedef struct tcp_socket_data tcp_socket_data_t;
    5656
    5757/** Type definition of the TCP socket specific data pointer.
    58  *  @see tcp_socket_data
    59  */
    60 typedef tcp_socket_data_t *     tcp_socket_data_ref;
     58 * @see tcp_socket_data
     59 */
     60typedef tcp_socket_data_t *tcp_socket_data_ref;
    6161
    6262/** Type definition of the TCP operation data.
    63  *  @see tcp_operation
    64  */
    65 typedef struct tcp_operation    tcp_operation_t;
     63 * @see tcp_operation
     64 */
     65typedef struct tcp_operation tcp_operation_t;
    6666
    6767/** Type definition of the TCP operation data pointer.
    68  *  @see tcp_operation
    69  */
    70 typedef tcp_operation_t *       tcp_operation_ref;
     68 * @see tcp_operation
     69 */
     70typedef tcp_operation_t *tcp_operation_ref;
    7171
    7272/** TCP socket state type definition.
    73  *  @see tcp_socket_state
    74  */
    75 typedef enum tcp_socket_state   tcp_socket_state_t;
    76 
    77 /** TCP socket state.
    78  */
    79 enum tcp_socket_state{
     73 * @see tcp_socket_state
     74 */
     75typedef enum tcp_socket_state tcp_socket_state_t;
     76
     77/** TCP socket state. */
     78enum tcp_socket_state {
    8079        /** Initial.
    81          *  Not connected or bound.
     80         *
     81         * Not connected or bound.
    8282         */
    8383        TCP_SOCKET_INITIAL,
     84       
    8485        /** Listening.
    85          *  Awaiting a connection request from another TCP layer.
    86          *  When SYN is received a new bound socket in the TCP_SOCKET_SYN_RECEIVED state should be created.
     86         *
     87         * Awaiting a connection request from another TCP layer.
     88         * When SYN is received a new bound socket in the
     89         * TCP_SOCKET_SYN_RECEIVED state should be created.
    8790         */
    8891        TCP_SOCKET_LISTEN,
     92       
    8993        /** Connecting issued.
    90          *  A~SYN has been sent, and TCP is awaiting the response SYN.
    91          *  Should continue to the TCP_SOCKET_ESTABLISHED state.
     94         *
     95         * A SYN has been sent, and TCP is awaiting the response SYN.
     96         * Should continue to the TCP_SOCKET_ESTABLISHED state.
    9297         */
    9398        TCP_SOCKET_SYN_SENT,
     99       
    94100        /** Connecting received.
    95          *  A~SYN has been received, a~SYN has been sent, and TCP is awaiting an ACK.
    96          *  Should continue to the TCP_SOCKET_ESTABLISHED state.
     101         *
     102         * A SYN has been received, a SYN has been sent, and TCP is awaiting an
     103         * ACK. Should continue to the TCP_SOCKET_ESTABLISHED state.
    97104         */
    98105        TCP_SOCKET_SYN_RECEIVED,
     106       
    99107        /** Connected.
    100          *  The three-way handshake has been completed.
     108         *
     109         * The three-way handshake has been completed.
    101110         */
    102111        TCP_SOCKET_ESTABLISHED,
     112       
    103113        /** Closing started.
    104          *  The local application has issued a~CLOSE.
    105          *  TCP has sent a~FIN, and is awaiting an ACK or a~FIN.
    106          *  Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is received.
    107          *  Should continue to the TCP_SOCKET_CLOSING state when a~FIN is received.
     114         *
     115         * The local application has issued a CLOSE.
     116         * TCP has sent a FIN, and is awaiting an ACK or a FIN.
     117         * Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is
     118         * received.
     119         * Should continue to the TCP_SOCKET_CLOSING state when a FIN is
     120         * received.
    108121         */
    109122        TCP_SOCKET_FIN_WAIT_1,
     123       
    110124        /** Closing confirmed.
    111          *  A~FIN has been sent, and an ACK received.
    112          *  TCP is awaiting a~FIN from the remote TCP layer.
    113          *  Should continue to the TCP_SOCKET_CLOSING state.
     125         *
     126         * A FIN has been sent, and an ACK received.
     127         * TCP is awaiting a~FIN from the remote TCP layer.
     128         * Should continue to the TCP_SOCKET_CLOSING state.
    114129         */
    115130        TCP_SOCKET_FIN_WAIT_2,
     131       
    116132        /** Closing.
    117          *  A FIN has been sent, a FIN has been received, and an ACK has been sent.
    118          *  TCP is awaiting an ACK for the FIN that was sent.
    119          *  Should continue to the TCP_SOCKET_TIME_WAIT state.
     133         *
     134         * A FIN has been sent, a FIN has been received, and an ACK has been
     135         * sent.
     136         * TCP is awaiting an ACK for the FIN that was sent.
     137         * Should continue to the TCP_SOCKET_TIME_WAIT state.
    120138         */
    121139        TCP_SOCKET_CLOSING,
     140       
    122141        /** Closing received.
    123          *  TCP has received a~FIN, and has sent an ACK.
    124          *  It is awaiting a~close request from the local application before sending a~FIN.
    125          *  Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state.
     142         *
     143         * TCP has received a FIN, and has sent an ACK.
     144         * It is awaiting a close request from the local application before
     145         * sending a FIN.
     146         * Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state.
    126147         */
    127148        TCP_SOCKET_CLOSE_WAIT,
    128         /**
    129          *  A~FIN has been received, and an ACK and a~FIN have been sent.
    130          *  TCP is awaiting an ACK.
    131          *  Should continue to the TCP_SOCKET_TIME_WAIT state.
     149       
     150        /**
     151         * A FIN has been received, and an ACK and a FIN have been sent.
     152         * TCP is awaiting an ACK.
     153         * Should continue to the TCP_SOCKET_TIME_WAIT state.
    132154         */
    133155        TCP_SOCKET_LAST_ACK,
     156       
    134157        /** Closing finished.
    135          *  FINs have been received and ACK’d, and TCP is waiting two MSLs to remove the connection from the table.
     158         *
     159         * FINs have been received and ACK’d, and TCP is waiting two MSLs to
     160         * remove the connection from the table.
    136161         */
    137162        TCP_SOCKET_TIME_WAIT,
     163       
    138164        /** Closed.
    139          *  Imaginary, this indicates that a~connection has been removed from the connection table.
     165         *
     166         * Imaginary, this indicates that a connection has been removed from
     167         * the connection table.
    140168         */
    141169        TCP_SOCKET_CLOSED
    142170};
    143171
    144 /** TCP operation data.
    145  */
    146 struct tcp_operation{
    147         /** Operation result.
    148          */
     172/** TCP operation data. */
     173struct tcp_operation {
     174        /** Operation result. */
    149175        int result;
    150         /** Safety lock.
    151          */
     176        /** Safety lock. */
    152177        fibril_mutex_t mutex;
    153         /** Operation result signaling.
    154          */
     178        /** Operation result signaling. */
    155179        fibril_condvar_t condvar;
    156180};
    157181
    158 /** TCP socket specific data.
    159  */
    160 struct tcp_socket_data{
    161         /** TCP socket state.
    162          */
     182/** TCP socket specific data. */
     183struct tcp_socket_data {
     184        /** TCP socket state. */
    163185        tcp_socket_state_t state;
    164         /** Data fragment size.
    165          *  Sending optimalization.
     186       
     187        /**
     188         * Data fragment size.
     189         * Sending optimalization.
    166190         */
    167191        size_t data_fragment_size;
    168         /** Device identifier.
    169         */
     192       
     193        /** Device identifier. */
    170194        device_id_t device_id;
    171         /** Listening backlog.
    172          *  The maximal number of connected but not yet accepted sockets.
     195       
     196        /**
     197         * Listening backlog.
     198         * The maximal number of connected but not yet accepted sockets.
    173199         */
    174200        int backlog;
    175 //      /** Segment size.
    176 //       */
    177 //      size_t                  segment_size;
    178         /** Parent listening socket identifier.
    179          *  Set if this socket is an accepted one.
     201       
     202//      /** Segment size. */
     203//      size_t segment_size;
     204
     205        /**
     206         * Parent listening socket identifier.
     207         * Set if this socket is an accepted one.
    180208         */
    181209        int listening_socket_id;
    182         /** Treshold size in bytes.
    183         */
     210       
     211        /** Treshold size in bytes. */
    184212        size_t treshold;
    185         /** Window size in bytes.
    186          */
     213        /** Window size in bytes. */
    187214        size_t window;
    188         /** Acknowledgement timeout.
    189          */
     215        /** Acknowledgement timeout. */
    190216        suseconds_t timeout;
    191         /** Last acknowledged byte.
    192          */
     217        /** Last acknowledged byte. */
    193218        uint32_t acknowledged;
    194         /** Next incoming sequence number.
    195          */
     219        /** Next incoming sequence number. */
    196220        uint32_t next_incoming;
    197         /** Incoming FIN.
    198          */
     221        /** Incoming FIN. */
    199222        uint32_t fin_incoming;
    200         /** Next outgoing sequence number.
    201          */
     223        /** Next outgoing sequence number. */
    202224        uint32_t next_outgoing;
    203         /** Last outgoing sequence number.
    204          */
     225        /** Last outgoing sequence number. */
    205226        uint32_t last_outgoing;
    206         /** Outgoing FIN.
    207          */
     227        /** Outgoing FIN. */
    208228        uint32_t fin_outgoing;
    209         /** Expected sequence number by the remote host.
    210          *  The sequence number the other host expects.
    211          *  The notification is sent only upon a packet reecival.
     229       
     230        /**
     231         * Expected sequence number by the remote host.
     232         * The sequence number the other host expects.
     233         * The notification is sent only upon a packet reecival.
    212234         */
    213235        uint32_t expected;
    214         /** Expected sequence number counter.
    215          *  Counts the number of received notifications for the same sequence number.
     236       
     237        /**
     238         * Expected sequence number counter.
     239         * Counts the number of received notifications for the same sequence
     240         * number.
    216241         */
    217242        int expected_count;
     243       
    218244        /** Incoming packet queue.
    219          *  Packets are buffered until received in the right order.
    220          *  The packets are excluded after successfully read.
    221          *  Packets are sorted by their starting byte.
    222          *  Packets metric is set as their data length.
     245         *
     246         * Packets are buffered until received in the right order.
     247         * The packets are excluded after successfully read.
     248         * Packets are sorted by their starting byte.
     249         * Packets metric is set as their data length.
    223250         */
    224251        packet_t incoming;
     252       
    225253        /** Outgoing packet queue.
    226          *  Packets are buffered until acknowledged by the remote host in the right order.
    227          *  The packets are excluded after acknowledged.
    228          *  Packets are sorted by their starting byte.
    229          *  Packets metric is set as their data length.
     254         *
     255         * Packets are buffered until acknowledged by the remote host in the
     256         * right order.
     257         * The packets are excluded after acknowledged.
     258         * Packets are sorted by their starting byte.
     259         * Packets metric is set as their data length.
    230260         */
    231261        packet_t outgoing;
    232         /** IP pseudo header.
    233         */
     262       
     263        /** IP pseudo header. */
    234264        void *pseudo_header;
    235         /** IP pseudo header length.
    236          */
     265        /** IP pseudo header length. */
    237266        size_t headerlen;
    238         /** Remote host address.
    239          */
    240         struct sockaddr * addr;
    241         /** Remote host address length.
    242          */
     267        /** Remote host address. */
     268        struct sockaddr *addr;
     269        /** Remote host address length. */
    243270        socklen_t addrlen;
    244         /** Remote host port.
    245          */
     271        /** Remote host port. */
    246272        uint16_t dest_port;
    247         /** Parent local sockets.
    248          */
     273        /** Parent local sockets. */
    249274        socket_cores_ref local_sockets;
     275       
    250276        /** Local sockets safety lock.
    251          *  May be locked for writing while holding the global lock for reading when changing the local sockets only.
    252          *  The global lock may to be locked only before locking the local lock.
    253          *  The global lock may be locked more weakly than the local lock.
    254          *  The global lock may be released before releasing the local lock.
    255          *  @see tcp_globals:lock
    256          */
    257         fibril_rwlock_t * local_lock;
    258         /** Pending operation data.
    259          */
     277         *
     278         * May be locked for writing while holding the global lock for reading
     279         * when changing the local sockets only.
     280         * The global lock may be locked only before locking the local lock.
     281         * The global lock may be locked more weakly than the local lock.
     282         * The global lock may be released before releasing the local lock.
     283         * @see tcp_globals:lock
     284         */
     285        fibril_rwlock_t *local_lock;
     286       
     287        /** Pending operation data. */
    260288        tcp_operation_t operation;
    261         /** Timeouts in a row counter.
    262          *  If TCP_MAX_TIMEOUTS is reached, the connection is lost.
     289       
     290        /**
     291         * Timeouts in a row counter.
     292         * If TCP_MAX_TIMEOUTS is reached, the connection is lost.
    263293         */
    264294        int timeout_count;
    265295};
    266296
    267 /** TCP global data.
    268  */
    269 struct  tcp_globals{
    270         /** Networking module phone.
    271          */
     297/** TCP global data. */
     298struct tcp_globals {
     299        /** Networking module phone. */
    272300        int net_phone;
    273         /** IP module phone.
    274          */
     301        /** IP module phone. */
    275302        int ip_phone;
    276         /** ICMP module phone.
    277          */
     303        /** ICMP module phone. */
    278304        int icmp_phone;
    279         /** Last used free port.
    280          */
     305        /** Last used free port. */
    281306        int last_used_port;
    282         /** Active sockets.
    283          */
     307        /** Active sockets. */
    284308        socket_ports_t sockets;
    285         /** Device packet dimensions.
    286          */
     309        /** Device packet dimensions. */
    287310        packet_dimensions_t dimensions;
    288         /** Safety lock.
    289          *  Write lock is used only for adding or removing socket ports.
     311       
     312        /**
     313         * Safety lock.
     314         * Write lock is used only for adding or removing socket ports.
    290315         */
    291316        fibril_rwlock_t lock;
     
    296321/** @}
    297322 */
    298 
  • uspace/srv/net/tl/tcp/tcp_header.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP header definition.
    35  *  Based on the RFC~793.
     34 * TCP header definition.
     35 * Based on the RFC 793.
    3636 */
    3737
    38 #ifndef __NET_TCP_HEADER_H__
    39 #define __NET_TCP_HEADER_H__
     38#ifndef NET_TCP_HEADER_H_
     39#define NET_TCP_HEADER_H_
    4040
    4141#include <sys/types.h>
    4242
    43 /** TCP header size in bytes.
    44  */
    45 #define TCP_HEADER_SIZE                 sizeof(tcp_header_t)
     43/** TCP header size in bytes. */
     44#define TCP_HEADER_SIZE                         sizeof(tcp_header_t)
    4645
    4746/** Returns the actual TCP header length in bytes.
    48  *  @param[in] header The TCP packet header.
     47 * @param[in] header The TCP packet header.
    4948 */
    50 #define TCP_HEADER_LENGTH(header)               ((header)->header_length * 4u)
     49#define TCP_HEADER_LENGTH(header)               ((header)->header_length * 4U)
    5150
    5251/** Returns the TCP header length.
    53  *  @param[in] length The TCP header length in bytes.
     52 * @param[in] length The TCP header length in bytes.
    5453 */
    55 #define TCP_COMPUTE_HEADER_LENGTH(length)               ((uint8_t) ((length) / 4u))
     54#define TCP_COMPUTE_HEADER_LENGTH(length)       ((uint8_t) ((length) / 4U))
    5655
    5756/** Type definition of the transmission datagram header.
    58  *  @see tcp_header
     57 * @see tcp_header
    5958 */
    60 typedef struct tcp_header       tcp_header_t;
     59typedef struct tcp_header tcp_header_t;
    6160
    6261/** Type definition of the transmission datagram header pointer.
    63  *  @see tcp_header
     62 * @see tcp_header
    6463 */
    65 typedef tcp_header_t *          tcp_header_ref;
     64typedef tcp_header_t *tcp_header_ref;
    6665
    6766/** Type definition of the transmission datagram header option.
    68  *  @see tcp_option
     67 * @see tcp_option
    6968 */
    70 typedef struct tcp_option       tcp_option_t;
     69typedef struct tcp_option tcp_option_t;
    7170
    7271/** Type definition of the transmission datagram header option pointer.
    73  *  @see tcp_option
     72 * @see tcp_option
    7473 */
    75 typedef tcp_option_t *          tcp_option_ref;
     74typedef tcp_option_t *tcp_option_ref;
    7675
    77 /** Type definition of the Maximum segment size TCP option.
    78  *  @see ...
    79  */
    80 typedef struct tcp_max_segment_size_option      tcp_max_segment_size_option_t;
     76/** Type definition of the Maximum segment size TCP option. */
     77typedef struct tcp_max_segment_size_option tcp_max_segment_size_option_t;
    8178
    8279/** Type definition of the Maximum segment size TCP option pointer.
    83  *  @see tcp_max_segment_size_option
     80 * @see tcp_max_segment_size_option
    8481 */
    85 typedef tcp_max_segment_size_option_t *         tcp_max_segment_size_option_ref;
     82typedef tcp_max_segment_size_option_t *tcp_max_segment_size_option_ref;
    8683
    87 /** Transmission datagram header.
    88  */
    89 struct tcp_header{
    90         /** The source port number.
    91          */
     84/** Transmission datagram header. */
     85struct tcp_header {
    9286        uint16_t source_port;
    93         /** The destination port number.
    94          */
    9587        uint16_t destination_port;
    96         /** The sequence number of the first data octet in this segment (except when SYN is present).
    97          *  If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.
    98          */
    9988        uint32_t sequence_number;
    100         /** If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive.
    101          *  Once a~connection is established this is always sent.
    102          *  @see acknowledge
    103          */
    10489        uint32_t acknowledgement_number;
     90       
    10591#ifdef ARCH_IS_BIG_ENDIAN
    106         /** The number of 32~bit words in the TCP Header.
    107          *  This indicates where the data begins.
    108          *  The TCP header (even one including options) is an integral number of 32~bits long.
    109          */
    11092        uint8_t header_length:4;
    111         /** Four bits reserved for future use.
    112          *  Must be zero.
    113          */
    11493        uint8_t reserved1:4;
    11594#else
    116         /** Four bits reserved for future use.
    117          *  Must be zero.
    118          */
    11995        uint8_t reserved1:4;
    120         /** The number of 32~bit words in the TCP Header.
    121          *  This indicates where the data begins.
    122          *  The TCP header (even one including options) is an integral number of 32~bits long.
    123          */
    12496        uint8_t header_length:4;
    12597#endif
     98
    12699#ifdef ARCH_IS_BIG_ENDIAN
    127         /** Two bits reserved for future use.
    128          *  Must be zero.
    129          */
    130100        uint8_t reserved2:2;
    131         /** Urgent Pointer field significant.
    132          *  @see tcp_header:urgent_pointer
    133          */
    134101        uint8_t urgent:1;
    135         /** Acknowledgment field significant
    136          *  @see tcp_header:acknowledgement_number
    137          */
    138102        uint8_t acknowledge:1;
    139         /** Push function.
    140          */
    141103        uint8_t push:1;
    142         /** Reset the connection.
    143          */
    144104        uint8_t reset:1;
    145         /** Synchronize the sequence numbers.
    146          */
    147105        uint8_t synchronize:1;
    148         /** No more data from the sender.
    149          */
    150106        uint8_t finalize:1;
    151107#else
    152         /** No more data from the sender.
    153          */
    154108        uint8_t finalize:1;
    155         /** Synchronize the sequence numbers.
    156          */
    157109        uint8_t synchronize:1;
    158         /** Reset the connection.
    159          */
    160110        uint8_t reset:1;
    161         /** Push function.
    162          */
    163111        uint8_t push:1;
    164         /** Acknowledgment field significant.
    165          *  @see tcp_header:acknowledgement_number
    166          */
    167112        uint8_t acknowledge:1;
    168         /** Urgent Pointer field significant.
    169          *  @see tcp_header:urgent_pointer
    170          */
    171113        uint8_t urgent:1;
    172         /** Two bits reserved for future use.
    173          *  Must be zero.
    174          */
    175114        uint8_t reserved2:2;
    176115#endif
    177         /** The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept.
    178          *  @see tcp_header:acknowledge
    179          */
     116
    180117        uint16_t window;
    181         /** The checksum field is the 16~bit one's complement of the one's complement sum of all 16~bit words in the header and text.
    182          *  If a~segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a~16~bit word for checksum purposes.
    183          *  The pad is not transmitted as part of the segment.
    184          *  While computing the checksum, the checksum field itself is replaced with zeros.
    185          *  The checksum also coves a~pseudo header conceptually.
    186          *  The pseudo header conceptually prefixed to the TCP header contains the source address, the destination address, the protocol, and the TCP length.
    187          *  This information gives protection against misrouted datagrams.
    188          *  If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).
    189          */
    190118        uint16_t checksum;
    191         /** This field communicates the current value of the urgent pointer as a~positive offset from the sequence number in this segment.
    192          *  The urgent pointer points to the sequence number of the octet following the urgent data.
    193          *  This field is only be interpreted in segments with the URG control bit set.
    194          *  @see tcp_header:urgent
    195          */
    196119        uint16_t urgent_pointer;
    197120} __attribute__ ((packed));
    198121
    199 /** Transmission datagram header option.
    200  */
    201 struct tcp_option{
    202         /** Option type.
    203          */
     122/** Transmission datagram header option. */
     123struct tcp_option {
     124        /** Option type. */
    204125        uint8_t type;
    205         /** Option length.
    206          */
     126        /** Option length. */
    207127        uint8_t length;
    208128};
    209129
    210 /** Maximum segment size TCP option.
    211  */
    212 struct tcp_max_segment_size_option{
     130/** Maximum segment size TCP option. */
     131struct tcp_max_segment_size_option {
    213132        /** TCP option.
    214          *  @see TCPOPT_MAX_SEGMENT_SIZE
    215          *  @see TCPOPT_MAX_SEGMENT_SIZE_LENGTH
     133         * @see TCPOPT_MAX_SEGMENT_SIZE
     134         * @see TCPOPT_MAX_SEGMENT_SIZE_LENGTH
    216135         */
    217136        tcp_option_t option;
    218         /** Maximum segment size in bytes.
    219         */
     137       
     138        /** Maximum segment size in bytes. */
    220139        uint16_t max_segment_size;
    221140} __attribute__ ((packed));
  • uspace/srv/net/tl/tcp/tcp_module.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP standalone module implementation.
    35  *  Contains skeleton module functions mapping.
    36  *  The functions are used by the module skeleton as module specific entry points.
    37  *  @see module.c
     34 * TCP standalone module implementation.
     35 * Contains skeleton module functions mapping.
     36 * The functions are used by the module skeleton as module specific entry
     37 * points.
     38 * @see module.c
    3839 */
     40
     41#include "tcp.h"
     42#include "tcp_module.h"
    3943
    4044#include <async.h>
    4145#include <stdio.h>
    42 #include <err.h>
     46#include <errno.h>
    4347#include <ipc/ipc.h>
    4448#include <ipc/services.h>
     
    4650#include <net/ip_protocols.h>
    4751#include <net/modules.h>
    48 
    4952#include <net/packet.h>
    5053#include <net_interface.h>
     54
    5155#include <ip_interface.h>
    5256#include <tl_local.h>
    5357
    54 #include "tcp.h"
    55 #include "tcp_module.h"
     58/** TCP module global data. */
     59extern tcp_globals_t tcp_globals;
    5660
    57 /** TCP module global data.
    58  */
    59 extern tcp_globals_t    tcp_globals;
    60 
    61 /** Starts the TCP module.
    62  *  Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.
    63  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    64  *  @returns EOK on successful module termination.
    65  *  @returns Other error codes as defined for the tcp_initialize() function.
    66  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
    67  */
    6861int tl_module_start_standalone(async_client_conn_t client_connection)
    6962{
    70         ERROR_DECLARE;
    71        
     63        ipcarg_t phonehash;
     64        int rc;
     65
    7266        async_set_client_connection(client_connection);
    7367        tcp_globals.net_phone = net_connect_module();
    74         ERROR_PROPAGATE(pm_init());
    75        
    76         ipcarg_t phonehash;
    77         if (ERROR_OCCURRED(tcp_initialize(client_connection))
    78             || ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))) {
    79                 pm_destroy();
    80                 return ERROR_CODE;
    81         }
     68
     69        rc = pm_init();
     70        if (rc != EOK)
     71                return rc;
     72
     73        rc = tcp_initialize(client_connection);
     74        if (rc != EOK)
     75                goto out;
     76
     77        rc = REGISTER_ME(SERVICE_TCP, &phonehash);
     78        if (rc != EOK)
     79                goto out;
    8280       
    8381        async_manager();
    8482       
     83out:
    8584        pm_destroy();
    86         return EOK;
     85        return rc;
    8786}
    8887
    89 /** Processes the TCP message.
    90  *  @param[in] callid The message identifier.
    91  *  @param[in] call The message parameters.
    92  *  @param[out] answer The message answer parameters.
    93  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    94  *  @returns EOK on success.
    95  *  @returns Other error codes as defined for the tcp_message() function.
    96  */
    97 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     88int
     89tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     90    ipc_call_t *answer, int *answer_count)
     91{
    9892        return tcp_message_standalone(callid, call, answer, answer_count);
    9993}
  • uspace/srv/net/tl/tcp/tcp_module.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup tcp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  TCP module functions.
    35  *  The functions are used as TCP module entry points.
     34 * TCP module functions.
     35 * The functions are used as TCP module entry points.
    3636 */
    3737
    38 #ifndef __NET_TCP_MODULE_H__
    39 #define __NET_TCP_MODULE_H__
     38#ifndef NET_TCP_MODULE_H_
     39#define NET_TCP_MODULE_H_
    4040
    4141#include <async.h>
    4242#include <ipc/ipc.h>
    4343
    44 /** Initializes the TCP module.
    45  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    46  *  @returns EOK on success.
    47  *  @returns ENOMEM if there is not enough memory left.
    48  */
    49 extern int tcp_initialize(async_client_conn_t client_connection);
    50 
    51 /** Processes the TCP message.
    52  *  @param[in] callid The message identifier.
    53  *  @param[in] call The message parameters.
    54  *  @param[out] answer The message answer parameters.
    55  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    56  *  @returns EOK on success.
    57  *  @returns ENOTSUP if the message is not known.
    58  *  @see tcp_interface.h
    59  *  @see IS_NET_TCP_MESSAGE()
    60  */
    61 extern int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
     44extern int tcp_initialize(async_client_conn_t);
     45extern int tcp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
     46    int *);
    6247
    6348#endif
  • uspace/srv/net/tl/udp/udp.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  UDP module implementation.
    35  *  @see udp.h
    36  */
     34 * UDP module implementation.
     35 * @see udp.h
     36 */
     37
     38#include "udp.h"
     39#include "udp_header.h"
     40#include "udp_module.h"
    3741
    3842#include <async.h>
     
    4549#include <ipc/tl.h>
    4650#include <ipc/socket.h>
     51#include <adt/dynamic_fifo.h>
    4752#include <errno.h>
    48 #include <err.h>
    4953
    5054#include <net/socket_codes.h>
     
    5559#include <net/modules.h>
    5660
    57 #include <adt/dynamic_fifo.h>
    5861#include <packet_client.h>
    5962#include <packet_remote.h>
     
    6972#include <tl_interface.h>
    7073
    71 #include "udp.h"
    72 #include "udp_header.h"
    73 #include "udp_module.h"
    74 
    7574/** UDP module name. */
    7675#define NAME    "UDP protocol"
     
    9190#define UDP_FREE_PORTS_END              65535
    9291
    93 /** Processes the received UDP packet queue.
    94  *
    95  *  Is used as an entry point from the underlying IP module.
    96  *  Locks the global lock and calls udp_process_packet() function.
    97  *
    98  *  @param[in] device_id The receiving device identifier.
    99  *  @param[in,out] packet The received packet queue.
    100  *  @param receiver     The target service. Ignored parameter.
    101  *  @param[in] error    The packet error reporting service. Prefixes the
    102  *                      received packet.
    103  *  @returns            EOK on success.
    104  *  @returns            Other error codes as defined for the
    105  *                      udp_process_packet() function.
    106  */
    107 int
    108 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
    109     services_t error);
    110 
    111 /** Processes the received UDP packet queue.
    112  *
    113  *  Notifies the destination socket application.
    114  *  Releases the packet on error or sends an ICMP error notification.
    115  *
    116  *  @param[in] device_id The receiving device identifier.
    117  *  @param[in,out] packet The received packet queue.
    118  *  @param[in] error    The packet error reporting service. Prefixes the
    119  *                      received packet.
    120  *  @returns            EOK on success.
    121  *  @returns            EINVAL if the packet is not valid.
    122  *  @returns            EINVAL if the stored packet address is not the
    123  *                      an_addr_t.
    124  *  @returns            EINVAL if the packet does not contain any data.
    125  *  @returns            NO_DATA if the packet content is shorter than the user
    126  *                      datagram header.
    127  *  @returns            ENOMEM if there is not enough memory left.
    128  *  @returns            EADDRNOTAVAIL if the destination socket does not exist.
    129  *  @returns            Other error codes as defined for the
    130  *                      ip_client_process_packet() function.
    131  */
    132 int
    133 udp_process_packet(device_id_t device_id, packet_t packet, services_t error);
    134 
    135 /** Releases the packet and returns the result.
    136  *
    137  *  @param[in] packet   The packet queue to be released.
    138  *  @param[in] result   The result to be returned.
    139  *  @return             The result parameter.
    140  */
    141 int udp_release_and_return(packet_t packet, int result);
    142 
    143 /** @name Socket messages processing functions
    144  */
    145 /*@{*/
    146 
    147 /** Processes the socket client messages.
    148  *
    149  *  Runs until the client module disconnects.
    150  *
    151  *  @param[in] callid   The message identifier.
    152  *  @param[in] call     The message parameters.
    153  *  @returns            EOK on success.
    154  *  @see                socket.h
    155  */
    156 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call);
    157 
    158 /** Sends data from the socket to the remote address.
    159  *
    160  *  Binds the socket to a free port if not already connected/bound.
    161  *  Handles the NET_SOCKET_SENDTO message.
    162  *  Supports AF_INET and AF_INET6 address families.
    163  *
    164  *  @param[in,out] local_sockets The application local sockets.
    165  *  @param[in] socket_id Socket identifier.
    166  *  @param[in] addr     The destination address.
    167  *  @param[in] addrlen  The address length.
    168  *  @param[in] fragments The number of data fragments.
    169  *  @param[out] data_fragment_size The data fragment size in bytes.
    170  *  @param[in] flags    Various send flags.
    171  *  @returns            EOK on success.
    172  *  @returns            EAFNOTSUPPORT if the address family is not supported.
    173  *  @returns            ENOTSOCK if the socket is not found.
    174  *  @returns            EINVAL if the address is invalid.
    175  *  @returns            ENOTCONN if the sending socket is not and cannot be
    176  *                      bound.
    177  *  @returns            ENOMEM if there is not enough memory left.
    178  *  @returns            Other error codes as defined for the
    179  *                      socket_read_packet_data() function.
    180  *  @returns            Other error codes as defined for the
    181  *                      ip_client_prepare_packet() function.
    182  *  @returns            Other error codes as defined for the ip_send_msg()
    183  *                      function.
    184  */
    185 int
    186 udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    187     const struct sockaddr * addr, socklen_t addrlen, int fragments,
    188     size_t * data_fragment_size, int flags);
    189 
    190 /** Receives data to the socket.
    191  *
    192  *  Handles the NET_SOCKET_RECVFROM message.
    193  *  Replies the source address as well.
    194  *
    195  *  @param[in] local_sockets The application local sockets.
    196  *  @param[in] socket_id Socket identifier.
    197  *  @param[in] flags    Various receive flags.
    198  *  @param[out] addrlen The source address length.
    199  *  @returns            The number of bytes received.
    200  *  @returns            ENOTSOCK if the socket is not found.
    201  *  @returns            NO_DATA if there are no received packets or data.
    202  *  @returns            ENOMEM if there is not enough memory left.
    203  *  @returns            EINVAL if the received address is not an IP address.
    204  *  @returns            Other error codes as defined for the packet_translate()
    205  *                      function.
    206  *  @returns            Other error codes as defined for the data_reply()
    207  *                      function.
    208  */
    209 int
    210 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    211     size_t * addrlen);
    212 
    213 /*@}*/
    214 
    215 /** UDP global data.
    216  */
     92/** UDP global data.  */
    21793udp_globals_t udp_globals;
    21894
     95/** Initializes the UDP module.
     96 *
     97 * @param[in] client_connection The client connection processing function. The
     98 *                      module skeleton propagates its own one.
     99 * @returns             EOK on success.
     100 * @returns             ENOMEM if there is not enough memory left.
     101 */
    219102int udp_initialize(async_client_conn_t client_connection)
    220103{
    221         ERROR_DECLARE;
    222 
    223104        measured_string_t names[] = {
    224105                {
    225                         str_dup("UDP_CHECKSUM_COMPUTING"),
     106                        (char *) "UDP_CHECKSUM_COMPUTING",
    226107                        22
    227108                },
    228109                {
    229                         str_dup("UDP_AUTOBINDING"),
     110                        (char *) "UDP_AUTOBINDING",
    230111                        15
    231112                }
     
    233114        measured_string_ref configuration;
    234115        size_t count = sizeof(names) / sizeof(measured_string_t);
    235         char * data;
     116        char *data;
     117        int rc;
    236118
    237119        fibril_rwlock_initialize(&udp_globals.lock);
     
    240122        udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP,
    241123            ICMP_CONNECT_TIMEOUT);
     124       
    242125        udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP,
    243126            SERVICE_UDP, client_connection);
    244         if (udp_globals.ip_phone < 0)
     127        if (udp_globals.ip_phone < 0) {
     128                fibril_rwlock_write_unlock(&udp_globals.lock);
    245129                return udp_globals.ip_phone;
     130        }
    246131
    247132        // read default packet dimensions
    248         ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
    249             &udp_globals.packet_dimension));
    250         ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets));
    251         if (ERROR_OCCURRED(packet_dimensions_initialize(
    252             &udp_globals.dimensions))) {
     133        rc = ip_packet_size_req(udp_globals.ip_phone, -1,
     134            &udp_globals.packet_dimension);
     135        if (rc != EOK) {
     136                fibril_rwlock_write_unlock(&udp_globals.lock);
     137                return rc;
     138        }
     139       
     140        rc = socket_ports_initialize(&udp_globals.sockets);
     141        if (rc != EOK) {
     142                fibril_rwlock_write_unlock(&udp_globals.lock);
     143                return rc;
     144        }
     145       
     146        rc = packet_dimensions_initialize(&udp_globals.dimensions);
     147        if (rc != EOK) {
    253148                socket_ports_destroy(&udp_globals.sockets);
    254                 return ERROR_CODE;
    255         }
     149                fibril_rwlock_write_unlock(&udp_globals.lock);
     150                return rc;
     151        }
     152       
    256153        udp_globals.packet_dimension.prefix += sizeof(udp_header_t);
    257154        udp_globals.packet_dimension.content -= sizeof(udp_header_t);
    258155        udp_globals.last_used_port = UDP_FREE_PORTS_START - 1;
    259156
    260         // get configuration
    261157        udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING;
    262158        udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING;
     159
     160        // get configuration
    263161        configuration = &names[0];
    264         ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration,
    265             count, &data));
     162        rc = net_get_conf_req(udp_globals.net_phone, &configuration, count,
     163            &data);
     164        if (rc != EOK) {
     165                socket_ports_destroy(&udp_globals.sockets);
     166                fibril_rwlock_write_unlock(&udp_globals.lock);
     167                return rc;
     168        }
     169       
    266170        if (configuration) {
    267171                if (configuration[0].value)
     
    280184}
    281185
    282 int
    283 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
    284     services_t error)
     186/** Releases the packet and returns the result.
     187 *
     188 * @param[in] packet    The packet queue to be released.
     189 * @param[in] result    The result to be returned.
     190 * @return              The result parameter.
     191 */
     192static int udp_release_and_return(packet_t packet, int result)
    285193{
    286         int result;
    287 
    288         fibril_rwlock_write_lock(&udp_globals.lock);
    289         result = udp_process_packet(device_id, packet, error);
    290         if (result != EOK)
    291                 fibril_rwlock_write_unlock(&udp_globals.lock);
    292 
     194        pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    293195        return result;
    294196}
    295197
    296 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
     198/** Processes the received UDP packet queue.
     199 *
     200 * Notifies the destination socket application.
     201 * Releases the packet on error or sends an ICMP error notification.
     202 *
     203 * @param[in] device_id The receiving device identifier.
     204 * @param[in,out] packet The received packet queue.
     205 * @param[in] error     The packet error reporting service. Prefixes the
     206 *                      received packet.
     207 * @returns             EOK on success.
     208 * @returns             EINVAL if the packet is not valid.
     209 * @returns             EINVAL if the stored packet address is not the
     210 *                      an_addr_t.
     211 * @returns             EINVAL if the packet does not contain any data.
     212 * @returns             NO_DATA if the packet content is shorter than the user
     213 *                      datagram header.
     214 * @returns             ENOMEM if there is not enough memory left.
     215 * @returns             EADDRNOTAVAIL if the destination socket does not exist.
     216 * @returns             Other error codes as defined for the
     217 *                      ip_client_process_packet() function.
     218 */
     219static int
     220udp_process_packet(device_id_t device_id, packet_t packet, services_t error)
    297221{
    298         ERROR_DECLARE;
    299 
    300222        size_t length;
    301223        size_t offset;
     
    314236        struct sockaddr *dest;
    315237        packet_dimension_ref packet_dimension;
    316 
    317         if (error) {
    318                 switch (error) {
    319                 case SERVICE_ICMP:
    320                         // ignore error
    321                         // length = icmp_client_header_length(packet);
    322                         // process error
    323                         result = icmp_client_process_packet(packet, &type,
    324                             &code, NULL, NULL);
    325                         if (result < 0)
    326                                 return udp_release_and_return(packet, result);
    327                         length = (size_t) result;
    328                         if (ERROR_OCCURRED(packet_trim(packet, length, 0)))
    329                                 return udp_release_and_return(packet,
    330                                     ERROR_CODE);
    331                         break;
    332                 default:
    333                         return udp_release_and_return(packet, ENOTSUP);
    334                 }
     238        int rc;
     239
     240        switch (error) {
     241        case SERVICE_NONE:
     242                break;
     243        case SERVICE_ICMP:
     244                // ignore error
     245                // length = icmp_client_header_length(packet);
     246                // process error
     247                result = icmp_client_process_packet(packet, &type,
     248                    &code, NULL, NULL);
     249                if (result < 0)
     250                        return udp_release_and_return(packet, result);
     251                length = (size_t) result;
     252                rc = packet_trim(packet, length, 0);
     253                if (rc != EOK)
     254                        return udp_release_and_return(packet, rc);
     255                break;
     256        default:
     257                return udp_release_and_return(packet, ENOTSUP);
    335258        }
    336259
     
    348271
    349272        // trim all but UDP header
    350         if (ERROR_OCCURRED(packet_trim(packet, offset, 0)))
    351                 return udp_release_and_return(packet, ERROR_CODE);
     273        rc = packet_trim(packet, offset, 0);
     274        if (rc != EOK)
     275                return udp_release_and_return(packet, rc);
    352276
    353277        // get udp header
     
    374298
    375299        // compute header checksum if set
    376         if (header->checksum && (!error)) {
     300        if (header->checksum && !error) {
    377301                result = packet_get_addr(packet, (uint8_t **) &src,
    378302                    (uint8_t **) &dest);
    379                 if( result <= 0)
     303                if (result <= 0)
    380304                        return udp_release_and_return(packet, result);
    381 
    382                 if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP,
    383                     src, result, dest, result, total_length, &ip_header,
    384                     &length))) {
    385                         return udp_release_and_return(packet, ERROR_CODE);
     305               
     306                rc = ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest,
     307                    result, total_length, &ip_header, &length);
     308                if (rc != EOK) {
     309                        return udp_release_and_return(packet, rc);
    386310                } else {
    387311                        checksum = compute_checksum(0, ip_header, length);
     
    396320
    397321        do {
    398                 ++ fragments;
     322                fragments++;
    399323                length = packet_get_data_length(next_packet);
    400324                if (length <= 0)
     
    402326
    403327                if (total_length < length) {
    404                         if (ERROR_OCCURRED(packet_trim(next_packet, 0,
    405                             length - total_length))) {
    406                                 return udp_release_and_return(packet,
    407                                     ERROR_CODE);
    408                         }
     328                        rc = packet_trim(next_packet, 0, length - total_length);
     329                        if (rc != EOK)
     330                                return udp_release_and_return(packet, rc);
    409331
    410332                        // add partial checksum if set
     
    455377
    456378        // queue the received packet
    457         if (ERROR_OCCURRED(dyn_fifo_push(&socket->received,
    458             packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) ||
    459             ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone,
    460             &udp_globals.dimensions, device_id, &packet_dimension))) {
    461                 return udp_release_and_return(packet, ERROR_CODE);
    462         }
     379        rc = dyn_fifo_push(&socket->received, packet_get_id(packet),
     380            SOCKET_MAX_RECEIVED_SIZE);
     381        if (rc != EOK)
     382                return udp_release_and_return(packet, rc);
     383               
     384        rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
     385            &udp_globals.dimensions, device_id, &packet_dimension);
     386        if (rc != EOK)
     387                return udp_release_and_return(packet, rc);
    463388
    464389        // notify the destination socket
     
    471396}
    472397
    473 int
    474 udp_message_standalone(ipc_callid_t callid, ipc_call_t * call,
    475     ipc_call_t * answer, int * answer_count)
     398/** Processes the received UDP packet queue.
     399 *
     400 * Is used as an entry point from the underlying IP module.
     401 * Locks the global lock and calls udp_process_packet() function.
     402 *
     403 * @param[in] device_id The receiving device identifier.
     404 * @param[in,out] packet The received packet queue.
     405 * @param receiver      The target service. Ignored parameter.
     406 * @param[in] error     The packet error reporting service. Prefixes the
     407 *                      received packet.
     408 * @returns             EOK on success.
     409 * @returns             Other error codes as defined for the
     410 *                      udp_process_packet() function.
     411 */
     412static int
     413udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver,
     414    services_t error)
    476415{
    477         ERROR_DECLARE;
    478 
     416        int result;
     417
     418        fibril_rwlock_write_lock(&udp_globals.lock);
     419        result = udp_process_packet(device_id, packet, error);
     420        if (result != EOK)
     421                fibril_rwlock_write_unlock(&udp_globals.lock);
     422
     423        return result;
     424}
     425
     426/** Sends data from the socket to the remote address.
     427 *
     428 * Binds the socket to a free port if not already connected/bound.
     429 * Handles the NET_SOCKET_SENDTO message.
     430 * Supports AF_INET and AF_INET6 address families.
     431 *
     432 * @param[in,out] local_sockets The application local sockets.
     433 * @param[in] socket_id Socket identifier.
     434 * @param[in] addr      The destination address.
     435 * @param[in] addrlen   The address length.
     436 * @param[in] fragments The number of data fragments.
     437 * @param[out] data_fragment_size The data fragment size in bytes.
     438 * @param[in] flags     Various send flags.
     439 * @returns             EOK on success.
     440 * @returns             EAFNOTSUPPORT if the address family is not supported.
     441 * @returns             ENOTSOCK if the socket is not found.
     442 * @returns             EINVAL if the address is invalid.
     443 * @returns             ENOTCONN if the sending socket is not and cannot be
     444 *                      bound.
     445 * @returns             ENOMEM if there is not enough memory left.
     446 * @returns             Other error codes as defined for the
     447 *                      socket_read_packet_data() function.
     448 * @returns             Other error codes as defined for the
     449 *                      ip_client_prepare_packet() function.
     450 * @returns             Other error codes as defined for the ip_send_msg()
     451 *                      function.
     452 */
     453static int
     454udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
     455    const struct sockaddr *addr, socklen_t addrlen, int fragments,
     456    size_t *data_fragment_size, int flags)
     457{
     458        socket_core_ref socket;
    479459        packet_t packet;
    480 
    481         *answer_count = 0;
    482 
    483         switch (IPC_GET_METHOD(*call)) {
    484         case NET_TL_RECEIVED:
    485                 if (!ERROR_OCCURRED(packet_translate_remote(
    486                     udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))) {
    487                         ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call),
    488                             packet, SERVICE_UDP, IPC_GET_ERROR(call));
     460        packet_t next_packet;
     461        udp_header_ref header;
     462        int index;
     463        size_t total_length;
     464        int result;
     465        uint16_t dest_port;
     466        uint32_t checksum;
     467        void *ip_header;
     468        size_t headerlen;
     469        device_id_t device_id;
     470        packet_dimension_ref packet_dimension;
     471        int rc;
     472       
     473        rc = tl_get_address_port(addr, addrlen, &dest_port);
     474        if (rc != EOK)
     475                return rc;
     476
     477        socket = socket_cores_find(local_sockets, socket_id);
     478        if (!socket)
     479                return ENOTSOCK;
     480
     481        if ((socket->port <= 0) && udp_globals.autobinding) {
     482                // bind the socket to a random free port if not bound
     483                rc = socket_bind_free_port(&udp_globals.sockets, socket,
     484                    UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
     485                    udp_globals.last_used_port);
     486                if (rc != EOK)
     487                        return rc;
     488                // set the next port as the search starting port number
     489                udp_globals.last_used_port = socket->port;
     490        }
     491
     492        if (udp_globals.checksum_computing) {
     493                rc = ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr,
     494                    addrlen, &device_id, &ip_header, &headerlen);
     495                if (rc != EOK)
     496                        return rc;
     497                // get the device packet dimension
     498//              rc = tl_get_ip_packet_dimension(udp_globals.ip_phone,
     499//                  &udp_globals.dimensions, device_id, &packet_dimension);
     500//              if (rc != EOK)
     501//                      return rc;
     502        }
     503//      } else {
     504                // do not ask all the time
     505                rc = ip_packet_size_req(udp_globals.ip_phone, -1,
     506                    &udp_globals.packet_dimension);
     507                if (rc != EOK)
     508                        return rc;
     509                packet_dimension = &udp_globals.packet_dimension;
     510//      }
     511
     512        // read the first packet fragment
     513        result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
     514            UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
     515        if (result < 0)
     516                return result;
     517
     518        total_length = (size_t) result;
     519        if (udp_globals.checksum_computing)
     520                checksum = compute_checksum(0, packet_get_data(packet),
     521                    packet_get_data_length(packet));
     522        else
     523                checksum = 0;
     524
     525        // prefix the udp header
     526        header = PACKET_PREFIX(packet, udp_header_t);
     527        if (!header)
     528                return udp_release_and_return(packet, ENOMEM);
     529
     530        bzero(header, sizeof(*header));
     531        // read the rest of the packet fragments
     532        for (index = 1; index < fragments; index++) {
     533                result = tl_socket_read_packet_data(udp_globals.net_phone,
     534                    &next_packet, 0, packet_dimension, addr, addrlen);
     535                if (result < 0)
     536                        return udp_release_and_return(packet, result);
     537
     538                rc = pq_add(&packet, next_packet, index, 0);
     539                if (rc != EOK)
     540                        return udp_release_and_return(packet, rc);
     541
     542                total_length += (size_t) result;
     543                if (udp_globals.checksum_computing) {
     544                        checksum = compute_checksum(checksum,
     545                            packet_get_data(next_packet),
     546                            packet_get_data_length(next_packet));
    489547                }
    490                 return ERROR_CODE;
     548        }
     549
     550        // set the udp header
     551        header->source_port = htons((socket->port > 0) ? socket->port : 0);
     552        header->destination_port = htons(dest_port);
     553        header->total_length = htons(total_length + sizeof(*header));
     554        header->checksum = 0;
     555        if (udp_globals.checksum_computing) {
     556                // update the pseudo header
     557                rc = ip_client_set_pseudo_header_data_length(ip_header,
     558                    headerlen, total_length + UDP_HEADER_SIZE);
     559                if (rc != EOK) {
     560                        free(ip_header);
     561                        return udp_release_and_return(packet, rc);
     562                }
     563
     564                // finish the checksum computation
     565                checksum = compute_checksum(checksum, ip_header, headerlen);
     566                checksum = compute_checksum(checksum, (uint8_t *) header,
     567                    sizeof(*header));
     568                header->checksum =
     569                    htons(flip_checksum(compact_checksum(checksum)));
     570                free(ip_header);
     571        } else {
     572                device_id = DEVICE_INVALID_ID;
     573        }
     574
     575        // prepare the first packet fragment
     576        rc = ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0);
     577        if (rc != EOK)
     578                return udp_release_and_return(packet, rc);
     579
     580        /* Release the UDP global lock on success. */
     581        fibril_rwlock_write_unlock(&udp_globals.lock);
     582
     583        // send the packet
     584        ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
     585
     586        return EOK;
     587}
     588
     589/** Receives data to the socket.
     590 *
     591 * Handles the NET_SOCKET_RECVFROM message.
     592 * Replies the source address as well.
     593 *
     594 * @param[in] local_sockets The application local sockets.
     595 * @param[in] socket_id Socket identifier.
     596 * @param[in] flags     Various receive flags.
     597 * @param[out] addrlen  The source address length.
     598 * @returns             The number of bytes received.
     599 * @returns             ENOTSOCK if the socket is not found.
     600 * @returns             NO_DATA if there are no received packets or data.
     601 * @returns             ENOMEM if there is not enough memory left.
     602 * @returns             EINVAL if the received address is not an IP address.
     603 * @returns             Other error codes as defined for the packet_translate()
     604 *                      function.
     605 * @returns             Other error codes as defined for the data_reply()
     606 *                      function.
     607 */
     608static int
     609udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
     610    size_t *addrlen)
     611{
     612        socket_core_ref socket;
     613        int packet_id;
     614        packet_t packet;
     615        udp_header_ref header;
     616        struct sockaddr *addr;
     617        size_t length;
     618        uint8_t *data;
     619        int result;
     620        int rc;
     621
     622        // find the socket
     623        socket = socket_cores_find(local_sockets, socket_id);
     624        if (!socket)
     625                return ENOTSOCK;
     626
     627        // get the next received packet
     628        packet_id = dyn_fifo_value(&socket->received);
     629        if (packet_id < 0)
     630                return NO_DATA;
    491631       
    492         case IPC_M_CONNECT_TO_ME:
    493                 return udp_process_client_messages(callid, * call);
    494         }
    495 
    496         return ENOTSUP;
     632        rc = packet_translate_remote(udp_globals.net_phone, &packet, packet_id);
     633        if (rc != EOK) {
     634                (void) dyn_fifo_pop(&socket->received);
     635                return rc;
     636        }
     637
     638        // get udp header
     639        data = packet_get_data(packet);
     640        if (!data) {
     641                (void) dyn_fifo_pop(&socket->received);
     642                return udp_release_and_return(packet, NO_DATA);
     643        }
     644        header = (udp_header_ref) data;
     645
     646        // set the source address port
     647        result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
     648        rc = tl_set_address_port(addr, result, ntohs(header->source_port));
     649        if (rc != EOK) {
     650                (void) dyn_fifo_pop(&socket->received);
     651                return udp_release_and_return(packet, rc);
     652        }
     653        *addrlen = (size_t) result;
     654
     655        // send the source address
     656        rc = data_reply(addr, *addrlen);
     657        switch (rc) {
     658        case EOK:
     659                break;
     660        case EOVERFLOW:
     661                return rc;
     662        default:
     663                (void) dyn_fifo_pop(&socket->received);
     664                return udp_release_and_return(packet, rc);
     665        }
     666
     667        // trim the header
     668        rc = packet_trim(packet, UDP_HEADER_SIZE, 0);
     669        if (rc != EOK) {
     670                (void) dyn_fifo_pop(&socket->received);
     671                return udp_release_and_return(packet, rc);
     672        }
     673
     674        // reply the packets
     675        rc = socket_reply_packets(packet, &length);
     676        switch (rc) {
     677        case EOK:
     678                break;
     679        case EOVERFLOW:
     680                return rc;
     681        default:
     682                (void) dyn_fifo_pop(&socket->received);
     683                return udp_release_and_return(packet, rc);
     684        }
     685
     686        (void) dyn_fifo_pop(&socket->received);
     687
     688        // release the packet and return the total length
     689        return udp_release_and_return(packet, (int) length);
    497690}
    498691
    499 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
     692/** Processes the socket client messages.
     693 *
     694 * Runs until the client module disconnects.
     695 *
     696 * @param[in] callid    The message identifier.
     697 * @param[in] call      The message parameters.
     698 * @returns             EOK on success.
     699 *
     700 * @see socket.h
     701 */
     702static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call)
    500703{
    501704        int res;
     
    638841}
    639842
     843/** Processes the UDP message.
     844 *
     845 * @param[in] callid    The message identifier.
     846 * @param[in] call      The message parameters.
     847 * @param[out] answer   The message answer parameters.
     848 * @param[out] answer_count The last parameter for the actual answer in the
     849 *                      answer parameter.
     850 * @returns             EOK on success.
     851 * @returns             ENOTSUP if the message is not known.
     852 *
     853 * @see udp_interface.h
     854 * @see IS_NET_UDP_MESSAGE()
     855 */
    640856int
    641 udp_sendto_message(socket_cores_ref local_sockets, int socket_id,
    642     const struct sockaddr *addr, socklen_t addrlen, int fragments,
    643     size_t *data_fragment_size, int flags)
     857udp_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     858    ipc_call_t *answer, int *answer_count)
    644859{
    645         ERROR_DECLARE;
    646 
    647         socket_core_ref socket;
    648860        packet_t packet;
    649         packet_t next_packet;
    650         udp_header_ref header;
    651         int index;
    652         size_t total_length;
    653         int result;
    654         uint16_t dest_port;
    655         uint32_t checksum;
    656         void *ip_header;
    657         size_t headerlen;
    658         device_id_t device_id;
    659         packet_dimension_ref packet_dimension;
    660 
    661         ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &dest_port));
    662 
    663         socket = socket_cores_find(local_sockets, socket_id);
    664         if (!socket)
    665                 return ENOTSOCK;
    666 
    667         if ((socket->port <= 0) && udp_globals.autobinding) {
    668                 // bind the socket to a random free port if not bound
    669 //              do {
    670                         // try to find a free port
    671 //                      fibril_rwlock_read_unlock(&udp_globals.lock);
    672 //                      fibril_rwlock_write_lock(&udp_globals.lock);
    673                         // might be changed in the meantime
    674 //                      if (socket->port <= 0) {
    675                                 if (ERROR_OCCURRED(socket_bind_free_port(
    676                                     &udp_globals.sockets, socket,
    677                                     UDP_FREE_PORTS_START, UDP_FREE_PORTS_END,
    678                                     udp_globals.last_used_port))) {
    679 //                                      fibril_rwlock_write_unlock(
    680 //                                          &udp_globals.lock);
    681 //                                      fibril_rwlock_read_lock(
    682 //                                          &udp_globals.lock);
    683                                         return ERROR_CODE;
    684                                 }
    685                                 // set the next port as the search starting port
    686                                 // number
    687                                 udp_globals.last_used_port = socket->port;
    688 //                      }
    689 //                      fibril_rwlock_write_unlock(&udp_globals.lock);
    690 //                      fibril_rwlock_read_lock(&udp_globals.lock);
    691                         // might be changed in the meantime
    692 //              } while (socket->port <= 0);
    693         }
    694 
    695         if (udp_globals.checksum_computing) {
    696                 if (ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone,
    697                     IPPROTO_UDP, addr, addrlen, &device_id, &ip_header,
    698                     &headerlen))) {
    699                         return udp_release_and_return(packet, ERROR_CODE);
    700                 }
    701                 // get the device packet dimension
    702 //              ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone,
    703 //                  &udp_globals.dimensions, device_id, &packet_dimension));
    704         }
    705 //      } else {
    706                 // do not ask all the time
    707                 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1,
    708                     &udp_globals.packet_dimension));
    709                 packet_dimension = &udp_globals.packet_dimension;
    710 //      }
    711 
    712         // read the first packet fragment
    713         result = tl_socket_read_packet_data(udp_globals.net_phone, &packet,
    714             UDP_HEADER_SIZE, packet_dimension, addr, addrlen);
    715         if (result < 0)
    716                 return result;
    717 
    718         total_length = (size_t) result;
    719         if (udp_globals.checksum_computing)
    720                 checksum = compute_checksum(0, packet_get_data(packet),
    721                     packet_get_data_length(packet));
    722         else
    723                 checksum = 0;
    724 
    725         // prefix the udp header
    726         header = PACKET_PREFIX(packet, udp_header_t);
    727         if(! header)
    728                 return udp_release_and_return(packet, ENOMEM);
    729 
    730         bzero(header, sizeof(*header));
    731         // read the rest of the packet fragments
    732         for (index = 1; index < fragments; ++ index) {
    733                 result = tl_socket_read_packet_data(udp_globals.net_phone,
    734                     &next_packet, 0, packet_dimension, addr, addrlen);
    735                 if (result < 0)
    736                         return udp_release_and_return(packet, result);
    737 
    738                 if (ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0)))
    739                         return udp_release_and_return(packet, ERROR_CODE);
    740 
    741                 total_length += (size_t) result;
    742                 if (udp_globals.checksum_computing) {
    743                         checksum = compute_checksum(checksum,
    744                             packet_get_data(next_packet),
    745                             packet_get_data_length(next_packet));
    746                 }
    747         }
    748 
    749         // set the udp header
    750         header->source_port = htons((socket->port > 0) ? socket->port : 0);
    751         header->destination_port = htons(dest_port);
    752         header->total_length = htons(total_length + sizeof(*header));
    753         header->checksum = 0;
    754         if (udp_globals.checksum_computing) {
    755                 // update the pseudo header
    756                 if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(
    757                     ip_header, headerlen, total_length + UDP_HEADER_SIZE))) {
    758                         free(ip_header);
    759                         return udp_release_and_return(packet, ERROR_CODE);
    760                 }
    761 
    762                 // finish the checksum computation
    763                 checksum = compute_checksum(checksum, ip_header, headerlen);
    764                 checksum = compute_checksum(checksum, (uint8_t *) header,
    765                     sizeof(*header));
    766                 header->checksum =
    767                     htons(flip_checksum(compact_checksum(checksum)));
    768                 free(ip_header);
    769         } else {
    770                 device_id = DEVICE_INVALID_ID;
    771         }
    772 
    773         // prepare the first packet fragment
    774         if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0,
    775             0, 0))) {
    776                 return udp_release_and_return(packet, ERROR_CODE);
    777         }
    778 
    779         // send the packet
    780         fibril_rwlock_write_unlock(&udp_globals.lock);
    781         ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0);
    782 
    783         return EOK;
     861        int rc;
     862
     863        *answer_count = 0;
     864
     865        switch (IPC_GET_METHOD(*call)) {
     866        case NET_TL_RECEIVED:
     867                rc = packet_translate_remote(udp_globals.net_phone, &packet,
     868                    IPC_GET_PACKET(call));
     869                if (rc != EOK)
     870                        return rc;
     871                return udp_received_msg(IPC_GET_DEVICE(call), packet,
     872                    SERVICE_UDP, IPC_GET_ERROR(call));
     873        case IPC_M_CONNECT_TO_ME:
     874                return udp_process_client_messages(callid, * call);
     875        }
     876
     877        return ENOTSUP;
    784878}
    785879
    786 int
    787 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,
    788     size_t *addrlen)
    789 {
    790         ERROR_DECLARE;
    791 
    792         socket_core_ref socket;
    793         int packet_id;
    794         packet_t packet;
    795         udp_header_ref header;
    796         struct sockaddr *addr;
    797         size_t length;
    798         uint8_t *data;
    799         int result;
    800 
    801         // find the socket
    802         socket = socket_cores_find(local_sockets, socket_id);
    803         if (!socket)
    804                 return ENOTSOCK;
    805 
    806         // get the next received packet
    807         packet_id = dyn_fifo_value(&socket->received);
    808         if (packet_id < 0)
    809                 return NO_DATA;
    810 
    811         ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet,
    812             packet_id));
    813 
    814         // get udp header
    815         data = packet_get_data(packet);
    816         if (!data) {
    817                 pq_release_remote(udp_globals.net_phone, packet_id);
    818                 return NO_DATA;
    819         }
    820         header = (udp_header_ref) data;
    821 
    822         // set the source address port
    823         result = packet_get_addr(packet, (uint8_t **) &addr, NULL);
    824         if (ERROR_OCCURRED(tl_set_address_port(addr, result,
    825             ntohs(header->source_port)))) {
    826                 pq_release_remote(udp_globals.net_phone, packet_id);
    827                 return ERROR_CODE;
    828         }
    829         *addrlen = (size_t) result;
    830 
    831         // send the source address
    832         ERROR_PROPAGATE(data_reply(addr, * addrlen));
    833 
    834         // trim the header
    835         ERROR_PROPAGATE(packet_trim(packet, UDP_HEADER_SIZE, 0));
    836 
    837         // reply the packets
    838         ERROR_PROPAGATE(socket_reply_packets(packet, &length));
    839 
    840         // release the packet
    841         dyn_fifo_pop(&socket->received);
    842         pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    843 
    844         // return the total length
    845         return (int) length;
    846 }
    847 
    848 int udp_release_and_return(packet_t packet, int result)
    849 {
    850         pq_release_remote(udp_globals.net_phone, packet_get_id(packet));
    851         return result;
    852 }
    853 
    854880/** Default thread for new connections.
    855881 *
    856  *  @param[in] iid      The initial message identifier.
    857  *  @param[in] icall    The initial message call structure.
    858  *
     882 * @param[in] iid       The initial message identifier.
     883 * @param[in] icall     The initial message call structure.
    859884 */
    860885static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall)
     
    882907               
    883908                /*
    884                  * End if said to either by the message or the processing result
     909                 * End if told to either by the message or the processing
     910                 * result.
    885911                 */
    886912                if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) ||
     
    895921/** Starts the module.
    896922 *
    897  *  @param argc         The count of the command line arguments. Ignored
    898  *                      parameter.
    899  *  @param argv         The command line parameters. Ignored parameter.
    900  *
    901  *  @returns            EOK on success.
    902  *  @returns            Other error codes as defined for each specific module
     923 * @returns             EOK on success.
     924 * @returns             Other error codes as defined for each specific module
    903925 *                      start function.
    904926 */
    905927int main(int argc, char *argv[])
    906928{
    907         ERROR_DECLARE;
     929        int rc;
    908930       
    909931        /* Start the module */
    910         if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection)))
    911                 return ERROR_CODE;
    912        
    913         return EOK;
     932        rc = tl_module_start_standalone(tl_client_connection);
     933        return rc;
    914934}
    915935
  • uspace/srv/net/tl/udp/udp.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  UDP module.
     34 * UDP module.
    3535 */
    3636
    37 #ifndef __NET_UDP_H__
    38 #define __NET_UDP_H__
     37#ifndef NET_UDP_H_
     38#define NET_UDP_H_
    3939
    4040#include <fibril_synch.h>
     
    4343
    4444/** Type definition of the UDP global data.
    45  *  @see udp_globals
     45 * @see udp_globals
    4646 */
    47 typedef struct udp_globals      udp_globals_t;
     47typedef struct udp_globals udp_globals_t;
    4848
    49 /** UDP global data.
    50  */
    51 struct  udp_globals{
    52         /** Networking module phone.
    53          */
     49/** UDP global data. */
     50struct udp_globals {
     51        /** Networking module phone. */
    5452        int net_phone;
    55         /** IP module phone.
    56          */
     53        /** IP module phone. */
    5754        int ip_phone;
    58         /** ICMP module phone.
    59          */
     55        /** ICMP module phone. */
    6056        int icmp_phone;
    61         /** Packet dimension.
    62          */
     57        /** Packet dimension. */
    6358        packet_dimension_t packet_dimension;
    64         /** Indicates whether UDP checksum computing is enabled.
    65          */
     59        /** Indicates whether UDP checksum computing is enabled. */
    6660        int checksum_computing;
    67         /** Indicates whether UDP autobnding on send is enabled.
    68          */
     61        /** Indicates whether UDP autobnding on send is enabled. */
    6962        int autobinding;
    70         /** Last used free port.
    71          */
     63        /** Last used free port. */
    7264        int last_used_port;
    73         /** Active sockets.
    74          */
     65        /** Active sockets. */
    7566        socket_ports_t sockets;
    76         /** Device packet dimensions.
    77          */
     67        /** Device packet dimensions. */
    7868        packet_dimensions_t dimensions;
    79         /** Safety lock.
    80          */
     69        /** Safety lock. */
    8170        fibril_rwlock_t lock;
    8271};
     
    8675/** @}
    8776 */
    88 
  • uspace/srv/net/tl/udp/udp_header.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  UDP header definition.
    35  *  Based on the RFC~768.
     34 * UDP header definition.
     35 * Based on the RFC 768.
    3636 */
    3737
    38 #ifndef __NET_UDP_HEADER_H__
    39 #define __NET_UDP_HEADER_H__
     38#ifndef NET_UDP_HEADER_H_
     39#define NET_UDP_HEADER_H_
    4040
    4141#include <sys/types.h>
    4242
    43 /** UDP header size in bytes.
    44  */
    45 #define UDP_HEADER_SIZE                 sizeof(udp_header_t)
     43/** UDP header size in bytes. */
     44#define UDP_HEADER_SIZE         sizeof(udp_header_t)
    4645
    4746/** Type definition of the user datagram header.
    48  *  @see udp_header
     47 * @see udp_header
    4948 */
    50 typedef struct udp_header       udp_header_t;
     49typedef struct udp_header udp_header_t;
    5150
    5251/** Type definition of the user datagram header pointer.
    53  *  @see udp_header
     52 * @see udp_header
    5453 */
    55 typedef udp_header_t *          udp_header_ref;
     54typedef udp_header_t *udp_header_ref;
    5655
    57 /** User datagram header.
    58  */
    59 struct udp_header{
    60         /** Source Port is an optional field, when meaningful, it indicates the port of the sending process, and may be assumed to be the port to which a reply should be addressed in the absence of any other information.
    61          *  If not used, a value of zero is inserted.
    62          */
     56/** User datagram header. */
     57struct udp_header {
    6358        uint16_t source_port;
    64         /** Destination port has a meaning within the context of a particular internet destination address.
    65          */
    6659        uint16_t destination_port;
    67         /** Length is the length in octets of this user datagram including this header and the data.
    68          *  This means the minimum value of the length is eight.
    69          */
    7060        uint16_t total_length;
    71         /** Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.
    72          *  The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length.
    73          *  This information gives protection against misrouted datagrams.
    74          *  If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).
    75          *  An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care).
    76          */
    7761        uint16_t checksum;
    7862} __attribute__ ((packed));
  • uspace/srv/net/tl/udp/udp_module.c

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  UDP standalone module implementation.
    35  *  Contains skeleton module functions mapping.
    36  *  The functions are used by the module skeleton as module specific entry points.
    37  *  @see module.c
     34 * UDP standalone module implementation.
     35 * Contains skeleton module functions mapping.
     36 * The functions are used by the module skeleton as module specific entry
     37 * points.
     38 * @see module.c
    3839 */
     40
     41#include "udp.h"
     42#include "udp_module.h"
    3943
    4044#include <async.h>
    4145#include <stdio.h>
    42 #include <err.h>
     46#include <errno.h>
    4347#include <ipc/ipc.h>
    4448#include <ipc/services.h>
     
    4650#include <net/modules.h>
    4751#include <net/packet.h>
     52
    4853#include <net_interface.h>
    4954#include <tl_local.h>
    5055
    51 #include "udp.h"
    52 #include "udp_module.h"
     56/** UDP module global data. */
     57extern udp_globals_t udp_globals;
    5358
    54 /** UDP module global data.
    55  */
    56 extern udp_globals_t    udp_globals;
    57 
    58 /** Starts the UDP module.
    59  *  Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.
    60  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    61  *  @returns EOK on successful module termination.
    62  *  @returns Other error codes as defined for the udp_initialize() function.
    63  *  @returns Other error codes as defined for the REGISTER_ME() macro function.
    64  */
    65 int tl_module_start_standalone(async_client_conn_t client_connection){
    66         ERROR_DECLARE;
    67 
     59int tl_module_start_standalone(async_client_conn_t client_connection)
     60{
    6861        ipcarg_t phonehash;
     62        int rc;
    6963
    7064        async_set_client_connection(client_connection);
    7165        udp_globals.net_phone = net_connect_module();
    72         if(udp_globals.net_phone < 0){
     66        if (udp_globals.net_phone < 0)
    7367                return udp_globals.net_phone;
    74         }
    75         ERROR_PROPAGATE(pm_init());
    76         if(ERROR_OCCURRED(udp_initialize(client_connection))
    77                 || ERROR_OCCURRED(REGISTER_ME(SERVICE_UDP, &phonehash))){
    78                 pm_destroy();
    79                 return ERROR_CODE;
    80         }
     68       
     69        rc = pm_init();
     70        if (rc != EOK)
     71                return EOK;
     72               
     73        rc = udp_initialize(client_connection);
     74        if (rc != EOK)
     75                goto out;
     76       
     77        rc = REGISTER_ME(SERVICE_UDP, &phonehash);
     78        if (rc != EOK)
     79                goto out;
    8180
    8281        async_manager();
    8382
     83out:
    8484        pm_destroy();
    85         return EOK;
     85        return rc;
    8686}
    8787
    88 /** Processes the UDP message.
    89  *  @param[in] callid The message identifier.
    90  *  @param[in] call The message parameters.
    91  *  @param[out] answer The message answer parameters.
    92  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    93  *  @returns EOK on success.
    94  *  @returns Other error codes as defined for the udp_message() function.
    95  */
    96 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){
     88int
     89tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call,
     90    ipc_call_t *answer, int *answer_count)
     91{
    9792        return udp_message_standalone(callid, call, answer, answer_count);
    9893}
  • uspace/srv/net/tl/udp/udp_module.h

    rd70a463 rb40bfac  
    2828
    2929/** @addtogroup udp
    30  *  @{
     30 * @{
    3131 */
    3232
    3333/** @file
    34  *  UDP module functions.
    35  *  The functions are used as UDP module entry points.
     34 * UDP module functions.
     35 * The functions are used as UDP module entry points.
    3636 */
    3737
    38 #ifndef __NET_UDP_MODULE_H__
    39 #define __NET_UDP_MODULE_H__
     38#ifndef NET_UDP_MODULE_H_
     39#define NET_UDP_MODULE_H_
    4040
    4141#include <async.h>
    4242#include <ipc/ipc.h>
    4343
    44 /** Initializes the UDP module.
    45  *  @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.
    46  *  @returns EOK on success.
    47  *  @returns ENOMEM if there is not enough memory left.
    48  */
    49 extern int udp_initialize(async_client_conn_t client_connection);
    50 
    51 /** Processes the UDP message.
    52  *  @param[in] callid The message identifier.
    53  *  @param[in] call The message parameters.
    54  *  @param[out] answer The message answer parameters.
    55  *  @param[out] answer_count The last parameter for the actual answer in the answer parameter.
    56  *  @returns EOK on success.
    57  *  @returns ENOTSUP if the message is not known.
    58  *  @see udp_interface.h
    59  *  @see IS_NET_UDP_MESSAGE()
    60  */
    61 extern int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);
     44extern int udp_initialize(async_client_conn_t);
     45extern int udp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *,
     46    int *);
    6247
    6348#endif
  • uspace/srv/taskmon/taskmon.c

    rd70a463 rb40bfac  
    5050static void fault_event(ipc_callid_t callid, ipc_call_t *call)
    5151{
    52         const char *argv[6];
    5352        const char *fname;
    54         char *dump_fname;
    5553        char *s_taskid;
    56         const char **s;
     54        int rc;
    5755
    5856        task_id_t taskid;
     
    6765        }
    6866
     67        printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread);
     68
     69        fname = "/app/taskdump";
     70
     71#ifdef CONFIG_WRITE_CORE_FILES
     72        char *dump_fname;
     73
    6974        if (asprintf(&dump_fname, "/data/core%" PRIuTASKID, taskid) < 0) {
    7075                printf("Memory allocation failed.\n");
     
    7277        }
    7378
    74         printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread);
    75 
    76 #ifdef CONFIG_WRITE_CORE_FILES
    77         argv[0] = "/app/taskdump";
    78         argv[1] = "-c";
    79         argv[2] = dump_fname;
    80         argv[3] = "-t";
    81         argv[4] = s_taskid;
    82         argv[5] = NULL;
     79        printf(NAME ": Executing %s -c %s -t %s\n", dump_fname, s_taskid);
     80        rc = task_spawnl(NULL, fname, fname, "-c", dump_fname, "-t", s_taskid,
     81            NULL);
    8382#else
    84         argv[0] = "/app/taskdump";
    85         argv[1] = "-t";
    86         argv[2] = s_taskid;
    87         argv[3] = NULL;
     83        printf(NAME ": Executing %s -t %s\n", s_taskid);
     84        rc = task_spawnl(NULL, fname, fname, "-t", s_taskid, NULL);
    8885#endif
    89         fname = argv[0];
    90 
    91         printf(NAME ": Executing");
    92        
    93         s = argv;
    94         while (*s != NULL) {
    95                 printf(" %s", *s);
    96                 ++s;
     86        if (rc != EOK) {
     87                printf("%s: Error spawning %s (%s).\n", NAME, fname,
     88                    str_error(rc));
    9789        }
    98         putchar('\n');
    99        
    100         int err;
    101         if (!task_spawn(fname, argv, &err))
    102                 printf("%s: Error spawning %s (%s).\n", NAME, fname,
    103                     str_error(err));
    10490}
    10591
Note: See TracChangeset for help on using the changeset viewer.