Changeset f1938c6 in mainline
- Timestamp:
- 2011-01-17T15:41:30Z (14 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- a2d8d59, ffaba00
- Parents:
- 9f3864a
- Location:
- uspace
- Files:
-
- 1 deleted
- 12 edited
- 1 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/app/ping/ping.c
r9f3864a rf1938c6 340 340 config.dest_str, config.size, config.size); 341 341 342 int icmp_phone = icmp_connect_module( SERVICE_ICMP,ICMP_CONNECT_TIMEOUT);342 int icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 343 343 if (icmp_phone < 0) { 344 344 fprintf(stderr, "%s: Unable to connect to ICMP service (%s)\n", NAME, -
uspace/lib/c/generic/net/icmp_common.c
r9f3864a rf1938c6 27 27 */ 28 28 29 /** @addtogroup libc 29 /** @addtogroup libc 30 30 * @{ 31 31 */ … … 38 38 #include <net/modules.h> 39 39 #include <net/icmp_common.h> 40 41 40 #include <ipc/services.h> 42 41 #include <ipc/icmp.h> 43 44 42 #include <sys/time.h> 45 43 #include <async.h> 46 44 47 /** Connect sto the ICMP module.45 /** Connect to the ICMP module. 48 46 * 49 * @param service The ICMP module service. Ignored parameter. 50 * @param[in] timeout The connection timeout in microseconds. No timeout if 51 * set to zero. 52 * @return The ICMP module phone on success. 53 * @return ETIMEOUT if the connection timeouted. 47 * @param[in] timeout Connection timeout in microseconds, zero 48 * for no timeout. 49 * 50 * @return ICMP module phone on success. 51 * @return ETIMEOUT if the connection timeouted. 52 * 54 53 */ 55 int icmp_connect_module(s ervices_t service, suseconds_t timeout)54 int icmp_connect_module(suseconds_t timeout) 56 55 { 57 int phone; 58 59 phone = connect_to_service_timeout(SERVICE_ICMP, timeout); 60 if (phone >= 0) 61 async_req_0_0(phone, NET_ICMP_INIT); 62 63 return phone; 56 return connect_to_service_timeout(SERVICE_ICMP, timeout); 64 57 } 65 58 -
uspace/lib/c/include/ipc/icmp.h
r9f3864a rf1938c6 33 33 /** @file 34 34 * ICMP module messages. 35 * @see icmp_ interface.h35 * @see icmp_remote.h 36 36 */ 37 37 … … 48 48 /** ICMP module messages. */ 49 49 typedef enum { 50 /** Send secho request. @see icmp_echo() */50 /** Send echo request. @see icmp_echo() */ 51 51 NET_ICMP_ECHO = NET_ICMP_FIRST, 52 52 53 53 /** 54 * Send sdestination unreachable error message.54 * Send destination unreachable error message. 55 55 * @see icmp_destination_unreachable_msg() 56 56 */ … … 58 58 59 59 /** 60 * Send ssource quench error message.60 * Send source quench error message. 61 61 * @see icmp_source_quench_msg() 62 62 */ … … 64 64 65 65 /** 66 * Send stime exceeded error message.66 * Send time exceeded error message. 67 67 * @see icmp_time_exceeded_msg() 68 68 */ … … 70 70 71 71 /** 72 * Send sparameter problem error message.72 * Send parameter problem error message. 73 73 * @see icmp_parameter_problem_msg() 74 74 */ 75 NET_ICMP_PARAMETERPROB, 76 77 /** Initializes new connection. */ 78 NET_ICMP_INIT 79 } icmp_messages; 75 NET_ICMP_PARAMETERPROB 76 } icmp_messages_t; 80 77 81 78 /** @name ICMP specific message parameters definitions */ -
uspace/lib/c/include/net/icmp_common.h
r9f3864a rf1938c6 41 41 #include <sys/time.h> 42 42 43 /** Default timeout for incoming connections in microseconds . */44 #define ICMP_CONNECT_TIMEOUT (1 * 1000 * 1000)43 /** Default timeout for incoming connections in microseconds (1 sec). */ 44 #define ICMP_CONNECT_TIMEOUT 1000000 45 45 46 extern int icmp_connect_module(s ervices_t, suseconds_t);46 extern int icmp_connect_module(suseconds_t); 47 47 48 48 #endif -
uspace/lib/net/include/icmp_remote.h
r9f3864a rf1938c6 27 27 */ 28 28 29 /** @addtogroup libnet 29 /** @addtogroup libnet 30 30 * @{ 31 31 */ 32 32 33 #ifndef LIBNET_ICMP_ INTERFACE_H_34 #define LIBNET_ICMP_ INTERFACE_H_33 #ifndef LIBNET_ICMP_REMOTE_H_ 34 #define LIBNET_ICMP_REMOTE_H_ 35 35 36 36 #include <net/socket_codes.h> … … 54 54 extern int icmp_source_quench_msg(int, packet_t *); 55 55 extern int icmp_time_exceeded_msg(int, icmp_code_t, packet_t *); 56 extern int icmp_parameter_problem_msg(int, icmp_code_t, icmp_param_t, packet_t *); 56 extern int icmp_parameter_problem_msg(int, icmp_code_t, icmp_param_t, 57 packet_t *); 57 58 58 59 /*@}*/ -
uspace/lib/net/include/tl_skel.h
r9f3864a rf1938c6 61 61 extern int tl_initialize(int net_phone); 62 62 63 /** Per-connection module initialization. 64 * 65 * This has to be implemented in user code. 66 * 67 */ 68 extern void tl_connection(void); 69 63 70 /** Process the transport layer module message. 64 71 * … … 74 81 * 75 82 */ 76 extern int tl_m odule_message(ipc_callid_t, ipc_call_t *,83 extern int tl_message(ipc_callid_t, ipc_call_t *, 77 84 ipc_call_t *, size_t *); 78 85 -
uspace/lib/net/tl/icmp_remote.c
r9f3864a rf1938c6 33 33 /** @file 34 34 * ICMP interface implementation for remote modules. 35 * @see icmp_ interface.h35 * @see icmp_remote.h 36 36 */ 37 37 38 #include <icmp_ interface.h>38 #include <icmp_remote.h> 39 39 #include <net/modules.h> 40 40 #include <packet_client.h> -
uspace/lib/net/tl/tl_common.c
r9f3864a rf1938c6 27 27 */ 28 28 29 /** @addtogroup libnet 29 /** @addtogroup libnet 30 30 * @{ 31 31 */ … … 39 39 #include <packet_client.h> 40 40 #include <packet_remote.h> 41 #include <icmp_ interface.h>41 #include <icmp_remote.h> 42 42 #include <ip_remote.h> 43 43 #include <ip_interface.h> -
uspace/lib/net/tl/tl_skel.c
r9f3864a rf1938c6 56 56 ipc_answer_0(iid, EOK); 57 57 58 /* Per-connection initialization */ 59 tl_connection(); 60 58 61 while (true) { 59 62 ipc_call_t answer; … … 68 71 69 72 /* Process the message */ 70 int res = tl_module_message(callid, &call, &answer, 71 &count); 73 int res = tl_message(callid, &call, &answer, &count); 72 74 73 75 /* -
uspace/srv/net/il/ip/ip.c
r9f3864a rf1938c6 67 67 #include <net_checksum.h> 68 68 #include <icmp_client.h> 69 #include <icmp_ interface.h>69 #include <icmp_remote.h> 70 70 #include <ip_client.h> 71 71 #include <ip_interface.h> -
uspace/srv/net/tl/icmp/icmp.c
r9f3864a rf1938c6 33 33 /** @file 34 34 * ICMP module implementation. 35 * @see icmp.h36 35 */ 37 36 … … 51 50 #include <byteorder.h> 52 51 #include <errno.h> 52 #include <adt/hash_table.h> 53 53 54 54 #include <net/socket_codes.h> … … 64 64 #include <net_checksum.h> 65 65 #include <icmp_client.h> 66 #include <icmp_ interface.h>66 #include <icmp_remote.h> 67 67 #include <il_remote.h> 68 68 #include <ip_client.h> … … 73 73 #include <icmp_header.h> 74 74 75 #include "icmp.h" 76 77 /** ICMP module name. */ 75 /** ICMP module name */ 78 76 #define NAME "icmp" 79 77 80 /** Default ICMP error reporting. */ 81 #define NET_DEFAULT_ICMP_ERROR_REPORTING true 82 83 /** Default ICMP echo replying. */ 84 #define NET_DEFAULT_ICMP_ECHO_REPLYING true 85 86 /** Original datagram length in bytes transfered to the error notification 87 * message. 88 */ 89 #define ICMP_KEEP_LENGTH 8 90 91 /** Free identifier numbers pool start. */ 92 #define ICMP_FREE_IDS_START 1 93 94 /** Free identifier numbers pool end. */ 95 #define ICMP_FREE_IDS_END UINT16_MAX 96 97 /** Computes the ICMP datagram checksum. 98 * 99 * @param[in,out] header The ICMP datagram header. 100 * @param[in] length The total datagram length. 101 * @return The computed checksum. 78 /** Number of replies hash table keys */ 79 #define REPLY_KEYS 2 80 81 /** Number of replies hash table buckets */ 82 #define REPLY_BUCKETS 1024 83 84 /** 85 * Original datagram length in bytes transfered to the error 86 * notification message. 87 */ 88 #define ICMP_KEEP_LENGTH 8 89 90 /** Compute the ICMP datagram checksum. 91 * 92 * @param[in,out] header ICMP datagram header. 93 * @param[in] length Total datagram length. 94 * 95 * @return Computed checksum. 96 * 102 97 */ 103 98 #define ICMP_CHECKSUM(header, length) \ … … 105 100 106 101 /** An echo request datagrams pattern. */ 107 #define ICMP_ECHO_TEXT "Hello from HelenOS." 108 109 /** Computes an ICMP reply data key. 110 * 111 * @param[in] id The message identifier. 112 * @param[in] sequence The message sequence number. 113 * @return The computed ICMP reply data key. 114 */ 115 #define ICMP_GET_REPLY_KEY(id, sequence) \ 116 (((id) << 16) | (sequence & 0xFFFF)) 117 118 119 /** ICMP global data. */ 120 icmp_globals_t icmp_globals; 121 122 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t); 123 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t); 124 125 /** Releases the packet and returns the result. 126 * 127 * @param[in] packet The packet queue to be released. 128 * @param[in] result The result to be returned. 129 * @return The result parameter. 130 */ 131 static int icmp_release_and_return(packet_t *packet, int result) 132 { 133 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 134 return result; 135 } 136 137 /** Sends the ICMP message. 138 * 139 * Sets the message type and code and computes the checksum. 102 #define ICMP_ECHO_TEXT "ICMP hello from HelenOS." 103 104 /** ICMP reply data. */ 105 typedef struct { 106 /** Hash table link */ 107 link_t link; 108 109 /** Reply identification and sequence */ 110 icmp_param_t id; 111 icmp_param_t sequence; 112 113 /** Reply signaling */ 114 fibril_condvar_t condvar; 115 116 /** Reply result */ 117 int result; 118 } icmp_reply_t; 119 120 /** Global data */ 121 static int phone_net = -1; 122 static int phone_ip = -1; 123 static bool error_reporting = true; 124 static bool echo_replying = true; 125 126 /** ICMP client identification counter */ 127 static atomic_t icmp_client; 128 static packet_dimension_t icmp_dimension; 129 130 /** ICMP identifier and sequence number */ 131 static fibril_local icmp_param_t icmp_id; 132 static fibril_local icmp_param_t icmp_seq; 133 134 /** Reply hash table */ 135 static fibril_mutex_t reply_lock; 136 static hash_table_t replies; 137 138 static hash_index_t replies_hash(unsigned long key[]) 139 { 140 /* 141 * ICMP identifier and sequence numbers 142 * are 16-bit values. 143 */ 144 hash_index_t index = (key[0] & 0xffff) << 16 | (key[1] & 0xffff); 145 return index % REPLY_BUCKETS; 146 } 147 148 static int replies_compare(unsigned long key[], hash_count_t keys, link_t *item) 149 { 150 icmp_reply_t *reply = 151 hash_table_get_instance(item, icmp_reply_t, link); 152 153 if (keys == 1) 154 return (reply->id == key[0]); 155 else 156 return ((reply->id == key[0]) && (reply->sequence == key[1])); 157 } 158 159 static void replies_remove_callback(link_t *item) 160 { 161 } 162 163 static hash_table_operations_t reply_ops = { 164 .hash = replies_hash, 165 .compare = replies_compare, 166 .remove_callback = replies_remove_callback 167 }; 168 169 /** Release the packet and return the result. 170 * 171 * @param[in] packet Packet queue to be released. 172 * 173 */ 174 static void icmp_release(packet_t *packet) 175 { 176 pq_release_remote(phone_net, packet_get_id(packet)); 177 } 178 179 /** Send the ICMP message. 180 * 181 * Set the message type and code and compute the checksum. 140 182 * Error messages are sent only if allowed in the configuration. 141 * Releases the packet on errors. 142 * 143 * @param[in] type The message type. 144 * @param[in] code The message code. 145 * @param[in] packet The message packet to be sent. 146 * @param[in] header The ICMP header. 147 * @param[in] error The error service to be announced. Should be 148 * SERVICE_ICMP or zero. 149 * @param[in] ttl The time to live. 150 * @param[in] tos The type of service. 151 * @param[in] dont_fragment The value indicating whether the datagram must not 152 * be fragmented. Is used as a MTU discovery. 153 * @return EOK on success. 154 * @return EPERM if the error message is not allowed. 155 */ 156 static int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t *packet, 157 icmp_header_t *header, services_t error, ip_ttl_t ttl, ip_tos_t tos, 158 int dont_fragment) 159 { 160 int rc; 161 183 * Release the packet on errors. 184 * 185 * @param[in] type Message type. 186 * @param[in] code Message code. 187 * @param[in] packet Message packet to be sent. 188 * @param[in] header ICMP header. 189 * @param[in] error Error service to be announced. Should be 190 * SERVICE_ICMP or zero. 191 * @param[in] ttl Time to live. 192 * @param[in] tos Type of service. 193 * @param[in] dont_fragment Disable fragmentation. 194 * 195 * @return EOK on success. 196 * @return EPERM if the error message is not allowed. 197 * 198 */ 199 static int icmp_send_packet(icmp_type_t type, icmp_code_t code, 200 packet_t *packet, icmp_header_t *header, services_t error, ip_ttl_t ttl, 201 ip_tos_t tos, bool dont_fragment) 202 { 162 203 /* Do not send an error if disabled */ 163 if (error && !icmp_globals.error_reporting) 164 return icmp_release_and_return(packet, EPERM); 165 204 if ((error) && (!error_reporting)) { 205 icmp_release(packet); 206 return EPERM; 207 } 208 166 209 header->type = type; 167 210 header->code = code; … … 170 213 packet_get_data_length(packet)); 171 214 172 rc = ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos,215 int rc = ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, 173 216 dont_fragment, 0); 174 if (rc != EOK) 175 return icmp_release_and_return(packet, rc); 176 177 return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, 178 error); 179 } 180 181 /** Prepares the ICMP error packet. 182 * 183 * Truncates the original packet if longer than ICMP_KEEP_LENGTH bytes. 184 * Prefixes and returns the ICMP header. 185 * 186 * @param[in,out] packet The original packet. 217 if (rc != EOK) { 218 icmp_release(packet); 219 return rc; 220 } 221 222 return ip_send_msg(phone_ip, -1, packet, SERVICE_ICMP, error); 223 } 224 225 /** Prepare the ICMP error packet. 226 * 227 * Truncate the original packet if longer than ICMP_KEEP_LENGTH bytes. 228 * Prefix and return the ICMP header. 229 * 230 * @param[in,out] packet Original packet. 231 * 187 232 * @return The prefixed ICMP header. 188 233 * @return NULL on errors. 234 * 189 235 */ 190 236 static icmp_header_t *icmp_prepare_packet(packet_t *packet) 191 237 { 192 icmp_header_t *header; 193 size_t header_length; 194 size_t total_length; 195 196 total_length = packet_get_data_length(packet); 238 size_t total_length = packet_get_data_length(packet); 197 239 if (total_length <= 0) 198 240 return NULL; 199 200 header_length = ip_client_header_length(packet);241 242 size_t header_length = ip_client_header_length(packet); 201 243 if (header_length <= 0) 202 244 return NULL; 203 245 204 246 /* Truncate if longer than 64 bits (without the IP header) */ 205 247 if ((total_length > header_length + ICMP_KEEP_LENGTH) && 206 248 (packet_trim(packet, 0, 207 total_length - header_length - ICMP_KEEP_LENGTH) != EOK)) {249 total_length - header_length - ICMP_KEEP_LENGTH) != EOK)) 208 250 return NULL; 209 } 210 211 header = PACKET_PREFIX(packet, icmp_header_t); 251 252 icmp_header_t *header = PACKET_PREFIX(packet, icmp_header_t); 212 253 if (!header) 213 254 return NULL; 214 255 215 256 bzero(header, sizeof(*header)); 216 257 return header; 217 258 } 218 259 219 /** Requests an echo message. 220 * 221 * Sends a packet with specified parameters to the target host and waits for 222 * the reply upto the given timeout. 223 * Blocks the caller until the reply or the timeout occurs. 224 * 225 * @param[in] id The message identifier. 226 * @param[in] sequence The message sequence parameter. 227 * @param[in] size The message data length in bytes. 228 * @param[in] timeout The timeout in miliseconds. 229 * @param[in] ttl The time to live. 230 * @param[in] tos The type of service. 231 * @param[in] dont_fragment The value indicating whether the datagram must not 232 * be fragmented. Is used as a MTU discovery. 233 * @param[in] addr The target host address. 234 * @param[in] addrlen The torget host address length. 235 * @return ICMP_ECHO on success. 236 * @return ETIMEOUT if the reply has not arrived before the 237 * timeout. 238 * @return ICMP type of the received error notification. 239 * @return EINVAL if the addrlen parameter is less or equal to 240 * zero. 241 * @return ENOMEM if there is not enough memory left. 242 * @return EPARTY if there was an internal error. 260 /** Request an echo message. 261 * 262 * Send a packet with specified parameters to the target host 263 * and wait for the reply upto the given timeout. 264 * Block the caller until the reply or the timeout occurs. 265 * 266 * @param[in] id Message identifier. 267 * @param[in] sequence Message sequence parameter. 268 * @param[in] size Message data length in bytes. 269 * @param[in] timeout Timeout in miliseconds. 270 * @param[in] ttl Time to live. 271 * @param[in] tos Type of service. 272 * @param[in] dont_fragment Disable fragmentation. 273 * @param[in] addr Target host address. 274 * @param[in] addrlen Torget host address length. 275 * 276 * @return ICMP_ECHO on success. 277 * @return ETIMEOUT if the reply has not arrived before the 278 * timeout. 279 * @return ICMP type of the received error notification. 280 * @return EINVAL if the addrlen parameter is less or equal to 281 * zero. 282 * @return ENOMEM if there is not enough memory left. 283 * @return EPARTY if there was an internal error. 284 * 243 285 */ 244 286 static int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, 245 mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, 246 const struct sockaddr * addr, socklen_t addrlen) 247 { 248 icmp_header_t *header; 249 packet_t *packet; 250 size_t length; 251 uint8_t *data; 252 icmp_reply_t *reply; 253 int reply_key; 254 int index; 255 int rc; 256 287 mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, bool dont_fragment, 288 const struct sockaddr *addr, socklen_t addrlen) 289 { 257 290 if (addrlen <= 0) 258 291 return EINVAL; 259 260 length = (size_t) addrlen; 261 /* TODO do not ask all the time */ 262 rc = ip_packet_size_req(icmp_globals.ip_phone, -1, 263 &icmp_globals.packet_dimension); 264 if (rc != EOK) 265 return rc; 266 267 packet = packet_get_4_remote(icmp_globals.net_phone, size, 268 icmp_globals.packet_dimension.addr_len, 269 ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, 270 icmp_globals.packet_dimension.suffix); 292 293 size_t length = (size_t) addrlen; 294 295 packet_t *packet = packet_get_4_remote(phone_net, size, 296 icmp_dimension.addr_len, ICMP_HEADER_SIZE + icmp_dimension.prefix, 297 icmp_dimension.suffix); 271 298 if (!packet) 272 299 return ENOMEM; 273 300 274 301 /* Prepare the requesting packet, set the destination address. */ 275 rc = packet_set_addr(packet, NULL, (const uint8_t *) addr, length); 276 if (rc != EOK) 277 return icmp_release_and_return(packet, rc); 278 302 int rc = packet_set_addr(packet, NULL, (const uint8_t *) addr, length); 303 if (rc != EOK) { 304 icmp_release(packet); 305 return rc; 306 } 307 279 308 /* Allocate space in the packet */ 280 data = (uint8_t *) packet_suffix(packet, size); 281 if (!data) 282 return icmp_release_and_return(packet, ENOMEM); 283 309 uint8_t *data = (uint8_t *) packet_suffix(packet, size); 310 if (!data) { 311 icmp_release(packet); 312 return ENOMEM; 313 } 314 284 315 /* Fill the data */ 285 316 length = 0; … … 289 320 } 290 321 memcpy(data + length, ICMP_ECHO_TEXT, size - length); 291 322 292 323 /* Prefix the header */ 293 header = PACKET_PREFIX(packet, icmp_header_t); 294 if (!header) 295 return icmp_release_and_return(packet, ENOMEM); 296 324 icmp_header_t *header = PACKET_PREFIX(packet, icmp_header_t); 325 if (!header) { 326 icmp_release(packet); 327 return ENOMEM; 328 } 329 297 330 bzero(header, sizeof(*header)); 298 331 header->un.echo.identifier = id; 299 332 header->un.echo.sequence_number = sequence; 300 333 301 334 /* Prepare the reply structure */ 302 reply = malloc(sizeof(*reply)); 303 if (!reply) 304 return icmp_release_and_return(packet, ENOMEM); 305 306 fibril_mutex_initialize(&reply->mutex); 307 fibril_mutex_lock(&reply->mutex); 335 icmp_reply_t *reply = malloc(sizeof(icmp_reply_t)); 336 if (!reply) { 337 icmp_release(packet); 338 return ENOMEM; 339 } 340 341 reply->id = id; 342 reply->sequence = sequence; 308 343 fibril_condvar_initialize(&reply->condvar); 309 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, 310 header->un.echo.sequence_number); 311 index = icmp_replies_add(&icmp_globals.replies, reply_key, reply); 312 if (index < 0) { 313 free(reply); 314 return icmp_release_and_return(packet, index); 315 } 316 317 /* Unlock the globals so that we can wait for the reply */ 318 fibril_rwlock_write_unlock(&icmp_globals.lock); 319 344 345 /* Add the reply to the replies hash table */ 346 fibril_mutex_lock(&reply_lock); 347 348 unsigned long key[REPLY_KEYS] = {id, sequence}; 349 hash_table_insert(&replies, key, &reply->link); 350 320 351 /* Send the request */ 321 352 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, 322 353 dont_fragment); 323 354 324 355 /* Wait for the reply. Timeout in microseconds. */ 325 rc = fibril_condvar_wait_timeout(&reply->condvar, &reply ->mutex,356 rc = fibril_condvar_wait_timeout(&reply->condvar, &reply_lock, 326 357 timeout * 1000); 327 358 if (rc == EOK) 328 359 rc = reply->result; 329 330 /* Drop the reply mutex before locking the globals again*/331 fibril_mutex_unlock(&reply->mutex);332 fibril_rwlock_write_lock(&icmp_globals.lock);333 334 /* Destroy the reply structure */335 icmp_replies_exclude_index(&icmp_globals.replies, index);336 360 361 /* Remove the reply from the replies hash table */ 362 hash_table_remove(&replies, key, REPLY_KEYS); 363 364 fibril_mutex_unlock(&reply_lock); 365 366 free(reply); 367 337 368 return rc; 338 369 } 339 370 340 static int icmp_destination_unreachable _msg_local(int icmp_phone,341 icmp_code_t code, icmp_param_t mtu,packet_t *packet)342 { 343 icmp_header_t *header ;344 345 header = icmp_prepare_packet(packet);346 if (!header)347 return icmp_release_and_return(packet, ENOMEM);348 371 static int icmp_destination_unreachable(icmp_code_t code, icmp_param_t mtu, 372 packet_t *packet) 373 { 374 icmp_header_t *header = icmp_prepare_packet(packet); 375 if (!header) { 376 icmp_release(packet); 377 return ENOMEM; 378 } 379 349 380 if (mtu) 350 381 header->un.frag.mtu = mtu; 351 382 352 383 return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, 353 SERVICE_ICMP, 0, 0, 0);354 } 355 356 static int icmp_source_quench _msg_local(int icmp_phone,packet_t *packet)357 { 358 icmp_header_t *header ;359 360 header = icmp_prepare_packet(packet);361 if (!header)362 return icmp_release_and_return(packet, ENOMEM);363 384 SERVICE_ICMP, 0, 0, false); 385 } 386 387 static int icmp_source_quench(packet_t *packet) 388 { 389 icmp_header_t *header = icmp_prepare_packet(packet); 390 if (!header) { 391 icmp_release(packet); 392 return ENOMEM; 393 } 394 364 395 return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, 365 SERVICE_ICMP, 0, 0, 0); 366 } 367 368 static int icmp_time_exceeded_msg_local(int icmp_phone, icmp_code_t code, 396 SERVICE_ICMP, 0, 0, false); 397 } 398 399 static int icmp_time_exceeded(icmp_code_t code, packet_t *packet) 400 { 401 icmp_header_t *header = icmp_prepare_packet(packet); 402 if (!header) { 403 icmp_release(packet); 404 return ENOMEM; 405 } 406 407 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, 408 SERVICE_ICMP, 0, 0, false); 409 } 410 411 static int icmp_parameter_problem(icmp_code_t code, icmp_param_t pointer, 369 412 packet_t *packet) 370 413 { 371 icmp_header_t *header; 372 373 header = icmp_prepare_packet(packet); 374 if (!header) 375 return icmp_release_and_return(packet, ENOMEM); 376 377 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, 378 SERVICE_ICMP, 0, 0, 0); 379 } 380 381 static int icmp_parameter_problem_msg_local(int icmp_phone, icmp_code_t code, 382 icmp_param_t pointer, packet_t *packet) 383 { 384 icmp_header_t *header; 385 386 header = icmp_prepare_packet(packet); 387 if (!header) 388 return icmp_release_and_return(packet, ENOMEM); 389 414 icmp_header_t *header = icmp_prepare_packet(packet); 415 if (!header) { 416 icmp_release(packet); 417 return ENOMEM; 418 } 419 390 420 header->un.param.pointer = pointer; 391 421 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, 392 SERVICE_ICMP, 0, 0, 0);393 } 394 395 /** Tr iesto set the pending reply result as the received message type.422 SERVICE_ICMP, 0, 0, false); 423 } 424 425 /** Try to set the pending reply result as the received message type. 396 426 * 397 427 * If the reply data is not present, the reply timed out and the other fibril 398 * is already awake. 399 * Releases the packet.400 * 401 * @param[in] packet The received reply message.402 * @param[in] header The ICMP message header.403 * @param[in] type The received reply message type.404 * @param[in] code The received reply message code.405 */ 406 static void 428 * is already awake. The packet is released. 429 * 430 * @param[in] packet The received reply message. 431 * @param[in] header The ICMP message header. 432 * @param[in] type The received reply message type. 433 * @param[in] code The received reply message code. 434 * 435 */ 436 static void icmp_process_echo_reply(packet_t *packet, icmp_header_t *header, 407 437 icmp_type_t type, icmp_code_t code) 408 438 { 409 int reply_key; 410 icmp_reply_t *reply; 411 412 /* Compute the reply key */ 413 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, 414 header->un.echo.sequence_number); 415 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 416 439 unsigned long key[REPLY_KEYS] = 440 {header->un.echo.identifier, header->un.echo.sequence_number}; 441 icmp_release(packet); 442 417 443 /* Find the pending reply */ 418 fibril_rwlock_write_lock(&icmp_globals.lock); 419 reply = icmp_replies_find(&icmp_globals.replies, reply_key); 420 if (reply) { 444 fibril_mutex_lock(&reply_lock); 445 446 link_t *link = hash_table_find(&replies, key); 447 if (link != NULL) { 448 icmp_reply_t *reply = 449 hash_table_get_instance(link, icmp_reply_t, link); 450 421 451 reply->result = type; 422 452 fibril_condvar_signal(&reply->condvar); 423 453 } 424 fibril_rwlock_write_unlock(&icmp_globals.lock); 425 } 426 427 /** Processes the received ICMP packet. 428 * 429 * Notifies the destination socket application. 430 * 431 * @param[in,out] packet The received packet. 432 * @param[in] error The packet error reporting service. Prefixes the 433 * received packet. 434 * @return EOK on success. 435 * @return EINVAL if the packet is not valid. 436 * @return EINVAL if the stored packet address is not the an_addr_t. 437 * @return EINVAL if the packet does not contain any data. 438 * @return NO_DATA if the packet content is shorter than the user 439 * datagram header. 440 * @return ENOMEM if there is not enough memory left. 441 * @return EADDRNOTAVAIL if the destination socket does not exist. 442 * @return Other error codes as defined for the 443 * ip_client_process_packet() function. 454 455 fibril_mutex_unlock(&reply_lock); 456 } 457 458 /** Process the received ICMP packet. 459 * 460 * Notify the destination socket application. 461 * 462 * @param[in,out] packet Received packet. 463 * @param[in] error Packet error reporting service to prefix 464 * the received packet. 465 * 466 * @return EOK on success. 467 * @return EINVAL if the packet is not valid. 468 * @return EINVAL if the stored packet address is not the an_addr_t. 469 * @return EINVAL if the packet does not contain any data. 470 * @return NO_DATA if the packet content is shorter than the user 471 * datagram header. 472 * @return ENOMEM if there is not enough memory left. 473 * @return EADDRNOTAVAIL if the destination socket does not exist. 474 * @return Other error codes as defined for the 475 * ip_client_process_packet() function. 476 * 444 477 */ 445 478 static int icmp_process_packet(packet_t *packet, services_t error) 446 479 { 447 size_t length;448 uint8_t *src;449 int addrlen;450 int result;451 void *data;452 icmp_header_t *header;453 480 icmp_type_t type; 454 481 icmp_code_t code; … … 460 487 case SERVICE_ICMP: 461 488 /* Process error */ 462 result = icmp_client_process_packet(packet, &type, &code, NULL, 463 NULL); 464 if (result < 0) 465 return result; 466 length = (size_t) result; 489 rc = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 490 if (rc < 0) 491 return rc; 492 467 493 /* Remove the error header */ 468 rc = packet_trim(packet, length, 0);494 rc = packet_trim(packet, (size_t) rc, 0); 469 495 if (rc != EOK) 470 496 return rc; 497 471 498 break; 472 499 default: 473 500 return ENOTSUP; 474 501 } 475 502 476 503 /* Get rid of the IP header */ 477 length = ip_client_header_length(packet);504 size_t length = ip_client_header_length(packet); 478 505 rc = packet_trim(packet, length, 0); 479 506 if (rc != EOK) 480 507 return rc; 481 508 482 509 length = packet_get_data_length(packet); 483 510 if (length <= 0) 484 511 return EINVAL; 485 512 486 513 if (length < ICMP_HEADER_SIZE) 487 514 return EINVAL; 488 489 data = packet_get_data(packet);515 516 void *data = packet_get_data(packet); 490 517 if (!data) 491 518 return EINVAL; 492 519 493 520 /* Get ICMP header */ 494 header = (icmp_header_t *) data;495 521 icmp_header_t *header = (icmp_header_t *) data; 522 496 523 if (header->checksum) { 497 524 while (ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO) { … … 507 534 } 508 535 } 536 509 537 return EINVAL; 510 538 } 511 539 } 512 540 513 541 switch (header->type) { 514 542 case ICMP_ECHOREPLY: … … 517 545 else 518 546 icmp_process_echo_reply(packet, header, ICMP_ECHO, 0); 519 547 520 548 return EOK; 521 549 522 550 case ICMP_ECHO: 523 551 if (error) { … … 527 555 528 556 /* Do not send a reply if disabled */ 529 if (icmp_globals.echo_replying) { 530 addrlen = packet_get_addr(packet, &src, NULL); 531 557 if (echo_replying) { 558 uint8_t *src; 559 int addrlen = packet_get_addr(packet, &src, NULL); 560 532 561 /* 533 * Set both addresses to the source one (avoid sthe562 * Set both addresses to the source one (avoid the 534 563 * source address deletion before setting the 535 564 * destination one). … … 542 571 return EOK; 543 572 } 544 573 545 574 return EINVAL; 546 575 } 547 576 548 577 return EPERM; 549 578 550 579 case ICMP_DEST_UNREACH: 551 580 case ICMP_SOURCE_QUENCH: … … 560 589 case ICMP_SKIP: 561 590 case ICMP_PHOTURIS: 562 ip_received_error_msg( icmp_globals.ip_phone, -1, packet,591 ip_received_error_msg(phone_ip, -1, packet, 563 592 SERVICE_IP, SERVICE_ICMP); 564 593 return EOK; 565 594 566 595 default: 567 596 return ENOTSUP; … … 569 598 } 570 599 571 /** Processes the received ICMP packet.572 *573 * Is used as an entry point from the underlying IP module.574 * Releases the packet on error.575 *576 * @param device_id The device identifier. Ignored parameter.577 * @param[in,out] packet The received packet.578 * @param receiver The target service. Ignored parameter.579 * @param[in] error The packet error reporting service. Prefixes the580 * received packet.581 * @return EOK on success.582 * @return Other error codes as defined for the583 * icmp_process_packet() function.584 */585 static int icmp_received_msg_local(device_id_t device_id, packet_t *packet,586 services_t receiver, services_t error)587 {588 int rc;589 590 rc = icmp_process_packet(packet, error);591 if (rc != EOK)592 return icmp_release_and_return(packet, rc);593 594 return EOK;595 }596 597 600 /** Process IPC messages from the IP module 598 601 * … … 603 606 static void icmp_receiver(ipc_callid_t iid, ipc_call_t *icall) 604 607 { 608 bool loop = true; 605 609 packet_t *packet; 606 610 int rc; 607 611 608 while ( true) {612 while (loop) { 609 613 switch (IPC_GET_IMETHOD(*icall)) { 610 614 case NET_TL_RECEIVED: 611 rc = packet_translate_remote( icmp_globals.net_phone, &packet,615 rc = packet_translate_remote(phone_net, &packet, 612 616 IPC_GET_PACKET(*icall)); 613 if (rc == EOK) 614 rc = icmp_received_msg_local(IPC_GET_DEVICE(*icall), packet, 615 SERVICE_ICMP, IPC_GET_ERROR(*icall)); 617 if (rc == EOK) { 618 rc = icmp_process_packet(packet, IPC_GET_ERROR(*icall)); 619 if (rc != EOK) 620 icmp_release(packet); 621 } 616 622 617 623 ipc_answer_0(iid, (sysarg_t) rc); 618 624 break; 625 case IPC_M_PHONE_HUNGUP: 626 loop = false; 627 continue; 619 628 default: 620 629 ipc_answer_0(iid, (sysarg_t) ENOTSUP); … … 649 658 uint8_t *data; 650 659 651 fibril_rwlock_initialize(&icmp_globals.lock); 652 fibril_rwlock_write_lock(&icmp_globals.lock); 653 icmp_replies_initialize(&icmp_globals.replies); 654 icmp_echo_data_initialize(&icmp_globals.echo_data); 655 656 icmp_globals.net_phone = net_phone; 657 658 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, 659 SERVICE_ICMP, icmp_receiver); 660 if (icmp_globals.ip_phone < 0) { 661 fibril_rwlock_write_unlock(&icmp_globals.lock); 662 return icmp_globals.ip_phone; 663 } 664 665 int rc = ip_packet_size_req(icmp_globals.ip_phone, -1, 666 &icmp_globals.packet_dimension); 667 if (rc != EOK) { 668 fibril_rwlock_write_unlock(&icmp_globals.lock); 660 if (!hash_table_create(&replies, REPLY_BUCKETS, REPLY_KEYS, &reply_ops)) 661 return ENOMEM; 662 663 fibril_mutex_initialize(&reply_lock); 664 atomic_set(&icmp_client, 0); 665 666 phone_net = net_phone; 667 phone_ip = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, 668 icmp_receiver); 669 if (phone_ip < 0) 670 return phone_ip; 671 672 int rc = ip_packet_size_req(phone_ip, -1, &icmp_dimension); 673 if (rc != EOK) 669 674 return rc; 670 } 671 672 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE; 673 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE; 674 675 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING; 676 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING; 675 676 icmp_dimension.prefix += ICMP_HEADER_SIZE; 677 icmp_dimension.content -= ICMP_HEADER_SIZE; 677 678 678 679 /* Get configuration */ 679 680 configuration = &names[0]; 680 rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count, 681 &data); 682 if (rc != EOK) { 683 fibril_rwlock_write_unlock(&icmp_globals.lock); 681 rc = net_get_conf_req(phone_net, &configuration, count, &data); 682 if (rc != EOK) 684 683 return rc; 685 }686 684 687 685 if (configuration) { 688 if (configuration[0].value) { 689 icmp_globals.error_reporting = 690 (configuration[0].value[0] == 'y'); 691 } 692 if (configuration[1].value) { 693 icmp_globals.echo_replying = 694 (configuration[1].value[0] == 'y'); 695 } 686 if (configuration[0].value) 687 error_reporting = (configuration[0].value[0] == 'y'); 688 689 if (configuration[1].value) 690 echo_replying = (configuration[1].value[0] == 'y'); 691 696 692 net_free_settings(configuration, data); 697 693 } 698 694 699 fibril_rwlock_write_unlock(&icmp_globals.lock);700 695 return EOK; 701 696 } 702 697 703 /** Processes the generic client messages. 704 * 705 * @param[in] call The message parameters. 706 * @return EOK on success. 707 * @return ENOTSUP if the message is not known. 708 * @return Other error codes as defined for the packet_translate() 709 * function. 710 * @return Other error codes as defined for the 711 * icmp_destination_unreachable_msg_local() function. 712 * @return Other error codes as defined for the 713 * icmp_source_quench_msg_local() function. 714 * @return Other error codes as defined for the 715 * icmp_time_exceeded_msg_local() function. 716 * @return Other error codes as defined for the 717 * icmp_parameter_problem_msg_local() function. 718 * 719 * @see icmp_interface.h 720 */ 721 static int icmp_process_message(ipc_call_t *call) 722 { 698 /** Per-connection initialization 699 * 700 */ 701 void tl_connection(void) 702 { 703 icmp_id = (icmp_param_t) atomic_postinc(&icmp_client); 704 icmp_seq = 1; 705 } 706 707 /** Process the ICMP message. 708 * 709 * @param[in] callid Message identifier. 710 * @param[in] call Message parameters. 711 * @param[out] answer Answer. 712 * @param[out] count Number of arguments of the answer. 713 * 714 * @return EOK on success. 715 * @return ENOTSUP if the message is not known. 716 * @return Other error codes as defined for the packet_translate() 717 * function. 718 * @return Other error codes as defined for the 719 * icmp_destination_unreachable() function. 720 * @return Other error codes as defined for the 721 * icmp_source_quench() function. 722 * @return Other error codes as defined for the 723 * icmp_time_exceeded() function. 724 * @return Other error codes as defined for the 725 * icmp_parameter_problem() function. 726 * 727 * @see icmp_remote.h 728 * @see IS_NET_ICMP_MESSAGE() 729 * 730 */ 731 int tl_message(ipc_callid_t callid, ipc_call_t *call, 732 ipc_call_t *answer, size_t *count) 733 { 734 struct sockaddr *addr; 735 size_t size; 723 736 packet_t *packet; 724 737 int rc; 725 738 739 *count = 0; 740 726 741 switch (IPC_GET_IMETHOD(*call)) { 742 case NET_ICMP_ECHO: 743 rc = async_data_write_accept((void **) &addr, false, 0, 0, 0, &size); 744 if (rc != EOK) 745 return rc; 746 747 rc = icmp_echo(icmp_id, icmp_seq, ICMP_GET_SIZE(*call), 748 ICMP_GET_TIMEOUT(*call), ICMP_GET_TTL(*call), 749 ICMP_GET_TOS(*call), ICMP_GET_DONT_FRAGMENT(*call), 750 addr, (socklen_t) size); 751 752 free(addr); 753 icmp_seq++; 754 return rc; 755 727 756 case NET_ICMP_DEST_UNREACH: 728 rc = packet_translate_remote( icmp_globals.net_phone, &packet,757 rc = packet_translate_remote(phone_net, &packet, 729 758 IPC_GET_PACKET(*call)); 730 759 if (rc != EOK) 731 760 return rc; 732 return icmp_destination_unreachable_msg_local(0, 733 ICMP_GET_CODE(*call), ICMP_GET_MTU(*call), packet); 761 762 return icmp_destination_unreachable(ICMP_GET_CODE(*call), 763 ICMP_GET_MTU(*call), packet); 764 734 765 case NET_ICMP_SOURCE_QUENCH: 735 rc = packet_translate_remote( icmp_globals.net_phone, &packet,766 rc = packet_translate_remote(phone_net, &packet, 736 767 IPC_GET_PACKET(*call)); 737 768 if (rc != EOK) 738 769 return rc; 739 return icmp_source_quench_msg_local(0, packet); 770 771 return icmp_source_quench(packet); 772 740 773 case NET_ICMP_TIME_EXCEEDED: 741 rc = packet_translate_remote( icmp_globals.net_phone, &packet,774 rc = packet_translate_remote(phone_net, &packet, 742 775 IPC_GET_PACKET(*call)); 743 776 if (rc != EOK) 744 777 return rc; 745 return icmp_time_exceeded_msg_local(0, ICMP_GET_CODE(*call), 746 packet); 778 779 return icmp_time_exceeded(ICMP_GET_CODE(*call), packet); 780 747 781 case NET_ICMP_PARAMETERPROB: 748 rc = packet_translate_remote( icmp_globals.net_phone, &packet,782 rc = packet_translate_remote(phone_net, &packet, 749 783 IPC_GET_PACKET(*call)); 750 784 if (rc != EOK) 751 785 return rc; 752 return icmp_parameter_problem_msg_local(0, ICMP_GET_CODE(*call), 786 787 return icmp_parameter_problem(ICMP_GET_CODE(*call), 753 788 ICMP_GET_POINTER(*call), packet); 754 default:755 return ENOTSUP;756 }757 }758 759 /** Assigns a new identifier for the connection.760 *761 * Fills the echo data parameter with the assigned values.762 *763 * @param[in,out] echo_data The echo data to be bound.764 * @return Index of the inserted echo data.765 * @return EBADMEM if the echo_data parameter is NULL.766 * @return ENOTCONN if no free identifier have been found.767 */768 static int icmp_bind_free_id(icmp_echo_t *echo_data)769 {770 icmp_param_t index;771 772 if (!echo_data)773 return EBADMEM;774 775 /* From the last used one */776 index = icmp_globals.last_used_id;777 do {778 index++;779 /* til the range end */780 if (index >= ICMP_FREE_IDS_END) {781 /* start from the range beginning */782 index = ICMP_FREE_IDS_START - 1;783 do {784 index++;785 /* til the last used one */786 if (index >= icmp_globals.last_used_id) {787 /* none found */788 return ENOTCONN;789 }790 } while(icmp_echo_data_find(&icmp_globals.echo_data,791 index) != NULL);792 793 /* Found, break immediately */794 break;795 }796 } while (icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL);797 798 echo_data->identifier = index;799 echo_data->sequence_number = 0;800 801 return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data);802 }803 804 /** Processes the client messages.805 *806 * Remembers the assigned identifier and sequence numbers.807 * Runs until the client module disconnects.808 *809 * @param[in] callid The message identifier.810 * @param[in] call The message parameters.811 * @return EOK.812 *813 * @see icmp_interface.h814 * @see icmp_api.h815 */816 static int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call)817 {818 bool keep_on_going = true;819 ipc_call_t answer;820 size_t answer_count;821 size_t length;822 struct sockaddr *addr;823 ipc_callid_t data_callid;824 icmp_echo_t *echo_data;825 int rc = EOK;826 827 /*828 * Accept the connection829 * - Answer the first NET_ICMP_INIT call.830 */831 answer_count = 0;832 833 echo_data = (icmp_echo_t *) malloc(sizeof(*echo_data));834 if (!echo_data)835 return ENOMEM;836 837 /* Assign a new identifier */838 fibril_rwlock_write_lock(&icmp_globals.lock);839 rc = icmp_bind_free_id(echo_data);840 fibril_rwlock_write_unlock(&icmp_globals.lock);841 if (rc < 0) {842 free(echo_data);843 return rc;844 }845 846 while (keep_on_going) {847 /* Answer the call */848 answer_call(callid, rc, &answer, answer_count);849 850 /* Refresh data */851 refresh_answer(&answer, &answer_count);852 853 /* Get the next call */854 callid = async_get_call(&call);855 856 /* Process the call */857 switch (IPC_GET_IMETHOD(call)) {858 case IPC_M_PHONE_HUNGUP:859 keep_on_going = false;860 rc = EHANGUP;861 break;862 863 case NET_ICMP_ECHO:864 if (!async_data_write_receive(&data_callid, &length)) {865 rc = EINVAL;866 break;867 }868 869 addr = malloc(length);870 if (!addr) {871 rc = ENOMEM;872 break;873 }874 875 rc = async_data_write_finalize(data_callid, addr,876 length);877 if (rc != EOK) {878 free(addr);879 break;880 }881 882 fibril_rwlock_write_lock(&icmp_globals.lock);883 rc = icmp_echo(echo_data->identifier,884 echo_data->sequence_number, ICMP_GET_SIZE(call),885 ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call),886 ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call),887 addr, (socklen_t) length);888 fibril_rwlock_write_unlock(&icmp_globals.lock);889 890 free(addr);891 892 if (echo_data->sequence_number < UINT16_MAX)893 echo_data->sequence_number++;894 else895 echo_data->sequence_number = 0;896 897 break;898 899 default:900 rc = icmp_process_message(&call);901 }902 903 }904 905 /* Release the identifier */906 fibril_rwlock_write_lock(&icmp_globals.lock);907 icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier);908 fibril_rwlock_write_unlock(&icmp_globals.lock);909 910 return rc;911 }912 913 /** Processes the ICMP message.914 *915 * @param[in] callid The message identifier.916 * @param[in] call The message parameters.917 * @param[out] answer The message answer parameters.918 * @param[out] answer_count The last parameter for the actual answer in the919 * answer parameter.920 * @return EOK on success.921 * @return ENOTSUP if the message is not known.922 *923 * @see icmp_interface.h924 * @see IS_NET_ICMP_MESSAGE()925 */926 int tl_module_message (ipc_callid_t callid, ipc_call_t *call,927 ipc_call_t *answer, size_t *answer_count)928 {929 *answer_count = 0;930 switch (IPC_GET_IMETHOD(*call)) {931 case NET_ICMP_INIT:932 return icmp_process_client_messages(callid, *call);933 default:934 return icmp_process_message(call);935 789 } 936 790 -
uspace/srv/net/tl/tcp/tcp.c
r9f3864a rf1938c6 64 64 #include <ip_interface.h> 65 65 #include <icmp_client.h> 66 #include <icmp_ interface.h>66 #include <icmp_remote.h> 67 67 #include <net_interface.h> 68 68 #include <socket_core.h> … … 1204 1204 } 1205 1205 1206 /** Per-connection initialization 1207 * 1208 */ 1209 void tl_connection(void) 1210 { 1211 } 1212 1206 1213 /** Processes the TCP message. 1207 1214 * … … 1217 1224 * @see IS_NET_TCP_MESSAGE() 1218 1225 */ 1219 int tl_m odule_message(ipc_callid_t callid, ipc_call_t *call,1226 int tl_message(ipc_callid_t callid, ipc_call_t *call, 1220 1227 ipc_call_t *answer, size_t *answer_count) 1221 1228 { … … 2472 2479 tcp_globals.net_phone = net_phone; 2473 2480 2474 tcp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 2475 ICMP_CONNECT_TIMEOUT); 2481 tcp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 2476 2482 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 2477 2483 SERVICE_TCP, tcp_receiver); -
uspace/srv/net/tl/udp/udp.c
r9f3864a rf1938c6 61 61 #include <ip_interface.h> 62 62 #include <icmp_client.h> 63 #include <icmp_ interface.h>63 #include <icmp_remote.h> 64 64 #include <net_interface.h> 65 65 #include <socket_core.h> … … 393 393 udp_globals.net_phone = net_phone; 394 394 395 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 396 ICMP_CONNECT_TIMEOUT); 395 udp_globals.icmp_phone = icmp_connect_module(ICMP_CONNECT_TIMEOUT); 397 396 398 397 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, … … 878 877 } 879 878 879 /** Per-connection initialization 880 * 881 */ 882 void tl_connection(void) 883 { 884 } 885 880 886 /** Processes the UDP message. 881 887 * … … 891 897 * @see IS_NET_UDP_MESSAGE() 892 898 */ 893 int tl_m odule_message(ipc_callid_t callid, ipc_call_t *call,899 int tl_message(ipc_callid_t callid, ipc_call_t *call, 894 900 ipc_call_t *answer, size_t *answer_count) 895 901 {
Note:
See TracChangeset
for help on using the changeset viewer.