Changeset 0c37135 in mainline for uspace


Ignore:
Timestamp:
2012-04-18T07:32:58Z (14 years ago)
Author:
Frantisek Princ <frantisek.princ@…>
Branches:
lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
Children:
5f67cd61
Parents:
3d93289a (diff), 63920b0 (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 with mainline

Location:
uspace
Files:
46 added
74 deleted
26 edited
46 moved

Legend:

Unmodified
Added
Removed
  • uspace/Makefile

    r3d93289a r0c37135  
    4242        app/getterm \
    4343        app/init \
     44        app/inetcfg \
    4445        app/kill \
    4546        app/killall \
     
    7576        srv/devman \
    7677        srv/loader \
     78        srv/net/ethip \
     79        srv/net/inet \
     80        srv/net/tcp \
     81        srv/net/udp \
    7782        srv/ns \
    7883        srv/taskmon \
     
    98103        srv/hid/remcons \
    99104        srv/hw/char/s3c24xx_uart \
    100         srv/net/il/arp \
    101         srv/net/il/ip \
    102         srv/net/tl/icmp \
    103         srv/net/tl/udp \
    104         srv/net/tl/tcp \
    105         srv/net/nil/eth \
    106         srv/net/nil/nildummy \
    107         srv/net/net \
    108105        drv/infrastructure/root \
    109106        drv/infrastructure/rootvirt \
  • uspace/app/inetcfg/Makefile

    r3d93289a r0c37135  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2012 Jiri Svoboda
    43# All rights reserved.
    54#
     
    2827#
    2928
    30 USPACE_PREFIX = ../../../..
    31 LIBS = $(LIBNET_PREFIX)/libnet.a
    32 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
    33 BINARY = ip
     29USPACE_PREFIX = ../..
     30BINARY = inetcfg
    3431
    3532SOURCES = \
    36         ip.c
     33        inetcfg.c
    3734
    3835include $(USPACE_PREFIX)/Makefile.common
  • uspace/app/init/init.c

    r3d93289a r0c37135  
    305305        srv_start("/srv/s3c24ts");
    306306       
    307         spawn("/srv/net");
     307        spawn("/srv/ethip");
     308        spawn("/srv/inet");
     309        spawn("/srv/tcp");
     310        spawn("/srv/udp");
    308311       
    309312        spawn("/srv/fb");
  • uspace/app/netecho/netecho.c

    r3d93289a r0c37135  
    373373                address_in.sin_family = AF_INET;
    374374                address_in.sin_port = htons(port);
     375                address_in.sin_addr.s_addr = INADDR_ANY;
    375376                address = (struct sockaddr *) &address_in;
    376377                addrlen = sizeof(address_in);
  • uspace/app/netecho/print_error.c

    r3d93289a r0c37135  
    4040#include <errno.h>
    4141
    42 #include <net/icmp_codes.h>
    43 
    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  */
    51 void 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         }
    99 
    100         if (suffix)
    101                 fprintf(output, "%s", suffix);
    102 }
    103 
    10442/** Prints the error description.
    10543 *
    106  * Supports ICMP and socket error codes.
     44 * Supports socket error codes.
    10745 *
    10846 * @param[in] output The description output stream. May be NULL.
     
    11351void print_error(FILE *output, int error_code, const char *prefix, const char *suffix)
    11452{
    115         if (IS_ICMP_ERROR(error_code))
    116                 icmp_print_error(output, error_code, prefix, suffix);
    117         else if(IS_SOCKET_ERROR(error_code))
     53        if(IS_SOCKET_ERROR(error_code))
    11854                socket_print_error(output, error_code, prefix, suffix);
    11955}
  • uspace/app/ping/Makefile

    r3d93289a r0c37135  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2012 Jiri Svoboda
    43# All rights reserved.
    54#
     
    2928
    3029USPACE_PREFIX = ../..
    31 LIBS =
    32 EXTRA_CFLAGS =
    3330BINARY = ping
    3431
    3532SOURCES = \
    36         ping.c \
    37         print_error.c
     33        ping.c
    3834
    3935include $(USPACE_PREFIX)/Makefile.common
  • uspace/app/ping/ping.c

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * Packet Internet Network Grouper.
     32/** @file ICMP echo utility.
    3533 */
    3634
    3735#include <async.h>
     36#include <bool.h>
     37#include <errno.h>
     38#include <fibril_synch.h>
     39#include <inet/inetping.h>
     40#include <io/console.h>
    3841#include <stdio.h>
    39 #include <str.h>
    40 #include <task.h>
    41 #include <time.h>
    42 #include <ipc/services.h>
    43 #include <str_error.h>
    44 #include <errno.h>
    45 #include <arg_parse.h>
    46 
    47 #include <net/icmp_api.h>
    48 #include <net/in.h>
    49 #include <net/in6.h>
    50 #include <net/inet.h>
    51 #include <net/socket_parse.h>
    52 #include <net/ip_codes.h>
    53 
    54 #include "print_error.h"
    55 
    56 #define NAME  "ping"
    57 
    58 #define CL_OK           0
    59 #define CL_USAGE        -1
    60 #define CL_MISSING      -2
    61 #define CL_INVALID      -3
    62 #define CL_UNSUPPORTED  -4
    63 #define CL_ERROR        -5
    64 
    65 /** Ping configuration
    66  *
    67  */
    68 typedef struct {
    69         bool verbose;               /**< Verbose printouts. */
    70         size_t size;                /**< Outgoing packet size. */
    71         unsigned int count;         /**< Number of packets to send. */
    72         suseconds_t timeout;        /**< Reply wait timeout. */
    73         int af;                     /**< Address family. */
    74         ip_tos_t tos;               /**< Type of service. */
    75         ip_ttl_t ttl;               /**< Time-to-live. */
    76         bool fragments;             /**< Fragmentation. */
    77        
    78         char *dest_addr;            /**< Destination address. */
    79         struct sockaddr_in dest;    /**< IPv4 destionation. */
    80         struct sockaddr_in6 dest6;  /**< IPv6 destionation. */
    81        
    82         struct sockaddr *dest_raw;  /**< Raw destination address. */
    83         socklen_t dest_len;         /**< Raw destination address length. */
    84        
    85         /** Converted address string. */
    86         char dest_str[INET6_ADDRSTRLEN];
    87 } ping_config_t;
    88 
    89 
    90 static void usage(void)
    91 {
    92         printf(
    93             "Usage: ping [-c count] [-s size] [-W timeout] [-f family] [-t ttl]\n" \
    94             "            [-Q tos] [--dont_fragment] destination\n" \
    95             "\n" \
    96             "Options:\n" \
    97             "\t-c count\n" \
    98             "\t--count=count\n" \
    99             "\t\tNumber of outgoing packets (default: 4)\n" \
    100             "\n" \
    101             "\t-s size\n" \
    102             "\t--size=bytes\n" \
    103             "\t\tOutgoing packet size (default: 56 bytes)\n" \
    104             "\n" \
    105             "\t-W timeout\n" \
    106             "\t--timeout=ms\n" \
    107             "\t\tReply wait timeout (default: 3000 ms)\n" \
    108             "\n" \
    109             "\t-f family\n" \
    110             "\t--family=family\n" \
    111             "\t\tDestination address family, AF_INET or AF_INET6 (default: AF_INET)\n" \
    112             "\n" \
    113             "\t-t ttl\n" \
    114             "\t--ttl=ttl\n" \
    115             "\t\tOutgoing packet time-to-live (default: 0)\n" \
    116             "\n" \
    117             "\t-Q tos\n" \
    118             "\t--tos=tos\n" \
    119             "\t\tOutgoing packet type of service (default: 0)\n" \
    120             "\n" \
    121             "\t--dont_fragment\n" \
    122             "\t\tDisable packet fragmentation (default: enabled)\n" \
    123             "\n" \
    124             "\t-v\n" \
    125             "\t--verbose\n" \
    126             "\t\tVerbose operation\n" \
    127             "\n" \
    128             "\t-h\n" \
    129             "\t--help\n" \
    130             "\t\tPrint this usage information\n"
    131         );
    132 }
    133 
    134 static int args_parse(int argc, char *argv[], ping_config_t *config)
    135 {
    136         if (argc < 2)
    137                 return CL_USAGE;
    138        
     42#include <stdlib.h>
     43#include <sys/types.h>
     44
     45#define NAME "ping"
     46
     47/** Delay between subsequent ping requests in microseconds */
     48#define PING_DELAY (1000 * 1000)
     49
     50/** Ping request timeout in microseconds */
     51#define PING_TIMEOUT (1000 * 1000)
     52
     53static int ping_ev_recv(inetping_sdu_t *);
     54
     55static bool done = false;
     56static FIBRIL_CONDVAR_INITIALIZE(done_cv);
     57static FIBRIL_MUTEX_INITIALIZE(done_lock);
     58
     59static inetping_ev_ops_t ev_ops = {
     60        .recv = ping_ev_recv
     61};
     62
     63static inet_addr_t src_addr;
     64static inet_addr_t dest_addr;
     65
     66static bool ping_repeat = false;
     67
     68static void print_syntax(void)
     69{
     70        printf("syntax: " NAME " [-r] <addr>\n");
     71}
     72
     73static int addr_parse(const char *text, inet_addr_t *addr)
     74{
     75        unsigned long a[4];
     76        char *cp = (char *)text;
    13977        int i;
    140         int ret;
    141        
    142         for (i = 1; i < argc; i++) {
    143                
    144                 /* Not an option */
    145                 if (argv[i][0] != '-')
     78
     79        for (i = 0; i < 3; i++) {
     80                a[i] = strtoul(cp, &cp, 10);
     81                if (*cp != '.')
     82                        return EINVAL;
     83                ++cp;
     84        }
     85
     86        a[3] = strtoul(cp, &cp, 10);
     87        if (*cp != '\0')
     88                return EINVAL;
     89
     90        addr->ipv4 = 0;
     91        for (i = 0; i < 4; i++) {
     92                if (a[i] > 255)
     93                        return EINVAL;
     94                addr->ipv4 = (addr->ipv4 << 8) | a[i];
     95        }
     96
     97        return EOK;
     98}
     99
     100static int addr_format(inet_addr_t *addr, char **bufp)
     101{
     102        int rc;
     103
     104        rc = asprintf(bufp, "%d.%d.%d.%d", addr->ipv4 >> 24,
     105            (addr->ipv4 >> 16) & 0xff, (addr->ipv4 >> 8) & 0xff,
     106            addr->ipv4 & 0xff);
     107
     108        if (rc < 0)
     109                return ENOMEM;
     110
     111        return EOK;
     112}
     113
     114static void ping_signal_done(void)
     115{
     116        fibril_mutex_lock(&done_lock);
     117        done = true;
     118        fibril_mutex_unlock(&done_lock);
     119        fibril_condvar_broadcast(&done_cv);
     120}
     121
     122static int ping_ev_recv(inetping_sdu_t *sdu)
     123{
     124        char *asrc, *adest;
     125        int rc;
     126
     127        rc = addr_format(&sdu->src, &asrc);
     128        if (rc != EOK)
     129                return ENOMEM;
     130
     131        rc = addr_format(&sdu->dest, &adest);
     132        if (rc != EOK) {
     133                free(asrc);
     134                return ENOMEM;
     135        }
     136        printf("Received ICMP echo reply: from %s to %s, seq. no %u, "
     137            "payload size %zu\n", asrc, adest, sdu->seq_no, sdu->size);
     138
     139        if (!ping_repeat) {
     140                ping_signal_done();
     141        }
     142
     143        free(asrc);
     144        free(adest);
     145        return EOK;
     146}
     147
     148static int ping_send(uint16_t seq_no)
     149{
     150        inetping_sdu_t sdu;
     151        int rc;
     152
     153        sdu.src = src_addr;
     154        sdu.dest = dest_addr;
     155        sdu.seq_no = seq_no;
     156        sdu.data = (void *) "foo";
     157        sdu.size = 3;
     158
     159        rc = inetping_send(&sdu);
     160        if (rc != EOK) {
     161                printf(NAME ": Failed sending echo request (%d).\n", rc);
     162                return rc;
     163        }
     164
     165        return EOK;
     166}
     167
     168static int transmit_fibril(void *arg)
     169{
     170        uint16_t seq_no = 0;
     171
     172        while (true) {
     173                fibril_mutex_lock(&done_lock);
     174                if (done) {
     175                        fibril_mutex_unlock(&done_lock);
     176                        return 0;
     177                }
     178                fibril_mutex_unlock(&done_lock);
     179
     180                (void) ping_send(++seq_no);
     181                async_usleep(PING_DELAY);
     182        }
     183
     184        return 0;
     185}
     186
     187static int input_fibril(void *arg)
     188{
     189        console_ctrl_t *con;
     190        kbd_event_t ev;
     191
     192        con = console_init(stdin, stdout);
     193        printf("[Press Ctrl-Q to quit]\n");
     194
     195        while (true) {
     196                if (!console_get_kbd_event(con, &ev))
    146197                        break;
    147                
    148                 /* Options terminator */
    149                 if (str_cmp(argv[i], "--") == 0) {
    150                         i++;
    151                         break;
    152                 }
    153                
    154                 int off;
    155                
    156                 /* Usage */
    157                 if ((off = arg_parse_short_long(argv[i], "-h", "--help")) != -1)
    158                         return CL_USAGE;
    159                
    160                 /* Verbose */
    161                 if ((off = arg_parse_short_long(argv[i], "-v", "--verbose")) != -1) {
    162                         config->verbose = true;
    163                         continue;
    164                 }
    165                
    166                 /* Don't fragment */
    167                 if (str_cmp(argv[i], "--dont_fragment") == 0) {
    168                         config->fragments = false;
    169                         continue;
    170                 }
    171                
    172                 /* Count */
    173                 if ((off = arg_parse_short_long(argv[i], "-c", "--count=")) != -1) {
    174                         int tmp;
    175                         ret = arg_parse_int(argc, argv, &i, &tmp, off);
    176                        
    177                         if ((ret != EOK) || (tmp < 0))
    178                                 return i;
    179                        
    180                         config->count = (unsigned int) tmp;
    181                         continue;
    182                 }
    183                
    184                 /* Outgoing packet size */
    185                 if ((off = arg_parse_short_long(argv[i], "-s", "--size=")) != -1) {
    186                         int tmp;
    187                         ret = arg_parse_int(argc, argv, &i, &tmp, off);
    188                        
    189                         if ((ret != EOK) || (tmp < 0))
    190                                 return i;
    191                        
    192                         config->size = (size_t) tmp;
    193                         continue;
    194                 }
    195                
    196                 /* Reply wait timeout */
    197                 if ((off = arg_parse_short_long(argv[i], "-W", "--timeout=")) != -1) {
    198                         int tmp;
    199                         ret = arg_parse_int(argc, argv, &i, &tmp, off);
    200                        
    201                         if ((ret != EOK) || (tmp < 0))
    202                                 return i;
    203                        
    204                         config->timeout = (suseconds_t) tmp;
    205                         continue;
    206                 }
    207                
    208                 /* Address family */
    209                 if ((off = arg_parse_short_long(argv[i], "-f", "--family=")) != -1) {
    210                         ret = arg_parse_name_int(argc, argv, &i, &config->af, off,
    211                             socket_parse_address_family);
    212                        
    213                         if (ret != EOK)
    214                                 return i;
    215                        
    216                         continue;
    217                 }
    218                
    219                 /* Type of service */
    220                 if ((off = arg_parse_short_long(argv[i], "-Q", "--tos=")) != -1) {
    221                         int tmp;
    222                         ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
    223                             socket_parse_address_family);
    224                        
    225                         if ((ret != EOK) || (tmp < 0))
    226                                 return i;
    227                        
    228                         config->tos = (ip_tos_t) tmp;
    229                         continue;
    230                 }
    231                
    232                 /* Time to live */
    233                 if ((off = arg_parse_short_long(argv[i], "-t", "--ttl=")) != -1) {
    234                         int tmp;
    235                         ret = arg_parse_name_int(argc, argv, &i, &tmp, off,
    236                             socket_parse_address_family);
    237                        
    238                         if ((ret != EOK) || (tmp < 0))
    239                                 return i;
    240                        
    241                         config->ttl = (ip_ttl_t) tmp;
    242                         continue;
    243                 }
    244         }
    245        
    246         if (i >= argc)
    247                 return CL_MISSING;
    248        
    249         config->dest_addr = argv[i];
    250        
    251         /* Resolve destionation address */
    252         switch (config->af) {
    253         case AF_INET:
    254                 config->dest_raw = (struct sockaddr *) &config->dest;
    255                 config->dest_len = sizeof(config->dest);
    256                 config->dest.sin_family = config->af;
    257                 ret = inet_pton(config->af, config->dest_addr,
    258                     (uint8_t *) &config->dest.sin_addr.s_addr);
    259                 break;
    260         case AF_INET6:
    261                 config->dest_raw = (struct sockaddr *) &config->dest6;
    262                 config->dest_len = sizeof(config->dest6);
    263                 config->dest6.sin6_family = config->af;
    264                 ret = inet_pton(config->af, config->dest_addr,
    265                     (uint8_t *) &config->dest6.sin6_addr.s6_addr);
    266                 break;
    267         default:
    268                 return CL_UNSUPPORTED;
    269         }
    270        
    271         if (ret != EOK)
    272                 return CL_INVALID;
    273        
    274         /* Convert destination address back to string */
    275         switch (config->af) {
    276         case AF_INET:
    277                 ret = inet_ntop(config->af,
    278                     (uint8_t *) &config->dest.sin_addr.s_addr,
    279                     config->dest_str, sizeof(config->dest_str));
    280                 break;
    281         case AF_INET6:
    282                 ret = inet_ntop(config->af,
    283                     (uint8_t *) &config->dest6.sin6_addr.s6_addr,
    284                     config->dest_str, sizeof(config->dest_str));
    285                 break;
    286         default:
    287                 return CL_UNSUPPORTED;
    288         }
    289        
    290         if (ret != EOK)
    291                 return CL_ERROR;
    292        
    293         return CL_OK;
     198
     199                if (ev.type == KEY_PRESS && (ev.mods & (KM_ALT | KM_SHIFT)) ==
     200                    0 && (ev.mods & KM_CTRL) != 0) {
     201                        /* Ctrl+key */
     202                        if (ev.key == KC_Q) {
     203                                ping_signal_done();
     204                                return 0;
     205                        }
     206                }
     207        }
     208
     209        return 0;
    294210}
    295211
    296212int main(int argc, char *argv[])
    297213{
    298         ping_config_t config;
    299        
    300         /* Default configuration */
    301         config.verbose = false;
    302         config.size = 56;
    303         config.count = 4;
    304         config.timeout = 3000;
    305         config.af = AF_INET;
    306         config.tos = 0;
    307         config.ttl = 0;
    308         config.fragments = true;
    309        
    310         int ret = args_parse(argc, argv, &config);
    311        
    312         switch (ret) {
    313         case CL_OK:
    314                 break;
    315         case CL_USAGE:
    316                 usage();
    317                 return 0;
    318         case CL_MISSING:
    319                 fprintf(stderr, "%s: Destination address missing\n", NAME);
    320                 return 1;
    321         case CL_INVALID:
    322                 fprintf(stderr, "%s: Destination address '%s' invalid or malformed\n",
    323                     NAME, config.dest_addr);
    324                 return 2;
    325         case CL_UNSUPPORTED:
    326                 fprintf(stderr, "%s: Destination address '%s' unsupported\n",
    327                     NAME, config.dest_addr);
    328                 return 3;
    329         case CL_ERROR:
    330                 fprintf(stderr, "%s: Destination address '%s' error\n",
    331                     NAME, config.dest_addr);
    332                 return 4;
    333         default:
    334                 fprintf(stderr, "%s: Unknown or invalid option '%s'\n", NAME,
    335                     argv[ret]);
    336                 return 5;
    337         }
    338        
    339         printf("PING %s (%s) %zu(%zu) bytes of data\n", config.dest_addr,
    340             config.dest_str, config.size, config.size);
    341        
    342         async_sess_t *sess = icmp_connect_module();
    343         if (!sess) {
    344                 fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME,
    345                     str_error(errno));
    346                 return errno;
    347         }
    348        
    349         unsigned int seq;
    350         for (seq = 0; seq < config.count; seq++) {
    351                 struct timeval t0;
    352                 ret = gettimeofday(&t0, NULL);
    353                 if (ret != EOK) {
    354                         fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
    355                             str_error(ret));
    356                        
    357                         async_hangup(sess);
    358                         return ret;
    359                 }
    360                
    361                 /* Ping! */
    362                 int result = icmp_echo_msg(sess, config.size, config.timeout,
    363                     config.ttl, config.tos, !config.fragments, config.dest_raw,
    364                     config.dest_len);
    365                
    366                 struct timeval t1;
    367                 ret = gettimeofday(&t1, NULL);
    368                 if (ret != EOK) {
    369                         fprintf(stderr, "%s: gettimeofday failed (%s)\n", NAME,
    370                             str_error(ret));
    371                        
    372                         async_hangup(sess);
    373                         return ret;
    374                 }
    375                
    376                 suseconds_t elapsed = tv_sub(&t1, &t0);
    377                
    378                 switch (result) {
    379                 case ICMP_ECHO:
    380                         printf("%zu bytes from ? (?): icmp_seq=%u ttl=? time=%ld.%04ld\n",
    381                                 config.size, seq, elapsed / 1000, elapsed % 1000);
    382                         break;
    383                 case ETIMEOUT:
    384                         printf("%zu bytes from ? (?): icmp_seq=%u Timed out\n",
    385                                 config.size, seq);
    386                         break;
    387                 default:
    388                         print_error(stdout, result, NULL, "\n");
    389                 }
    390         }
    391        
    392         async_hangup(sess);
    393        
     214        int rc;
     215        int argi;
     216
     217        rc = inetping_init(&ev_ops);
     218        if (rc != EOK) {
     219                printf(NAME ": Failed connecting to internet ping service "
     220                    "(%d).\n", rc);
     221                return 1;
     222        }
     223
     224        argi = 1;
     225        if (argi < argc && str_cmp(argv[argi], "-r") == 0) {
     226                ping_repeat = true;
     227                ++argi;
     228        } else {
     229                ping_repeat = false;
     230        }
     231
     232        if (argc - argi != 1) {
     233                print_syntax();
     234                return 1;
     235        }
     236
     237        /* Parse destination address */
     238        rc = addr_parse(argv[argi], &dest_addr);
     239        if (rc != EOK) {
     240                printf(NAME ": Invalid address format.\n");
     241                print_syntax();
     242                return 1;
     243        }
     244
     245        /* Determine source address */
     246        rc = inetping_get_srcaddr(&dest_addr, &src_addr);
     247        if (rc != EOK) {
     248                printf(NAME ": Failed determining source address.\n");
     249                return 1;
     250        }
     251
     252        fid_t fid;
     253
     254        if (ping_repeat) {
     255                fid = fibril_create(transmit_fibril, NULL);
     256                if (fid == 0) {
     257                        printf(NAME ": Failed creating transmit fibril.\n");
     258                        return 1;
     259                }
     260
     261                fibril_add_ready(fid);
     262
     263                fid = fibril_create(input_fibril, NULL);
     264                if (fid == 0) {
     265                        printf(NAME ": Failed creating input fibril.\n");
     266                        return 1;
     267                }
     268
     269                fibril_add_ready(fid);
     270        } else {
     271                ping_send(1);
     272        }
     273
     274        fibril_mutex_lock(&done_lock);
     275        rc = EOK;
     276        while (!done && rc != ETIMEOUT) {
     277                rc = fibril_condvar_wait_timeout(&done_cv, &done_lock,
     278                        ping_repeat ? 0 : PING_TIMEOUT);
     279        }
     280        fibril_mutex_unlock(&done_lock);
     281
     282        if (rc == ETIMEOUT) {
     283                printf(NAME ": Echo request timed out.\n");
     284                return 1;
     285        }
     286
    394287        return 0;
    395288}
  • uspace/app/tester/print/print1.c

    r3d93289a r0c37135  
    4242       
    4343        TPRINTF("Testing printf(\"%%8.10s\", \"text\"):\n");
    44         TPRINTF("Expected output: \"text\"\n");
     44        TPRINTF("Expected output: \"    text\"\n");
    4545        TPRINTF("Real output:     \"%8.10s\"\n\n", "text");
    4646       
     
    4949        TPRINTF("Real output:     \"%8.10s\"\n\n", "very long text");
    5050       
     51        TPRINTF("Testing printf(\"%%-*.*s\", 7, 7, \"text\"):\n");
     52        TPRINTF("Expected output: \"text   \"\n");
     53        TPRINTF("Real output:     \"%-*.*s\"\n\n", 7, 7, "text");
     54       
    5155        return NULL;
    5256}
  • uspace/app/top/screen.c

    r3d93289a r0c37135  
    3737
    3838#include <stdio.h>
     39#include <stdlib.h>
    3940#include <io/console.h>
    4041#include <io/style.h>
     
    4344#include <stats.h>
    4445#include <inttypes.h>
     46#include <macros.h>
    4547#include "screen.h"
    4648#include "top.h"
     
    4850#define USEC_COUNT  1000000
    4951
    50 static sysarg_t warn_col = 0;
    51 static sysarg_t warn_row = 0;
    5252static suseconds_t timeleft = 0;
    5353
    5454console_ctrl_t *console;
    5555
     56static sysarg_t warning_col = 0;
     57static sysarg_t warning_row = 0;
     58static suseconds_t warning_timeleft = 0;
     59static char *warning_text = NULL;
     60
    5661static void screen_style_normal(void)
    5762{
     
    6469        console_flush(console);
    6570        console_set_style(console, STYLE_INVERTED);
     71}
     72
     73static void screen_style_emphasis(void)
     74{
     75        console_flush(console);
     76        console_set_style(console, STYLE_EMPHASIS);
    6677}
    6778
     
    126137void screen_done(void)
    127138{
     139        free(warning_text);
     140        warning_text = NULL;
     141
    128142        screen_restart(true);
    129143       
     
    277291}
    278292
    279 static inline void print_tasks_head(void)
     293static inline void print_help_head(void)
    280294{
    281295        screen_style_inverted();
    282         printf("[taskid] [thrds] [resident] [%%resi] [virtual] [%%virt]"
    283             " [%%user] [%%kern] [name");
     296        printf("Help");
    284297        screen_newline();
    285298        screen_style_normal();
    286299}
    287300
    288 static inline void print_tasks(data_t *data)
    289 {
    290         sysarg_t cols;
    291         sysarg_t rows;
    292         screen_get_size(&cols, &rows);
     301static inline void print_help(void)
     302{
     303        sysarg_t cols;
     304        sysarg_t rows;
     305        screen_get_size(&cols, &rows);
     306       
     307        screen_newline();
     308       
     309        printf("Operation modes:");
     310        screen_newline();
     311       
     312        printf(" t .. tasks statistics");
     313        screen_newline();
     314       
     315        printf(" i .. IPC statistics");
     316        screen_newline();
     317       
     318        printf(" e .. exceptions statistics");
     319        screen_newline();
     320       
     321        printf("      a .. toggle display of all/hot exceptions");
     322        screen_newline();
     323
     324        printf(" h .. toggle this help screen");
     325        screen_newline();
     326
     327        screen_newline();
     328
     329        printf("Other keys:");
     330        screen_newline();
     331       
     332        printf(" s .. choose column to sort by");
     333        screen_newline();
     334       
     335        printf(" r .. toggle reversed sorting");
     336        screen_newline();
     337       
     338        printf(" q .. quit");
     339        screen_newline();
    293340       
    294341        sysarg_t col;
     
    296343        screen_get_pos(&col, &row);
    297344       
    298         size_t i;
    299         for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
    300                 stats_task_t *task = data->tasks + data->tasks_map[i];
    301                 perc_task_t *perc = data->tasks_perc + data->tasks_map[i];
    302                
    303                 uint64_t resmem;
    304                 const char *resmem_suffix;
    305                 bin_order_suffix(task->resmem, &resmem, &resmem_suffix, true);
    306                
    307                 uint64_t virtmem;
    308                 const char *virtmem_suffix;
    309                 bin_order_suffix(task->virtmem, &virtmem, &virtmem_suffix, true);
    310                
    311                 printf("%-8" PRIu64 " %7zu %7" PRIu64 "%s ",
    312                     task->task_id, task->threads, resmem, resmem_suffix);
    313                 print_percent(perc->resmem, 2);
    314                 printf(" %6" PRIu64 "%s ", virtmem, virtmem_suffix);
    315                 print_percent(perc->virtmem, 2);
    316                 puts(" ");
    317                 print_percent(perc->ucycles, 2);
    318                 puts(" ");
    319                 print_percent(perc->kcycles, 2);
    320                 puts(" ");
    321                 print_string(task->name);
    322                
    323                 screen_newline();
    324         }
    325        
    326345        while (row < rows) {
    327346                screen_newline();
     
    330349}
    331350
    332 static inline void print_ipc_head(void)
    333 {
     351static inline void print_table_head(const table_t *table)
     352{
     353        sysarg_t cols;
     354        sysarg_t rows;
     355        screen_get_size(&cols, &rows);
     356
    334357        screen_style_inverted();
    335         printf("[taskid] [cls snt] [cls rcv] [ans snt]"
    336             " [ans rcv] [irq rcv] [forward] [name");
     358        for (size_t i = 0; i < table->num_columns; i++) {
     359                const char *name = table->columns[i].name;
     360                int width = table->columns[i].width;
     361                if (i != 0) {
     362                        puts(" ");
     363                }
     364                if (width == 0) {
     365                        sysarg_t col;
     366                        sysarg_t row;
     367                        screen_get_pos(&col, &row);
     368                        width = cols - col - 1;
     369                }
     370                printf("[%-*.*s]", width - 2, width - 2, name);
     371        }
    337372        screen_newline();
    338373        screen_style_normal();
    339374}
    340375
    341 static inline void print_ipc(data_t *data)
     376static inline void print_table(const table_t *table)
    342377{
    343378        sysarg_t cols;
     
    350385       
    351386        size_t i;
    352         for (i = 0; (i < data->tasks_count) && (row < rows); i++, row++) {
    353                 uint64_t call_sent;
    354                 uint64_t call_received;
    355                 uint64_t answer_sent;
    356                 uint64_t answer_received;
    357                 uint64_t irq_notif_received;
    358                 uint64_t forwarded;
    359                
    360                 char call_sent_suffix;
    361                 char call_received_suffix;
    362                 char answer_sent_suffix;
    363                 char answer_received_suffix;
    364                 char irq_notif_received_suffix;
    365                 char forwarded_suffix;
    366                
    367                 order_suffix(data->tasks[i].ipc_info.call_sent, &call_sent,
    368                     &call_sent_suffix);
    369                 order_suffix(data->tasks[i].ipc_info.call_received,
    370                     &call_received, &call_received_suffix);
    371                 order_suffix(data->tasks[i].ipc_info.answer_sent,
    372                     &answer_sent, &answer_sent_suffix);
    373                 order_suffix(data->tasks[i].ipc_info.answer_received,
    374                     &answer_received, &answer_received_suffix);
    375                 order_suffix(data->tasks[i].ipc_info.irq_notif_received,
    376                     &irq_notif_received, &irq_notif_received_suffix);
    377                 order_suffix(data->tasks[i].ipc_info.forwarded, &forwarded,
    378                     &forwarded_suffix);
    379                
    380                 printf("%-8" PRIu64 " %8" PRIu64 "%c %8" PRIu64 "%c"
    381                      " %8" PRIu64 "%c %8" PRIu64 "%c %8" PRIu64 "%c"
    382                      " %8" PRIu64 "%c ", data->tasks[i].task_id,
    383                      call_sent, call_sent_suffix,
    384                      call_received, call_received_suffix,
    385                      answer_sent, answer_sent_suffix,
    386                      answer_received, answer_received_suffix,
    387                      irq_notif_received, irq_notif_received_suffix,
    388                      forwarded, forwarded_suffix);
    389                 print_string(data->tasks[i].name);
    390                
    391                 screen_newline();
     387        for (i = 0; (i < table->num_fields) && (row < rows); i++) {
     388                size_t column_index = i % table->num_columns;
     389                int width = table->columns[column_index].width;
     390                field_t *field = &table->fields[i];
     391
     392                if (column_index != 0) {
     393                        puts(" ");
     394                }
     395
     396                if (width == 0) {
     397                        screen_get_pos(&col, &row);
     398                        width = cols - col - 1;
     399                }
     400
     401                switch (field->type) {
     402                case FIELD_EMPTY:
     403                        printf("%*s", width, "");
     404                        break;
     405                case FIELD_UINT:
     406                        printf("%*" PRIu64, width, field->uint);
     407                        break;
     408                case FIELD_UINT_SUFFIX_BIN: {
     409                        uint64_t val = field->uint;
     410                        const char *suffix;
     411                        width -= 3;
     412                        bin_order_suffix(val, &val, &suffix, true);
     413                        printf("%*" PRIu64 "%s", width, val, suffix);
     414                        break;
     415                }
     416                case FIELD_UINT_SUFFIX_DEC: {
     417                        uint64_t val = field->uint;
     418                        char suffix;
     419                        width -= 1;
     420                        order_suffix(val, &val, &suffix);
     421                        printf("%*" PRIu64 "%c", width, val, suffix);
     422                        break;
     423                }
     424                case FIELD_PERCENT:
     425                        width -= 5; /* nnn.% */
     426                        if (width > 2) {
     427                                printf("%*s", width - 2, "");
     428                                width = 2;
     429                        }
     430                        print_percent(field->fixed, width);
     431                        break;
     432                case FIELD_STRING:
     433                        printf("%-*.*s", width, width, field->string);
     434                        break;
     435                }
     436
     437                if (column_index == table->num_columns - 1) {
     438                        screen_newline();
     439                        row++;
     440                }
    392441        }
    393442       
     
    398447}
    399448
    400 static inline void print_excs_head(void)
    401 {
    402         screen_style_inverted();
    403         printf("[exc   ] [count   ] [%%count] [cycles  ] [%%cycles] [description");
    404         screen_newline();
    405         screen_style_normal();
    406 }
    407 
    408 static inline void print_excs(data_t *data)
     449static inline void print_sort(table_t *table)
    409450{
    410451        sysarg_t cols;
     
    415456        sysarg_t row;
    416457        screen_get_pos(&col, &row);
    417        
    418         size_t i;
    419         for (i = 0; (i < data->exceptions_count) && (row < rows); i++) {
    420                 /* Filter-out cold exceptions if not instructed otherwise */
    421                 if ((!excs_all) && (!data->exceptions[i].hot))
    422                         continue;
    423                
    424                 uint64_t count;
    425                 uint64_t cycles;
    426                
    427                 char count_suffix;
    428                 char cycles_suffix;
    429                
    430                 order_suffix(data->exceptions[i].count, &count, &count_suffix);
    431                 order_suffix(data->exceptions[i].cycles, &cycles, &cycles_suffix);
    432                
    433                 printf("%-8u %9" PRIu64 "%c  ",
    434                      data->exceptions[i].id, count, count_suffix);
    435                 print_percent(data->exceptions_perc[i].count, 2);
    436                 printf(" %9" PRIu64 "%c   ", cycles, cycles_suffix);
    437                 print_percent(data->exceptions_perc[i].cycles, 2);
    438                 puts(" ");
    439                 print_string(data->exceptions[i].desc);
    440                
     458
     459        size_t num = min(table->num_columns, rows - row);
     460        for (size_t i = 0; i < num; i++) {
     461                printf("%c - %s", table->columns[i].key, table->columns[i].name);
    441462                screen_newline();
    442463                row++;
     
    449470}
    450471
    451 static void print_help(void)
    452 {
    453         sysarg_t cols;
    454         sysarg_t rows;
    455         screen_get_size(&cols, &rows);
    456        
    457         sysarg_t col;
    458         sysarg_t row;
    459         screen_get_pos(&col, &row);
    460        
    461         screen_newline();
    462        
    463         printf("Operation modes:");
    464         screen_newline();
    465        
    466         printf(" t .. tasks statistics");
    467         screen_newline();
    468        
    469         printf(" i .. IPC statistics");
    470         screen_newline();
    471        
    472         printf(" e .. exceptions statistics");
    473         screen_newline();
    474        
    475         printf("      a .. toggle display of all/hot exceptions");
    476         screen_newline();
    477        
    478         row += 6;
    479        
    480         while (row < rows) {
    481                 screen_newline();
    482                 row++;
    483         }
     472static inline void print_warning(void)
     473{
     474        screen_get_pos(&warning_col, &warning_row);
     475        if (warning_timeleft > 0) {
     476                screen_style_emphasis();
     477                print_string(warning_text);
     478                screen_style_normal();
     479        } else {
     480                free(warning_text);
     481                warning_text = NULL;
     482        }
     483        screen_newline();
    484484}
    485485
     
    492492        print_cpu_info(data);
    493493        print_physmem_info(data);
    494        
    495         /* Empty row for warnings */
    496         screen_get_pos(&warn_col, &warn_row);
    497         screen_newline();
    498        
    499         switch (op_mode) {
    500         case OP_TASKS:
    501                 print_tasks_head();
    502                 print_tasks(data);
     494        print_warning();
     495       
     496        switch (screen_mode) {
     497        case SCREEN_TABLE:
     498                print_table_head(&data->table);
     499                print_table(&data->table);
    503500                break;
    504         case OP_IPC:
    505                 print_ipc_head();
    506                 print_ipc(data);
     501        case SCREEN_SORT:
     502                print_sort(&data->table);
    507503                break;
    508         case OP_EXCS:
    509                 print_excs_head();
    510                 print_excs(data);
    511                 break;
    512         case OP_HELP:
    513                 print_tasks_head();
     504        case SCREEN_HELP:
     505                print_help_head();
    514506                print_help();
    515507        }
     
    518510}
    519511
    520 void print_warning(const char *fmt, ...)
    521 {
    522         screen_moveto(warn_col, warn_row);
    523        
     512void show_warning(const char *fmt, ...)
     513{
     514        sysarg_t cols;
     515        sysarg_t rows;
     516        screen_get_size(&cols, &rows);
     517
     518        size_t warning_text_size = 1 + cols * sizeof(*warning_text);
     519        free(warning_text);
     520        warning_text = malloc(warning_text_size);
     521        if (!warning_text)
     522                return;
     523
    524524        va_list args;
    525525        va_start(args, fmt);
    526         vprintf(fmt, args);
     526        vsnprintf(warning_text, warning_text_size, fmt, args);
    527527        va_end(args);
    528528       
    529         screen_newline();
     529        warning_timeleft = 2 * USEC_COUNT;
     530
     531        screen_moveto(warning_col, warning_row);
     532        print_warning();
    530533        console_flush(console);
    531534}
     
    555558                kbd_event_t event;
    556559               
     560                warning_timeleft -= timeleft;
    557561                if (!console_get_kbd_event_timeout(console, &event, &timeleft)) {
    558562                        timeleft = 0;
    559563                        return -1;
    560564                }
     565                warning_timeleft += timeleft;
    561566               
    562567                if (event.type == KEY_PRESS)
  • uspace/app/top/screen.h

    r3d93289a r0c37135  
    4343extern void screen_done(void);
    4444extern void print_data(data_t *);
    45 extern void print_warning(const char *, ...);
     45extern void show_warning(const char *, ...);
    4646
    4747extern int tgetchar(unsigned int);
  • uspace/app/top/top.c

    r3d93289a r0c37135  
    5555#define MINUTE  60
    5656
    57 op_mode_t op_mode = OP_TASKS;
    58 sort_mode_t sort_mode = SORT_TASK_CYCLES;
    59 bool excs_all = false;
     57typedef enum {
     58        OP_TASKS,
     59        OP_IPC,
     60        OP_EXCS,
     61} op_mode_t;
     62
     63static const column_t task_columns[] = {
     64        {"taskid",   't',  8},
     65        {"thrds",    'h',  7},
     66        {"resident", 'r', 10},
     67        {"%resi",    'R',  7},
     68        {"virtual",  'v',  9},
     69        {"%virt",    'V',  7},
     70        {"%user",    'U',  7},
     71        {"%kern",    'K',  7},
     72        {"name",     'd',  0},
     73};
     74
     75enum {
     76        TASK_COL_ID = 0,
     77        TASK_COL_NUM_THREADS,
     78        TASK_COL_RESIDENT,
     79        TASK_COL_PERCENT_RESIDENT,
     80        TASK_COL_VIRTUAL,
     81        TASK_COL_PERCENT_VIRTUAL,
     82        TASK_COL_PERCENT_USER,
     83        TASK_COL_PERCENT_KERNEL,
     84        TASK_COL_NAME,
     85        TASK_NUM_COLUMNS,
     86};
     87
     88static const column_t ipc_columns[] = {
     89        {"taskid",  't', 8},
     90        {"cls snt", 'c', 9},
     91        {"cls rcv", 'C', 9},
     92        {"ans snt", 'a', 9},
     93        {"ans rcv", 'A', 9},
     94        {"forward", 'f', 9},
     95        {"name",    'd', 0},
     96};
     97
     98enum {
     99        IPC_COL_TASKID = 0,
     100        IPC_COL_CLS_SNT,
     101        IPC_COL_CLS_RCV,
     102        IPC_COL_ANS_SNT,
     103        IPC_COL_ANS_RCV,
     104        IPC_COL_FORWARD,
     105        IPC_COL_NAME,
     106        IPC_NUM_COLUMNS,
     107};
     108
     109static const column_t exception_columns[] = {
     110        {"exc",         'e',  8},
     111        {"count",       'n', 10},
     112        {"%count",      'N',  8},
     113        {"cycles",      'c', 10},
     114        {"%cycles",     'C',  9},
     115        {"description", 'd',  0},
     116};
     117
     118enum {
     119        EXCEPTION_COL_ID = 0,
     120        EXCEPTION_COL_COUNT,
     121        EXCEPTION_COL_PERCENT_COUNT,
     122        EXCEPTION_COL_CYCLES,
     123        EXCEPTION_COL_PERCENT_CYCLES,
     124        EXCEPTION_COL_DESCRIPTION,
     125        EXCEPTION_NUM_COLUMNS,
     126};
     127
     128screen_mode_t screen_mode = SCREEN_TABLE;
     129static op_mode_t op_mode = OP_TASKS;
     130static size_t sort_column = TASK_COL_PERCENT_USER;
     131static int sort_reverse = -1;
     132static bool excs_all = false;
    60133
    61134static const char *read_data(data_t *target)
     
    67140        target->tasks = NULL;
    68141        target->tasks_perc = NULL;
    69         target->tasks_map = NULL;
    70142        target->threads = NULL;
    71143        target->exceptions = NULL;
     
    76148        target->ecycles_diff = NULL;
    77149        target->ecount_diff = NULL;
     150        target->table.name = NULL;
     151        target->table.num_columns = 0;
     152        target->table.columns = NULL;
     153        target->table.num_fields = 0;
     154        target->table.fields = NULL;
    78155       
    79156        /* Get current time */
     
    117194        if (target->tasks_perc == NULL)
    118195                return "Not enough memory for task utilization";
    119        
    120         target->tasks_map =
    121             (size_t *) calloc(target->tasks_count, sizeof(size_t));
    122         if (target->tasks_map == NULL)
    123                 return "Not enough memory for task map";
    124196       
    125197        /* Get threads */
     
    289361static int cmp_data(void *a, void *b, void *arg)
    290362{
    291         size_t ia = *((size_t *) a);
    292         size_t ib = *((size_t *) b);
    293         data_t *data = (data_t *) arg;
    294        
    295         uint64_t acycles = data->ucycles_diff[ia] + data->kcycles_diff[ia];
    296         uint64_t bcycles = data->ucycles_diff[ib] + data->kcycles_diff[ib];
    297        
    298         if (acycles > bcycles)
    299                 return -1;
    300        
    301         if (acycles < bcycles)
    302                 return 1;
    303        
     363        field_t *fa = (field_t *)a + sort_column;
     364        field_t *fb = (field_t *)b + sort_column;
     365       
     366        if (fa->type > fb->type)
     367                return 1 * sort_reverse;
     368
     369        if (fa->type < fb->type)
     370                return -1 * sort_reverse;
     371
     372        switch (fa->type) {
     373        case FIELD_EMPTY:
     374                return 0;
     375        case FIELD_UINT_SUFFIX_BIN: /* fallthrough */
     376        case FIELD_UINT_SUFFIX_DEC: /* fallthrough */
     377        case FIELD_UINT:
     378                if (fa->uint > fb->uint)
     379                        return 1 * sort_reverse;
     380                if (fa->uint < fb->uint)
     381                        return -1 * sort_reverse;
     382                return 0;
     383        case FIELD_PERCENT:
     384                if (fa->fixed.upper * fb->fixed.lower
     385                    > fb->fixed.upper * fa->fixed.lower)
     386                        return 1 * sort_reverse;
     387                if (fa->fixed.upper * fb->fixed.lower
     388                    < fb->fixed.upper * fa->fixed.lower)
     389                        return -1 * sort_reverse;
     390                return 0;
     391        case FIELD_STRING:
     392                return str_cmp(fa->string, fb->string) * sort_reverse;
     393        }
     394
    304395        return 0;
    305396}
    306397
    307 static void sort_data(data_t *data)
    308 {
    309         size_t i;
    310        
    311         for (i = 0; i < data->tasks_count; i++)
    312                 data->tasks_map[i] = i;
    313        
    314         qsort((void *) data->tasks_map, data->tasks_count,
    315             sizeof(size_t), cmp_data, (void *) data);
     398static void sort_table(table_t *table)
     399{
     400        if (sort_column >= table->num_columns)
     401                sort_column = 0;
     402        /* stable sort is probably best, so we use gsort */
     403        gsort((void *) table->fields, table->num_fields / table->num_columns,
     404            sizeof(field_t) * table->num_columns, cmp_data, NULL);
     405}
     406
     407static const char *fill_task_table(data_t *data)
     408{
     409        data->table.name = "Tasks";
     410        data->table.num_columns = TASK_NUM_COLUMNS;
     411        data->table.columns = task_columns;
     412        data->table.num_fields = data->tasks_count * TASK_NUM_COLUMNS;
     413        data->table.fields = calloc(data->table.num_fields,
     414            sizeof(field_t));
     415        if (data->table.fields == NULL)
     416                return "Not enough memory for table fields";
     417
     418        field_t *field = data->table.fields;
     419        for (size_t i = 0; i < data->tasks_count; i++) {
     420                stats_task_t *task = &data->tasks[i];
     421                perc_task_t *perc = &data->tasks_perc[i];
     422                field[TASK_COL_ID].type = FIELD_UINT;
     423                field[TASK_COL_ID].uint = task->task_id;
     424                field[TASK_COL_NUM_THREADS].type = FIELD_UINT;
     425                field[TASK_COL_NUM_THREADS].uint = task->threads;
     426                field[TASK_COL_RESIDENT].type = FIELD_UINT_SUFFIX_BIN;
     427                field[TASK_COL_RESIDENT].uint = task->resmem;
     428                field[TASK_COL_PERCENT_RESIDENT].type = FIELD_PERCENT;
     429                field[TASK_COL_PERCENT_RESIDENT].fixed = perc->resmem;
     430                field[TASK_COL_VIRTUAL].type = FIELD_UINT_SUFFIX_BIN;
     431                field[TASK_COL_VIRTUAL].uint = task->virtmem;
     432                field[TASK_COL_PERCENT_VIRTUAL].type = FIELD_PERCENT;
     433                field[TASK_COL_PERCENT_VIRTUAL].fixed = perc->virtmem;
     434                field[TASK_COL_PERCENT_USER].type = FIELD_PERCENT;
     435                field[TASK_COL_PERCENT_USER].fixed = perc->ucycles;
     436                field[TASK_COL_PERCENT_KERNEL].type = FIELD_PERCENT;
     437                field[TASK_COL_PERCENT_KERNEL].fixed = perc->kcycles;
     438                field[TASK_COL_NAME].type = FIELD_STRING;
     439                field[TASK_COL_NAME].string = task->name;
     440                field += TASK_NUM_COLUMNS;
     441        }
     442
     443        return NULL;
     444}
     445
     446static const char *fill_ipc_table(data_t *data)
     447{
     448        data->table.name = "IPC";
     449        data->table.num_columns = IPC_NUM_COLUMNS;
     450        data->table.columns = ipc_columns;
     451        data->table.num_fields = data->tasks_count * IPC_NUM_COLUMNS;
     452        data->table.fields = calloc(data->table.num_fields,
     453            sizeof(field_t));
     454        if (data->table.fields == NULL)
     455                return "Not enough memory for table fields";
     456
     457        field_t *field = data->table.fields;
     458        for (size_t i = 0; i < data->tasks_count; i++) {
     459                field[IPC_COL_TASKID].type = FIELD_UINT;
     460                field[IPC_COL_TASKID].uint = data->tasks[i].task_id;
     461                field[IPC_COL_CLS_SNT].type = FIELD_UINT_SUFFIX_DEC;
     462                field[IPC_COL_CLS_SNT].uint = data->tasks[i].ipc_info.call_sent;
     463                field[IPC_COL_CLS_RCV].type = FIELD_UINT_SUFFIX_DEC;
     464                field[IPC_COL_CLS_RCV].uint = data->tasks[i].ipc_info.call_received;
     465                field[IPC_COL_ANS_SNT].type = FIELD_UINT_SUFFIX_DEC;
     466                field[IPC_COL_ANS_SNT].uint = data->tasks[i].ipc_info.answer_sent;
     467                field[IPC_COL_ANS_RCV].type = FIELD_UINT_SUFFIX_DEC;
     468                field[IPC_COL_ANS_RCV].uint = data->tasks[i].ipc_info.answer_received;
     469                field[IPC_COL_FORWARD].type = FIELD_UINT_SUFFIX_DEC;
     470                field[IPC_COL_FORWARD].uint = data->tasks[i].ipc_info.forwarded;
     471                field[IPC_COL_NAME].type = FIELD_STRING;
     472                field[IPC_COL_NAME].string = data->tasks[i].name;
     473                field += IPC_NUM_COLUMNS;
     474        }
     475
     476        return NULL;
     477}
     478
     479static const char *fill_exception_table(data_t *data)
     480{
     481        data->table.name = "Exceptions";
     482        data->table.num_columns = EXCEPTION_NUM_COLUMNS;
     483        data->table.columns = exception_columns;
     484        data->table.num_fields = data->exceptions_count *
     485            EXCEPTION_NUM_COLUMNS;
     486        data->table.fields = calloc(data->table.num_fields, sizeof(field_t));
     487        if (data->table.fields == NULL)
     488                return "Not enough memory for table fields";
     489
     490        field_t *field = data->table.fields;
     491        for (size_t i = 0; i < data->exceptions_count; i++) {
     492                if (!excs_all && !data->exceptions[i].hot)
     493                        continue;
     494                field[EXCEPTION_COL_ID].type = FIELD_UINT;
     495                field[EXCEPTION_COL_ID].uint = data->exceptions[i].id;
     496                field[EXCEPTION_COL_COUNT].type = FIELD_UINT_SUFFIX_DEC;
     497                field[EXCEPTION_COL_COUNT].uint = data->exceptions[i].count;
     498                field[EXCEPTION_COL_PERCENT_COUNT].type = FIELD_PERCENT;
     499                field[EXCEPTION_COL_PERCENT_COUNT].fixed = data->exceptions_perc[i].count;
     500                field[EXCEPTION_COL_CYCLES].type = FIELD_UINT_SUFFIX_DEC;
     501                field[EXCEPTION_COL_CYCLES].uint = data->exceptions[i].cycles;
     502                field[EXCEPTION_COL_PERCENT_CYCLES].type = FIELD_PERCENT;
     503                field[EXCEPTION_COL_PERCENT_CYCLES].fixed = data->exceptions_perc[i].cycles;
     504                field[EXCEPTION_COL_DESCRIPTION].type = FIELD_STRING;
     505                field[EXCEPTION_COL_DESCRIPTION].string = data->exceptions[i].desc;
     506                field += EXCEPTION_NUM_COLUMNS;
     507        }
     508
     509        /* in case any cold exceptions were ignored */
     510        data->table.num_fields = field - data->table.fields;
     511
     512        return NULL;
     513}
     514
     515static const char *fill_table(data_t *data)
     516{
     517        if (data->table.fields != NULL) {
     518                free(data->table.fields);
     519                data->table.fields = NULL;
     520        }
     521
     522        switch (op_mode) {
     523        case OP_TASKS:
     524                return fill_task_table(data);
     525        case OP_IPC:
     526                return fill_ipc_table(data);
     527        case OP_EXCS:
     528                return fill_exception_table(data);
     529        }
     530        return NULL;
    316531}
    317532
     
    356571        if (target->ecount_diff != NULL)
    357572                free(target->ecount_diff);
     573
     574        if (target->table.fields != NULL)
     575                free(target->table.fields);
    358576}
    359577
     
    367585        printf("Reading initial data...\n");
    368586       
    369         if ((ret = read_data(&data_prev)) != NULL)
     587        if ((ret = read_data(&data)) != NULL)
    370588                goto out;
    371589       
    372590        /* Compute some rubbish to have initialised values */
    373         compute_percentages(&data_prev, &data_prev);
     591        compute_percentages(&data, &data);
    374592       
    375593        /* And paint screen until death */
    376594        while (true) {
    377595                int c = tgetchar(UPDATE_INTERVAL);
    378                 if (c < 0) {
     596
     597                if (c < 0) { /* timeout */
     598                        data_prev = data;
    379599                        if ((ret = read_data(&data)) != NULL) {
    380                                 free_data(&data);
     600                                free_data(&data_prev);
    381601                                goto out;
    382602                        }
    383603                       
    384604                        compute_percentages(&data_prev, &data);
    385                         sort_data(&data);
    386                         print_data(&data);
    387605                        free_data(&data_prev);
    388                         data_prev = data;
    389                        
    390                         continue;
    391                 }
    392                
     606
     607                        c = -1;
     608                }
     609
     610                if (screen_mode == SCREEN_HELP && c >= 0) {
     611                        if (c == 'h' || c == '?')
     612                                c = -1;
     613                        /* go back to table and handle the key */
     614                        screen_mode = SCREEN_TABLE;
     615                }
     616
     617                if (screen_mode == SCREEN_SORT && c >= 0) {
     618                        for (size_t i = 0; i < data.table.num_columns; i++) {
     619                                if (data.table.columns[i].key == c) {
     620                                        sort_column = i;
     621                                        screen_mode = SCREEN_TABLE;
     622                                }
     623                        }
     624
     625                        c = -1;
     626                }
     627
    393628                switch (c) {
    394                         case 't':
    395                                 print_warning("Showing task statistics");
    396                                 op_mode = OP_TASKS;
     629                case -1: /* do nothing */
     630                        break;
     631                case 't':
     632                        op_mode = OP_TASKS;
     633                        break;
     634                case 'i':
     635                        op_mode = OP_IPC;
     636                        break;
     637                case 'e':
     638                        op_mode = OP_EXCS;
     639                        break;
     640                case 's':
     641                        screen_mode = SCREEN_SORT;
     642                        break;
     643                case 'r':
     644                        sort_reverse = -sort_reverse;
     645                        break;
     646                case 'h':
     647                case '?':
     648                        screen_mode = SCREEN_HELP;
     649                        break;
     650                case 'q':
     651                        goto out;
     652                case 'a':
     653                        if (op_mode == OP_EXCS) {
     654                                excs_all = !excs_all;
     655                                if (excs_all)
     656                                        show_warning("Showing all exceptions");
     657                                else
     658                                        show_warning("Showing only hot exceptions");
    397659                                break;
    398                         case 'i':
    399                                 print_warning("Showing IPC statistics");
    400                                 op_mode = OP_IPC;
    401                                 break;
    402                         case 'e':
    403                                 print_warning("Showing exception statistics");
    404                                 op_mode = OP_EXCS;
    405                                 break;
    406                         case 'h':
    407                                 print_warning("Showing help");
    408                                 op_mode = OP_HELP;
    409                                 break;
    410                         case 'q':
    411                                 goto out;
    412                         case 'a':
    413                                 if (op_mode == OP_EXCS) {
    414                                         excs_all = !excs_all;
    415                                         if (excs_all)
    416                                                 print_warning("Showing all exceptions");
    417                                         else
    418                                                 print_warning("Showing only hot exceptions");
    419                                         break;
    420                                 }
    421                         default:
    422                                 print_warning("Unknown command \"%c\", use \"h\" for help", c);
    423                                 break;
    424                 }
     660                        }
     661                        /* fallthrough */
     662                default:
     663                        show_warning("Unknown command \"%c\", use \"h\" for help", c);
     664                        continue; /* don't redraw */
     665                }
     666
     667                if ((ret = fill_table(&data)) != NULL) {
     668                        goto out;
     669                }
     670                sort_table(&data.table);
     671                print_data(&data);
    425672        }
    426673       
    427674out:
    428675        screen_done();
    429         free_data(&data_prev);
     676        free_data(&data);
    430677       
    431678        if (ret != NULL) {
  • uspace/app/top/top.h

    r3d93289a r0c37135  
    5151
    5252typedef enum {
    53         OP_TASKS,
    54         OP_IPC,
    55         OP_EXCS,
    56         OP_HELP
    57 } op_mode_t;
     53        SCREEN_TABLE,
     54        SCREEN_SORT,
     55        SCREEN_HELP,
     56} screen_mode_t;
    5857
    59 typedef enum {
    60         SORT_TASK_CYCLES
    61 } sort_mode_t;
    62 
    63 extern op_mode_t op_mode;
    64 extern sort_mode_t sort_mode;
    65 extern bool excs_all;
     58extern screen_mode_t screen_mode;
    6659
    6760typedef struct {
     
    8780} perc_exc_t;
    8881
     82typedef enum {
     83        FIELD_EMPTY, FIELD_UINT, FIELD_UINT_SUFFIX_BIN, FIELD_UINT_SUFFIX_DEC,
     84        FIELD_PERCENT, FIELD_STRING
     85} field_type_t;
     86
     87typedef struct {
     88        field_type_t type;
     89        union {
     90                fixed_float fixed;
     91                uint64_t uint;
     92                const char *string;
     93        };
     94} field_t;
     95
     96typedef struct {
     97        const char *name;
     98        char key;
     99        int width;
     100} column_t;
     101
     102typedef struct {
     103        const char *name;
     104        size_t num_columns;
     105        const column_t *columns;
     106        size_t num_fields;
     107        field_t *fields;
     108} table_t;
     109
    89110typedef struct {
    90111        time_t hours;
     
    107128        stats_task_t *tasks;
    108129        perc_task_t *tasks_perc;
    109         size_t *tasks_map;
    110130       
    111131        size_t threads_count;
     
    122142        uint64_t *ecycles_diff;
    123143        uint64_t *ecount_diff;
     144
     145        table_t table;
    124146} data_t;
    125147
  • uspace/drv/nic/e1k/Makefile

    r3d93289a r0c37135  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a $(LIBNIC_PREFIX)/libnic.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBNIC_PREFIX)/include
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNIC_PREFIX)/libnic.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNIC_PREFIX)/include
    3232BINARY = e1k
    3333
  • uspace/drv/nic/e1k/e1k.c

    r3d93289a r0c37135  
    4949#include <device/pci.h>
    5050#include <nic.h>
    51 #include <nil_remote.h>
    5251#include <ops/nic.h>
    5352#include "e1k.h"
  • uspace/drv/nic/lo/Makefile

    r3d93289a r0c37135  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a $(LIBNIC_PREFIX)/libnic.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBNIC_PREFIX)/include
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNIC_PREFIX)/libnic.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNIC_PREFIX)/include
    3232BINARY = lo
    3333
  • uspace/drv/nic/ne2k/Makefile

    r3d93289a r0c37135  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a $(LIBNIC_PREFIX)/libnic.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBNIC_PREFIX)/include
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNIC_PREFIX)/libnic.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNIC_PREFIX)/include
    3232BINARY = ne2k
    3333
  • uspace/drv/nic/rtl8139/Makefile

    r3d93289a r0c37135  
    2828
    2929USPACE_PREFIX = ../../..
    30 LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNET_PREFIX)/libnet.a $(LIBNIC_PREFIX)/libnic.a
    31 EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNET_PREFIX)/include -I$(LIBNIC_PREFIX)/include
     30LIBS = $(LIBDRV_PREFIX)/libdrv.a $(LIBNIC_PREFIX)/libnic.a
     31EXTRA_CFLAGS += -I$(LIBDRV_PREFIX)/include -I$(LIBNIC_PREFIX)/include
    3232BINARY = rtl8139
    3333
  • uspace/drv/nic/rtl8139/driver.c

    r3d93289a r0c37135  
    4444#include <sysinfo.h>
    4545#include <ipc/ns.h>
    46 
    47 #include <net_checksum.h>
    4846
    4947#include <str.h>
  • uspace/lib/c/Makefile

    r3d93289a r0c37135  
    8787        generic/task.c \
    8888        generic/futex.c \
     89        generic/inet.c \
     90        generic/inetcfg.c \
     91        generic/inetping.c \
    8992        generic/io/asprintf.c \
    9093        generic/io/io.c \
     
    97100        generic/io/printf_core.c \
    98101        generic/io/console.c \
     102        generic/iplink.c \
     103        generic/iplink_srv.c \
    99104        generic/malloc.c \
    100105        generic/sysinfo.c \
     
    108113        generic/adt/hash_set.c \
    109114        generic/adt/dynamic_fifo.c \
    110         generic/adt/measured_strings.c \
    111115        generic/adt/char_map.c \
    112116        generic/adt/prodcons.c \
     
    118122        generic/vfs/canonify.c \
    119123        generic/net/inet.c \
    120         generic/net/icmp_common.c \
    121         generic/net/icmp_api.c \
    122124        generic/net/modules.c \
    123         generic/net/packet.c \
    124125        generic/net/socket_client.c \
    125126        generic/net/socket_parse.c \
  • uspace/lib/c/generic/io/printf_core.c

    r3d93289a r0c37135  
    283283        /* Print leading spaces. */
    284284        size_t strw = str_length(str);
    285         if (precision == 0)
     285        if ((precision == 0) || (precision > strw))
    286286                precision = strw;
    287287       
     
    331331        /* Print leading spaces. */
    332332        size_t strw = wstr_length(str);
    333         if (precision == 0)
     333        if ((precision == 0) || (precision > strw))
    334334                precision = strw;
    335335       
  • uspace/lib/c/include/inet/inet.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup libc
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * Hardware types according to the on-line IANA - Address Resolution Protocol
    35  * (ARP) Parameters
    36  * http://www.iana.org/assignments/arp-parameters/arp-parameters.xml,
    37  * cited January 14 2009.
    3833 */
    3934
    40 #ifndef LIBNET_NET_HARDWARE_H_
    41 #define LIBNET_NET_HARDWARE_H_
     35#ifndef LIBC_INET_INET_H_
     36#define LIBC_INET_INET_H_
    4237
    4338#include <sys/types.h>
    4439
    45 /** Network interface layer type type definition. */
    46 typedef uint8_t hw_type_t;
     40#define INET_TTL_MAX 255
    4741
    48 /** @name Network interface layer types definitions */
    49 /*@{*/
     42typedef struct {
     43        uint32_t ipv4;
     44} inet_addr_t;
    5045
    51 /** Ethernet (10Mb) hardware type. */
    52 #define HW_ETHER                1
     46typedef struct {
     47        inet_addr_t src;
     48        inet_addr_t dest;
     49        uint8_t tos;
     50        void *data;
     51        size_t size;
     52} inet_dgram_t;
    5353
    54 /*@}*/
     54typedef struct {
     55        int (*recv)(inet_dgram_t *);
     56} inet_ev_ops_t;
     57
     58typedef enum {
     59        INET_DF = 1
     60} inet_df_t;
     61
     62extern int inet_init(uint8_t, inet_ev_ops_t *);
     63extern int inet_send(inet_dgram_t *, uint8_t, inet_df_t);
     64extern int inet_get_srcaddr(inet_addr_t *, uint8_t, inet_addr_t *);
    5565
    5666#endif
     
    5868/** @}
    5969 */
    60 
  • uspace/lib/c/include/inet/inetping.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2828
    2929/** @addtogroup libc
    30  *  @{
     30 * @{
     31 */
     32/** @file
    3133 */
    3234
    33 /** @file
    34  * ICMP common interface implementation.
    35  * @see icmp_common.h
    36  */
     35#ifndef LIBC_INET_INETPING_H_
     36#define LIBC_INET_INETPING_H_
    3737
    38 #include <net/modules.h>
    39 #include <net/icmp_common.h>
    40 #include <ipc/services.h>
    41 #include <ipc/icmp.h>
    42 #include <sys/time.h>
    43 #include <async.h>
     38#include <inet/inet.h>
     39#include <sys/types.h>
    4440
    45 /** Connect to the ICMP module.
    46  *
    47  * @return ICMP module session.
    48  *
    49  */
    50 async_sess_t *icmp_connect_module(void)
    51 {
    52         return connect_to_service(SERVICE_ICMP);
    53 }
     41typedef struct {
     42        inet_addr_t src;
     43        inet_addr_t dest;
     44        uint16_t seq_no;
     45        void *data;
     46        size_t size;
     47} inetping_sdu_t;
     48
     49typedef struct inetping_ev_ops {
     50        int (*recv)(inetping_sdu_t *);
     51} inetping_ev_ops_t;
     52
     53extern int inetping_init(inetping_ev_ops_t *);
     54extern int inetping_send(inetping_sdu_t *);
     55extern int inetping_get_srcaddr(inet_addr_t *, inet_addr_t *);
     56
     57
     58#endif
    5459
    5560/** @}
  • uspace/lib/c/include/inet/iplink.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
    30  *  @{
     29/** @addtogroup libc
     30 * @{
     31 */
     32/** @file
    3133 */
    3234
    33 #ifndef LIBNET_ICMP_REMOTE_H_
    34 #define LIBNET_ICMP_REMOTE_H_
     35#ifndef LIBC_INET_IPLINK_H_
     36#define LIBC_INET_IPLINK_H_
    3537
    36 #include <net/socket_codes.h>
     38#include <async.h>
    3739#include <sys/types.h>
    38 #include <net/device.h>
    39 #include <adt/measured_strings.h>
    40 #include <net/packet.h>
    41 #include <net/inet.h>
    42 #include <net/ip_codes.h>
    43 #include <net/icmp_codes.h>
    44 #include <net/icmp_common.h>
    45 #include <async.h>
    4640
    47 /** @name ICMP module interface
    48  * This interface is used by other modules.
    49  */
    50 /*@{*/
     41struct iplink_ev_ops;
    5142
    52 extern int icmp_destination_unreachable_msg(async_sess_t *, icmp_code_t,
    53     icmp_param_t, packet_t *);
    54 extern int icmp_source_quench_msg(async_sess_t *, packet_t *);
    55 extern int icmp_time_exceeded_msg(async_sess_t *, icmp_code_t, packet_t *);
    56 extern int icmp_parameter_problem_msg(async_sess_t *, icmp_code_t, icmp_param_t,
    57     packet_t *);
     43typedef struct {
     44        async_sess_t *sess;
     45        struct iplink_ev_ops *ev_ops;
     46} iplink_t;
    5847
    59 /*@}*/
     48typedef struct {
     49        uint32_t ipv4;
     50} iplink_addr_t;
     51
     52/** IP link Service Data Unit */
     53typedef struct {
     54        /** Local source address */
     55        iplink_addr_t lsrc;
     56        /** Local destination address */
     57        iplink_addr_t ldest;
     58        /** Serialized IP packet */
     59        void *data;
     60        /** Size of @c data in bytes */
     61        size_t size;
     62} iplink_sdu_t;
     63
     64typedef struct iplink_ev_ops {
     65        int (*recv)(iplink_t *, iplink_sdu_t *);
     66} iplink_ev_ops_t;
     67
     68extern int iplink_open(async_sess_t *, iplink_ev_ops_t *, iplink_t **);
     69extern void iplink_close(iplink_t *);
     70extern int iplink_send(iplink_t *, iplink_sdu_t *);
     71extern int iplink_addr_add(iplink_t *, iplink_addr_t *);
     72extern int iplink_addr_remove(iplink_t *, iplink_addr_t *);
     73extern int iplink_get_mtu(iplink_t *, size_t *);
    6074
    6175#endif
  • uspace/lib/c/include/inet/iplink_srv.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2828
    2929/** @addtogroup libc
    30  *  @{
     30 * @{
     31 */
     32/** @file
    3133 */
    3234
    33 /** @file
    34  * Character string with measured length.
    35  * The structure has been designed for serialization of character strings
    36  * between modules.
    37  */
     35#ifndef LIBC_INET_IPLINK_SRV_H_
     36#define LIBC_INET_IPLINK_SRV_H_
    3837
    39 #ifndef LIBC_MEASURED_STRINGS_H_
    40 #define LIBC_MEASURED_STRINGS_H_
     38#include <async.h>
     39#include <fibril_synch.h>
     40#include <bool.h>
     41#include <sys/types.h>
    4142
    42 #include <sys/types.h>
    43 #include <async.h>
     43struct iplink_ops;
    4444
    45 /** Type definition of the character string with measured length.
    46  * @see measured_string
    47  */
    48 typedef struct measured_string measured_string_t;
     45typedef struct {
     46        fibril_mutex_t lock;
     47        bool connected;
     48        struct iplink_ops *ops;
     49        void *arg;
     50        async_sess_t *client_sess;
     51} iplink_srv_t;
    4952
    50 /** Character string with measured length.
    51  *
    52  * This structure has been designed for serialization of character strings
    53  * between modules.
    54  */
    55 struct measured_string {
    56         /** Character string data. */
    57         uint8_t *value;
    58         /** Character string length. */
    59         size_t length;
    60 };
     53typedef struct {
     54        uint32_t ipv4;
     55} iplink_srv_addr_t;
    6156
    62 extern measured_string_t *measured_string_create_bulk(const uint8_t *, size_t);
    63 extern measured_string_t *measured_string_copy(measured_string_t *);
     57/** IP link Service Data Unit */
     58typedef struct {
     59        /** Local source address */
     60        iplink_srv_addr_t lsrc;
     61        /** Local destination address */
     62        iplink_srv_addr_t ldest;
     63        /** Serialized IP packet */
     64        void *data;
     65        /** Size of @c data in bytes */
     66        size_t size;
     67} iplink_srv_sdu_t;
    6468
    65 extern int measured_strings_receive(measured_string_t **, uint8_t **, size_t);
    66 extern int measured_strings_reply(const measured_string_t *, size_t);
     69typedef struct iplink_ops {
     70        int (*open)(iplink_srv_t *);
     71        int (*close)(iplink_srv_t *);
     72        int (*send)(iplink_srv_t *, iplink_srv_sdu_t *);
     73        int (*get_mtu)(iplink_srv_t *, size_t *);
     74        int (*addr_add)(iplink_srv_t *, iplink_srv_addr_t *);
     75        int (*addr_remove)(iplink_srv_t *, iplink_srv_addr_t *);
     76} iplink_ops_t;
    6777
    68 extern int measured_strings_return(async_exch_t *, measured_string_t **,
    69     uint8_t **, size_t);
    70 extern int measured_strings_send(async_exch_t *, const measured_string_t *,
    71     size_t);
     78extern void iplink_srv_init(iplink_srv_t *);
     79
     80extern int iplink_conn(ipc_callid_t, ipc_call_t *, void *);
     81extern int iplink_ev_recv(iplink_srv_t *, iplink_srv_sdu_t *);
    7282
    7383#endif
  • uspace/lib/c/include/ipc/inet.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
    3  * Copyright (c) 2011 Radim Vansa
     2 * Copyright (c) 2012 Jiri Svoboda
    43 * All rights reserved.
    54 *
     
    2827 */
    2928
    30 /** @addtogroup libpacket
     29/** @addtogroup libcipc
    3130 * @{
    3231 */
    33 
    3432/** @file
    35  * Packet server.
    36  * The hosting module has to be compiled with both the packet.c and the
    37  * packet_server.c source files. To function correctly, initialization of the
    38  * packet map by the pm_init() function has to happen at the first place. Then
    39  * the packet messages have to be processed by the packet_server_message()
    40  * function. The packet map should be released by the pm_destroy() function
    41  * during the module termination.
    42  * @see IS_NET_PACKET_MESSAGE()
    4333 */
    4434
    45 #ifndef NET_PACKET_SERVER_H_
    46 #define NET_PACKET_SERVER_H_
     35#ifndef LIBC_IPC_INET_H_
     36#define LIBC_IPC_INET_H_
    4737
    4838#include <ipc/common.h>
    4939
    50 extern int packet_server_init(void);
    51 extern int packet_server_message(ipc_callid_t, ipc_call_t *, ipc_call_t *,
    52     size_t *);
     40/** Inet ports */
     41typedef enum {
     42        /** Default port */
     43        INET_PORT_DEFAULT = 1,
     44        /** Configuration port */
     45        INET_PORT_CFG,
     46        /** Ping service port */
     47        INET_PORT_PING
     48} inet_port_t;
     49
     50/** Requests on Inet default port */
     51typedef enum {
     52        INET_CALLBACK_CREATE = IPC_FIRST_USER_METHOD,
     53        INET_GET_SRCADDR,
     54        INET_SEND,
     55        INET_SET_PROTO
     56} inet_request_t;
     57
     58/** Events on Inet default port */
     59typedef enum {
     60        INET_EV_RECV = IPC_FIRST_USER_METHOD
     61} inet_event_t;
     62
     63/** Requests on Inet configuration port */
     64typedef enum {
     65        INETCFG_ADDR_CREATE_STATIC = IPC_FIRST_USER_METHOD,
     66        INETCFG_ADDR_DELETE,
     67        INETCFG_ADDR_GET,
     68        INETCFG_ADDR_GET_ID,
     69        INETCFG_GET_ADDR_LIST,
     70        INETCFG_GET_LINK_LIST,
     71        INETCFG_GET_SROUTE_LIST,
     72        INETCFG_LINK_GET,
     73        INETCFG_SROUTE_CREATE,
     74        INETCFG_SROUTE_DELETE,
     75        INETCFG_SROUTE_GET,
     76        INETCFG_SROUTE_GET_ID
     77} inetcfg_request_t;
     78
     79/** Events on Inet ping port */
     80typedef enum {
     81        INETPING_EV_RECV = IPC_FIRST_USER_METHOD
     82} inetping_event_t;
     83
     84/** Requests on Inet ping port */
     85typedef enum {
     86        INETPING_SEND = IPC_FIRST_USER_METHOD,
     87        INETPING_GET_SRCADDR
     88} inetping_request_t;
    5389
    5490#endif
    5591
    56 /** @}
     92/**
     93 * @}
    5794 */
  • uspace/lib/c/include/ipc/iplink.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
     29/** @addtogroup libcipc
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * Transport layer modules messages.
    35  * @see tl_interface.h
    3633 */
    3734
    38 #ifndef LIBC_TL_MESSAGES_H_
    39 #define LIBC_TL_MESSAGES_H_
     35#ifndef LIBC_IPC_IPLINK_H_
     36#define LIBC_IPC_IPLINK_H_
    4037
    41 #include <ipc/net.h>
     38#include <ipc/common.h>
    4239
    43 /** Transport layer modules messages. */
    4440typedef enum {
    45         /** Packet received message.
    46          * @see tl_received_msg()
    47          */
    48         NET_TL_RECEIVED = NET_TL_FIRST
    49 } tl_messages;
     41        IPLINK_GET_MTU = IPC_FIRST_USER_METHOD,
     42        IPLINK_SEND,
     43        IPLINK_ADDR_ADD,
     44        IPLINK_ADDR_REMOVE
     45} iplink_request_t;
     46
     47typedef enum {
     48        IPLINK_EV_RECV = IPC_FIRST_USER_METHOD
     49} iplink_event_t;
    5050
    5151#endif
    5252
    53 /** @}
     53/**
     54 * @}
    5455 */
  • uspace/lib/c/include/ipc/services.h

    r3d93289a r0c37135  
    4848        SERVICE_IRC        = FOURCC('i', 'r', 'c', ' '),
    4949        SERVICE_CLIPBOARD  = FOURCC('c', 'l', 'i', 'p'),
    50         SERVICE_NETWORKING = FOURCC('n', 'e', 't', ' '),
    51         SERVICE_ETHERNET   = FOURCC('e', 't', 'h', ' '),
    52         SERVICE_NILDUMMY   = FOURCC('n', 'i', 'l', 'd'),
    53         SERVICE_IP         = FOURCC('i', 'p', 'v', '4'),
    54         SERVICE_ARP        = FOURCC('a', 'r', 'p', ' '),
    55         SERVICE_ICMP       = FOURCC('i', 'c', 'm', 'p'),
    5650        SERVICE_UDP        = FOURCC('u', 'd', 'p', ' '),
    5751        SERVICE_TCP        = FOURCC('t', 'c', 'p', ' ')
    5852} services_t;
     53
     54#define SERVICE_NAME_INET     "net/inet"
     55#define SERVICE_NAME_INETCFG  "net/inetcfg"
     56#define SERVICE_NAME_INETPING "net/inetping"
    5957
    6058#endif
  • uspace/lib/c/include/ipc/socket.h

    r3d93289a r0c37135  
    3838#define LIBC_SOCKET_MESSAGES_H_
    3939
    40 #include <ipc/net.h>
    41 
    4240/** Socket client messages. */
    4341typedef enum {
    4442        /** Creates a new socket. @see socket() */
    45         NET_SOCKET = NET_SOCKET_FIRST,
     43        NET_SOCKET = IPC_FIRST_USER_METHOD,
    4644        /** Binds the socket. @see bind() */
    4745        NET_SOCKET_BIND,
  • uspace/lib/c/include/net/in.h

    r3d93289a r0c37135  
    4545#define INET_ADDRSTRLEN  (4 * 3 + 3 + 1)
    4646
     47#define INADDR_ANY 0
     48
    4749/** Type definition of the INET address.
    4850 * @see in_addr
  • uspace/lib/net/Makefile

    r3d93289a r0c37135  
    3333
    3434SOURCES = \
    35         generic/generic.c \
    36         generic/net_remote.c \
    37         generic/net_checksum.c \
    38         generic/packet_client.c \
    39         generic/packet_remote.c \
    40         generic/protocol_map.c \
    41         adt/module_map.c \
    42         nil/nil_remote.c \
    43         nil/nil_skel.c \
    44         il/il_remote.c \
    45         il/il_skel.c \
    46         il/ip_remote.c \
    47         il/ip_client.c \
    48         il/arp_remote.c \
    49         tl/icmp_remote.c \
    50         tl/icmp_client.c \
    51         tl/socket_core.c \
    52         tl/tl_common.c \
    53         tl/tl_remote.c \
    54         tl/tl_skel.c
     35        tl/socket_core.c
    5536
    5637include $(USPACE_PREFIX)/Makefile.common
  • uspace/lib/net/include/socket_core.h

    r3d93289a r0c37135  
    4444#include <net/in.h>
    4545#include <net/device.h>
    46 #include <net/packet.h>
    4746#include <async.h>
    4847
     
    8079        /** Bound port. */
    8180        int port;
    82         /** Received packets queue. */
    83         dyn_fifo_t received;
    8481        /** Sockets for acceptance queue. */
    8582        dyn_fifo_t accepted;
     
    118115extern int socket_destroy(async_sess_t *, int, socket_cores_t *,
    119116    socket_ports_t *, void (*)(socket_core_t *));
    120 extern int socket_reply_packets(packet_t *, size_t *);
    121117extern socket_core_t *socket_port_find(socket_ports_t *, int, const uint8_t *,
    122118    size_t);
  • uspace/lib/net/tl/socket_core.c

    r3d93289a r0c37135  
    3636
    3737#include <socket_core.h>
    38 #include <packet_client.h>
    39 #include <packet_remote.h>
    4038#include <net/socket_codes.h>
    4139#include <net/in.h>
    4240#include <net/inet.h>
    43 #include <net/packet.h>
    4441#include <net/modules.h>
    4542#include <stdint.h>
     
    9289        }
    9390       
    94         /* Release all received packets */
    95         int packet_id;
    96         while ((packet_id = dyn_fifo_pop(&socket->received)) >= 0)
    97                 pq_release_remote(sess, packet_id);
    98        
    99         dyn_fifo_destroy(&socket->received);
    10091        dyn_fifo_destroy(&socket->accepted);
    10192       
     
    448439        socket->key_length = 0;
    449440        socket->specific_data = specific_data;
    450         rc = dyn_fifo_initialize(&socket->received, SOCKET_INITIAL_RECEIVED_SIZE);
     441       
     442        rc = dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
    451443        if (rc != EOK) {
    452444                free(socket);
    453445                return rc;
    454446        }
    455        
    456         rc = dyn_fifo_initialize(&socket->accepted, SOCKET_INITIAL_ACCEPTED_SIZE);
    457         if (rc != EOK) {
    458                 dyn_fifo_destroy(&socket->received);
    459                 free(socket);
    460                 return rc;
    461         }
    462447        socket->socket_id = *socket_id;
    463448        rc = socket_cores_add(local_sockets, socket->socket_id, socket);
    464449        if (rc < 0) {
    465                 dyn_fifo_destroy(&socket->received);
    466450                dyn_fifo_destroy(&socket->accepted);
    467451                free(socket);
     
    506490        socket_destroy_core(sess, socket, local_sockets, global_sockets,
    507491            socket_release);
    508        
    509         return EOK;
    510 }
    511 
    512 /** Replies the packet or the packet queue data to the application via the
    513  * socket.
    514  *
    515  * Uses the current message processing fibril.
    516  *
    517  * @param[in] packet    The packet to be transfered.
    518  * @param[out] length   The total data length.
    519  * @return              EOK on success.
    520  * @return              EBADMEM if the length parameter is NULL.
    521  * @return              ENOMEM if there is not enough memory left.
    522  * @return              Other error codes as defined for the data_reply()
    523  *                      function.
    524  */
    525 int socket_reply_packets(packet_t *packet, size_t *length)
    526 {
    527         packet_t *next_packet;
    528         size_t fragments;
    529         size_t *lengths;
    530         size_t index;
    531         int rc;
    532 
    533         if (!length)
    534                 return EBADMEM;
    535 
    536         next_packet = pq_next(packet);
    537         if (!next_packet) {
    538                 /* Write all if only one fragment */
    539                 rc = data_reply(packet_get_data(packet),
    540                     packet_get_data_length(packet));
    541                 if (rc != EOK)
    542                         return rc;
    543                 /* Store the total length */
    544                 *length = packet_get_data_length(packet);
    545         } else {
    546                 /* Count the packet fragments */
    547                 fragments = 1;
    548                 next_packet = pq_next(packet);
    549                 while ((next_packet = pq_next(next_packet)))
    550                         ++fragments;
    551                
    552                 /* Compute and store the fragment lengths */
    553                 lengths = (size_t *) malloc(sizeof(size_t) * fragments +
    554                     sizeof(size_t));
    555                 if (!lengths)
    556                         return ENOMEM;
    557                
    558                 lengths[0] = packet_get_data_length(packet);
    559                 lengths[fragments] = lengths[0];
    560                 next_packet = pq_next(packet);
    561                
    562                 for (index = 1; index < fragments; ++index) {
    563                         lengths[index] = packet_get_data_length(next_packet);
    564                         lengths[fragments] += lengths[index];
    565                         next_packet = pq_next(packet);
    566                 }
    567                
    568                 /* Write the fragment lengths */
    569                 rc = data_reply(lengths, sizeof(int) * (fragments + 1));
    570                 if (rc != EOK) {
    571                         free(lengths);
    572                         return rc;
    573                 }
    574                 next_packet = packet;
    575                
    576                 /* Write the fragments */
    577                 for (index = 0; index < fragments; ++index) {
    578                         rc = data_reply(packet_get_data(next_packet),
    579                             lengths[index]);
    580                         if (rc != EOK) {
    581                                 free(lengths);
    582                                 return rc;
    583                         }
    584                         next_packet = pq_next(next_packet);
    585                 }
    586                
    587                 /* Store the total length */
    588                 *length = lengths[fragments];
    589                 free(lengths);
    590         }
    591492       
    592493        return EOK;
  • uspace/srv/loc/loc.c

    r3d93289a r0c37135  
    12961296        categ_dir_add_cat(&cdir, cat);
    12971297
     1298        cat = category_new("iplink");
     1299        categ_dir_add_cat(&cdir, cat);
     1300
    12981301        cat = category_new("keyboard");
    12991302        categ_dir_add_cat(&cdir, cat);
  • uspace/srv/net/ethip/Makefile

    r3d93289a r0c37135  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2012 Jiri Svoboda
    43# All rights reserved.
    54#
     
    2827#
    2928
    30 USPACE_PREFIX = ../../../..
    31 LIBS = $(LIBNET_PREFIX)/libnet.a
    32 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
    33 BINARY = arp
     29USPACE_PREFIX = ../../..
     30BINARY = ethip
    3431
    3532SOURCES = \
    36         arp.c
     33        arp.c \
     34        atrans.c \
     35        ethip.c \
     36        ethip_nic.c \
     37        pdu.c
    3738
    3839include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/ethip/pdu.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup inet
    3030 * @{
    3131 */
     32/**
     33 * @file
     34 * @brief
     35 */
    3236
    33 #ifndef LIBNET_PACKET_REMOTE_H_
    34 #define LIBNET_PACKET_REMOTE_H_
     37#ifndef ETH_PDU_H_
     38#define ETH_PDU_H_
    3539
    36 #include <net/packet.h>
    37 #include <sys/types.h>
    38 #include <async.h>
     40#include "ethip.h"
    3941
    40 extern int packet_translate_remote(async_sess_t *, packet_t **, packet_id_t);
    41 extern packet_t *packet_get_4_remote(async_sess_t *, size_t, size_t, size_t,
    42     size_t);
    43 extern packet_t *packet_get_1_remote(async_sess_t *, size_t);
    44 extern void pq_release_remote(async_sess_t *, packet_id_t);
     42extern int eth_pdu_encode(eth_frame_t *, void **, size_t *);
     43extern int eth_pdu_decode(void *, size_t, eth_frame_t *);
     44extern void mac48_encode(mac48_addr_t *, void *);
     45extern void mac48_decode(void *, mac48_addr_t *);
     46extern int arp_pdu_encode(arp_eth_packet_t *, void **, size_t *);
     47extern int arp_pdu_decode(void *, size_t, arp_eth_packet_t *);
     48
    4549
    4650#endif
  • uspace/srv/net/ethip/std.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup ethip
    3030 * @{
    3131 */
    32 /** @file
    33  * General CRC and checksum computation.
     32/**
     33 * @file Ethernet, IP/Ethernet standard definitions
     34 *
    3435 */
    3536
    36 #ifndef LIBNET_CHECKSUM_H_
    37 #define LIBNET_CHECKSUM_H_
     37#ifndef ETHIP_STD_H_
     38#define ETHIP_STD_H_
    3839
    39 #include <byteorder.h>
    4040#include <sys/types.h>
    4141
    42 /** IP checksum value for computed zero checksum.
    43  *
    44  * Zero is returned as 0xFFFF (not flipped)
    45  *
    46  */
    47 #define IP_CHECKSUM_ZERO  0xffffU
     42#define ETH_ADDR_SIZE 6
     43#define IPV4_ADDR_SIZE 4
     44#define ETH_FRAME_MIN_SIZE 60
    4845
    49 #ifdef __BE__
     46/** Ethernet frame header */
     47typedef struct {
     48        /** Destination Address */
     49        uint8_t dest[ETH_ADDR_SIZE];
     50        /** Source Address */
     51        uint8_t src[ETH_ADDR_SIZE];
     52        /** Ethertype or Length */
     53        uint16_t etype_len;
     54} eth_header_t;
    5055
    51 #define compute_crc32(seed, data, length) \
    52         compute_crc32_be(seed, (uint8_t *) data, length)
     56/** ARP packet format (for 48-bit MAC addresses and IPv4) */
     57typedef struct {
     58        /** Hardware address space */
     59        uint16_t hw_addr_space;
     60        /** Protocol address space */
     61        uint16_t proto_addr_space;
     62        /** Hardware address size */
     63        uint8_t hw_addr_size;
     64        /** Protocol address size */
     65        uint8_t proto_addr_size;
     66        /** Opcode */
     67        uint16_t opcode;
     68        /** Sender hardware address */
     69        uint8_t sender_hw_addr[ETH_ADDR_SIZE];
     70        /** Sender protocol address */
     71        uint32_t sender_proto_addr;
     72        /** Target hardware address */
     73        uint8_t target_hw_addr[ETH_ADDR_SIZE];
     74        /** Target protocol address */
     75        uint32_t target_proto_addr;
     76} __attribute__((packed)) arp_eth_packet_fmt_t;
    5377
    54 #endif
     78enum arp_opcode_fmt {
     79        AOP_REQUEST = 1,
     80        AOP_REPLY   = 2
     81};
    5582
    56 #ifdef __LE__
     83enum arp_hw_addr_space {
     84        AHRD_ETHERNET = 1
     85};
    5786
    58 #define compute_crc32(seed, data, length) \
    59         compute_crc32_le(seed, (uint8_t *) data, length)
     87/** IP Ethertype */
     88enum ether_type {
     89        ETYPE_ARP = 0x0806,
     90        ETYPE_IP  = 0x0800
     91};
    6092
    61 #endif
    62 
    63 extern uint32_t compute_crc32_le(uint32_t, uint8_t *, size_t);
    64 extern uint32_t compute_crc32_be(uint32_t, uint8_t *, size_t);
    65 extern uint32_t compute_checksum(uint32_t, uint8_t *, size_t);
    66 extern uint16_t compact_checksum(uint32_t);
    67 extern uint16_t flip_checksum(uint16_t);
    68 extern uint16_t ip_checksum(uint8_t *, size_t);
    6993
    7094#endif
  • uspace/srv/net/inet/Makefile

    r3d93289a r0c37135  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2012 Jiri Svoboda
    43# All rights reserved.
    54#
     
    2827#
    2928
    30 USPACE_PREFIX = ../../../..
    31 LIBS = $(LIBNET_PREFIX)/libnet.a
    32 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
    33 BINARY = icmp
    34 STATIC_ONLY = y
     29USPACE_PREFIX = ../../..
     30BINARY = inet
    3531
    3632SOURCES = \
    37         icmp.c
     33        addrobj.c \
     34        icmp.c \
     35        inet.c \
     36        inet_link.c \
     37        inet_util.c \
     38        inetcfg.c \
     39        inetping.c \
     40        pdu.c \
     41        reass.c \
     42        sroute.c
    3843
    3944include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/inet/addrobj.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup inet
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * Internetwork layer module interface for the underlying network interface
    35  * layer. This interface is always called by the remote modules.
     32/**
     33 * @file
     34 * @brief
    3635 */
    3736
    38 #ifndef LIBNET_IL_REMOTE_H_
    39 #define LIBNET_IL_REMOTE_H_
     37#ifndef INET_ADDROBJ_H_
     38#define INET_ADDROBJ_H_
    4039
    41 #include <ipc/services.h>
    4240#include <sys/types.h>
    43 #include <net/device.h>
    44 #include <net/packet.h>
    45 #include <async.h>
     41#include "inet.h"
    4642
    47 /** @name Internetwork layer module interface
    48  * This interface is used by other modules.
    49  */
    50 /*@{*/
     43typedef enum {
     44        /* Find matching network address (using mask) */
     45        iaf_net,
     46        /* Find exact local address (not using mask) */
     47        iaf_addr
     48} inet_addrobj_find_t;
    5149
    52 extern int il_device_state_msg(async_sess_t *, nic_device_id_t,
    53     nic_device_state_t, services_t);
    54 extern int il_received_msg(async_sess_t *, nic_device_id_t, packet_t *,
    55     services_t);
    56 extern int il_mtu_changed_msg(async_sess_t *, nic_device_id_t, size_t,
    57     services_t);
    58 extern int il_addr_changed_msg(async_sess_t *, nic_device_id_t, size_t,
    59     const uint8_t *);
     50extern inet_addrobj_t *inet_addrobj_new(void);
     51extern void inet_addrobj_delete(inet_addrobj_t *);
     52extern void inet_addrobj_add(inet_addrobj_t *);
     53extern void inet_addrobj_remove(inet_addrobj_t *);
     54extern inet_addrobj_t *inet_addrobj_find(inet_addr_t *, inet_addrobj_find_t);
     55extern inet_addrobj_t *inet_addrobj_find_by_name(const char *, inet_link_t *);
     56extern inet_addrobj_t *inet_addrobj_get_by_id(sysarg_t);
     57extern int inet_addrobj_send_dgram(inet_addrobj_t *, inet_addr_t *,
     58    inet_dgram_t *, uint8_t, uint8_t, int);
     59extern int inet_addrobj_get_id_list(sysarg_t **, size_t *);
    6060
    61 /*@}*/
    6261
    6362#endif
  • uspace/srv/net/inet/icmp_std.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup udp
     29/** @addtogroup inet
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * UDP header definition.
    35  * Based on the RFC 768.
     32/**
     33 * @file ICMP standard definitions
     34 *
    3635 */
    3736
    38 #ifndef NET_UDP_HEADER_H_
    39 #define NET_UDP_HEADER_H_
     37#ifndef ICMP_STD_H_
     38#define ICMP_STD_H_
    4039
    4140#include <sys/types.h>
    4241
    43 /** UDP header size in bytes. */
    44 #define UDP_HEADER_SIZE         sizeof(udp_header_t)
     42#define IP_PROTO_ICMP 1
    4543
    46 /** Type definition of the user datagram header.
    47  * @see udp_header
    48  */
    49 typedef struct udp_header udp_header_t;
     44/** Type of service used for ICMP */
     45#define ICMP_TOS        0
    5046
    51 /** User datagram header. */
    52 struct udp_header {
    53         uint16_t source_port;
    54         uint16_t destination_port;
    55         uint16_t total_length;
     47/** ICMP message type */
     48enum icmp_type {
     49        ICMP_ECHO_REPLY   = 0,
     50        ICMP_ECHO_REQUEST = 8
     51};
     52
     53/** ICMP Echo Request or Reply message header */
     54typedef struct {
     55        /** ICMP message type */
     56        uint8_t type;
     57        /** Code (0) */
     58        uint8_t code;
     59        /** Internet checksum of the ICMP message */
    5660        uint16_t checksum;
    57 } __attribute__ ((packed));
     61        /** Indentifier */
     62        uint16_t ident;
     63        /** Sequence number */
     64        uint16_t seq_no;
     65} icmp_echo_t;
    5866
    5967#endif
  • uspace/srv/net/inet/inet_std.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
     29/** @addtogroup inet
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * ARP module messages.
    35  * @see arp_interface.h
     32/**
     33 * @file IP header definitions
     34 *
    3635 */
    3736
    38 #ifndef LIBC_ARP_MESSAGES_
    39 #define LIBC_ARP_MESSAGES_
     37#ifndef INET_STD_H_
     38#define INET_STD_H_
    4039
    41 #include <ipc/net.h>
     40#include <sys/types.h>
    4241
    43 /** ARP module messages. */
    44 typedef enum {
    45         /** Clean cache message.
    46          * @see arp_clean_cache()
    47         */
    48         NET_ARP_CLEAN_CACHE = NET_ARP_FIRST,
    49         /** Clear address cache message.
    50          * @see arp_clear_address_msg()
    51         */
    52         NET_ARP_CLEAR_ADDRESS,
    53         /** Clear device cache message.
    54          * @see arp_clear_device_req()
    55         */
    56         NET_ARP_CLEAR_DEVICE,
    57         /** New device message.
    58          * @see arp_device_req()
    59         */
    60         NET_ARP_DEVICE,
    61         /** Address translation message.
    62          * @see arp_translate_req()
    63         */
    64         NET_ARP_TRANSLATE
    65 } arp_messages;
     42/** Internet Datagram header (fixed part) */
     43typedef struct {
     44        /** Version, Internet Header Length */
     45        uint8_t ver_ihl;
     46        /* Type of Service */
     47        uint8_t tos;
     48        /** Total Length */
     49        uint16_t tot_len;
     50        /** Identification */
     51        uint16_t id;
     52        /** Flags, Fragment Offset */
     53        uint16_t flags_foff;
     54        /** Time to Live */
     55        uint8_t ttl;
     56        /** Protocol */
     57        uint8_t proto;
     58        /** Header Checksum */
     59        uint16_t chksum;
     60        /** Source Address */
     61        uint32_t src_addr;
     62        /** Destination Address */
     63        uint32_t dest_addr;
     64} ip_header_t;
    6665
    67 /** @name ARP specific message parameters definitions */
    68 /*@{*/
     66/** Bits in ip_header_t.ver_ihl */
     67enum ver_ihl_bits {
     68        /** Version, highest bit */
     69        VI_VERSION_h = 7,
     70        /** Version, lowest bit */
     71        VI_VERSION_l = 4,
     72        /** Internet Header Length, highest bit */
     73        VI_IHL_h     = 3,
     74        /** Internet Header Length, lowest bit */
     75        VI_IHL_l     = 0
     76};
    6977
    70 /** Return the protocol service message parameter.
    71  *
    72  * @param[in] call Message call structure.
    73  *
    74  */
    75 #define ARP_GET_NETIF(call) ((services_t) IPC_GET_ARG2(call))
     78/** Bits in ip_header_t.flags_foff */
     79enum flags_foff_bits {
     80        /** Reserved, must be zero */
     81        FF_FLAG_RSVD = 15,
     82        /** Don't Fragment */
     83        FF_FLAG_DF = 14,
     84        /** More Fragments */
     85        FF_FLAG_MF = 13,
     86        /** Fragment Offset, highest bit */
     87        FF_FRAGOFF_h = 12,
     88        /** Fragment Offset, lowest bit */
     89        FF_FRAGOFF_l = 0
     90};
    7691
    77 /*@}*/
     92/** Fragment offset is expressed in units of 8 bytes */
     93#define FRAG_OFFS_UNIT 8
    7894
    7995#endif
  • uspace/srv/net/tcp/Makefile

    r3d93289a r0c37135  
    2727#
    2828
    29 USPACE_PREFIX = ../../../..
     29USPACE_PREFIX = ../../..
    3030LIBS = $(LIBNET_PREFIX)/libnet.a
    3131EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
  • uspace/srv/net/tcp/conn.c

    r3d93289a r0c37135  
    309309}
    310310
    311 /** Compare two sockets.
    312  *
    313  * Two sockets are equal if the address is equal and the port number
    314  * is equal.
    315  */
     311/** Match socket with pattern. */
    316312static bool tcp_socket_match(tcp_sock_t *sock, tcp_sock_t *patt)
    317313{
     
    332328}
    333329
    334 /** Match socket with pattern. */
     330/** Match socket pair with pattern. */
    335331static bool tcp_sockpair_match(tcp_sockpair_t *sp, tcp_sockpair_t *pattern)
    336332{
     
    357353tcp_conn_t *tcp_conn_find_ref(tcp_sockpair_t *sp)
    358354{
    359         log_msg(LVL_DEBUG, "tcp_conn_find(%p)", sp);
     355        log_msg(LVL_DEBUG, "tcp_conn_find_ref(%p)", sp);
    360356
    361357        fibril_mutex_lock(&conn_list_lock);
  • uspace/srv/net/tcp/pdu.c

    r3d93289a r0c37135  
    255255}
    256256
    257 /** Encode outgoing PDU */
     257/** Decode incoming PDU */
    258258int tcp_pdu_decode(tcp_pdu_t *pdu, tcp_sockpair_t *sp, tcp_segment_t **seg)
    259259{
     
    279279}
    280280
    281 /** Decode incoming PDU */
     281/** Encode outgoing PDU */
    282282int tcp_pdu_encode(tcp_sockpair_t *sp, tcp_segment_t *seg, tcp_pdu_t **pdu)
    283283{
  • uspace/srv/net/tcp/sock.c

    r3d93289a r0c37135  
    3838#include <async.h>
    3939#include <errno.h>
     40#include <inet/inet.h>
    4041#include <io/log.h>
    41 #include <ip_client.h>
     42#include <ipc/services.h>
    4243#include <ipc/socket.h>
    4344#include <net/modules.h>
    4445#include <net/socket.h>
     46#include <ns.h>
    4547
    4648#include "sock.h"
     
    6365static socket_ports_t gsock;
    6466
     67static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg);
    6568static void tcp_sock_cstate_cb(tcp_conn_t *conn, void *arg);
    6669
    67 void tcp_sock_init(void)
    68 {
     70int tcp_sock_init(void)
     71{
     72        int rc;
     73
    6974        socket_ports_initialize(&gsock);
     75
     76        async_set_client_connection(tcp_sock_connection);
     77
     78        rc = service_register(SERVICE_TCP);
     79        if (rc != EOK)
     80                return EEXIST;
     81
     82        return EOK;
    7083}
    7184
     
    273286        tcp_sock_t lsocket;
    274287        tcp_sock_t fsocket;
    275         nic_device_id_t dev_id;
    276         tcp_phdr_t *phdr;
    277         size_t phdr_len;
    278288
    279289        log_msg(LVL_DEBUG, "tcp_sock_connect()");
     
    309319
    310320        if (socket->laddr.ipv4 == TCP_IPV4_ANY) {
    311                 /* Find route to determine local IP address. */
    312                 rc = ip_get_route_req(ip_sess, IPPROTO_TCP,
    313                     (struct sockaddr *)addr, sizeof(*addr), &dev_id,
    314                     (void **)&phdr, &phdr_len);
     321                /* Determine local IP address */
     322                inet_addr_t loc_addr, rem_addr;
     323
     324                rem_addr.ipv4 = uint32_t_be2host(addr->sin_addr.s_addr);
     325                rc = inet_get_srcaddr(&rem_addr, 0, &loc_addr);
    315326                if (rc != EOK) {
    316327                        fibril_mutex_unlock(&socket->lock);
    317328                        async_answer_0(callid, rc);
    318                         log_msg(LVL_DEBUG, "tcp_transmit_connect: Failed to find route.");
    319                         return;
    320                 }
    321 
    322                 socket->laddr.ipv4 = uint32_t_be2host(phdr->src_addr);
     329                        log_msg(LVL_DEBUG, "tcp_sock_connect: Failed to "
     330                            "determine local address.");
     331                        return;
     332                }
     333
     334                socket->laddr.ipv4 = loc_addr.ipv4;
    323335                log_msg(LVL_DEBUG, "Local IP address is %x", socket->laddr.ipv4);
    324                 free(phdr);
    325336        }
    326337
     
    713724        }
    714725
    715         rc = socket_destroy(net_sess, socket_id, &client->sockets, &gsock,
     726        rc = socket_destroy(NULL, socket_id, &client->sockets, &gsock,
    716727            tcp_free_sock_data);
    717728        if (rc != EOK) {
     
    764775}
    765776
    766 int tcp_sock_connection(async_sess_t *sess, ipc_callid_t iid, ipc_call_t icall)
     777static void tcp_sock_connection(ipc_callid_t iid, ipc_call_t *icall, void *arg)
    767778{
    768779        ipc_callid_t callid;
     
    773784        async_answer_0(iid, EOK);
    774785
    775         client.sess = sess;
     786        client.sess = async_callback_receive(EXCHANGE_SERIALIZE);
    776787        socket_cores_initialize(&client.sockets);
    777788
     
    824835                }
    825836        }
    826 
    827         return EOK;
    828837}
    829838
  • uspace/srv/net/tcp/sock.h

    r3d93289a r0c37135  
    3838#include <async.h>
    3939
    40 extern void tcp_sock_init(void);
    41 extern int tcp_sock_connection(async_sess_t *, ipc_callid_t, ipc_call_t);
     40extern int tcp_sock_init(void);
    4241
    4342#endif
  • uspace/srv/net/tcp/tcp.h

    r3d93289a r0c37135  
    3737
    3838#include <async.h>
    39 #include <packet_remote.h>
    4039#include "tcp_type.h"
    4140
    42 extern async_sess_t *net_sess;
    43 extern async_sess_t *ip_sess;
    4441extern void tcp_transmit_pdu(tcp_pdu_t *);
    4542
  • uspace/srv/net/udp/Makefile

    r3d93289a r0c37135  
    11#
    2 # Copyright (c) 2005 Martin Decky
    3 # Copyright (c) 2007 Jakub Jermar
     2# Copyright (c) 2012 Jiri Svoboda
    43# All rights reserved.
    54#
     
    2827#
    2928
    30 USPACE_PREFIX = ../../../..
     29USPACE_PREFIX = ../../..
    3130LIBS = $(LIBNET_PREFIX)/libnet.a
    3231EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include
     
    3433
    3534SOURCES = \
    36         udp.c
     35        assoc.c \
     36        msg.c \
     37        sock.c \
     38        pdu.c \
     39        ucall.c \
     40        udp.c \
     41        udp_inet.c
    3742
    3843include $(USPACE_PREFIX)/Makefile.common
  • uspace/srv/net/udp/assoc.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup udp
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * Ethernet protocol numbers according to the on-line IANA - Ethernet numbers
    35  * http://www.iana.org/assignments/ethernet-numbers
    36  * cited January 17 2009.
     32/** @file UDP associations
    3733 */
    3834
    39 #ifndef LIBNET_ETHERNET_PROTOCOLS_H_
    40 #define LIBNET_ETHERNET_PROTOCOLS_H_
     35#ifndef ASSOC_H
     36#define ASSOC_H
    4137
    4238#include <sys/types.h>
     39#include "udp_type.h"
    4340
    44 /** Ethernet protocol type definition. */
    45 typedef uint16_t eth_type_t;
     41extern udp_assoc_t *udp_assoc_new(udp_sock_t *, udp_sock_t *);
     42extern void udp_assoc_delete(udp_assoc_t *);
     43extern void udp_assoc_add(udp_assoc_t *);
     44extern void udp_assoc_remove(udp_assoc_t *);
     45extern void udp_assoc_addref(udp_assoc_t *);
     46extern void udp_assoc_delref(udp_assoc_t *);
     47extern void udp_assoc_set_foreign(udp_assoc_t *, udp_sock_t *);
     48extern void udp_assoc_set_local(udp_assoc_t *, udp_sock_t *);
     49extern int udp_assoc_send(udp_assoc_t *, udp_sock_t *, udp_msg_t *);
     50extern int udp_assoc_recv(udp_assoc_t *, udp_msg_t **, udp_sock_t *);
     51extern void udp_assoc_received(udp_sockpair_t *, udp_msg_t *);
    4652
    47 /** @name Ethernet protocols definitions */
    48 /*@{*/
    49 
    50 /** Ethernet minimal protocol number.
    51  * According to the IEEE 802.3 specification.
    52  */
    53 #define ETH_MIN_PROTO           0x0600 /* 1536 */
    54 
    55 /** Internet IP (IPv4) ethernet protocol type. */
    56 #define ETH_P_IP                0x0800
    57 
    58 /** ARP ethernet protocol type. */
    59 #define ETH_P_ARP               0x0806
    60 
    61 /*@}*/
    6253
    6354#endif
  • uspace/srv/net/udp/sock.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
    30  *  @{
     29/** @addtogroup udp
     30 * @{
     31 */
     32/** @file Socket provider
    3133 */
    3234
    33 /** @file
    34  * ICMP module common interface.
    35  */
     35#ifndef SOCK_H
     36#define SOCK_H
    3637
    37 #ifndef LIBC_ICMP_COMMON_H_
    38 #define LIBC_ICMP_COMMON_H_
    39 
    40 #include <ipc/services.h>
    41 #include <sys/time.h>
    4238#include <async.h>
    4339
    44 extern async_sess_t *icmp_connect_module(void);
     40extern int udp_sock_init(void);
    4541
    4642#endif
  • uspace/srv/net/udp/ucall.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libc
     29/** @addtogroup udp
    3030 * @{
    3131 */
    32 
    33 /** @file
    34  * ICMP module application interface.
     32/** @file UDP user calls
    3533 */
    3634
    37 #ifndef LIBC_ICMP_API_H_
    38 #define LIBC_ICMP_API_H_
     35#ifndef UCALL_H
     36#define UCALL_H
    3937
    40 #include <net/socket_codes.h>
    41 #include <net/inet.h>
    4238#include <sys/types.h>
    43 #include <sys/time.h>
    44 #include <adt/measured_strings.h>
    45 #include <net/ip_codes.h>
    46 #include <net/icmp_codes.h>
    47 #include <net/icmp_common.h>
    48 #include <async.h>
     39#include "udp_type.h"
    4940
    50 /** @name ICMP module application interface
    51  * This interface is used by other application modules.
    52  */
    53 /*@{*/
    54 
    55 extern int icmp_echo_msg(async_sess_t *, size_t, mseconds_t, ip_ttl_t, ip_tos_t,
    56     int, const struct sockaddr *, socklen_t);
    57 
    58 /*@}*/
     41extern udp_error_t udp_uc_create(udp_assoc_t **);
     42extern udp_error_t udp_uc_set_foreign(udp_assoc_t *, udp_sock_t *);
     43extern udp_error_t udp_uc_set_local(udp_assoc_t *, udp_sock_t *);
     44extern udp_error_t udp_uc_send(udp_assoc_t *, udp_sock_t *, void *, size_t,
     45    xflags_t);
     46extern udp_error_t udp_uc_receive(udp_assoc_t *, void *, size_t, size_t *,
     47    xflags_t *, udp_sock_t *);
     48extern void udp_uc_status(udp_assoc_t *, udp_assoc_status_t *);
     49extern void udp_uc_destroy(udp_assoc_t *);
    5950
    6051#endif
  • uspace/srv/net/udp/udp.c

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2008 Lukas Mejdrech
     2 * Copyright (c) 2012 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    3131 */
    3232
    33 /** @file
    34  * UDP module.
     33/**
     34 * @file UDP (User Datagram Protocol) service
    3535 */
    3636
    37 #ifndef NET_UDP_H_
    38 #define NET_UDP_H_
     37#include <async.h>
     38#include <errno.h>
     39#include <io/log.h>
     40#include <stdio.h>
     41#include <task.h>
    3942
    40 #include <async.h>
    41 #include <fibril_synch.h>
    42 #include <socket_core.h>
    43 #include <tl_common.h>
     43#include "udp_inet.h"
     44#include "sock.h"
    4445
    45 /** Type definition of the UDP global data.
    46  * @see udp_globals
     46#define NAME       "udp"
     47
     48static int udp_init(void)
     49{
     50        int rc;
     51
     52        log_msg(LVL_DEBUG, "udp_init()");
     53
     54        rc = udp_inet_init();
     55        if (rc != EOK) {
     56                log_msg(LVL_ERROR, "Failed connecting to internet service.");
     57                return ENOENT;
     58        }
     59
     60        rc = udp_sock_init();
     61        if (rc != EOK) {
     62                log_msg(LVL_ERROR, "Failed initializing socket service.");
     63                return ENOENT;
     64        }
     65
     66        return EOK;
     67}
     68
     69int main(int argc, char **argv)
     70{
     71        int rc;
     72
     73        printf(NAME ": UDP (User Datagram Protocol) service\n");
     74
     75        rc = log_init(NAME, LVL_WARN);
     76        if (rc != EOK) {
     77                printf(NAME ": Failed to initialize log.\n");
     78                return 1;
     79        }
     80
     81        rc = udp_init();
     82        if (rc != EOK)
     83                return 1;
     84
     85        printf(NAME ": Accepting connections.\n");
     86        task_retval(0);
     87        async_manager();
     88
     89        /* Not reached */
     90        return 0;
     91}
     92
     93/**
     94 * @}
    4795 */
    48 typedef struct udp_globals udp_globals_t;
    49 
    50 /** UDP global data. */
    51 struct udp_globals {
    52         /** Networking module session. */
    53         async_sess_t *net_sess;
    54         /** IP module session. */
    55         async_sess_t *ip_sess;
    56         /** ICMP module session. */
    57         async_sess_t *icmp_sess;
    58         /** Packet dimension. */
    59         packet_dimension_t packet_dimension;
    60         /** Indicates whether UDP checksum computing is enabled. */
    61         int checksum_computing;
    62         /** Indicates whether UDP autobnding on send is enabled. */
    63         int autobinding;
    64         /** Last used free port. */
    65         int last_used_port;
    66         /** Active sockets. */
    67         socket_ports_t sockets;
    68         /** Device packet dimensions. */
    69         packet_dimensions_t dimensions;
    70         /** Safety lock. */
    71         fibril_rwlock_t lock;
    72 };
    73 
    74 #endif
    75 
    76 /** @}
    77  */
  • uspace/srv/net/udp/udp_inet.h

    r3d93289a r0c37135  
    11/*
    2  * Copyright (c) 2009 Lukas Mejdrech
     2 * Copyright (c) 2011 Jiri Svoboda
    33 * All rights reserved.
    44 *
     
    2727 */
    2828
    29 /** @addtogroup libnet
     29/** @addtogroup udp
    3030 * @{
    3131 */
    32 
    3332/** @file
    34  * ICMP client interface.
    3533 */
    3634
    37 #ifndef LIBNET_ICMP_CLIENT_H_
    38 #define LIBNET_ICMP_CLIENT_H_
     35#ifndef UDP_INET_H
     36#define UDP_INET_H
    3937
    40 #include <net/icmp_codes.h>
    41 #include <net/packet.h>
     38#include "udp_type.h"
    4239
    43 extern int icmp_client_process_packet(packet_t *, icmp_type_t *, icmp_code_t *,
    44     icmp_param_t *, icmp_param_t *);
    45 extern size_t icmp_client_header_length(packet_t *);
     40extern int udp_inet_init(void);
     41extern int udp_transmit_pdu(udp_pdu_t *);
    4642
    4743#endif
Note: See TracChangeset for help on using the changeset viewer.