- Timestamp:
- 2010-11-08T07:13:25Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 63a1e60
- Parents:
- d70a463 (diff), 3da12d74 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- uspace
- Files:
-
- 49 edited
- 4 moved
Legend:
- Unmodified
- Added
- Removed
-
uspace/Makefile
rd70a463 rb40bfac 52 52 app/usb \ 53 53 app/virtusbkbd \ 54 app/netstart \ 54 55 app/netecho \ 55 56 app/nettest1 \ … … 89 90 srv/net/tl/tcp \ 90 91 srv/net/net \ 91 srv/net/netstart \92 92 drv/root 93 93 -
uspace/app/bdsh/exec.c
rd70a463 rb40bfac 41 41 #include <fcntl.h> 42 42 #include <str_error.h> 43 #include <errno.h> 43 44 44 45 #include "config.h" … … 116 117 task_exit_t texit; 117 118 char *tmp; 118 int r etval;119 int rc, retval; 119 120 120 121 tmp = str_dup(find_command(cmd)); 121 122 free(found); 122 123 123 tid = task_spawn(tmp, (const char **) argv, &retval);124 rc = task_spawnv(&tid, tmp, (const char **) argv); 124 125 free(tmp); 125 126 126 if ( tid == 0) {127 if (rc != 0) { 127 128 cli_error(CL_EEXEC, "%s: Cannot spawn `%s' (%s)", progname, cmd, 128 str_error(r etval));129 str_error(rc)); 129 130 return 1; 130 131 } 131 132 132 task_wait(tid, &texit, &retval); 133 if (texit != TASK_EXIT_NORMAL) { 133 rc = task_wait(tid, &texit, &retval); 134 if (rc != EOK) { 135 printf("%s: Failed waiting for command (%s)\n", str_error(rc)); 136 } else if (texit != TASK_EXIT_NORMAL) { 134 137 printf("%s: Command failed (unexpectedly terminated)\n", progname); 135 138 } else if (retval != 0) { 136 printf("%s: Command failed ( %s)\n",137 progname, str_error(retval));139 printf("%s: Command failed (exit code %d)\n", 140 progname, retval); 138 141 } 139 142 -
uspace/app/getterm/getterm.c
rd70a463 rb40bfac 41 41 #include <task.h> 42 42 #include <str_error.h> 43 #include <errno.h> 43 44 #include "version.h" 44 45 … … 74 75 static task_id_t spawn(const char *fname) 75 76 { 76 const char *args[2]; 77 task_id_t id; 78 int rc; 77 79 78 args[0] = fname; 79 args[1] = NULL; 80 81 int err; 82 task_id_t id = task_spawn(fname, args, &err); 83 84 if (id == 0) 80 rc = task_spawnl(&id, fname, fname, NULL); 81 if (rc != EOK) { 85 82 printf("%s: Error spawning %s (%s)\n", APP_NAME, fname, 86 str_error(err)); 83 str_error(rc)); 84 return 0; 85 } 87 86 88 87 return id; -
uspace/app/init/init.c
rd70a463 rb40bfac 124 124 static void spawn(const char *fname) 125 125 { 126 const char *argv[2];126 int rc; 127 127 struct stat s; 128 128 … … 131 131 132 132 printf("%s: Spawning %s\n", NAME, fname); 133 134 argv[0] = fname; 135 argv[1] = NULL; 136 137 int err; 138 if (!task_spawn(fname, argv, &err)) 133 rc = task_spawnl(NULL, fname, fname, NULL); 134 if (rc != EOK) { 139 135 printf("%s: Error spawning %s (%s)\n", NAME, fname, 140 str_error(err)); 136 str_error(rc)); 137 } 141 138 } 142 139 143 140 static void srv_start(const char *fname) 144 141 { 145 const char *argv[2];146 142 task_id_t id; 147 143 task_exit_t texit; … … 153 149 154 150 printf("%s: Starting %s\n", NAME, fname); 155 156 argv[0] = fname; 157 argv[1] = NULL; 158 159 id = task_spawn(fname, argv, &retval); 151 rc = task_spawnl(&id, fname, fname, NULL); 160 152 if (!id) { 161 153 printf("%s: Error spawning %s (%s)\n", NAME, fname, 162 str_error(r etval));154 str_error(rc)); 163 155 return; 164 156 } … … 167 159 if (rc != EOK) { 168 160 printf("%s: Error waiting for %s (%s(\n", NAME, fname, 169 str_error(retval)); 170 return; 171 } 172 173 if ((texit != TASK_EXIT_NORMAL) || (retval != 0)) { 174 printf("%s: Server %s failed to start (%s)\n", NAME, 175 fname, str_error(retval)); 161 str_error(rc)); 162 return; 163 } 164 165 if (texit != TASK_EXIT_NORMAL) { 166 printf("%s: Server %s failed to start (unexpectedly " 167 "terminated)\n", NAME, fname); 168 return; 169 } 170 171 if (retval != 0) { 172 printf("%s: Server %s failed to start (exit code %d)\n", NAME, 173 fname, retval); 176 174 } 177 175 } … … 179 177 static void console(const char *dev) 180 178 { 181 const char *argv[3];182 179 char hid_in[DEVMAP_NAME_MAXLEN]; 183 180 int rc; … … 190 187 dev_handle_t handle; 191 188 rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING); 192 193 if (rc == EOK) { 194 argv[0] = SRV_CONSOLE; 195 argv[1] = hid_in; 196 argv[2] = NULL; 197 198 if (!task_spawn(SRV_CONSOLE, argv, &rc)) 199 printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE, 200 hid_in, str_error(rc)); 201 } else 189 if (rc != EOK) { 202 190 printf("%s: Error waiting on %s (%s)\n", NAME, hid_in, 203 191 str_error(rc)); 192 return; 193 } 194 195 rc = task_spawnl(NULL, SRV_CONSOLE, SRV_CONSOLE, hid_in, NULL); 196 if (rc != EOK) { 197 printf("%s: Error spawning %s %s (%s)\n", NAME, SRV_CONSOLE, 198 hid_in, str_error(rc)); 199 } 204 200 } 205 201 206 202 static void getterm(const char *dev, const char *app) 207 203 { 208 const char *argv[4];209 204 char term[DEVMAP_NAME_MAXLEN]; 210 205 int rc; … … 217 212 dev_handle_t handle; 218 213 rc = devmap_device_get_handle(dev, &handle, IPC_FLAG_BLOCKING); 219 220 if (rc == EOK) { 221 argv[0] = APP_GETTERM; 222 argv[1] = term; 223 argv[2] = app; 224 argv[3] = NULL; 225 226 if (!task_spawn(APP_GETTERM, argv, &rc)) 227 printf("%s: Error spawning %s %s %s (%s)\n", NAME, APP_GETTERM, 228 term, app, str_error(rc)); 229 } else 214 if (rc != EOK) { 230 215 printf("%s: Error waiting on %s (%s)\n", NAME, term, 231 216 str_error(rc)); 217 return; 218 } 219 220 rc = task_spawnl(NULL, APP_GETTERM, APP_GETTERM, term, app, NULL); 221 if (rc != EOK) { 222 printf("%s: Error spawning %s %s %s (%s)\n", NAME, 223 APP_GETTERM, term, app, str_error(rc)); 224 } 232 225 } 233 226 -
uspace/app/netecho/netecho.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup netecho 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * Network echo application. 35 * Answers received packets. 36 36 */ 37 37 … … 41 41 #include <task.h> 42 42 #include <arg_parse.h> 43 #include <err.h>44 43 45 44 #include <net/in.h> … … 51 50 #include "print_error.h" 52 51 53 /** Network echo module name. 54 */ 52 /** Network echo module name. */ 55 53 #define NAME "Network Echo" 56 54 57 /** Prints the application help. 58 */ 59 void echo_print_help(void); 60 61 /** Module entry point. 62 * Reads command line parameters and starts listenning. 63 * @param[in] argc The number of command line parameters. 64 * @param[in] argv The command line parameters. 65 * @returns EOK on success. 66 */ 67 int main(int argc, char * argv[]); 68 69 void echo_print_help(void){ 55 static void echo_print_help(void) 56 { 70 57 printf( 71 58 "Network Echo aplication\n" \ … … 101 88 } 102 89 103 int main(int argc, char * argv[]){ 104 ERROR_DECLARE; 105 106 size_t size = 1024; 107 int verbose = 0; 108 char * reply = NULL; 109 sock_type_t type = SOCK_DGRAM; 110 int count = -1; 111 int family = PF_INET; 112 uint16_t port = 7; 113 int backlog = 3; 114 115 socklen_t max_length = sizeof(struct sockaddr_in6); 90 int main(int argc, char *argv[]) 91 { 92 size_t size = 1024; 93 int verbose = 0; 94 char *reply = NULL; 95 sock_type_t type = SOCK_DGRAM; 96 int count = -1; 97 int family = PF_INET; 98 uint16_t port = 7; 99 int backlog = 3; 100 101 socklen_t max_length = sizeof(struct sockaddr_in6); 116 102 uint8_t address_data[max_length]; 117 struct sockaddr * address= (struct sockaddr *) address_data;118 struct sockaddr_in * address_in= (struct sockaddr_in *) address;119 struct sockaddr_in6 * address_in6= (struct sockaddr_in6 *) address;103 struct sockaddr *address = (struct sockaddr *) address_data; 104 struct sockaddr_in *address_in = (struct sockaddr_in *) address; 105 struct sockaddr_in6 *address_in6 = (struct sockaddr_in6 *) address; 120 106 socklen_t addrlen; 121 107 char address_string[INET6_ADDRSTRLEN]; 122 uint8_t * 108 uint8_t *address_start; 123 109 int socket_id; 124 110 int listening_id; 125 char * 111 char *data; 126 112 size_t length; 127 113 int index; 128 114 size_t reply_length; 129 115 int value; 116 int rc; 130 117 131 118 // parse the command line arguments 132 for(index = 1; index < argc; ++ index){ 133 if(argv[index][0] == '-'){ 134 switch(argv[index][1]){ 135 case 'b': 136 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 0)); 137 break; 138 case 'c': 139 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 0)); 140 break; 141 case 'f': 142 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 143 break; 144 case 'h': 119 for (index = 1; index < argc; ++ index) { 120 if (argv[index][0] == '-') { 121 switch (argv[index][1]) { 122 case 'b': 123 rc = arg_parse_int(argc, argv, &index, &backlog, 0); 124 if (rc != EOK) 125 return rc; 126 break; 127 case 'c': 128 rc = arg_parse_int(argc, argv, &index, &count, 0); 129 if (rc != EOK) 130 return rc; 131 break; 132 case 'f': 133 rc = arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family); 134 if (rc != EOK) 135 return rc; 136 break; 137 case 'h': 138 echo_print_help(); 139 return EOK; 140 break; 141 case 'p': 142 rc = arg_parse_int(argc, argv, &index, &value, 0); 143 if (rc != EOK) 144 return rc; 145 port = (uint16_t) value; 146 break; 147 case 'r': 148 rc = arg_parse_string(argc, argv, &index, &reply, 0); 149 if (rc != EOK) 150 return rc; 151 break; 152 case 's': 153 rc = arg_parse_int(argc, argv, &index, &value, 0); 154 if (rc != EOK) 155 return rc; 156 size = (value >= 0) ? (size_t) value : 0; 157 break; 158 case 't': 159 rc = arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type); 160 if (rc != EOK) 161 return rc; 162 type = (sock_type_t) value; 163 break; 164 case 'v': 165 verbose = 1; 166 break; 167 // long options with the double minus sign ('-') 168 case '-': 169 if (str_lcmp(argv[index] + 2, "backlog=", 6) == 0) { 170 rc = arg_parse_int(argc, argv, &index, &backlog, 8); 171 if (rc != EOK) 172 return rc; 173 } else if (str_lcmp(argv[index] + 2, "count=", 6) == 0) { 174 rc = arg_parse_int(argc, argv, &index, &count, 8); 175 } else if (str_lcmp(argv[index] + 2, "family=", 7) == 0) { 176 rc = arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family); 177 if (rc != EOK) 178 return rc; 179 } else if (str_lcmp(argv[index] + 2, "help", 5) == 0) { 145 180 echo_print_help(); 146 181 return EOK; 147 break; 148 case 'p': 149 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 182 } else if (str_lcmp(argv[index] + 2, "port=", 5) == 0) { 183 rc = arg_parse_int(argc, argv, &index, &value, 7); 184 if (rc != EOK) 185 return rc; 150 186 port = (uint16_t) value; 151 break; 152 case 'r': 153 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 0)); 154 break; 155 case 's': 156 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 187 } else if (str_lcmp(argv[index] + 2, "reply=", 6) == 0) { 188 rc = arg_parse_string(argc, argv, &index, &reply, 8); 189 if (rc != EOK) 190 return rc; 191 } else if (str_lcmp(argv[index] + 2, "size=", 5) == 0) { 192 rc = arg_parse_int(argc, argv, &index, &value, 7); 193 if (rc != EOK) 194 return rc; 157 195 size = (value >= 0) ? (size_t) value : 0; 158 break; 159 case 't': 160 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 196 } else if (str_lcmp(argv[index] + 2, "type=", 5) == 0) { 197 rc = arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type); 198 if (rc != EOK) 199 return rc; 161 200 type = (sock_type_t) value; 162 break; 163 case 'v': 201 } else if (str_lcmp(argv[index] + 2, "verbose", 8) == 0) { 164 202 verbose = 1; 165 break; 166 // long options with the double minus sign ('-') 167 case '-': 168 if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){ 169 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &backlog, 8)); 170 }else if(str_lcmp(argv[index] + 2, "count=", 6) == 0){ 171 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &count, 8)); 172 }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 173 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 174 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 175 echo_print_help(); 176 return EOK; 177 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 178 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 179 port = (uint16_t) value; 180 }else if(str_lcmp(argv[index] + 2, "reply=", 6) == 0){ 181 ERROR_PROPAGATE(arg_parse_string(argc, argv, &index, &reply, 8)); 182 }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){ 183 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 184 size = (value >= 0) ? (size_t) value : 0; 185 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 186 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 187 type = (sock_type_t) value; 188 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 189 verbose = 1; 190 }else{ 191 echo_print_help(); 192 return EINVAL; 193 } 194 break; 195 default: 203 } else { 196 204 echo_print_help(); 197 205 return EINVAL; 206 } 207 break; 208 default: 209 echo_print_help(); 210 return EINVAL; 198 211 } 199 } else{212 } else { 200 213 echo_print_help(); 201 214 return EINVAL; … … 204 217 205 218 // check the buffer size 206 if (size <= 0){219 if (size <= 0) { 207 220 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 208 221 size = 1024; … … 210 223 // size plus the terminating null (\0) 211 224 data = (char *) malloc(size + 1); 212 if (! data){225 if (!data) { 213 226 fprintf(stderr, "Failed to allocate receive buffer.\n"); 214 227 return ENOMEM; … … 220 233 // prepare the address buffer 221 234 bzero(address_data, max_length); 222 switch (family){223 224 225 226 227 228 229 230 231 232 233 234 235 235 switch (family) { 236 case PF_INET: 237 address_in->sin_family = AF_INET; 238 address_in->sin_port = htons(port); 239 addrlen = sizeof(struct sockaddr_in); 240 break; 241 case PF_INET6: 242 address_in6->sin6_family = AF_INET6; 243 address_in6->sin6_port = htons(port); 244 addrlen = sizeof(struct sockaddr_in6); 245 break; 246 default: 247 fprintf(stderr, "Protocol family is not supported\n"); 248 return EAFNOSUPPORT; 236 249 } 237 250 238 251 // get a listening socket 239 252 listening_id = socket(family, type, 0); 240 if (listening_id < 0){253 if (listening_id < 0) { 241 254 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 242 255 return listening_id; … … 244 257 245 258 // if the stream socket is used 246 if (type == SOCK_STREAM){259 if (type == SOCK_STREAM) { 247 260 // check the backlog 248 if (backlog <= 0){261 if (backlog <= 0) { 249 262 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 250 263 backlog = 3; 251 264 } 252 265 // set the backlog 253 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 254 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); 255 return ERROR_CODE; 266 rc = listen(listening_id, backlog); 267 if (rc != EOK) { 268 socket_print_error(stderr, rc, "Socket listen: ", "\n"); 269 return rc; 256 270 } 257 271 } 258 272 259 273 // bind the listenning socket 260 if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){ 261 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n"); 262 return ERROR_CODE; 263 } 264 265 if(verbose){ 274 rc = bind(listening_id, address, addrlen); 275 if (rc != EOK) { 276 socket_print_error(stderr, rc, "Socket bind: ", "\n"); 277 return rc; 278 } 279 280 if (verbose) 266 281 printf("Socket %d listenning at %d\n", listening_id, port); 267 }268 282 269 283 socket_id = listening_id; … … 271 285 // do count times 272 286 // or indefinitely if set to a negative value 273 while (count){287 while (count) { 274 288 275 289 addrlen = max_length; 276 if (type == SOCK_STREAM){290 if (type == SOCK_STREAM) { 277 291 // acceept a socket if the stream socket is used 278 292 socket_id = accept(listening_id, address, &addrlen); 279 if (socket_id <= 0){293 if (socket_id <= 0) { 280 294 socket_print_error(stderr, socket_id, "Socket accept: ", "\n"); 281 } else{282 if (verbose){295 } else { 296 if (verbose) 283 297 printf("Socket %d accepted\n", socket_id); 284 }285 298 } 286 299 } 287 300 288 301 // if the datagram socket is used or the stream socked was accepted 289 if (socket_id > 0){302 if (socket_id > 0) { 290 303 291 304 // receive an echo request 292 305 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 293 if (value < 0){306 if (value < 0) { 294 307 socket_print_error(stderr, value, "Socket receive: ", "\n"); 295 } else{308 } else { 296 309 length = (size_t) value; 297 if (verbose){310 if (verbose) { 298 311 // print the header 299 312 300 313 // get the source port and prepare the address buffer 301 314 address_start = NULL; 302 switch (address->sa_family){303 304 305 306 307 308 309 310 311 312 315 switch (address->sa_family) { 316 case AF_INET: 317 port = ntohs(address_in->sin_port); 318 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 319 break; 320 case AF_INET6: 321 port = ntohs(address_in6->sin6_port); 322 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 323 break; 324 default: 325 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family); 313 326 } 314 327 // parse the source address 315 if(address_start){ 316 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ 317 fprintf(stderr, "Received address error %d\n", ERROR_CODE); 318 }else{ 328 if (address_start) { 329 rc = inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)); 330 if (rc != EOK) { 331 fprintf(stderr, "Received address error %d\n", rc); 332 } else { 319 333 data[length] = '\0'; 320 334 printf("Socket %d received %d bytes from %s:%d\n%s\n", socket_id, length, address_string, port, data); … … 324 338 325 339 // answer the request either with the static reply or the original data 326 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){ 327 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 328 } 329 340 rc = sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen); 341 if (rc != EOK) 342 socket_print_error(stderr, rc, "Socket send: ", "\n"); 330 343 } 331 344 332 345 // close the accepted stream socket 333 if (type == SOCK_STREAM){334 if(ERROR_OCCURRED(closesocket(socket_id))){335 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n");336 }346 if (type == SOCK_STREAM) { 347 rc = closesocket(socket_id); 348 if (rc != EOK) 349 socket_print_error(stderr, rc, "Close socket: ", "\n"); 337 350 } 338 351 … … 340 353 341 354 // decrease the count if positive 342 if (count > 0){343 -- count;344 if (verbose){355 if (count > 0) { 356 count--; 357 if (verbose) 345 358 printf("Waiting for next %d packet(s)\n", count); 346 } 347 } 348 } 349 350 if(verbose){ 359 } 360 } 361 362 if (verbose) 351 363 printf("Closing the socket\n"); 352 }353 364 354 365 // close the listenning socket 355 if(ERROR_OCCURRED(closesocket(listening_id))){ 356 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); 357 return ERROR_CODE; 358 } 359 360 if(verbose){ 366 rc = closesocket(listening_id); 367 if (rc != EOK) { 368 socket_print_error(stderr, rc, "Close socket: ", "\n"); 369 return rc; 370 } 371 372 if (verbose) 361 373 printf("Exiting\n"); 362 }363 374 364 375 return EOK; -
uspace/app/netecho/print_error.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup net_app 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Generic application error printing functions implementation. 35 35 */ 36 37 #include "print_error.h" 36 38 37 39 #include <stdio.h> … … 40 42 #include <net/icmp_codes.h> 41 43 42 #include "print_error.h" 44 /** Prints the specific ICMP error description. 45 * 46 * @param[in] output The description output stream. May be NULL. 47 * @param[in] error_code The ICMP error code. 48 * @param[in] prefix The error description prefix. May be NULL. 49 * @param[in] suffix The error description suffix. May be NULL. 50 */ 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 } 43 99 44 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 45 if(output){ 46 if(prefix){ 47 fprintf(output, "%s", prefix); 48 } 49 switch(error_code){ 50 case ICMP_DEST_UNREACH: 51 fprintf(output, "ICMP Destination Unreachable (%d) error", error_code); 52 break; 53 case ICMP_SOURCE_QUENCH: 54 fprintf(output, "ICMP Source Quench (%d) error", error_code); 55 break; 56 case ICMP_REDIRECT: 57 fprintf(output, "ICMP Redirect (%d) error", error_code); 58 break; 59 case ICMP_ALTERNATE_ADDR: 60 fprintf(output, "ICMP Alternate Host Address (%d) error", error_code); 61 break; 62 case ICMP_ROUTER_ADV: 63 fprintf(output, "ICMP Router Advertisement (%d) error", error_code); 64 break; 65 case ICMP_ROUTER_SOL: 66 fprintf(output, "ICMP Router Solicitation (%d) error", error_code); 67 break; 68 case ICMP_TIME_EXCEEDED: 69 fprintf(output, "ICMP Time Exceeded (%d) error", error_code); 70 break; 71 case ICMP_PARAMETERPROB: 72 fprintf(output, "ICMP Paramenter Problem (%d) error", error_code); 73 break; 74 case ICMP_CONVERSION_ERROR: 75 fprintf(output, "ICMP Datagram Conversion Error (%d) error", error_code); 76 break; 77 case ICMP_REDIRECT_MOBILE: 78 fprintf(output, "ICMP Mobile Host Redirect (%d) error", error_code); 79 break; 80 case ICMP_SKIP: 81 fprintf(output, "ICMP SKIP (%d) error", error_code); 82 break; 83 case ICMP_PHOTURIS: 84 fprintf(output, "ICMP Photuris (%d) error", error_code); 85 break; 86 default: 87 fprintf(output, "Other (%d) error", error_code); 88 } 89 if(suffix){ 90 fprintf(output, "%s", suffix); 91 } 92 } 100 if (suffix) 101 fprintf(output, "%s", suffix); 93 102 } 94 103 95 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 96 if(IS_ICMP_ERROR(error_code)){ 104 /** Prints the error description. 105 * 106 * Supports ICMP and socket error codes. 107 * 108 * @param[in] output The description output stream. May be NULL. 109 * @param[in] error_code The error code. 110 * @param[in] prefix The error description prefix. May be NULL. 111 * @param[in] suffix The error description suffix. May be NULL. 112 */ 113 void print_error(FILE *output, int error_code, const char *prefix, const char *suffix) 114 { 115 if (IS_ICMP_ERROR(error_code)) 97 116 icmp_print_error(output, error_code, prefix, suffix); 98 }else if(IS_SOCKET_ERROR(error_code)){117 else if(IS_SOCKET_ERROR(error_code)) 99 118 socket_print_error(output, error_code, prefix, suffix); 100 }101 119 } 102 120 103 void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 104 if(output){ 105 if(prefix){ 106 fprintf(output, "%s", prefix); 107 } 108 switch(error_code){ 109 case ENOTSOCK: 110 fprintf(output, "Not a socket (%d) error", error_code); 111 break; 112 case EPROTONOSUPPORT: 113 fprintf(output, "Protocol not supported (%d) error", error_code); 114 break; 115 case ESOCKTNOSUPPORT: 116 fprintf(output, "Socket type not supported (%d) error", error_code); 117 break; 118 case EPFNOSUPPORT: 119 fprintf(output, "Protocol family not supported (%d) error", error_code); 120 break; 121 case EAFNOSUPPORT: 122 fprintf(output, "Address family not supported (%d) error", error_code); 123 break; 124 case EADDRINUSE: 125 fprintf(output, "Address already in use (%d) error", error_code); 126 break; 127 case ENOTCONN: 128 fprintf(output, "Socket not connected (%d) error", error_code); 129 break; 130 case NO_DATA: 131 fprintf(output, "No data (%d) error", error_code); 132 break; 133 case EINPROGRESS: 134 fprintf(output, "Another operation in progress (%d) error", error_code); 135 break; 136 case EDESTADDRREQ: 137 fprintf(output, "Destination address required (%d) error", error_code); 138 case TRY_AGAIN: 139 fprintf(output, "Try again (%d) error", error_code); 140 default: 141 fprintf(output, "Other (%d) error", error_code); 142 } 143 if(suffix){ 144 fprintf(output, "%s", suffix); 145 } 121 /** Prints the specific socket error description. 122 * 123 * @param[in] output The description output stream. May be NULL. 124 * @param[in] error_code The socket error code. 125 * @param[in] prefix The error description prefix. May be NULL. 126 * @param[in] suffix The error description suffix. May be NULL. 127 */ 128 void socket_print_error(FILE *output, int error_code, const char *prefix, const char *suffix) 129 { 130 if (!output) 131 return; 132 133 if (prefix) 134 fprintf(output, "%s", prefix); 135 136 switch (error_code) { 137 case ENOTSOCK: 138 fprintf(output, "Not a socket (%d) error", error_code); 139 break; 140 case EPROTONOSUPPORT: 141 fprintf(output, "Protocol not supported (%d) error", error_code); 142 break; 143 case ESOCKTNOSUPPORT: 144 fprintf(output, "Socket type not supported (%d) error", error_code); 145 break; 146 case EPFNOSUPPORT: 147 fprintf(output, "Protocol family not supported (%d) error", error_code); 148 break; 149 case EAFNOSUPPORT: 150 fprintf(output, "Address family not supported (%d) error", error_code); 151 break; 152 case EADDRINUSE: 153 fprintf(output, "Address already in use (%d) error", error_code); 154 break; 155 case ENOTCONN: 156 fprintf(output, "Socket not connected (%d) error", error_code); 157 break; 158 case NO_DATA: 159 fprintf(output, "No data (%d) error", error_code); 160 break; 161 case EINPROGRESS: 162 fprintf(output, "Another operation in progress (%d) error", error_code); 163 break; 164 case EDESTADDRREQ: 165 fprintf(output, "Destination address required (%d) error", error_code); 166 case TRY_AGAIN: 167 fprintf(output, "Try again (%d) error", error_code); 168 default: 169 fprintf(output, "Other (%d) error", error_code); 146 170 } 171 172 if (suffix) 173 fprintf(output, "%s", suffix); 147 174 } 148 175 149 176 /** @} 150 177 */ 178 -
uspace/app/netecho/print_error.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup net_app 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Generic application error printing functions. 35 35 */ 36 36 37 #ifndef __NET_APP_PRINT__ 38 #define __NET_APP_PRINT__ 37 #ifndef NET_APP_PRINT_ 38 #define NET_APP_PRINT_ 39 40 #include <stdio.h> 39 41 40 42 /** Returns whether the error code may be an ICMP error code. 41 * @param[in] error_code The error code. 42 * @returns A value indicating whether the error code may be an ICMP error code. 43 * 44 * @param[in] error_code The error code. 45 * @returns A value indicating whether the error code may be an ICMP error code. 43 46 */ 44 #define IS_ICMP_ERROR(error_code) 47 #define IS_ICMP_ERROR(error_code) ((error_code) > 0) 45 48 46 49 /** Returns whether the error code may be socket error code. 47 * @param[in] error_code The error code. 48 * @returns A value indicating whether the error code may be a socket error code. 50 * 51 * @param[in] error_code The error code. 52 * @returns A value indicating whether the error code may be a socket error code. 49 53 */ 50 54 #define IS_SOCKET_ERROR(error_code) ((error_code) < 0) 51 55 52 /** Prints the specific ICMP error description. 53 * @param[in] output The description output stream. May be NULL. 54 * @param[in] error_code The ICMP error code. 55 * @param[in] prefix The error description prefix. May be NULL. 56 * @param[in] suffix The error description suffix. May be NULL. 57 */ 58 extern void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 59 60 /** Prints the error description. 61 * Supports ICMP and socket error codes. 62 * @param[in] output The description output stream. May be NULL. 63 * @param[in] error_code The error code. 64 * @param[in] prefix The error description prefix. May be NULL. 65 * @param[in] suffix The error description suffix. May be NULL. 66 */ 67 extern void print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 68 69 /** Prints the specific socket error description. 70 * @param[in] output The description output stream. May be NULL. 71 * @param[in] error_code The socket error code. 72 * @param[in] prefix The error description prefix. May be NULL. 73 * @param[in] suffix The error description suffix. May be NULL. 74 */ 75 extern void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 56 extern void icmp_print_error(FILE *, int, const char *, const char *); 57 extern void print_error(FILE *, int, const char *, const char *); 58 extern void socket_print_error(FILE *, int, const char *, const char *); 76 59 77 60 #endif -
uspace/app/netstart/Makefile
rd70a463 rb40bfac 28 28 # 29 29 30 USPACE_PREFIX = ../.. /..30 USPACE_PREFIX = ../.. 31 31 LIBS = $(LIBNET_PREFIX)/libnet.a 32 32 EXTRA_CFLAGS = -I$(LIBNET_PREFIX)/include … … 35 35 36 36 SOURCES = \ 37 netstart.c \ 38 self_test.c 37 netstart.c 39 38 40 39 include $(USPACE_PREFIX)/Makefile.common -
uspace/app/netstart/netstart.c
rd70a463 rb40bfac 32 32 33 33 /** @file 34 *35 34 * Start the networking subsystem. 36 * Perform networking self-test if executed37 * with the -s argument.38 *39 35 */ 40 36 … … 45 41 #include <task.h> 46 42 #include <str_error.h> 47 #include <err.h>48 43 #include <ipc/ipc.h> 49 44 #include <ipc/services.h> … … 52 47 #include <net/modules.h> 53 48 54 #include "self_test.h"55 56 49 /** Start a module. 57 50 * 58 * @param[in] desc The module description 59 * @param[in] path The module absolute path. 60 * 61 * @returns true on succesful spanwning 62 * @returns false on failure 63 * 51 * @param[in] desc The module description 52 * @param[in] path The module absolute path. 53 * @returns True on succesful spanwning. 54 * @returns False on failure 64 55 */ 65 56 static bool spawn(const char *desc, const char *path) 66 57 { 58 int rc; 59 67 60 printf("%s: Spawning %s (%s)\n", NAME, desc, path); 68 69 const char *argv[2]; 70 71 argv[0] = path; 72 argv[1] = NULL; 73 74 int err; 75 if (task_spawn(path, argv, &err) == 0) { 61 rc = task_spawnl(NULL, path, path, NULL); 62 if (rc != EOK) { 76 63 fprintf(stderr, "%s: Error spawning %s (%s)\n", NAME, path, 77 str_error( err));64 str_error(rc)); 78 65 return false; 79 66 } … … 84 71 int main(int argc, char *argv[]) 85 72 { 86 ERROR_DECLARE; 87 88 /* Run self-tests */ 89 if ((argc > 1) && (str_cmp(argv[1], "-s") == 0)) 90 ERROR_PROPAGATE(self_test()); 73 int rc; 91 74 92 75 if (!spawn("networking service", "/srv/net")) … … 96 79 97 80 int net_phone = connect_to_service(SERVICE_NETWORKING); 98 if (ERROR_OCCURRED(ipc_call_sync_0_0(net_phone, NET_NET_STARTUP))) { 99 fprintf(stderr, "%s: Startup error %d\n", NAME, ERROR_CODE); 100 return ERROR_CODE; 81 rc = ipc_call_sync_0_0(net_phone, NET_NET_STARTUP); 82 if (rc != EOK) { 83 fprintf(stderr, "%s: Startup error %d\n", NAME, rc); 84 return rc; 101 85 } 102 86 -
uspace/app/nettest1/nettest.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup nettest 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Networking test support functions implementation. 35 35 */ 36 36 37 37 #include <stdio.h> 38 #include <err.h>39 40 38 #include <net/socket.h> 41 39 … … 43 41 #include "print_error.h" 44 42 45 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){ 46 int index; 47 48 if(verbose){ 43 44 /** Creates new sockets. 45 * 46 * @param[in] verbose A value indicating whether to print out verbose information. 47 * @param[out] socket_ids A field to store the socket identifiers. 48 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 49 * @param[in] family The socket address family. 50 * @param[in] type The socket type. 51 * @returns EOK on success. 52 * @returns Other error codes as defined for the socket() function. 53 */ 54 int sockets_create(int verbose, int *socket_ids, int sockets, int family, sock_type_t type) 55 { 56 int index; 57 58 if (verbose) 49 59 printf("Create\t"); 50 } 51 fflush(stdout); 52 for(index = 0; index < sockets; ++ index){ 60 61 fflush(stdout); 62 63 for (index = 0; index < sockets; index++) { 53 64 socket_ids[index] = socket(family, type, 0); 54 if (socket_ids[index] < 0){65 if (socket_ids[index] < 0) { 55 66 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 56 67 socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n"); 57 68 return socket_ids[index]; 58 69 } 59 if(verbose){ 60 print_mark(index); 61 } 62 } 63 return EOK; 64 } 65 66 int sockets_close(int verbose, int * socket_ids, int sockets){ 67 ERROR_DECLARE; 68 69 int index; 70 71 if(verbose){ 70 if (verbose) 71 print_mark(index); 72 } 73 74 return EOK; 75 } 76 77 /** Closes sockets. 78 * 79 * @param[in] verbose A value indicating whether to print out verbose information. 80 * @param[in] socket_ids A field of stored socket identifiers. 81 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 82 * @returns EOK on success. 83 * @returns Other error codes as defined for the closesocket() function. 84 */ 85 int sockets_close(int verbose, int *socket_ids, int sockets) 86 { 87 int index; 88 int rc; 89 90 if (verbose) 72 91 printf("\tClose\t"); 73 } 74 fflush(stdout); 75 for(index = 0; index < sockets; ++ index){ 76 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){ 92 93 fflush(stdout); 94 95 for (index = 0; index < sockets; index++) { 96 rc = closesocket(socket_ids[index]); 97 if (rc != EOK) { 77 98 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 78 socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n"); 79 return ERROR_CODE; 80 } 81 if(verbose){ 82 print_mark(index); 83 } 84 } 85 return EOK; 86 } 87 88 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){ 89 ERROR_DECLARE; 90 91 int index; 92 93 if(verbose){ 99 socket_print_error(stderr, rc, "Socket close: ", "\n"); 100 return rc; 101 } 102 if (verbose) 103 print_mark(index); 104 } 105 106 return EOK; 107 } 108 109 /** Connects sockets. 110 * 111 * @param[in] verbose A value indicating whether to print out verbose information. 112 * @param[in] socket_ids A field of stored socket identifiers. 113 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 114 * @param[in] address The destination host address to connect to. 115 * @param[in] addrlen The length of the destination address in bytes. 116 * @returns EOK on success. 117 * @returns Other error codes as defined for the connect() function. 118 */ 119 int sockets_connect(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t addrlen) 120 { 121 int index; 122 int rc; 123 124 if (verbose) 94 125 printf("\tConnect\t"); 95 } 96 fflush(stdout); 97 for(index = 0; index < sockets; ++ index){ 98 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){ 99 socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n"); 100 return ERROR_CODE; 101 } 102 if(verbose){ 103 print_mark(index); 104 } 105 } 106 return EOK; 107 } 108 109 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){ 110 ERROR_DECLARE; 111 126 127 fflush(stdout); 128 129 for (index = 0; index < sockets; index++) { 130 rc = connect(socket_ids[index], address, addrlen); 131 if (rc != EOK) { 132 socket_print_error(stderr, rc, "Socket connect: ", "\n"); 133 return rc; 134 } 135 if (verbose) 136 print_mark(index); 137 } 138 139 return EOK; 140 } 141 142 /** Sends data via sockets. 143 * 144 * @param[in] verbose A value indicating whether to print out verbose information. 145 * @param[in] socket_ids A field of stored socket identifiers. 146 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 147 * @param[in] address The destination host address to send data to. 148 * @param[in] addrlen The length of the destination address in bytes. 149 * @param[in] data The data to be sent. 150 * @param[in] size The data size in bytes. 151 * @param[in] messages The number of datagrams per socket to be sent. 152 * @returns EOK on success. 153 * @returns Other error codes as defined for the sendto() function. 154 */ 155 int sockets_sendto(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t addrlen, char *data, int size, int messages) 156 { 112 157 int index; 113 158 int message; 114 115 if(verbose){ 159 int rc; 160 161 if (verbose) 116 162 printf("\tSendto\t"); 117 } 118 fflush(stdout); 119 for(index = 0; index < sockets; ++ index){ 120 for(message = 0; message < messages; ++ message){ 121 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){ 122 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 123 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 124 return ERROR_CODE; 125 } 126 } 127 if(verbose){ 128 print_mark(index); 129 } 130 } 131 return EOK; 132 } 133 134 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 163 164 fflush(stdout); 165 166 for (index = 0; index < sockets; index++) { 167 for (message = 0; message < messages; message++) { 168 rc = sendto(socket_ids[index], data, size, 0, address, addrlen); 169 if (rc != EOK) { 170 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 171 socket_print_error(stderr, rc, "Socket send: ", "\n"); 172 return rc; 173 } 174 } 175 if (verbose) 176 print_mark(index); 177 } 178 179 return EOK; 180 } 181 182 /** Receives data via sockets. 183 * 184 * @param[in] verbose A value indicating whether to print out verbose information. 185 * @param[in] socket_ids A field of stored socket identifiers. 186 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 187 * @param[in] address The source host address of received datagrams. 188 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 189 * @param[out] data The received data. 190 * @param[in] size The maximum data size in bytes. 191 * @param[in] messages The number of datagrams per socket to be received. 192 * @returns EOK on success. 193 * @returns Other error codes as defined for the recvfrom() function. 194 */ 195 int sockets_recvfrom(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t *addrlen, char *data, int size, int messages) 196 { 135 197 int value; 136 198 int index; 137 199 int message; 138 200 139 if (verbose){201 if (verbose) 140 202 printf("\tRecvfrom\t"); 141 } 142 fflush(stdout); 143 for(index = 0; index < sockets; ++ index){ 144 for(message = 0; message < messages; ++ message){ 203 204 fflush(stdout); 205 206 for (index = 0; index < sockets; index++) { 207 for (message = 0; message < messages; message++) { 145 208 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 146 if (value < 0){209 if (value < 0) { 147 210 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 148 211 socket_print_error(stderr, value, "Socket receive: ", "\n"); … … 150 213 } 151 214 } 152 if(verbose){ 153 print_mark(index); 154 } 155 } 156 return EOK; 157 } 158 159 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 160 ERROR_DECLARE; 161 215 if (verbose) 216 print_mark(index); 217 } 218 return EOK; 219 } 220 221 /** Sends and receives data via sockets. 222 * 223 * Each datagram is sent and a reply read consequently. 224 * The next datagram is sent after the reply is received. 225 * 226 * @param[in] verbose A value indicating whether to print out verbose information. 227 * @param[in] socket_ids A field of stored socket identifiers. 228 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 229 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 230 * @param[in] addrlen The length of the destination address in bytes. 231 * @param[in,out] data The data to be sent. The received data are set instead. 232 * @param[in] size The data size in bytes. 233 * @param[in] messages The number of datagrams per socket to be received. 234 * @returns EOK on success. 235 * @returns Other error codes as defined for the recvfrom() function. 236 */ 237 int sockets_sendto_recvfrom(int verbose, int *socket_ids, int sockets, struct sockaddr *address, socklen_t *addrlen, char *data, int size, int messages) 238 { 162 239 int value; 163 240 int index; 164 241 int message; 165 166 if(verbose){ 242 int rc; 243 244 if (verbose) 167 245 printf("\tSendto and recvfrom\t"); 168 } 169 fflush(stdout); 170 for(index = 0; index < sockets; ++ index){ 171 for(message = 0; message < messages; ++ message){ 172 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){ 173 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 174 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 175 return ERROR_CODE; 246 247 fflush(stdout); 248 249 for (index = 0; index < sockets; index++) { 250 for (message = 0; message < messages; message++) { 251 rc = sendto(socket_ids[index], data, size, 0, address, *addrlen); 252 if (rc != EOK) { 253 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 254 socket_print_error(stderr, rc, "Socket send: ", "\n"); 255 return rc; 176 256 } 177 257 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 178 if (value < 0){258 if (value < 0) { 179 259 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 180 260 socket_print_error(stderr, value, "Socket receive: ", "\n"); … … 182 262 } 183 263 } 184 if(verbose){ 185 print_mark(index); 186 } 187 } 188 return EOK; 189 } 190 191 void print_mark(int index){ 192 if((index + 1) % 10){ 264 if (verbose) 265 print_mark(index); 266 } 267 268 return EOK; 269 } 270 271 /** Prints a mark. 272 * 273 * If the index is a multiple of ten, a different mark is printed. 274 * 275 * @param[in] index The index of the mark to be printed. 276 */ 277 void print_mark(int index) 278 { 279 if ((index + 1) % 10) 193 280 printf("*"); 194 }else{281 else 195 282 printf("|"); 196 }197 283 fflush(stdout); 198 284 } -
uspace/app/nettest1/nettest.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup nettest 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Networking test support functions. 35 35 */ 36 36 37 #ifndef __NET_TEST__38 #define __NET_TEST__37 #ifndef NET_TEST_ 38 #define NET_TEST_ 39 39 40 40 #include <net/socket.h> 41 41 42 /** Prints a mark. 43 * If the index is a multiple of ten, a different mark is printed. 44 * @param[in] index The index of the mark to be printed. 45 */ 46 extern void print_mark(int index); 47 48 /** Creates new sockets. 49 * @param[in] verbose A value indicating whether to print out verbose information. 50 * @param[out] socket_ids A field to store the socket identifiers. 51 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 52 * @param[in] family The socket address family. 53 * @param[in] type The socket type. 54 * @returns EOK on success. 55 * @returns Other error codes as defined for the socket() function. 56 */ 57 extern int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type); 58 59 /** Closes sockets. 60 * @param[in] verbose A value indicating whether to print out verbose information. 61 * @param[in] socket_ids A field of stored socket identifiers. 62 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 63 * @returns EOK on success. 64 * @returns Other error codes as defined for the closesocket() function. 65 */ 66 extern int sockets_close(int verbose, int * socket_ids, int sockets); 67 68 /** Connects sockets. 69 * @param[in] verbose A value indicating whether to print out verbose information. 70 * @param[in] socket_ids A field of stored socket identifiers. 71 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 72 * @param[in] address The destination host address to connect to. 73 * @param[in] addrlen The length of the destination address in bytes. 74 * @returns EOK on success. 75 * @returns Other error codes as defined for the connect() function. 76 */ 77 extern int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen); 78 79 /** Sends data via sockets. 80 * @param[in] verbose A value indicating whether to print out verbose information. 81 * @param[in] socket_ids A field of stored socket identifiers. 82 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 83 * @param[in] address The destination host address to send data to. 84 * @param[in] addrlen The length of the destination address in bytes. 85 * @param[in] data The data to be sent. 86 * @param[in] size The data size in bytes. 87 * @param[in] messages The number of datagrams per socket to be sent. 88 * @returns EOK on success. 89 * @returns Other error codes as defined for the sendto() function. 90 */ 91 extern int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages); 92 93 /** Receives data via sockets. 94 * @param[in] verbose A value indicating whether to print out verbose information. 95 * @param[in] socket_ids A field of stored socket identifiers. 96 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 97 * @param[in] address The source host address of received datagrams. 98 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 99 * @param[out] data The received data. 100 * @param[in] size The maximum data size in bytes. 101 * @param[in] messages The number of datagrams per socket to be received. 102 * @returns EOK on success. 103 * @returns Other error codes as defined for the recvfrom() function. 104 */ 105 extern int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 106 107 /** Sends and receives data via sockets. 108 * Each datagram is sent and a reply read consequently. 109 * The next datagram is sent after the reply is received. 110 * @param[in] verbose A value indicating whether to print out verbose information. 111 * @param[in] socket_ids A field of stored socket identifiers. 112 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 113 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 114 * @param[in] addrlen The length of the destination address in bytes. 115 * @param[in,out] data The data to be sent. The received data are set instead. 116 * @param[in] size The data size in bytes. 117 * @param[in] messages The number of datagrams per socket to be received. 118 * @returns EOK on success. 119 * @returns Other error codes as defined for the recvfrom() function. 120 */ 121 extern int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 42 extern void print_mark(int); 43 extern int sockets_create(int, int *, int, int, sock_type_t); 44 extern int sockets_close(int, int *, int); 45 extern int sockets_connect(int, int *, int, struct sockaddr *, socklen_t); 46 extern int sockets_sendto(int, int *, int, struct sockaddr *, socklen_t, char *, int, int); 47 extern int sockets_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int); 48 extern int sockets_sendto_recvfrom(int, int *, int, struct sockaddr *, socklen_t *, char *, int, int); 122 49 123 50 #endif … … 125 52 /** @} 126 53 */ 54 -
uspace/app/nettest1/nettest1.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup nettest 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Networking test 1 application - sockets. 35 */ 34 * Networking test 1 application - sockets. 35 */ 36 37 #include "nettest.h" 38 #include "print_error.h" 36 39 37 40 #include <malloc.h> … … 41 44 #include <time.h> 42 45 #include <arg_parse.h> 43 #include <err.h>44 46 45 47 #include <net/in.h> … … 49 51 #include <net/socket_parse.h> 50 52 51 #include "nettest.h" 52 #include "print_error.h" 53 54 /** Echo module name. 55 */ 53 /** Echo module name. */ 56 54 #define NAME "Nettest1" 57 55 58 /** Packet data pattern. 59 */ 56 /** Packet data pattern. */ 60 57 #define NETTEST1_TEXT "Networking test 1 - sockets" 61 58 62 /** Module entry point. 63 * Starts testing. 64 * @param[in] argc The number of command line parameters. 65 * @param[in] argv The command line parameters. 66 * @returns EOK on success. 67 */ 68 int main(int argc, char * argv[]); 69 70 /** Prints the application help. 71 */ 72 void nettest1_print_help(void); 73 74 /** Refreshes the data. 75 * Fills the data block with the NETTEST1_TEXT pattern. 76 * @param[out] data The data block. 77 * @param[in] size The data block size in bytes. 78 */ 79 void nettest1_refresh_data(char * data, size_t size); 80 81 int main(int argc, char * argv[]){ 82 ERROR_DECLARE; 83 84 size_t size = 27; 85 int verbose = 0; 86 sock_type_t type = SOCK_DGRAM; 87 int sockets = 10; 88 int messages = 10; 89 int family = PF_INET; 90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 93 uint8_t address_data[max_length]; 94 struct sockaddr * address = (struct sockaddr *) address_data; 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 97 socklen_t addrlen; 98 // char address_string[INET6_ADDRSTRLEN]; 99 uint8_t * address_start; 100 101 int * socket_ids; 102 char * data; 59 static int family = PF_INET; 60 static sock_type_t type = SOCK_DGRAM; 61 static char *data; 62 static size_t size = 27; 63 static int verbose = 0; 64 65 static struct sockaddr *address; 66 static socklen_t addrlen; 67 68 static int sockets; 69 static int messages; 70 static uint16_t port; 71 72 static void nettest1_print_help(void) 73 { 74 printf( 75 "Network Networking test 1 aplication - sockets\n" 76 "Usage: echo [options] numeric_address\n" 77 "Where options are:\n" 78 "-f protocol_family | --family=protocol_family\n" 79 "\tThe listenning socket protocol family. Only the PF_INET and " 80 "PF_INET6 are supported.\n" 81 "\n" 82 "-h | --help\n" 83 "\tShow this application help.\n" 84 "\n" 85 "-m count | --messages=count\n" 86 "\tThe number of messages to send and receive per socket. The " 87 "default is 10.\n" 88 "\n" 89 "-n sockets | --sockets=count\n" 90 "\tThe number of sockets to use. The default is 10.\n" 91 "\n" 92 "-p port_number | --port=port_number\n" 93 "\tThe port number the application should send messages to. The " 94 "default is 7.\n" 95 "\n" 96 "-s packet_size | --size=packet_size\n" 97 "\tThe packet data size the application sends. The default is " 98 "28 bytes.\n" 99 "\n" 100 "-v | --verbose\n" 101 "\tShow all output messages.\n"); 102 } 103 104 /** Parse one command-line option. 105 * 106 * @param argc Number of all command-line arguments. 107 * @param argv All command-line arguments. 108 * @param index Current argument index (in, out). 109 */ 110 static int nettest1_parse_opt(int argc, char *argv[], int *index) 111 { 103 112 int value; 113 int rc; 114 115 switch (argv[*index][1]) { 116 /* 117 * Short options with only one letter 118 */ 119 case 'f': 120 rc = arg_parse_name_int(argc, argv, index, &family, 0, socket_parse_protocol_family); 121 if (rc != EOK) 122 return rc; 123 break; 124 case 'h': 125 nettest1_print_help(); 126 return EOK; 127 case 'm': 128 rc = arg_parse_int(argc, argv, index, &messages, 0); 129 if (rc != EOK) 130 return rc; 131 break; 132 case 'n': 133 rc = arg_parse_int(argc, argv, index, &sockets, 0); 134 if (rc != EOK) 135 return rc; 136 break; 137 case 'p': 138 rc = arg_parse_int(argc, argv, index, &value, 0); 139 if (rc != EOK) 140 return rc; 141 port = (uint16_t) value; 142 break; 143 case 's': 144 rc = arg_parse_int(argc, argv, index, &value, 0); 145 if (rc != EOK) 146 return rc; 147 size = (value >= 0) ? (size_t) value : 0; 148 break; 149 case 't': 150 rc = arg_parse_name_int(argc, argv, index, &value, 0, socket_parse_socket_type); 151 if (rc != EOK) 152 return rc; 153 type = (sock_type_t) value; 154 break; 155 case 'v': 156 verbose = 1; 157 break; 158 /* 159 * Long options with double dash ('-') 160 */ 161 case '-': 162 if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) { 163 rc = arg_parse_name_int(argc, argv, index, &family, 9, 164 socket_parse_protocol_family); 165 if (rc != EOK) 166 return rc; 167 } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) { 168 nettest1_print_help(); 169 return EOK; 170 } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) { 171 rc = arg_parse_int(argc, argv, index, &messages, 8); 172 if (rc != EOK) 173 return rc; 174 } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) { 175 rc = arg_parse_int(argc, argv, index, &sockets, 8); 176 if (rc != EOK) 177 return rc; 178 } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) { 179 rc = arg_parse_int(argc, argv, index, &value, 7); 180 if (rc != EOK) 181 return rc; 182 port = (uint16_t) value; 183 } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) { 184 rc = arg_parse_name_int(argc, argv, index, &value, 7, 185 socket_parse_socket_type); 186 if (rc != EOK) 187 return rc; 188 type = (sock_type_t) value; 189 } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) { 190 verbose = 1; 191 } else { 192 nettest1_print_help(); 193 return EINVAL; 194 } 195 break; 196 default: 197 nettest1_print_help(); 198 return EINVAL; 199 } 200 201 return EOK; 202 } 203 204 /** Fill buffer with the NETTEST1_TEXT pattern. 205 * 206 * @param buffer Data buffer. 207 * @param size Buffer size in bytes. 208 */ 209 static void nettest1_fill_buffer(char *buffer, size_t size) 210 { 211 size_t length; 212 213 length = 0; 214 while (size > length + sizeof(NETTEST1_TEXT) - 1) { 215 memcpy(buffer + length, NETTEST1_TEXT, 216 sizeof(NETTEST1_TEXT) - 1); 217 length += sizeof(NETTEST1_TEXT) - 1; 218 } 219 220 memcpy(buffer + length, NETTEST1_TEXT, size - length); 221 buffer[size] = '\0'; 222 } 223 224 static int nettest1_test(int *socket_ids, int nsockets, int nmessages) 225 { 226 int rc; 227 228 if (verbose) 229 printf("%d sockets, %d messages\n", nsockets, nmessages); 230 231 rc = sockets_create(verbose, socket_ids, nsockets, family, type); 232 if (rc != EOK) 233 return rc; 234 235 if (type == SOCK_STREAM) { 236 rc = sockets_connect(verbose, socket_ids, nsockets, address, 237 addrlen); 238 if (rc != EOK) 239 return rc; 240 } 241 242 rc = sockets_sendto_recvfrom(verbose, socket_ids, nsockets, address, 243 &addrlen, data, size, nmessages); 244 if (rc != EOK) 245 return rc; 246 247 rc = sockets_close(verbose, socket_ids, nsockets); 248 if (rc != EOK) 249 return rc; 250 251 if (verbose) 252 printf("\tOK\n"); 253 254 /****/ 255 256 rc = sockets_create(verbose, socket_ids, nsockets, family, type); 257 if (rc != EOK) 258 return rc; 259 260 if (type == SOCK_STREAM) { 261 rc = sockets_connect(verbose, socket_ids, nsockets, address, 262 addrlen); 263 if (rc != EOK) 264 return rc; 265 } 266 267 rc = sockets_sendto(verbose, socket_ids, nsockets, address, addrlen, 268 data, size, nmessages); 269 if (rc != EOK) 270 return rc; 271 272 rc = sockets_recvfrom(verbose, socket_ids, nsockets, address, &addrlen, 273 data, size, nmessages); 274 if (rc != EOK) 275 return rc; 276 277 rc = sockets_close(verbose, socket_ids, nsockets); 278 if (rc != EOK) 279 return rc; 280 281 if (verbose) 282 printf("\tOK\n"); 283 284 return EOK; 285 } 286 287 int main(int argc, char *argv[]) 288 { 289 290 socklen_t max_length; 291 uint8_t *address_data[sizeof(struct sockaddr_in6)]; 292 struct sockaddr_in *address_in; 293 struct sockaddr_in6 *address_in6; 294 uint8_t *address_start; 295 296 int *socket_ids; 104 297 int index; 105 298 struct timeval time_before; 106 299 struct timeval time_after; 107 300 108 // parse the command line arguments 109 // stop before the last argument if it does not start with the minus sign ('-') 110 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 111 // options should start with the minus sign ('-') 112 if(argv[index][0] == '-'){ 113 switch(argv[index][1]){ 114 // short options with only one letter 115 case 'f': 116 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 117 break; 118 case 'h': 119 nettest1_print_help(); 120 return EOK; 121 break; 122 case 'm': 123 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0)); 124 break; 125 case 'n': 126 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0)); 127 break; 128 case 'p': 129 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 130 port = (uint16_t) value; 131 break; 132 case 's': 133 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 134 size = (value >= 0) ? (size_t) value : 0; 135 break; 136 case 't': 137 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 138 type = (sock_type_t) value; 139 break; 140 case 'v': 141 verbose = 1; 142 break; 143 // long options with the double minus sign ('-') 144 case '-': 145 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 146 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 147 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 148 nettest1_print_help(); 149 return EOK; 150 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ 151 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8)); 152 }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){ 153 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8)); 154 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 155 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 156 port = (uint16_t) value; 157 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 158 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 159 type = (sock_type_t) value; 160 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 161 verbose = 1; 162 }else{ 163 nettest1_print_help(); 164 return EINVAL; 165 } 166 break; 167 default: 168 nettest1_print_help(); 169 return EINVAL; 170 } 171 }else{ 301 int rc; 302 303 max_length = sizeof(address_data); 304 address = (struct sockaddr *) address_data; 305 address_in = (struct sockaddr_in *) address; 306 address_in6 = (struct sockaddr_in6 *) address; 307 308 sockets = 10; 309 messages = 10; 310 port = 7; 311 312 /* 313 * Parse the command line arguments. Stop before the last argument 314 * if it does not start with dash ('-') 315 */ 316 for (index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); index++) { 317 /* Options should start with dash ('-') */ 318 if (argv[index][0] == '-') { 319 rc = nettest1_parse_opt(argc, argv, &index); 320 if (rc != EOK) 321 return rc; 322 } else { 172 323 nettest1_print_help(); 173 324 return EINVAL; … … 175 326 } 176 327 177 / / if not before the last argument containing the address178 if (index >= argc){328 /* If not before the last argument containing the address */ 329 if (index >= argc) { 179 330 printf("Command line error: missing address\n"); 180 331 nettest1_print_help(); … … 182 333 } 183 334 184 / / prepare the address buffer335 /* Prepare the address buffer */ 185 336 bzero(address_data, max_length); 186 switch(family){ 187 case PF_INET: 188 address_in->sin_family = AF_INET; 189 address_in->sin_port = htons(port); 190 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 191 addrlen = sizeof(struct sockaddr_in); 192 break; 193 case PF_INET6: 194 address_in6->sin6_family = AF_INET6; 195 address_in6->sin6_port = htons(port); 196 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 197 addrlen = sizeof(struct sockaddr_in6); 198 break; 199 default: 200 fprintf(stderr, "Address family is not supported\n"); 201 return EAFNOSUPPORT; 202 } 203 204 // parse the last argument which should contain the address 205 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 206 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); 207 return ERROR_CODE; 208 } 209 210 // check the buffer size 211 if(size <= 0){ 212 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 337 338 switch (family) { 339 case PF_INET: 340 address_in->sin_family = AF_INET; 341 address_in->sin_port = htons(port); 342 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 343 addrlen = sizeof(struct sockaddr_in); 344 break; 345 case PF_INET6: 346 address_in6->sin6_family = AF_INET6; 347 address_in6->sin6_port = htons(port); 348 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 349 addrlen = sizeof(struct sockaddr_in6); 350 break; 351 default: 352 fprintf(stderr, "Address family is not supported\n"); 353 return EAFNOSUPPORT; 354 } 355 356 /* Parse the last argument which should contain the address */ 357 rc = inet_pton(family, argv[argc - 1], address_start); 358 if (rc != EOK) { 359 fprintf(stderr, "Address parse error %d\n", rc); 360 return rc; 361 } 362 363 /* Check data buffer size */ 364 if (size <= 0) { 365 fprintf(stderr, "Data buffer size too small (%d). Using 1024 " 366 "bytes instead.\n", size); 213 367 size = 1024; 214 368 } 215 369 216 // prepare the buffer 217 // size plus the terminating null (\0) 370 /* 371 * Prepare data buffer. Allocate size bytes plus one for the 372 * trailing null character. 373 */ 218 374 data = (char *) malloc(size + 1); 219 if (! data){375 if (!data) { 220 376 fprintf(stderr, "Failed to allocate data buffer.\n"); 221 377 return ENOMEM; 222 378 } 223 nettest1_refresh_data(data, size); 224 225 // check the socket count 226 if(sockets <= 0){ 227 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 379 nettest1_fill_buffer(data, size); 380 381 /* Check socket count */ 382 if (sockets <= 0) { 383 fprintf(stderr, "Socket count too small (%d). Using " 384 "2 instead.\n", sockets); 228 385 sockets = 2; 229 386 } 230 387 231 // prepare the socket buffer 232 // count plus the terminating null (\0) 388 /* 389 * Prepare socket buffer. Allocate count fields plus the terminating 390 * null (\0). 391 */ 233 392 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 234 if (! socket_ids){393 if (!socket_ids) { 235 394 fprintf(stderr, "Failed to allocate receive buffer.\n"); 236 395 return ENOMEM; … … 238 397 socket_ids[sockets] = NULL; 239 398 240 if (verbose){399 if (verbose) 241 400 printf("Starting tests\n"); 242 } 243 244 if(verbose){ 245 printf("1 socket, 1 message\n"); 246 } 247 248 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 249 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 250 return ERROR_CODE; 251 } 252 253 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 254 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 255 if(verbose){ 256 printf("\tOK\n"); 257 } 258 259 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 260 if(type == SOCK_STREAM){ 261 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 262 } 263 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1)); 264 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 265 if(verbose){ 266 printf("\tOK\n"); 267 } 268 269 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 270 if(type == SOCK_STREAM){ 271 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 272 } 273 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, 1)); 274 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, 1)); 275 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 276 if(verbose){ 277 printf("\tOK\n"); 278 } 279 280 if(verbose){ 281 printf("1 socket, %d messages\n", messages); 282 } 283 284 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 285 if(type == SOCK_STREAM){ 286 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 287 } 288 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages)); 289 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 290 if(verbose){ 291 printf("\tOK\n"); 292 } 293 294 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, 1, family, type)); 295 if(type == SOCK_STREAM){ 296 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, 1, address, addrlen)); 297 } 298 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, 1, address, addrlen, data, size, messages)); 299 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, 1, address, &addrlen, data, size, messages)); 300 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, 1)); 301 if(verbose){ 302 printf("\tOK\n"); 303 } 304 305 if(verbose){ 306 printf("%d sockets, 1 message\n", sockets); 307 } 308 309 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 310 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 311 if(verbose){ 312 printf("\tOK\n"); 313 } 314 315 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 316 if(type == SOCK_STREAM){ 317 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 318 } 319 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1)); 320 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 321 if(verbose){ 322 printf("\tOK\n"); 323 } 324 325 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 326 if(type == SOCK_STREAM){ 327 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 328 } 329 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, 1)); 330 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, 1)); 331 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 332 if(verbose){ 333 printf("\tOK\n"); 334 } 335 336 if(verbose){ 337 printf("%d sockets, %d messages\n", sockets, messages); 338 } 339 340 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 341 if(type == SOCK_STREAM){ 342 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 343 } 344 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 345 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 346 if(verbose){ 347 printf("\tOK\n"); 348 } 349 350 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 351 if(type == SOCK_STREAM){ 352 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 353 } 354 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages)); 355 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 356 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 357 358 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 359 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 360 return ERROR_CODE; 361 } 362 363 if(verbose){ 364 printf("\tOK\n"); 365 } 366 367 printf("Tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 368 369 if(verbose){ 401 402 rc = gettimeofday(&time_before, NULL); 403 if (rc != EOK) { 404 fprintf(stderr, "Get time of day error %d\n", rc); 405 return rc; 406 } 407 408 nettest1_test(socket_ids, 1, 1); 409 nettest1_test(socket_ids, 1, messages); 410 nettest1_test(socket_ids, sockets, 1); 411 nettest1_test(socket_ids, sockets, messages); 412 413 rc = gettimeofday(&time_after, NULL); 414 if (rc != EOK) { 415 fprintf(stderr, "Get time of day error %d\n", rc); 416 return rc; 417 } 418 419 printf("Tested in %d microseconds\n", tv_sub(&time_after, 420 &time_before)); 421 422 if (verbose) 370 423 printf("Exiting\n"); 371 }372 424 373 425 return EOK; 374 426 } 375 427 376 void nettest1_print_help(void){377 printf(378 "Network Networking test 1 aplication - sockets\n" \379 "Usage: echo [options] numeric_address\n" \380 "Where options are:\n" \381 "-f protocol_family | --family=protocol_family\n" \382 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"383 "\n" \384 "-h | --help\n" \385 "\tShow this application help.\n"386 "\n" \387 "-m count | --messages=count\n" \388 "\tThe number of messages to send and receive per socket. The default is 10.\n" \389 "\n" \390 "-n sockets | --sockets=count\n" \391 "\tThe number of sockets to use. The default is 10.\n" \392 "\n" \393 "-p port_number | --port=port_number\n" \394 "\tThe port number the application should send messages to. The default is 7.\n" \395 "\n" \396 "-s packet_size | --size=packet_size\n" \397 "\tThe packet data size the application sends. The default is 28 bytes.\n" \398 "\n" \399 "-v | --verbose\n" \400 "\tShow all output messages.\n"401 );402 }403 404 void nettest1_refresh_data(char * data, size_t size){405 size_t length;406 407 // fill the data408 length = 0;409 while(size > length + sizeof(NETTEST1_TEXT) - 1){410 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1);411 length += sizeof(NETTEST1_TEXT) - 1;412 }413 memcpy(data + length, NETTEST1_TEXT, size - length);414 data[size] = '\0';415 }416 428 417 429 /** @} -
uspace/app/nettest2/nettest2.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup nettest 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * Networking test 2 application - transfer. 35 */ 34 * Networking test 2 application - transfer. 35 */ 36 37 #include "nettest.h" 38 #include "print_error.h" 36 39 37 40 #include <malloc.h> … … 41 44 #include <time.h> 42 45 #include <arg_parse.h> 43 #include < err.h>46 #include <bool.h> 44 47 45 48 #include <net/in.h> … … 49 52 #include <net/socket_parse.h> 50 53 51 #include "nettest.h" 52 #include "print_error.h" 53 54 /** Echo module name. 55 */ 54 /** Echo module name. */ 56 55 #define NAME "Nettest2" 57 56 58 /** Packet data pattern. 59 */ 57 /** Packet data pattern. */ 60 58 #define NETTEST2_TEXT "Networking test 2 - transfer" 61 59 62 /** Module entry point. 63 * Starts testing. 64 * @param[in] argc The number of command line parameters. 65 * @param[in] argv The command line parameters. 66 * @returns EOK on success. 67 */ 68 int main(int argc, char * argv[]); 69 70 /** Prints the application help. 71 */ 72 void nettest2_print_help(void); 73 74 /** Refreshes the data. 75 * Fills the data block with the NETTEST1_TEXT pattern. 76 * @param[out] data The data block. 77 * @param[in] size The data block size in bytes. 78 */ 79 void nettest2_refresh_data(char * data, size_t size); 80 81 int main(int argc, char * argv[]){ 82 ERROR_DECLARE; 83 84 size_t size = 28; 85 int verbose = 0; 86 sock_type_t type = SOCK_DGRAM; 87 int sockets = 10; 88 int messages = 10; 89 int family = PF_INET; 90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 93 uint8_t address_data[max_length]; 94 struct sockaddr * address = (struct sockaddr *) address_data; 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 60 static size_t size; 61 static bool verbose; 62 static sock_type_t type; 63 static int sockets; 64 static int messages; 65 static int family; 66 static uint16_t port; 67 68 static void nettest2_print_help(void) 69 { 70 printf( 71 "Network Networking test 2 aplication - UDP transfer\n" 72 "Usage: echo [options] address\n" 73 "Where options are:\n" 74 "-f protocol_family | --family=protocol_family\n" 75 "\tThe listenning socket protocol family. Only the PF_INET and " 76 "PF_INET6 are supported.\n" 77 "\n" 78 "-h | --help\n" 79 "\tShow this application help.\n" 80 "\n" 81 "-m count | --messages=count\n" 82 "\tThe number of messages to send and receive per socket. The " 83 "default is 10.\n" 84 "\n" 85 "-n sockets | --sockets=count\n" 86 "\tThe number of sockets to use. The default is 10.\n" 87 "\n" 88 "-p port_number | --port=port_number\n" 89 "\tThe port number the application should send messages to. The " 90 "default is 7.\n" 91 "\n" 92 "-s packet_size | --size=packet_size\n" 93 "\tThe packet data size the application sends. The default is 29 " 94 "bytes.\n" 95 "\n" 96 "-v | --verbose\n" 97 "\tShow all output messages.\n"); 98 } 99 100 /** Fill buffer with the NETTEST2_TEXT pattern. 101 * 102 * @param buffer Data buffer. 103 * @param size Buffer size in bytes. 104 */ 105 static void nettest2_fill_buffer(char *buffer, size_t size) 106 { 107 size_t length; 108 109 length = 0; 110 while (size > length + sizeof(NETTEST2_TEXT) - 1) { 111 memcpy(buffer + length, NETTEST2_TEXT, 112 sizeof(NETTEST2_TEXT) - 1); 113 length += sizeof(NETTEST2_TEXT) - 1; 114 } 115 116 memcpy(buffer + length, NETTEST2_TEXT, size - length); 117 buffer[size] = '\0'; 118 } 119 120 /** Parse one command-line option. 121 * 122 * @param argc Number of all command-line arguments. 123 * @param argv All command-line arguments. 124 * @param index Current argument index (in, out). 125 */ 126 static int nettest2_parse_opt(int argc, char *argv[], int *index) 127 { 128 int value; 129 int rc; 130 131 switch (argv[*index][1]) { 132 /* 133 * Short options with only one letter 134 */ 135 case 'f': 136 rc = arg_parse_name_int(argc, argv, index, &family, 0, 137 socket_parse_protocol_family); 138 if (rc != EOK) 139 return rc; 140 break; 141 case 'h': 142 nettest2_print_help(); 143 return EOK; 144 break; 145 case 'm': 146 rc = arg_parse_int(argc, argv, index, &messages, 0); 147 if (rc != EOK) 148 return rc; 149 break; 150 case 'n': 151 rc = arg_parse_int(argc, argv, index, &sockets, 0); 152 if (rc != EOK) 153 return rc; 154 break; 155 case 'p': 156 rc = arg_parse_int(argc, argv, index, &value, 0); 157 if (rc != EOK) 158 return rc; 159 port = (uint16_t) value; 160 break; 161 case 's': 162 rc = arg_parse_int(argc, argv, index, &value, 0); 163 if (rc != EOK) 164 return rc; 165 size = (value >= 0) ? (size_t) value : 0; 166 break; 167 case 't': 168 rc = arg_parse_name_int(argc, argv, index, &value, 0, 169 socket_parse_socket_type); 170 if (rc != EOK) 171 return rc; 172 type = (sock_type_t) value; 173 break; 174 case 'v': 175 verbose = true; 176 break; 177 /* 178 * Long options with double dash ('-') 179 */ 180 case '-': 181 if (str_lcmp(argv[*index] + 2, "family=", 7) == 0) { 182 rc = arg_parse_name_int(argc, argv, index, &family, 9, 183 socket_parse_protocol_family); 184 if (rc != EOK) 185 return rc; 186 } else if (str_lcmp(argv[*index] + 2, "help", 5) == 0) { 187 nettest2_print_help(); 188 return EOK; 189 } else if (str_lcmp(argv[*index] + 2, "messages=", 6) == 0) { 190 rc = arg_parse_int(argc, argv, index, &messages, 8); 191 if (rc != EOK) 192 return rc; 193 } else if (str_lcmp(argv[*index] + 2, "sockets=", 6) == 0) { 194 rc = arg_parse_int(argc, argv, index, &sockets, 8); 195 if (rc != EOK) 196 return rc; 197 } else if (str_lcmp(argv[*index] + 2, "port=", 5) == 0) { 198 rc = arg_parse_int(argc, argv, index, &value, 7); 199 if (rc != EOK) 200 return rc; 201 port = (uint16_t) value; 202 } else if (str_lcmp(argv[*index] + 2, "type=", 5) == 0) { 203 rc = arg_parse_name_int(argc, argv, index, &value, 7, 204 socket_parse_socket_type); 205 if (rc != EOK) 206 return rc; 207 type = (sock_type_t) value; 208 } else if (str_lcmp(argv[*index] + 2, "verbose", 8) == 0) { 209 verbose = 1; 210 } else { 211 nettest2_print_help(); 212 return EINVAL; 213 } 214 break; 215 default: 216 nettest2_print_help(); 217 return EINVAL; 218 } 219 220 return EOK; 221 } 222 223 int main(int argc, char *argv[]) 224 { 225 socklen_t max_length; 226 uint8_t address_data[sizeof(struct sockaddr_in6)]; 227 struct sockaddr *address; 228 struct sockaddr_in *address_in; 229 struct sockaddr_in6 *address_in6; 97 230 socklen_t addrlen; 98 // char address_string[INET6_ADDRSTRLEN]; 99 uint8_t * address_start; 100 101 int * socket_ids; 102 char * data; 103 int value; 231 uint8_t *address_start; 232 233 int *socket_ids; 234 char *data; 104 235 int index; 105 236 struct timeval time_before; 106 237 struct timeval time_after; 107 238 108 // parse the command line arguments 109 // stop before the last argument if it does not start with the minus sign ('-') 110 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 111 // options should start with the minus sign ('-') 112 if(argv[index][0] == '-'){ 113 switch(argv[index][1]){ 114 // short options with only one letter 115 case 'f': 116 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 0, socket_parse_protocol_family)); 117 break; 118 case 'h': 119 nettest2_print_help(); 120 return EOK; 121 break; 122 case 'm': 123 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 0)); 124 break; 125 case 'n': 126 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 0)); 127 break; 128 case 'p': 129 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 130 port = (uint16_t) value; 131 break; 132 case 's': 133 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 0)); 134 size = (value >= 0) ? (size_t) value : 0; 135 break; 136 case 't': 137 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 0, socket_parse_socket_type)); 138 type = (sock_type_t) value; 139 break; 140 case 'v': 141 verbose = 1; 142 break; 143 // long options with the double minus sign ('-') 144 case '-': 145 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 146 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &family, 9, socket_parse_protocol_family)); 147 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 148 nettest2_print_help(); 149 return EOK; 150 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ 151 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &messages, 8)); 152 }else if(str_lcmp(argv[index] + 2, "sockets=", 6) == 0){ 153 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &sockets, 8)); 154 }else if(str_lcmp(argv[index] + 2, "port=", 5) == 0){ 155 ERROR_PROPAGATE(arg_parse_int(argc, argv, &index, &value, 7)); 156 port = (uint16_t) value; 157 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 158 ERROR_PROPAGATE(arg_parse_name_int(argc, argv, &index, &value, 7, socket_parse_socket_type)); 159 type = (sock_type_t) value; 160 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ 161 verbose = 1; 162 }else{ 163 nettest2_print_help(); 164 return EINVAL; 165 } 166 break; 167 default: 168 nettest2_print_help(); 169 return EINVAL; 170 } 171 }else{ 239 int rc; 240 241 size = 28; 242 verbose = false; 243 type = SOCK_DGRAM; 244 sockets = 10; 245 messages = 10; 246 family = PF_INET; 247 port = 7; 248 249 max_length = sizeof(address_data); 250 address = (struct sockaddr *) address_data; 251 address_in = (struct sockaddr_in *) address; 252 address_in6 = (struct sockaddr_in6 *) address; 253 254 /* 255 * Parse the command line arguments. 256 * 257 * Stop before the last argument if it does not start with dash ('-') 258 */ 259 for (index = 1; (index < argc - 1) || ((index == argc - 1) && 260 (argv[index][0] == '-')); ++index) { 261 262 /* Options should start with dash ('-') */ 263 if (argv[index][0] == '-') { 264 rc = nettest2_parse_opt(argc, argv, &index); 265 if (rc != EOK) 266 return rc; 267 } else { 172 268 nettest2_print_help(); 173 269 return EINVAL; … … 175 271 } 176 272 177 / / if not before the last argument containing the address178 if (index >= argc){273 /* If not before the last argument containing the address */ 274 if (index >= argc) { 179 275 printf("Command line error: missing address\n"); 180 276 nettest2_print_help(); … … 182 278 } 183 279 184 / / prepare the address buffer280 /* Prepare the address buffer */ 185 281 bzero(address_data, max_length); 186 switch(family){ 187 case PF_INET: 188 address_in->sin_family = AF_INET; 189 address_in->sin_port = htons(port); 190 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 191 addrlen = sizeof(struct sockaddr_in); 192 break; 193 case PF_INET6: 194 address_in6->sin6_family = AF_INET6; 195 address_in6->sin6_port = htons(port); 196 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 197 addrlen = sizeof(struct sockaddr_in6); 198 break; 199 default: 200 fprintf(stderr, "Address family is not supported\n"); 201 return EAFNOSUPPORT; 202 } 203 204 // parse the last argument which should contain the address 205 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 206 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); 207 return ERROR_CODE; 208 } 209 210 // check the buffer size 211 if(size <= 0){ 212 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 282 283 switch (family) { 284 case PF_INET: 285 address_in->sin_family = AF_INET; 286 address_in->sin_port = htons(port); 287 address_start = (uint8_t *) &address_in->sin_addr.s_addr; 288 addrlen = sizeof(struct sockaddr_in); 289 break; 290 case PF_INET6: 291 address_in6->sin6_family = AF_INET6; 292 address_in6->sin6_port = htons(port); 293 address_start = (uint8_t *) &address_in6->sin6_addr.s6_addr; 294 addrlen = sizeof(struct sockaddr_in6); 295 break; 296 default: 297 fprintf(stderr, "Address family is not supported\n"); 298 return EAFNOSUPPORT; 299 } 300 301 /* Parse the last argument which should contain the address. */ 302 rc = inet_pton(family, argv[argc - 1], address_start); 303 if (rc != EOK) { 304 fprintf(stderr, "Address parse error %d\n", rc); 305 return rc; 306 } 307 308 /* Check data buffer size. */ 309 if (size <= 0) { 310 fprintf(stderr, "Data buffer size too small (%d). Using 1024 " 311 "bytes instead.\n", size); 213 312 size = 1024; 214 313 } 215 314 216 // prepare the buffer 217 // size plus terminating null (\0) 315 /* 316 * Prepare the buffer. Allocate size bytes plus one for terminating 317 * null character. 318 */ 218 319 data = (char *) malloc(size + 1); 219 if (! data){320 if (!data) { 220 321 fprintf(stderr, "Failed to allocate data buffer.\n"); 221 322 return ENOMEM; 222 323 } 223 nettest2_refresh_data(data, size); 224 225 // check the socket count 226 if(sockets <= 0){ 227 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 324 325 /* Fill buffer with a pattern. */ 326 nettest2_fill_buffer(data, size); 327 328 /* Check socket count. */ 329 if (sockets <= 0) { 330 fprintf(stderr, "Socket count too small (%d). Using " 331 "2 instead.\n", sockets); 228 332 sockets = 2; 229 333 } 230 334 231 // prepare the socket buffer 232 // count plus the terminating null (\0) 335 /* 336 * Prepare the socket buffer. 337 * Allocate count entries plus the terminating null (\0) 338 */ 233 339 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 234 if (! socket_ids){340 if (!socket_ids) { 235 341 fprintf(stderr, "Failed to allocate receive buffer.\n"); 236 342 return ENOMEM; … … 238 344 socket_ids[sockets] = NULL; 239 345 240 if (verbose){346 if (verbose) 241 347 printf("Starting tests\n"); 242 } 243 244 ERROR_PROPAGATE(sockets_create(verbose, socket_ids, sockets, family, type)); 245 246 if(type == SOCK_STREAM){ 247 ERROR_PROPAGATE(sockets_connect(verbose, socket_ids, sockets, address, addrlen)); 248 } 249 250 if(verbose){ 348 349 rc = sockets_create(verbose, socket_ids, sockets, family, type); 350 if (rc != EOK) 351 return rc; 352 353 if (type == SOCK_STREAM) { 354 rc = sockets_connect(verbose, socket_ids, sockets, 355 address, addrlen); 356 if (rc != EOK) 357 return rc; 358 } 359 360 if (verbose) 251 361 printf("\n"); 252 } 253 254 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 255 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 256 return ERROR_CODE; 257 } 258 259 ERROR_PROPAGATE(sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 260 261 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 262 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 263 return ERROR_CODE; 264 } 265 266 if(verbose){ 362 363 rc = gettimeofday(&time_before, NULL); 364 if (rc != EOK) { 365 fprintf(stderr, "Get time of day error %d\n", rc); 366 return rc; 367 } 368 369 rc = sockets_sendto_recvfrom(verbose, socket_ids, sockets, address, 370 &addrlen, data, size, messages); 371 if (rc != EOK) 372 return rc; 373 374 rc = gettimeofday(&time_after, NULL); 375 if (rc != EOK) { 376 fprintf(stderr, "Get time of day error %d\n", rc); 377 return rc; 378 } 379 380 if (verbose) 267 381 printf("\tOK\n"); 268 } 269 270 printf("sendto + recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 271 272 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 273 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 274 return ERROR_CODE; 275 } 276 277 ERROR_PROPAGATE(sockets_sendto(verbose, socket_ids, sockets, address, addrlen, data, size, messages)); 278 ERROR_PROPAGATE(sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, data, size, messages)); 279 280 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 281 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 282 return ERROR_CODE; 283 } 284 285 if(verbose){ 382 383 printf("sendto + recvfrom tested in %d microseconds\n", 384 tv_sub(&time_after, &time_before)); 385 386 rc = gettimeofday(&time_before, NULL); 387 if (rc != EOK) { 388 fprintf(stderr, "Get time of day error %d\n", rc); 389 return rc; 390 } 391 392 rc = sockets_sendto(verbose, socket_ids, sockets, address, addrlen, 393 data, size, messages); 394 if (rc != EOK) 395 return rc; 396 397 rc = sockets_recvfrom(verbose, socket_ids, sockets, address, &addrlen, 398 data, size, messages); 399 if (rc != EOK) 400 return rc; 401 402 rc = gettimeofday(&time_after, NULL); 403 if (rc != EOK) { 404 fprintf(stderr, "Get time of day error %d\n", rc); 405 return rc; 406 } 407 408 if (verbose) 286 409 printf("\tOK\n"); 287 } 288 289 printf("sendto, recvfrom tested in %d microseconds\n", tv_sub(&time_after, &time_before)); 290 291 ERROR_PROPAGATE(sockets_close(verbose, socket_ids, sockets)); 292 293 if(verbose){ 410 411 printf("sendto, recvfrom tested in %d microseconds\n", 412 tv_sub(&time_after, &time_before)); 413 414 rc = sockets_close(verbose, socket_ids, sockets); 415 if (rc != EOK) 416 return rc; 417 418 if (verbose) 294 419 printf("\nExiting\n"); 295 }296 420 297 421 return EOK; 298 422 } 299 423 300 void nettest2_print_help(void){301 printf(302 "Network Networking test 2 aplication - UDP transfer\n" \303 "Usage: echo [options] numeric_address\n" \304 "Where options are:\n" \305 "-f protocol_family | --family=protocol_family\n" \306 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n"307 "\n" \308 "-h | --help\n" \309 "\tShow this application help.\n"310 "\n" \311 "-m count | --messages=count\n" \312 "\tThe number of messages to send and receive per socket. The default is 10.\n" \313 "\n" \314 "-n sockets | --sockets=count\n" \315 "\tThe number of sockets to use. The default is 10.\n" \316 "\n" \317 "-p port_number | --port=port_number\n" \318 "\tThe port number the application should send messages to. The default is 7.\n" \319 "\n" \320 "-s packet_size | --size=packet_size\n" \321 "\tThe packet data size the application sends. The default is 29 bytes.\n" \322 "\n" \323 "-v | --verbose\n" \324 "\tShow all output messages.\n"325 );326 }327 328 void nettest2_refresh_data(char * data, size_t size){329 size_t length;330 331 // fill the data332 length = 0;333 while(size > length + sizeof(NETTEST2_TEXT) - 1){334 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1);335 length += sizeof(NETTEST2_TEXT) - 1;336 }337 memcpy(data + length, NETTEST2_TEXT, size - length);338 data[size] = '\0';339 }340 341 424 /** @} 342 425 */ -
uspace/app/redir/redir.c
rd70a463 rb40bfac 43 43 #include <task.h> 44 44 #include <str_error.h> 45 #include <errno.h> 45 46 46 47 #define NAME "redir" … … 76 77 static task_id_t spawn(int argc, char *argv[]) 77 78 { 78 const char **args = (const char **) calloc(argc + 1, sizeof(char *)); 79 const char **args; 80 task_id_t id; 81 int rc; 82 83 args = (const char **) calloc(argc + 1, sizeof(char *)); 79 84 if (!args) { 80 85 printf("No memory available\n"); … … 88 93 args[argc] = NULL; 89 94 90 int err; 91 task_id_t id = task_spawn(argv[0], args, &err); 95 rc = task_spawnv(&id, argv[0], args); 92 96 93 97 free(args); 94 98 95 if ( id == 0)99 if (rc != EOK) { 96 100 printf("%s: Error spawning %s (%s)\n", NAME, argv[0], 97 str_error(err)); 101 str_error(rc)); 102 } 98 103 99 104 return id; -
uspace/app/sbi/src/os/helenos.c
rd70a463 rb40bfac 249 249 task_id_t tid; 250 250 task_exit_t texit; 251 int r etval;252 253 tid = task_spawn(cmd[0], (char const * const *) cmd, &retval);254 if ( tid == 0) {251 int rc, retval; 252 253 rc = task_spawnv(&tid, cmd[0], (char const * const *) cmd); 254 if (rc != EOK) { 255 255 printf("Error: Failed spawning '%s' (%s).\n", cmd[0], 256 str_error(r etval));256 str_error(rc)); 257 257 exit(1); 258 258 } 259 259 260 260 /* XXX Handle exit status and return value. */ 261 task_wait(tid, &texit, &retval); 261 rc = task_wait(tid, &texit, &retval); 262 (void) rc; 262 263 263 264 return EOK; -
uspace/lib/c/generic/fibril_synch.c
rd70a463 rb40bfac 58 58 } 59 59 60 static bool check_for_deadlock(fibril_owner_info_t *oi)61 {62 while (oi && oi->owned_by) {63 if (oi->owned_by == (fibril_t *) fibril_get_id())64 return true;65 oi = oi->owned_by->waits_for;66 }67 68 return false;69 }70 71 60 static void print_deadlock(fibril_owner_info_t *oi) 72 61 { … … 89 78 oi = oi->owned_by->waits_for; 90 79 } 91 92 abort(); 93 } 80 } 81 82 83 static void check_for_deadlock(fibril_owner_info_t *oi) 84 { 85 while (oi && oi->owned_by) { 86 if (oi->owned_by == (fibril_t *) fibril_get_id()) { 87 print_deadlock(oi); 88 abort(); 89 } 90 oi = oi->owned_by->waits_for; 91 } 92 } 93 94 94 95 95 void fibril_mutex_initialize(fibril_mutex_t *fm) … … 113 113 link_initialize(&wdata.wu_event.link); 114 114 list_append(&wdata.wu_event.link, &fm->waiters); 115 116 if (check_for_deadlock(&fm->oi)) 117 print_deadlock(&fm->oi); 115 check_for_deadlock(&fm->oi); 118 116 f->waits_for = &fm->oi; 119 120 117 fibril_switch(FIBRIL_TO_MANAGER); 121 118 } else { … … 183 180 void fibril_rwlock_read_lock(fibril_rwlock_t *frw) 184 181 { 182 fibril_t *f = (fibril_t *) fibril_get_id(); 183 185 184 futex_down(&async_futex); 186 185 if (frw->writers) { 187 fibril_t *f = (fibril_t *) fibril_get_id();188 186 awaiter_t wdata; 189 187 … … 194 192 f->flags &= ~FIBRIL_WRITER; 195 193 list_append(&wdata.wu_event.link, &frw->waiters); 194 check_for_deadlock(&frw->oi); 195 f->waits_for = &frw->oi; 196 196 fibril_switch(FIBRIL_TO_MANAGER); 197 197 } else { 198 frw->readers++; 198 /* Consider the first reader the owner. */ 199 if (frw->readers++ == 0) 200 frw->oi.owned_by = f; 199 201 futex_up(&async_futex); 200 202 } … … 203 205 void fibril_rwlock_write_lock(fibril_rwlock_t *frw) 204 206 { 207 fibril_t *f = (fibril_t *) fibril_get_id(); 208 205 209 futex_down(&async_futex); 206 210 if (frw->writers || frw->readers) { 207 fibril_t *f = (fibril_t *) fibril_get_id();208 211 awaiter_t wdata; 209 212 … … 214 217 f->flags |= FIBRIL_WRITER; 215 218 list_append(&wdata.wu_event.link, &frw->waiters); 219 check_for_deadlock(&frw->oi); 220 f->waits_for = &frw->oi; 216 221 fibril_switch(FIBRIL_TO_MANAGER); 217 222 } else { 223 frw->oi.owned_by = f; 218 224 frw->writers++; 219 225 futex_up(&async_futex); … … 226 232 assert(frw->readers || (frw->writers == 1)); 227 233 if (frw->readers) { 228 if (--frw->readers) 234 if (--frw->readers) { 235 if (frw->oi.owned_by == (fibril_t *) fibril_get_id()) { 236 /* 237 * If this reader firbril was considered the 238 * owner of this rwlock, clear the ownership 239 * information even if there are still more 240 * readers. 241 * 242 * This is the limitation of the detection 243 * mechanism rooted in the fact that tracking 244 * all readers would require dynamically 245 * allocated memory for keeping linkage info. 246 */ 247 frw->oi.owned_by = NULL; 248 } 229 249 goto out; 250 } 230 251 } else { 231 252 frw->writers--; … … 233 254 234 255 assert(!frw->readers && !frw->writers); 256 257 frw->oi.owned_by = NULL; 235 258 236 259 while (!list_empty(&frw->waiters)) { … … 241 264 wdp = list_get_instance(tmp, awaiter_t, wu_event.link); 242 265 f = (fibril_t *) wdp->fid; 266 267 f->waits_for = NULL; 243 268 244 269 if (f->flags & FIBRIL_WRITER) { … … 250 275 fibril_add_ready(wdp->fid); 251 276 frw->writers++; 277 frw->oi.owned_by = f; 252 278 optimize_execution_power(); 253 279 break; … … 257 283 list_remove(&wdp->wu_event.link); 258 284 fibril_add_ready(wdp->fid); 259 frw->readers++; 285 if (frw->readers++ == 0) { 286 /* Consider the first reader the owner. */ 287 frw->oi.owned_by = f; 288 } 260 289 optimize_execution_power(); 261 290 } -
uspace/lib/c/generic/task.c
rd70a463 rb40bfac 39 39 #include <errno.h> 40 40 #include <loader/loader.h> 41 #include <stdarg.h> 41 42 #include <str.h> 42 43 #include <ipc/ns.h> … … 68 69 * 69 70 * This is really just a convenience wrapper over the more complicated 70 * loader API. 71 * 72 * @param path Pathname of the binary to execute. 73 * @param argv Command-line arguments. 74 * @param err If not NULL, the error value is stored here. 75 * 76 * @return ID of the newly created task or zero on error. 77 * 78 */ 79 task_id_t task_spawn(const char *path, const char *const args[], int *err) 80 { 71 * loader API. Arguments are passed as a null-terminated array of strings. 72 * 73 * @param id If not NULL, the ID of the task is stored here on success. 74 * @param path Pathname of the binary to execute. 75 * @param argv Command-line arguments. 76 * 77 * @return Zero on success or negative error code. 78 */ 79 int task_spawnv(task_id_t *id, const char *path, const char *const args[]) 80 { 81 loader_t *ldr; 82 task_id_t task_id; 83 int rc; 84 81 85 /* Connect to a program loader. */ 82 loader_t *ldr = loader_connect(); 83 if (ldr == NULL) { 84 if (err != NULL) 85 *err = EREFUSED; 86 87 return 0; 88 } 86 ldr = loader_connect(); 87 if (ldr == NULL) 88 return EREFUSED; 89 89 90 90 /* Get task ID. */ 91 task_id_t task_id; 92 int rc = loader_get_task_id(ldr, &task_id); 91 rc = loader_get_task_id(ldr, &task_id); 93 92 if (rc != EOK) 94 93 goto error; … … 149 148 free(ldr); 150 149 151 if ( err!= NULL)152 * err = EOK;153 154 return task_id;150 if (id != NULL) 151 *id = task_id; 152 153 return EOK; 155 154 156 155 error: … … 158 157 loader_abort(ldr); 159 158 free(ldr); 160 161 if (err != NULL) 162 *err = rc; 163 164 return 0; 159 return rc; 160 } 161 162 /** Create a new task by running an executable from the filesystem. 163 * 164 * This is really just a convenience wrapper over the more complicated 165 * loader API. Arguments are passed as a null-terminated list of arguments. 166 * 167 * @param id If not NULL, the ID of the task is stored here on success. 168 * @param path Pathname of the binary to execute. 169 * @param ... Command-line arguments. 170 * 171 * @return Zero on success or negative error code. 172 */ 173 int task_spawnl(task_id_t *task_id, const char *path, ...) 174 { 175 va_list ap; 176 int rc, cnt; 177 const char *arg; 178 const char **arglist; 179 180 /* Count the number of arguments. */ 181 cnt = 0; 182 va_start(ap, path); 183 do { 184 arg = va_arg(ap, const char *); 185 cnt++; 186 } while (arg != NULL); 187 va_end(ap); 188 189 /* Allocate argument list. */ 190 arglist = malloc(cnt * sizeof(const char *)); 191 if (arglist == NULL) 192 return ENOMEM; 193 194 /* Fill in arguments. */ 195 cnt = 0; 196 va_start(ap, path); 197 do { 198 arg = va_arg(ap, const char *); 199 arglist[cnt++] = arg; 200 } while (arg != NULL); 201 va_end(ap); 202 203 /* Spawn task. */ 204 rc = task_spawnv(task_id, path, arglist); 205 206 /* Free argument list. */ 207 free(arglist); 208 return rc; 165 209 } 166 210 -
uspace/lib/c/include/ipc/services.h
rd70a463 rb40bfac 39 39 40 40 typedef enum { 41 SERVICE_LOAD = 1, 41 SERVICE_NONE = 0, 42 SERVICE_LOAD, 42 43 SERVICE_PCI, 43 44 SERVICE_VIDEO, -
uspace/lib/c/include/task.h
rd70a463 rb40bfac 48 48 extern int task_set_name(const char *); 49 49 extern task_id_t task_spawn(const char *, const char *const[], int *); 50 extern int task_spawnv(task_id_t *, const char *path, const char *const []); 51 extern int task_spawnl(task_id_t *, const char *path, ...); 52 50 53 extern int task_wait(task_id_t id, task_exit_t *, int *); 51 54 extern int task_retval(int); -
uspace/lib/net/adt/module_map.c
rd70a463 rb40bfac 132 132 task_id_t spawn(const char *fname) 133 133 { 134 const char *argv[2];135 task_id_t res;134 task_id_t id; 135 int rc; 136 136 137 argv[0] = fname;138 argv[1] = NULL;139 res = task_spawn(fname, argv, NULL);137 rc = task_spawnl(&id, fname, fname, NULL); 138 if (rc != EOK) 139 return 0; 140 140 141 return res;141 return id; 142 142 } 143 143 -
uspace/lib/net/include/tl_local.h
rd70a463 rb40bfac 37 37 #include <async.h> 38 38 39 /** Starts the TL module. 40 * 41 * Initializes the client connection serving function, initializes the module, 42 * registers the module service and starts the async manager, processing IPC 43 * messages in an infinite loop. 44 * 45 * @param[in] client_connection The client connection processing function. The 46 * module skeleton propagates its own one. 47 * @returns EOK on successful module termination. 48 * @returns Other error codes as defined for the module initialize 49 * function. 50 * @returns Other error codes as defined for the REGISTER_ME() macro 51 * function. 52 */ 39 53 extern int tl_module_message_standalone(ipc_callid_t, ipc_call_t *, 40 54 ipc_call_t *, int *); 55 56 57 /** Processes the TL module message. 58 * 59 * @param[in] callid The message identifier. 60 * @param[in] call The message parameters. 61 * @param[out] answer The message answer parameters. 62 * @param[out] answer_count The last parameter for the actual answer in the 63 * answer parameter. 64 * @returns EOK on success. 65 * @returns Other error codes as defined for the module's message 66 * standalone function. 67 */ 41 68 extern int tl_module_start_standalone(async_client_conn_t); 42 69 -
uspace/lib/packet/generic/packet_server.c
rd70a463 rb40bfac 212 212 213 213 for (index = 0; index < FREE_QUEUES_COUNT; index++) { 214 if (length > ps_globals.sizes[index]) 214 if ((length > ps_globals.sizes[index]) && 215 (index < FREE_QUEUES_COUNT - 1)) 215 216 continue; 216 217 -
uspace/srv/devman/devman.c
rd70a463 rb40bfac 37 37 #include <ipc/devman.h> 38 38 #include <devmap.h> 39 #include <str_error.h> 39 40 40 41 #include "devman.h" … … 446 447 bool start_driver(driver_t *drv) 447 448 { 449 int rc; 450 448 451 printf(NAME ": start_driver '%s'\n", drv->name); 449 452 450 const char *argv[2]; 451 452 argv[0] = drv->name; 453 argv[1] = NULL; 454 455 int err; 456 if (task_spawn(drv->binary_path, argv, &err) == 0) { 457 printf(NAME ": error spawning %s, errno = %d\n", 458 drv->name, err); 453 rc = task_spawnl(NULL, drv->binary_path, drv->binary_path, NULL); 454 if (rc != EOK) { 455 printf(NAME ": error spawning %s (%s)\n", 456 drv->name, str_error(rc)); 459 457 return false; 460 458 } -
uspace/srv/net/il/arp/arp.c
rd70a463 rb40bfac 55 55 #include <ipc/il.h> 56 56 #include <byteorder.h> 57 #include <err .h>57 #include <errno.h> 58 58 59 59 #include <net/modules.h> … … 179 179 measured_string_ref address) 180 180 { 181 ERROR_DECLARE;181 int rc; 182 182 183 183 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 184 184 if (!*proto) 185 185 return ENOMEM; 186 186 187 (*proto)->service = service; 187 188 (*proto)->addr = address; 188 189 (*proto)->addr_data = address->value; 189 if (ERROR_OCCURRED(arp_addr_initialize(&(*proto)->addresses))) { 190 191 rc = arp_addr_initialize(&(*proto)->addresses); 192 if (rc != EOK) { 190 193 free(*proto); 191 return ERROR_CODE; 192 } 194 return rc; 195 } 196 193 197 return EOK; 194 198 } … … 214 218 services_t protocol, measured_string_ref address) 215 219 { 216 ERROR_DECLARE;217 218 220 arp_device_ref device; 219 221 arp_proto_ref proto; 222 hw_type_t hardware; 220 223 int index; 221 hw_type_t hardware;224 int rc; 222 225 223 226 fibril_rwlock_write_lock(&arp_globals.lock); … … 237 240 proto->addr_data = address->value; 238 241 } else { 239 if (ERROR_OCCURRED(arp_proto_create(&proto, protocol,240 address))) {242 rc = arp_proto_create(&proto, protocol, address); 243 if (rc != EOK) { 241 244 fibril_rwlock_write_unlock(&arp_globals.lock); 242 return ERROR_CODE;245 return rc; 243 246 } 244 247 index = arp_protos_add(&device->protos, proto->service, … … 265 268 device->hardware = hardware; 266 269 device->device_id = device_id; 267 if (ERROR_OCCURRED(arp_protos_initialize(&device->protos)) || 268 ERROR_OCCURRED(arp_proto_create(&proto, protocol, 269 address))) { 270 rc = arp_protos_initialize(&device->protos); 271 if (rc != EOK) { 270 272 fibril_rwlock_write_unlock(&arp_globals.lock); 271 273 free(device); 272 return ERROR_CODE; 274 return rc; 275 } 276 rc = arp_proto_create(&proto, protocol, address); 277 if (rc != EOK) { 278 fibril_rwlock_write_unlock(&arp_globals.lock); 279 free(device); 280 return rc; 273 281 } 274 282 index = arp_protos_add(&device->protos, proto->service, proto); … … 293 301 294 302 // get packet dimensions 295 if (ERROR_OCCURRED(nil_packet_size_req(device->phone, device_id, 296 &device->packet_dimension))) { 303 rc = nil_packet_size_req(device->phone, device_id, 304 &device->packet_dimension); 305 if (rc != EOK) { 297 306 fibril_rwlock_write_unlock(&arp_globals.lock); 298 307 arp_protos_destroy(&device->protos); 299 308 free(device); 300 return ERROR_CODE;309 return rc; 301 310 } 302 311 303 312 // get hardware address 304 if (ERROR_OCCURRED(nil_get_addr_req(device->phone, device_id, 305 &device->addr, &device->addr_data))) { 313 rc = nil_get_addr_req(device->phone, device_id, &device->addr, 314 &device->addr_data); 315 if (rc != EOK) { 306 316 fibril_rwlock_write_unlock(&arp_globals.lock); 307 317 arp_protos_destroy(&device->protos); 308 318 free(device); 309 return ERROR_CODE;319 return rc; 310 320 } 311 321 312 322 // get broadcast address 313 if (ERROR_OCCURRED(nil_get_broadcast_addr_req(device->phone,314 device_id, &device->broadcast_addr,315 &device->broadcast_data))) {323 rc = nil_get_broadcast_addr_req(device->phone, device_id, 324 &device->broadcast_addr, &device->broadcast_data); 325 if (rc != EOK) { 316 326 fibril_rwlock_write_unlock(&arp_globals.lock); 317 327 free(device->addr); … … 319 329 arp_protos_destroy(&device->protos); 320 330 free(device); 321 return ERROR_CODE; 322 } 323 324 if (ERROR_OCCURRED(arp_cache_add(&arp_globals.cache, 325 device->device_id, device))) { 331 return rc; 332 } 333 334 rc = arp_cache_add(&arp_globals.cache, device->device_id, 335 device); 336 if (rc != EOK) { 326 337 fibril_rwlock_write_unlock(&arp_globals.lock); 327 338 free(device->addr); … … 331 342 arp_protos_destroy(&device->protos); 332 343 free(device); 333 return ERROR_CODE;344 return rc; 334 345 } 335 346 printf("%s: Device registered (id: %d, type: 0x%x, service: %d," … … 351 362 int arp_initialize(async_client_conn_t client_connection) 352 363 { 353 ERROR_DECLARE;364 int rc; 354 365 355 366 fibril_rwlock_initialize(&arp_globals.lock); 356 367 fibril_rwlock_write_lock(&arp_globals.lock); 357 368 arp_globals.client_connection = client_connection; 358 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache));369 rc = arp_cache_initialize(&arp_globals.cache); 359 370 fibril_rwlock_write_unlock(&arp_globals.lock); 360 return EOK; 371 372 return rc; 361 373 } 362 374 … … 406 418 static int arp_receive_message(device_id_t device_id, packet_t packet) 407 419 { 408 ERROR_DECLARE;409 410 420 size_t length; 411 421 arp_header_ref header; … … 417 427 uint8_t *des_hw; 418 428 uint8_t *des_proto; 429 int rc; 419 430 420 431 length = packet_get_data_length(packet); … … 467 478 return ENOMEM; 468 479 469 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, 470 (char *) src_proto, CONVERT_SIZE(uint8_t, char, 471 header->protocol_length), hw_source)); 480 rc = arp_addr_add(&proto->addresses, (char *) src_proto, 481 CONVERT_SIZE(uint8_t, char, 482 header->protocol_length), hw_source); 483 if (rc != EOK) 484 return rc; 472 485 } 473 486 if (ntohs(header->operation) == ARPOP_REQUEST) { … … 480 493 memcpy(des_hw, hw_source->value, 481 494 header->hardware_length); 482 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, 483 header->hardware_length)); 495 496 rc = packet_set_addr(packet, src_hw, des_hw, 497 header->hardware_length); 498 if (rc != EOK) 499 return rc; 500 484 501 nil_send_msg(device->phone, device_id, packet, 485 502 SERVICE_ARP); … … 596 613 ipc_call_t *answer, int *answer_count) 597 614 { 598 ERROR_DECLARE;599 600 615 measured_string_ref address; 601 616 measured_string_ref translation; … … 603 618 packet_t packet; 604 619 packet_t next; 620 int rc; 605 621 606 622 *answer_count = 0; … … 610 626 611 627 case NET_ARP_DEVICE: 612 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 613 if (ERROR_OCCURRED(arp_device_message(IPC_GET_DEVICE(call), 614 IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address))) { 628 rc = measured_strings_receive(&address, &data, 1); 629 if (rc != EOK) 630 return rc; 631 632 rc = arp_device_message(IPC_GET_DEVICE(call), 633 IPC_GET_SERVICE(call), ARP_GET_NETIF(call), address); 634 if (rc != EOK) { 615 635 free(address); 616 636 free(data); 617 637 } 618 return ERROR_CODE;638 return rc; 619 639 620 640 case NET_ARP_TRANSLATE: 621 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 641 rc = measured_strings_receive(&address, &data, 1); 642 if (rc != EOK) 643 return rc; 644 622 645 fibril_rwlock_read_lock(&arp_globals.lock); 623 646 translation = arp_translate_message(IPC_GET_DEVICE(call), … … 629 652 return ENOENT; 630 653 } 631 ERROR_CODE= measured_strings_reply(translation, 1);654 rc = measured_strings_reply(translation, 1); 632 655 fibril_rwlock_read_unlock(&arp_globals.lock); 633 return ERROR_CODE;656 return rc; 634 657 635 658 case NET_ARP_CLEAR_DEVICE: … … 637 660 638 661 case NET_ARP_CLEAR_ADDRESS: 639 ERROR_PROPAGATE(measured_strings_receive(&address, &data, 1)); 662 rc = measured_strings_receive(&address, &data, 1); 663 if (rc != EOK) 664 return rc; 665 640 666 arp_clear_address_req(0, IPC_GET_DEVICE(call), 641 667 IPC_GET_SERVICE(call), address); … … 652 678 653 679 case NET_IL_RECEIVED: 654 if (ERROR_NONE(packet_translate_remote(arp_globals.net_phone, 655 &packet, IPC_GET_PACKET(call)))) { 656 fibril_rwlock_read_lock(&arp_globals.lock); 657 do { 658 next = pq_detach(packet); 659 ERROR_CODE = 660 arp_receive_message(IPC_GET_DEVICE(call), 661 packet); 662 if (ERROR_CODE != 1) { 663 pq_release_remote(arp_globals.net_phone, 664 packet_get_id(packet)); 665 } 666 packet = next; 667 } while (packet); 668 fibril_rwlock_read_unlock(&arp_globals.lock); 669 } 670 return ERROR_CODE; 680 rc = packet_translate_remote(arp_globals.net_phone, &packet, 681 IPC_GET_PACKET(call)); 682 if (rc != EOK) 683 return rc; 684 685 fibril_rwlock_read_lock(&arp_globals.lock); 686 do { 687 next = pq_detach(packet); 688 rc = arp_receive_message(IPC_GET_DEVICE(call), packet); 689 if (rc != 1) { 690 pq_release_remote(arp_globals.net_phone, 691 packet_get_id(packet)); 692 } 693 packet = next; 694 } while (packet); 695 fibril_rwlock_read_unlock(&arp_globals.lock); 696 697 return EOK; 671 698 672 699 case NET_IL_MTU_CHANGED: … … 727 754 int main(int argc, char *argv[]) 728 755 { 729 ERROR_DECLARE;756 int rc; 730 757 731 758 /* Start the module */ 732 ERROR_PROPAGATE(il_module_start_standalone(il_client_connection));733 return EOK;759 rc = il_module_start_standalone(il_client_connection); 760 return rc; 734 761 } 735 762 -
uspace/srv/net/il/arp/arp_module.c
rd70a463 rb40bfac 41 41 #include <async.h> 42 42 #include <stdio.h> 43 #include <err .h>43 #include <errno.h> 44 44 45 45 #include <ipc/ipc.h> … … 66 66 int il_module_start_standalone(async_client_conn_t client_connection) 67 67 { 68 ERROR_DECLARE; 68 ipcarg_t phonehash; 69 int rc; 69 70 70 71 async_set_client_connection(client_connection); 71 72 arp_globals.net_phone = net_connect_module(); 72 ERROR_PROPAGATE(pm_init());73 73 74 ipcarg_t phonehash; 75 if (ERROR_OCCURRED(arp_initialize(client_connection)) || 76 ERROR_OCCURRED(REGISTER_ME(SERVICE_ARP, &phonehash))) { 77 pm_destroy(); 78 return ERROR_CODE; 79 } 74 rc = pm_init(); 75 if (rc != EOK) 76 return rc; 77 78 rc = arp_initialize(client_connection); 79 if (rc != EOK) 80 goto out; 81 82 rc = REGISTER_ME(SERVICE_ARP, &phonehash); 83 if (rc != EOK) 84 goto out; 80 85 81 86 async_manager(); 82 87 88 out: 83 89 pm_destroy(); 84 return EOK;90 return rc; 85 91 } 86 92 -
uspace/srv/net/il/ip/ip.c
rd70a463 rb40bfac 41 41 #include <async.h> 42 42 #include <errno.h> 43 #include <err.h>44 43 #include <fibril_synch.h> 45 44 #include <stdio.h> … … 254 253 int ip_initialize(async_client_conn_t client_connection) 255 254 { 256 ERROR_DECLARE;255 int rc; 257 256 258 257 fibril_rwlock_initialize(&ip_globals.lock); … … 265 264 ip_globals.gateway.gateway.s_addr = 0; 266 265 ip_globals.gateway.netif = NULL; 267 ERROR_PROPAGATE(ip_netifs_initialize(&ip_globals.netifs));268 ERROR_PROPAGATE(ip_protos_initialize(&ip_globals.protos));269 266 ip_globals.client_connection = client_connection; 270 ERROR_PROPAGATE(modules_initialize(&ip_globals.modules)); 271 ERROR_PROPAGATE(add_module(NULL, &ip_globals.modules, ARP_NAME, 272 ARP_FILENAME, SERVICE_ARP, 0, arp_connect_module)); 267 268 rc = ip_netifs_initialize(&ip_globals.netifs); 269 if (rc != EOK) 270 goto out; 271 rc = ip_protos_initialize(&ip_globals.protos); 272 if (rc != EOK) 273 goto out; 274 rc = modules_initialize(&ip_globals.modules); 275 if (rc != EOK) 276 goto out; 277 rc = add_module(NULL, &ip_globals.modules, ARP_NAME, ARP_FILENAME, 278 SERVICE_ARP, 0, arp_connect_module); 279 280 out: 273 281 fibril_rwlock_write_unlock(&ip_globals.lock); 274 282 275 return EOK;283 return rc; 276 284 } 277 285 … … 302 310 static int ip_netif_initialize(ip_netif_ref ip_netif) 303 311 { 304 ERROR_DECLARE;305 306 312 measured_string_t names[] = { 307 313 { … … 342 348 char *data; 343 349 measured_string_t address; 344 int index;345 350 ip_route_ref route; 346 351 in_addr_t gateway; 352 int index; 353 int rc; 347 354 348 355 ip_netif->arp = NULL; … … 354 361 355 362 // get configuration 356 ERROR_PROPAGATE(net_get_device_conf_req(ip_globals.net_phone, 357 ip_netif->device_id, &configuration, count, &data)); 363 rc = net_get_device_conf_req(ip_globals.net_phone, ip_netif->device_id, 364 &configuration, count, &data); 365 if (rc != EOK) 366 return rc; 367 358 368 if (configuration) { 359 369 if (configuration[0].value) … … 383 393 return index; 384 394 } 385 if (ERROR_OCCURRED(inet_pton(AF_INET, 386 configuration[2].value, 387 (uint8_t *) &route->address.s_addr)) || 388 ERROR_OCCURRED(inet_pton(AF_INET, 389 configuration[3].value, 390 (uint8_t *) &route->netmask.s_addr)) || 395 396 if ((inet_pton(AF_INET, configuration[2].value, 397 (uint8_t *) &route->address.s_addr) != EOK) || 398 (inet_pton(AF_INET, configuration[3].value, 399 (uint8_t *) &route->netmask.s_addr) != EOK) || 391 400 (inet_pton(AF_INET, configuration[4].value, 392 401 (uint8_t *) &gateway.s_addr) == EINVAL) || … … 434 443 address.value = (char *) &route->address.s_addr; 435 444 address.length = CONVERT_SIZE(in_addr_t, char, 1); 436 ERROR_PROPAGATE(arp_device_req(ip_netif->arp->phone, 445 446 rc = arp_device_req(ip_netif->arp->phone, 437 447 ip_netif->device_id, SERVICE_IP, ip_netif->service, 438 &address)); 448 &address); 449 if (rc != EOK) 450 return rc; 439 451 } else { 440 452 ip_netif->arp = 0; … … 443 455 444 456 // get packet dimensions 445 ERROR_PROPAGATE(nil_packet_size_req(ip_netif->phone, 446 ip_netif->device_id, &ip_netif->packet_dimension)); 457 rc = nil_packet_size_req(ip_netif->phone, ip_netif->device_id, 458 &ip_netif->packet_dimension); 459 if (rc != EOK) 460 return rc; 461 447 462 if (ip_netif->packet_dimension.content < IP_MIN_CONTENT) { 448 463 printf("Maximum transmission unit %d bytes is too small, at " … … 610 625 measured_string_ref destination) 611 626 { 612 ERROR_DECLARE;613 614 627 size_t length; 615 628 ip_header_ref header; … … 617 630 ip_header_ref middle_header; 618 631 packet_t next; 632 int rc; 619 633 620 634 length = packet_get_data_length(packet); … … 624 638 header = (ip_header_ref) packet_get_data(packet); 625 639 if (destination) { 626 ERROR_PROPAGATE(packet_set_addr(packet, NULL, 627 (uint8_t *) destination->value, 628 CONVERT_SIZE(char, uint8_t, destination->length))); 640 rc = packet_set_addr(packet, NULL, (uint8_t *) destination->value, 641 CONVERT_SIZE(char, uint8_t, destination->length)); 629 642 } else { 630 ERROR_PROPAGATE(packet_set_addr(packet, NULL, NULL, 0)); 631 } 643 rc = packet_set_addr(packet, NULL, NULL, 0); 644 } 645 if (rc != EOK) 646 return rc; 647 632 648 header->version = IPV4; 633 649 header->fragment_offset_high = 0; … … 669 685 IP_HEADER_CHECKSUM(middle_header); 670 686 if (destination) { 671 if (ERROR_OCCURRED(packet_set_addr(next, NULL,687 rc = packet_set_addr(next, NULL, 672 688 (uint8_t *) destination->value, 673 689 CONVERT_SIZE(char, uint8_t, 674 destination->length)))) { 690 destination->length)); 691 if (rc != EOK) { 675 692 free(last_header); 676 return ERROR_CODE;693 return rc; 677 694 } 678 695 } … … 699 716 IP_HEADER_CHECKSUM(middle_header); 700 717 if (destination) { 701 if (ERROR_OCCURRED(packet_set_addr(next, NULL,718 rc = packet_set_addr(next, NULL, 702 719 (uint8_t *) destination->value, 703 CONVERT_SIZE(char, uint8_t, 704 destination->length)))) {720 CONVERT_SIZE(char, uint8_t, destination->length)); 721 if (rc != EOK) { 705 722 free(last_header); 706 return ERROR_CODE;707 723 return rc; 724 } 708 725 } 709 726 length += packet_get_data_length(next); … … 741 758 const struct sockaddr *src, const struct sockaddr *dest, socklen_t addrlen) 742 759 { 743 ERROR_DECLARE;744 745 760 void *data; 746 761 size_t offset; 762 int rc; 747 763 748 764 data = packet_suffix(new_packet, length); … … 752 768 memcpy(data, ((void *) header) + IP_TOTAL_LENGTH(header) - length, 753 769 length); 754 ERROR_PROPAGATE(packet_trim(packet, 0, length)); 770 771 rc = packet_trim(packet, 0, length); 772 if (rc != EOK) 773 return rc; 774 755 775 header->total_length = htons(IP_TOTAL_LENGTH(header) - length); 756 776 new_header->total_length = htons(IP_HEADER_LENGTH(new_header) + length); … … 761 781 IP_COMPUTE_FRAGMENT_OFFSET_LOW(offset); 762 782 new_header->header_checksum = IP_HEADER_CHECKSUM(new_header); 763 ERROR_PROPAGATE(packet_set_addr(new_packet, (const uint8_t *) src, 764 (const uint8_t *) dest, addrlen)); 783 784 rc = packet_set_addr(new_packet, (const uint8_t *) src, 785 (const uint8_t *) dest, addrlen); 786 if (rc != EOK) 787 return rc; 765 788 766 789 return pq_insert_after(packet, new_packet); … … 796 819 socklen_t addr_len) 797 820 { 798 ERROR_DECLARE;799 800 821 packet_t new_packet; 801 822 ip_header_ref header; … … 806 827 socklen_t addrlen; 807 828 int result; 829 int rc; 808 830 809 831 result = packet_get_addr(packet, (uint8_t **) &src, (uint8_t **) &dest); … … 839 861 840 862 // trim the unused space 841 if (ERROR_OCCURRED(packet_trim(new_packet, 0,842 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)) )) {843 return ip_release_and_return(packet, ERROR_CODE);844 }863 rc = packet_trim(new_packet, 0, 864 IP_HEADER_LENGTH(header) - IP_HEADER_LENGTH(last_header)); 865 if (rc != EOK) 866 return ip_release_and_return(packet, rc); 845 867 846 868 // biggest multiple of 8 lower than content 847 869 // TODO even fragmentation? 848 870 length = length & ~0x7; 849 if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet, header,850 871 872 rc = ip_fragment_packet_data(packet, new_packet, header, last_header, 851 873 ((IP_HEADER_DATA_LENGTH(header) - 852 874 ((length - IP_HEADER_LENGTH(header)) & ~0x7)) % 853 ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)), src, dest,854 addrlen))) {855 return ip_release_and_return(packet, ERROR_CODE);856 }875 ((length - IP_HEADER_LENGTH(last_header)) & ~0x7)), 876 src, dest, addrlen); 877 if (rc != EOK) 878 return ip_release_and_return(packet, rc); 857 879 858 880 // mark the first as fragmented … … 872 894 return ip_release_and_return(packet, ENOMEM); 873 895 874 if (ERROR_OCCURRED(ip_fragment_packet_data(packet, new_packet,875 header,middle_header,876 (length - IP_HEADER_LENGTH(middle_header)) & ~0x7, src,877 dest, addrlen))) {878 return ip_release_and_return(packet, ERROR_CODE);879 }896 rc = ip_fragment_packet_data(packet, new_packet, header, 897 middle_header, 898 (length - IP_HEADER_LENGTH(middle_header)) & ~0x7, 899 src, dest, addrlen); 900 if (rc != EOK) 901 return ip_release_and_return(packet, rc); 880 902 } 881 903 … … 974 996 in_addr_t *src, in_addr_t dest, services_t error) 975 997 { 976 ERROR_DECLARE;977 978 998 measured_string_t destination; 979 999 measured_string_ref translation; 980 1000 char *data; 981 1001 int phone; 1002 int rc; 982 1003 983 1004 // get destination hardware address … … 987 1008 destination.length = CONVERT_SIZE(dest.s_addr, char, 1); 988 1009 989 if (ERROR_OCCURRED(arp_translate_req(netif->arp->phone,990 netif->device_id, SERVICE_IP, &destination, &translation,991 &data))) {1010 rc = arp_translate_req(netif->arp->phone, netif->device_id, 1011 SERVICE_IP, &destination, &translation, &data); 1012 if (rc != EOK) { 992 1013 pq_release_remote(ip_globals.net_phone, 993 1014 packet_get_id(packet)); 994 return ERROR_CODE;1015 return rc; 995 1016 } 996 1017 … … 1014 1035 } 1015 1036 1016 if (ERROR_OCCURRED(ip_prepare_packet(src, dest, packet, translation))) { 1037 rc = ip_prepare_packet(src, dest, packet, translation); 1038 if (rc != EOK) { 1017 1039 pq_release_remote(ip_globals.net_phone, packet_get_id(packet)); 1018 1040 } else { … … 1032 1054 } 1033 1055 1034 return ERROR_CODE;1056 return rc; 1035 1057 } 1036 1058 … … 1158 1180 ip_device_req_local(int il_phone, device_id_t device_id, services_t netif) 1159 1181 { 1160 ERROR_DECLARE;1161 1162 1182 ip_netif_ref ip_netif; 1163 1183 ip_route_ref route; 1164 1184 int index; 1185 int rc; 1165 1186 1166 1187 ip_netif = (ip_netif_ref) malloc(sizeof(ip_netif_t)); … … 1168 1189 return ENOMEM; 1169 1190 1170 if (ERROR_OCCURRED(ip_routes_initialize(&ip_netif->routes))) { 1191 rc = ip_routes_initialize(&ip_netif->routes); 1192 if (rc != EOK) { 1171 1193 free(ip_netif); 1172 return ERROR_CODE;1194 return rc; 1173 1195 } 1174 1196 … … 1178 1200 1179 1201 fibril_rwlock_write_lock(&ip_globals.netifs_lock); 1180 if (ERROR_OCCURRED(ip_netif_initialize(ip_netif))) { 1202 1203 rc = ip_netif_initialize(ip_netif); 1204 if (rc != EOK) { 1181 1205 fibril_rwlock_write_unlock(&ip_globals.netifs_lock); 1182 1206 ip_routes_destroy(&ip_netif->routes); 1183 1207 free(ip_netif); 1184 return ERROR_CODE;1208 return rc; 1185 1209 } 1186 1210 if (ip_netif->arp) … … 1226 1250 services_t sender, services_t error) 1227 1251 { 1228 ERROR_DECLARE;1229 1230 1252 int addrlen; 1231 1253 ip_netif_ref netif; … … 1236 1258 in_addr_t *src; 1237 1259 int phone; 1260 int rc; 1238 1261 1239 1262 // addresses in the host byte order … … 1323 1346 } 1324 1347 1325 ERROR_CODE= ip_send_route(packet, netif, route, src, *dest, error);1348 rc = ip_send_route(packet, netif, route, src, *dest, error); 1326 1349 fibril_rwlock_read_unlock(&ip_globals.netifs_lock); 1327 1350 1328 return ERROR_CODE;1351 return rc; 1329 1352 } 1330 1353 … … 1431 1454 services_t error) 1432 1455 { 1433 ERROR_DECLARE;1434 1435 1456 ip_proto_ref proto; 1436 1457 int phone; … … 1442 1463 struct sockaddr_in dest_in; 1443 1464 socklen_t addrlen; 1465 int rc; 1444 1466 1445 1467 if ((header->flags & IPFLAG_MORE_FRAGMENTS) || … … 1467 1489 } 1468 1490 1469 if (ERROR_OCCURRED(packet_set_addr(packet, (uint8_t *) src,1470 (uint8_t *) dest, addrlen))) {1471 return ip_release_and_return(packet, ERROR_CODE);1472 }1491 rc = packet_set_addr(packet, (uint8_t *) src, (uint8_t *) dest, 1492 addrlen); 1493 if (rc != EOK) 1494 return ip_release_and_return(packet, rc); 1473 1495 1474 1496 // trim padding if present 1475 1497 if (!error && 1476 1498 (IP_TOTAL_LENGTH(header) < packet_get_data_length(packet))) { 1477 if (ERROR_OCCURRED(packet_trim(packet, 0, 1478 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)))) 1479 return ip_release_and_return(packet, ERROR_CODE); 1499 rc = packet_trim(packet, 0, 1500 packet_get_data_length(packet) - IP_TOTAL_LENGTH(header)); 1501 if (rc != EOK) 1502 return ip_release_and_return(packet, rc); 1480 1503 } 1481 1504 … … 1498 1521 received_msg = proto->received_msg; 1499 1522 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1500 ERROR_CODE= received_msg(device_id, packet, service, error);1523 rc = received_msg(device_id, packet, service, error); 1501 1524 } else { 1502 ERROR_CODE= tl_received_msg(proto->phone, device_id, packet,1525 rc = tl_received_msg(proto->phone, device_id, packet, 1503 1526 proto->service, error); 1504 1527 fibril_rwlock_read_unlock(&ip_globals.protos_lock); 1505 1528 } 1506 1529 1507 return ERROR_CODE;1530 return rc; 1508 1531 } 1509 1532 … … 1532 1555 ip_process_packet(device_id_t device_id, packet_t packet) 1533 1556 { 1534 ERROR_DECLARE;1535 1536 1557 ip_header_ref header; 1537 1558 in_addr_t dest; … … 1541 1562 struct sockaddr_in addr_in; 1542 1563 socklen_t addrlen; 1564 int rc; 1543 1565 1544 1566 header = (ip_header_ref) packet_get_data(packet); … … 1585 1607 } 1586 1608 1587 ERROR_PROPAGATE(packet_set_addr(packet, NULL, (uint8_t *) &addr, 1588 addrlen)); 1609 rc = packet_set_addr(packet, NULL, (uint8_t *) &addr, addrlen); 1610 if (rc != EOK) 1611 return rc; 1589 1612 1590 1613 route = ip_find_route(dest); … … 1867 1890 int *answer_count) 1868 1891 { 1869 ERROR_DECLARE;1870 1871 1892 packet_t packet; 1872 1893 struct sockaddr *addr; … … 1878 1899 size_t headerlen; 1879 1900 device_id_t device_id; 1901 int rc; 1880 1902 1881 1903 *answer_count = 0; … … 1893 1915 1894 1916 case NET_IL_SEND: 1895 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1896 &packet, IPC_GET_PACKET(call))); 1917 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1918 IPC_GET_PACKET(call)); 1919 if (rc != EOK) 1920 return rc; 1897 1921 return ip_send_msg_local(0, IPC_GET_DEVICE(call), packet, 0, 1898 1922 IPC_GET_ERROR(call)); … … 1903 1927 1904 1928 case NET_IL_RECEIVED: 1905 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1906 &packet, IPC_GET_PACKET(call))); 1929 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1930 IPC_GET_PACKET(call)); 1931 if (rc != EOK) 1932 return rc; 1907 1933 return ip_receive_message(IPC_GET_DEVICE(call), packet); 1908 1934 1909 1935 case NET_IP_RECEIVED_ERROR: 1910 ERROR_PROPAGATE(packet_translate_remote(ip_globals.net_phone, 1911 &packet, IPC_GET_PACKET(call))); 1936 rc = packet_translate_remote(ip_globals.net_phone, &packet, 1937 IPC_GET_PACKET(call)); 1938 if (rc != EOK) 1939 return rc; 1912 1940 return ip_received_error_msg_local(0, IPC_GET_DEVICE(call), 1913 1941 packet, IPC_GET_TARGET(call), IPC_GET_ERROR(call)); … … 1923 1951 1924 1952 case NET_IP_GET_ROUTE: 1925 ERROR_PROPAGATE(data_receive((void **) &addr, &addrlen)); 1926 ERROR_PROPAGATE(ip_get_route_req_local(0, IP_GET_PROTOCOL(call), 1927 addr, (socklen_t) addrlen, &device_id, &header, 1928 &headerlen)); 1953 rc = data_receive((void **) &addr, &addrlen); 1954 if (rc != EOK) 1955 return rc; 1956 1957 rc = ip_get_route_req_local(0, IP_GET_PROTOCOL(call), addr, 1958 (socklen_t) addrlen, &device_id, &header, &headerlen); 1959 if (rc != EOK) 1960 return rc; 1961 1929 1962 IPC_SET_DEVICE(answer, device_id); 1930 1963 IP_SET_HEADERLEN(answer, headerlen); 1931 1964 1932 1965 *answer_count = 2; 1933 1934 if (ERROR_NONE(data_reply(&headerlen, sizeof(headerlen)))) 1935 ERROR_CODE = data_reply(header, headerlen); 1966 1967 rc = data_reply(&headerlen, sizeof(headerlen)); 1968 if (rc == EOK) 1969 rc = data_reply(header, headerlen); 1936 1970 1937 1971 free(header); 1938 return ERROR_CODE;1972 return rc; 1939 1973 1940 1974 case NET_IL_PACKET_SPACE: 1941 ERROR_PROPAGATE(ip_packet_size_message(IPC_GET_DEVICE(call), 1942 &addrlen, &prefix, &content, &suffix)); 1975 rc = ip_packet_size_message(IPC_GET_DEVICE(call), &addrlen, 1976 &prefix, &content, &suffix); 1977 if (rc != EOK) 1978 return rc; 1979 1943 1980 IPC_SET_ADDR(answer, addrlen); 1944 1981 IPC_SET_PREFIX(answer, prefix); … … 2005 2042 int main(int argc, char *argv[]) 2006 2043 { 2007 ERROR_DECLARE;2044 int rc; 2008 2045 2009 2046 /* Start the module */ 2010 ERROR_PROPAGATE(il_module_start_standalone(il_client_connection));2011 return EOK;2047 rc = il_module_start_standalone(il_client_connection); 2048 return rc; 2012 2049 } 2013 2050 -
uspace/srv/net/il/ip/ip_module.c
rd70a463 rb40bfac 44 44 #include <ipc/ipc.h> 45 45 #include <ipc/services.h> 46 #include <err .h>46 #include <errno.h> 47 47 48 48 #include <net/modules.h> … … 66 66 int il_module_start_standalone(async_client_conn_t client_connection) 67 67 { 68 ERROR_DECLARE; 68 ipcarg_t phonehash; 69 int rc; 69 70 70 71 async_set_client_connection(client_connection); 71 72 ip_globals.net_phone = net_connect_module(); 72 ERROR_PROPAGATE(pm_init()); 73 74 rc = pm_init(); 75 if (rc != EOK) 76 return rc; 73 77 74 ipcarg_t phonehash; 75 if (ERROR_OCCURRED(ip_initialize(client_connection)) || 76 ERROR_OCCURRED(REGISTER_ME(SERVICE_IP, &phonehash))) { 77 pm_destroy(); 78 return ERROR_CODE; 79 } 78 rc = ip_initialize(client_connection); 79 if (rc != EOK) 80 goto out; 81 82 rc = REGISTER_ME(SERVICE_IP, &phonehash); 83 if (rc != EOK) 84 goto out; 80 85 81 86 async_manager(); 82 87 88 out: 83 89 pm_destroy(); 84 return EOK;90 return rc; 85 91 } 86 92 -
uspace/srv/net/net/net.c
rd70a463 rb40bfac 36 36 */ 37 37 38 #include "net.h" 39 38 40 #include <async.h> 39 41 #include <ctype.h> … … 52 54 53 55 #include <net/modules.h> 56 #include <net/packet.h> 57 #include <net/device.h> 58 54 59 #include <adt/char_map.h> 55 60 #include <adt/generic_char_map.h> 56 61 #include <adt/measured_strings.h> 57 62 #include <adt/module_map.h> 58 #include <net/packet.h> 63 59 64 #include <netif_remote.h> 60 #include <net/device.h>61 65 #include <nil_interface.h> 62 66 #include <net_interface.h> 63 67 #include <ip_interface.h> 64 68 65 #include "net.h" 66 67 /** Networking module name. 68 * 69 */ 69 /** Networking module name. */ 70 70 #define NAME "net" 71 71 72 /** File read buffer size. 73 * 74 */ 72 /** File read buffer size. */ 75 73 #define BUFFER_SIZE 256 76 74 77 /** Networking module global data. 78 * 79 */ 75 /** Networking module global data. */ 80 76 net_globals_t net_globals; 81 77 … … 100 96 measured_string_ref setting = 101 97 measured_string_create_bulk(value, 0); 102 103 98 if (!setting) 104 99 return ENOMEM; … … 206 201 unsigned int line_number = 0; 207 202 size_t index = 0; 208 while ( (!ferror(cfg)) && (!feof(cfg))) {203 while (!ferror(cfg) && !feof(cfg)) { 209 204 int read = fgetc(cfg); 210 205 if ((read > 0) && (read != '\n') && (read != '\r')) { … … 326 321 ipcarg_t phonehash; 327 322 328 if (ERROR_OCCURRED(net_initialize(client_connection)) 329 || ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))){323 if (ERROR_OCCURRED(net_initialize(client_connection)) || 324 ERROR_OCCURRED(REGISTER_ME(SERVICE_NETWORKING, &phonehash))) { 330 325 pm_destroy(); 331 326 return ERROR_CODE; … … 379 374 size_t count, char **data) 380 375 { 381 if (! (configuration && (count > 0)))376 if (!configuration || (count <= 0)) 382 377 return EINVAL; 383 378 … … 482 477 /* Inter-network layer startup */ 483 478 switch (netif->il->service) { 484 485 486 487 488 489 479 case SERVICE_IP: 480 ERROR_PROPAGATE(ip_device_req(netif->il->phone, netif->id, 481 internet_service)); 482 break; 483 default: 484 return ENOENT; 490 485 } 491 486 … … 511 506 ERROR_DECLARE; 512 507 513 const char *conf_files[] = {"lo", "ne2k"}; 508 const char *conf_files[] = { 509 "lo", 510 "ne2k" 511 }; 514 512 size_t count = sizeof(conf_files) / sizeof(char *); 515 513 … … 603 601 *answer_count = 0; 604 602 switch (IPC_GET_METHOD(*call)) { 605 606 607 608 609 610 611 612 613 614 615 616 617 618 619 620 621 622 623 624 625 626 627 628 629 630 631 603 case IPC_M_PHONE_HUNGUP: 604 return EOK; 605 case NET_NET_GET_DEVICE_CONF: 606 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, 607 IPC_GET_COUNT(call))); 608 net_get_device_conf_req(0, IPC_GET_DEVICE(call), &strings, 609 IPC_GET_COUNT(call), NULL); 610 611 /* Strings should not contain received data anymore */ 612 free(data); 613 614 ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call)); 615 free(strings); 616 return ERROR_CODE; 617 case NET_NET_GET_CONF: 618 ERROR_PROPAGATE(measured_strings_receive(&strings, &data, 619 IPC_GET_COUNT(call))); 620 net_get_conf_req(0, &strings, IPC_GET_COUNT(call), NULL); 621 622 /* Strings should not contain received data anymore */ 623 free(data); 624 625 ERROR_CODE = measured_strings_reply(strings, IPC_GET_COUNT(call)); 626 free(strings); 627 return ERROR_CODE; 628 case NET_NET_STARTUP: 629 return startup(); 632 630 } 633 631 return ENOTSUP; … … 661 659 int res = net_module_message(callid, &call, &answer, &answer_count); 662 660 663 /* End if said to either by the message or the processing result */661 /* End if told to either by the message or the processing result */ 664 662 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 665 663 return; -
uspace/srv/net/net/net.h
rd70a463 rb40bfac 36 36 */ 37 37 38 #ifndef __NET_NET_H__39 #define __NET_NET_H__38 #ifndef NET_NET_H_ 39 #define NET_NET_H_ 40 40 41 41 #include <ipc/ipc.h> -
uspace/srv/net/net/net_standalone.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup net 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * Wrapper for the standalone networking module. 35 35 */ 36 36 37 #include "net.h" 38 37 39 #include <str.h> 38 40 #include <adt/measured_strings.h> 41 #include <adt/module_map.h> 39 42 #include <ipc/ipc.h> 40 43 #include <ipc/net.h> 41 44 42 45 #include <ip_interface.h> 43 #include <adt/measured_strings.h>44 #include <adt/module_map.h>45 46 #include <packet_server.h> 46 47 47 #include "net.h" 48 49 /** Networking module global data. 50 */ 48 /** Networking module global data. */ 51 49 extern net_globals_t net_globals; 52 50 … … 60 58 * 61 59 */ 62 int net_initialize_build(async_client_conn_t client_connection){ 60 int net_initialize_build(async_client_conn_t client_connection) 61 { 63 62 ERROR_DECLARE; 64 63 -
uspace/srv/net/netif/lo/lo.c
rd70a463 rb40bfac 37 37 #include <async.h> 38 38 #include <errno.h> 39 #include <err.h>40 39 #include <stdio.h> 41 40 #include <str.h> … … 83 82 int netif_get_device_stats(device_id_t device_id, device_stats_ref stats) 84 83 { 85 ERROR_DECLARE;86 87 84 netif_device_t *device; 85 int rc; 88 86 89 87 if (!stats) 90 88 return EBADMEM; 91 ERROR_PROPAGATE(find_device(device_id, &device)); 89 rc = find_device(device_id, &device); 90 if (rc != EOK) 91 return rc; 92 92 memcpy(stats, (device_stats_ref) device->specific, 93 93 sizeof(device_stats_t)); … … 164 164 int netif_probe_message(device_id_t device_id, int irq, uintptr_t io) 165 165 { 166 ERROR_DECLARE;167 168 166 netif_device_t *device; 167 int rc; 169 168 170 169 // create a new device 171 ERROR_PROPAGATE(create(device_id, &device)); 170 rc = create(device_id, &device); 171 if (rc != EOK) 172 return rc; 172 173 // print the settings 173 174 printf("%s: Device created (id: %d)\n", NAME, device->device_id); … … 177 178 int netif_send_message(device_id_t device_id, packet_t packet, services_t sender) 178 179 { 179 ERROR_DECLARE;180 181 180 netif_device_t *device; 182 181 size_t length; 183 182 packet_t next; 184 183 int phone; 185 186 ERROR_PROPAGATE(find_device(device_id, &device)); 184 int rc; 185 186 rc = find_device(device_id, &device); 187 if (rc != EOK) 188 return EOK; 187 189 if (device->state != NETIF_ACTIVE) { 188 190 netif_pq_release(packet_get_id(packet)); … … 259 261 int main(int argc, char *argv[]) 260 262 { 261 ERROR_DECLARE;263 int rc; 262 264 263 265 /* Start the module */ 264 ERROR_PROPAGATE(netif_module_start(netif_client_connection));265 return EOK;266 rc = netif_module_start(netif_client_connection); 267 return rc; 266 268 } 267 269 -
uspace/srv/net/nil/eth/eth.c
rd70a463 rb40bfac 42 42 #include <byteorder.h> 43 43 #include <str.h> 44 #include <err .h>44 #include <errno.h> 45 45 46 46 #include <ipc/ipc.h> … … 196 196 int nil_initialize(int net_phone) 197 197 { 198 ERROR_DECLARE;198 int rc; 199 199 200 200 fibril_rwlock_initialize(ð_globals.devices_lock); … … 208 208 CONVERT_SIZE(uint8_t, char, ETH_ADDR)); 209 209 if (!eth_globals.broadcast_addr) { 210 ERROR_CODE= ENOMEM;210 rc = ENOMEM; 211 211 goto out; 212 212 } 213 if (ERROR_OCCURRED(eth_devices_initialize(ð_globals.devices))) { 213 rc = eth_devices_initialize(ð_globals.devices); 214 if (rc != EOK) { 214 215 free(eth_globals.broadcast_addr); 215 216 goto out; 216 217 } 217 if (ERROR_OCCURRED(eth_protos_initialize(ð_globals.protos))) { 218 rc = eth_protos_initialize(ð_globals.protos); 219 if (rc != EOK) { 218 220 free(eth_globals.broadcast_addr); 219 221 eth_devices_destroy(ð_globals.devices); … … 223 225 fibril_rwlock_write_unlock(ð_globals.devices_lock); 224 226 225 return ERROR_CODE;227 return rc; 226 228 } 227 229 … … 234 236 static void eth_receiver(ipc_callid_t iid, ipc_call_t *icall) 235 237 { 236 ERROR_DECLARE;237 238 238 packet_t packet; 239 int rc; 239 240 240 241 while (true) { … … 246 247 break; 247 248 case NET_NIL_RECEIVED: 248 if (ERROR_NONE(packet_translate_remote(249 eth_globals.net_phone, &packet,250 IPC_GET_PACKET(icall)))) {251 ERROR_CODE= nil_received_msg_local(0,249 rc = packet_translate_remote(eth_globals.net_phone, 250 &packet, IPC_GET_PACKET(icall)); 251 if (rc == EOK) { 252 rc = nil_received_msg_local(0, 252 253 IPC_GET_DEVICE(icall), packet, 0); 253 254 } 254 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);255 ipc_answer_0(iid, (ipcarg_t) rc); 255 256 break; 256 257 default: … … 282 283 eth_device_message(device_id_t device_id, services_t service, size_t mtu) 283 284 { 284 ERROR_DECLARE;285 286 285 eth_device_ref device; 287 286 int index; … … 300 299 char *data; 301 300 eth_proto_ref proto; 301 int rc; 302 302 303 303 fibril_rwlock_write_lock(ð_globals.devices_lock); … … 351 351 352 352 configuration = &names[0]; 353 if (ERROR_OCCURRED(net_get_device_conf_req(eth_globals.net_phone, 354 device->device_id, &configuration, count, &data))) { 353 rc = net_get_device_conf_req(eth_globals.net_phone, device->device_id, 354 &configuration, count, &data); 355 if (rc != EOK) { 355 356 fibril_rwlock_write_unlock(ð_globals.devices_lock); 356 357 free(device); 357 return ERROR_CODE;358 return rc; 358 359 } 359 360 if (configuration) { … … 387 388 388 389 // get hardware address 389 if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, 390 &device->addr, &device->addr_data))) { 390 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 391 &device->addr_data); 392 if (rc != EOK) { 391 393 fibril_rwlock_write_unlock(ð_globals.devices_lock); 392 394 free(device); 393 return ERROR_CODE;395 return rc; 394 396 } 395 397 … … 429 431 static eth_proto_ref eth_process_packet(int flags, packet_t packet) 430 432 { 431 ERROR_DECLARE;432 433 433 eth_header_snap_ref header; 434 434 size_t length; … … 437 437 size_t suffix; 438 438 eth_fcs_ref fcs; 439 uint8_t * data; 439 uint8_t *data; 440 int rc; 440 441 441 442 length = packet_get_data_length(packet); … … 488 489 489 490 if (IS_DUMMY(flags)) { 490 if ( (~compute_crc32(~0U, data, length * 8)) != ntohl(*fcs))491 if (~compute_crc32(~0U, data, length * 8) != ntohl(*fcs)) 491 492 return NULL; 492 493 suffix += sizeof(eth_fcs_t); 493 494 } 494 495 495 if (ERROR_OCCURRED(packet_set_addr(packet,496 header->header. source_address, header->header.destination_address,497 ETH_ADDR)) || ERROR_OCCURRED(packet_trim(packet, prefix, suffix))) {496 rc = packet_set_addr(packet, header->header.source_address, 497 header->header.destination_address, ETH_ADDR); 498 if (rc != EOK) 498 499 return NULL; 499 } 500 501 rc = packet_trim(packet, prefix, suffix); 502 if (rc != EOK) 503 return NULL; 500 504 501 505 return eth_protos_find(ð_globals.protos, type); … … 781 785 eth_send_message(device_id_t device_id, packet_t packet, services_t sender) 782 786 { 783 ERROR_DECLARE;784 785 787 eth_device_ref device; 786 788 packet_t next; 787 789 packet_t tmp; 788 790 int ethertype; 791 int rc; 789 792 790 793 ethertype = htons(protocol_map(SERVICE_ETHERNET, sender)); … … 804 807 next = packet; 805 808 do { 806 if (ERROR_OCCURRED(eth_prepare_packet(device->flags, next, 807 (uint8_t *) device->addr->value, ethertype, device->mtu))) { 809 rc = eth_prepare_packet(device->flags, next, 810 (uint8_t *) device->addr->value, ethertype, device->mtu); 811 if (rc != EOK) { 808 812 // release invalid packet 809 813 tmp = pq_detach(next); … … 832 836 ipc_call_t *answer, int *answer_count) 833 837 { 834 ERROR_DECLARE;835 836 838 measured_string_ref address; 837 839 packet_t packet; … … 840 842 size_t suffix; 841 843 size_t content; 844 int rc; 842 845 843 846 *answer_count = 0; … … 850 853 IPC_GET_SERVICE(call), IPC_GET_MTU(call)); 851 854 case NET_NIL_SEND: 852 ERROR_PROPAGATE(packet_translate_remote(eth_globals.net_phone, 853 &packet, IPC_GET_PACKET(call))); 855 rc = packet_translate_remote(eth_globals.net_phone, &packet, 856 IPC_GET_PACKET(call)); 857 if (rc != EOK) 858 return rc; 854 859 return eth_send_message(IPC_GET_DEVICE(call), packet, 855 860 IPC_GET_SERVICE(call)); 856 861 case NET_NIL_PACKET_SPACE: 857 ERROR_PROPAGATE(eth_packet_space_message(IPC_GET_DEVICE(call), 858 &addrlen, &prefix, &content, &suffix)); 862 rc = eth_packet_space_message(IPC_GET_DEVICE(call), &addrlen, 863 &prefix, &content, &suffix); 864 if (rc != EOK) 865 return rc; 859 866 IPC_SET_ADDR(answer, addrlen); 860 867 IPC_SET_PREFIX(answer, prefix); … … 864 871 return EOK; 865 872 case NET_NIL_ADDR: 866 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 867 ETH_LOCAL_ADDR, &address)); 873 rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_LOCAL_ADDR, 874 &address); 875 if (rc != EOK) 876 return rc; 868 877 return measured_strings_reply(address, 1); 869 878 case NET_NIL_BROADCAST_ADDR: 870 ERROR_PROPAGATE(eth_addr_message(IPC_GET_DEVICE(call), 871 ETH_BROADCAST_ADDR, &address)); 879 rc = eth_addr_message(IPC_GET_DEVICE(call), ETH_BROADCAST_ADDR, 880 &address); 881 if (rc != EOK) 882 return EOK; 872 883 return measured_strings_reply(address, 1); 873 884 case IPC_M_CONNECT_TO_ME: … … 923 934 int main(int argc, char *argv[]) 924 935 { 925 ERROR_DECLARE;936 int rc; 926 937 927 938 /* Start the module */ 928 ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));929 return EOK;939 rc = nil_module_start_standalone(nil_client_connection); 940 return rc; 930 941 } 931 942 -
uspace/srv/net/nil/eth/eth_module.c
rd70a463 rb40bfac 40 40 #include <async.h> 41 41 #include <stdio.h> 42 #include <err .h>42 #include <errno.h> 43 43 44 44 #include <ipc/ipc.h> … … 52 52 int nil_module_start_standalone(async_client_conn_t client_connection) 53 53 { 54 ERROR_DECLARE; 54 ipcarg_t phonehash; 55 int rc; 55 56 56 57 async_set_client_connection(client_connection); 57 58 int net_phone = net_connect_module(); 58 ERROR_PROPAGATE(pm_init()); 59 60 rc = pm_init(); 61 if (rc != EOK) 62 return rc; 59 63 60 ipcarg_t phonehash; 61 if (ERROR_OCCURRED(nil_initialize(net_phone)) || 62 ERROR_OCCURRED(REGISTER_ME(SERVICE_ETHERNET, &phonehash))) { 63 pm_destroy(); 64 return ERROR_CODE; 65 } 64 rc = nil_initialize(net_phone); 65 if (rc != EOK) 66 goto out; 67 68 rc = REGISTER_ME(SERVICE_ETHERNET, &phonehash); 69 if (rc != EOK) 70 goto out; 66 71 67 72 async_manager(); 68 73 74 out: 69 75 pm_destroy(); 70 return EOK;76 return rc; 71 77 } 72 78 -
uspace/srv/net/nil/nildummy/nildummy.c
rd70a463 rb40bfac 41 41 #include <stdio.h> 42 42 #include <str.h> 43 #include <err.h>44 43 #include <ipc/ipc.h> 45 44 #include <ipc/net.h> … … 82 81 int nil_initialize(int net_phone) 83 82 { 84 ERROR_DECLARE;83 int rc; 85 84 86 85 fibril_rwlock_initialize(&nildummy_globals.devices_lock); … … 91 90 nildummy_globals.net_phone = net_phone; 92 91 nildummy_globals.proto.phone = 0; 93 ERROR_CODE= nildummy_devices_initialize(&nildummy_globals.devices);92 rc = nildummy_devices_initialize(&nildummy_globals.devices); 94 93 95 94 fibril_rwlock_write_unlock(&nildummy_globals.protos_lock); 96 95 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 97 96 98 return ERROR_CODE;97 return rc; 99 98 } 100 99 … … 107 106 static void nildummy_receiver(ipc_callid_t iid, ipc_call_t *icall) 108 107 { 109 ERROR_DECLARE;110 111 108 packet_t packet; 109 int rc; 112 110 113 111 while (true) { 114 112 switch (IPC_GET_METHOD(*icall)) { 115 113 case NET_NIL_DEVICE_STATE: 116 ERROR_CODE= nil_device_state_msg_local(0,114 rc = nil_device_state_msg_local(0, 117 115 IPC_GET_DEVICE(icall), IPC_GET_STATE(icall)); 118 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);116 ipc_answer_0(iid, (ipcarg_t) rc); 119 117 break; 120 118 121 119 case NET_NIL_RECEIVED: 122 if (ERROR_NONE(packet_translate_remote(123 nildummy_globals.net_phone, &packet,124 IPC_GET_PACKET(icall)))) {125 ERROR_CODE= nil_received_msg_local(0,120 rc = packet_translate_remote(nildummy_globals.net_phone, 121 &packet, IPC_GET_PACKET(icall)); 122 if (rc == EOK) { 123 rc = nil_received_msg_local(0, 126 124 IPC_GET_DEVICE(icall), packet, 0); 127 125 } 128 ipc_answer_0(iid, (ipcarg_t) ERROR_CODE);126 ipc_answer_0(iid, (ipcarg_t) rc); 129 127 break; 130 128 … … 155 153 nildummy_device_message(device_id_t device_id, services_t service, size_t mtu) 156 154 { 157 ERROR_DECLARE;158 159 155 nildummy_device_ref device; 160 156 int index; 157 int rc; 161 158 162 159 fibril_rwlock_write_lock(&nildummy_globals.devices_lock); … … 216 213 217 214 // get hardware address 218 if (ERROR_OCCURRED(netif_get_addr_req(device->phone, device->device_id, 219 &device->addr, &device->addr_data))) { 215 rc = netif_get_addr_req(device->phone, device->device_id, &device->addr, 216 &device->addr_data); 217 if (rc != EOK) { 220 218 fibril_rwlock_write_unlock(&nildummy_globals.devices_lock); 221 219 free(device); 222 return ERROR_CODE;220 return rc; 223 221 } 224 222 … … 380 378 ipc_call_t *answer, int *answer_count) 381 379 { 382 ERROR_DECLARE;383 384 380 measured_string_ref address; 385 381 packet_t packet; … … 388 384 size_t suffix; 389 385 size_t content; 386 int rc; 390 387 391 388 *answer_count = 0; … … 399 396 400 397 case NET_NIL_SEND: 401 ERROR_PROPAGATE(packet_translate_remote( 402 nildummy_globals.net_phone, &packet, IPC_GET_PACKET(call))); 398 rc = packet_translate_remote(nildummy_globals.net_phone, 399 &packet, IPC_GET_PACKET(call)); 400 if (rc != EOK) 401 return rc; 403 402 return nildummy_send_message(IPC_GET_DEVICE(call), packet, 404 403 IPC_GET_SERVICE(call)); 405 404 406 405 case NET_NIL_PACKET_SPACE: 407 ERROR_PROPAGATE(nildummy_packet_space_message( 408 IPC_GET_DEVICE(call), &addrlen, &prefix, &content, 409 &suffix)); 406 rc = nildummy_packet_space_message(IPC_GET_DEVICE(call), 407 &addrlen, &prefix, &content, &suffix); 408 if (rc != EOK) 409 return rc; 410 410 IPC_SET_ADDR(answer, addrlen); 411 411 IPC_SET_PREFIX(answer, prefix); … … 416 416 417 417 case NET_NIL_ADDR: 418 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call), 419 &address)); 418 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address); 419 if (rc != EOK) 420 return rc; 420 421 return measured_strings_reply(address, 1); 421 422 422 423 case NET_NIL_BROADCAST_ADDR: 423 ERROR_PROPAGATE(nildummy_addr_message(IPC_GET_DEVICE(call), 424 &address)); 424 rc = nildummy_addr_message(IPC_GET_DEVICE(call), &address); 425 if (rc != EOK) 426 return rc; 425 427 return measured_strings_reply(address, 1); 426 428 … … 476 478 int main(int argc, char *argv[]) 477 479 { 478 ERROR_DECLARE;480 int rc; 479 481 480 482 /* Start the module */ 481 ERROR_PROPAGATE(nil_module_start_standalone(nil_client_connection));482 return EOK;483 rc = nil_module_start_standalone(nil_client_connection); 484 return rc; 483 485 } 484 486 -
uspace/srv/net/nil/nildummy/nildummy.h
rd70a463 rb40bfac 62 62 * @see nildummy_proto 63 63 */ 64 typedef struct nildummy_proto 64 typedef struct nildummy_proto nildummy_proto_t; 65 65 66 66 /** Type definition of the dummy nil protocol specific data pointer. … … 100 100 101 101 /** Dummy nil global data. */ 102 struct 102 struct nildummy_globals { 103 103 /** Networking module phone. */ 104 104 int net_phone; -
uspace/srv/net/nil/nildummy/nildummy_module.c
rd70a463 rb40bfac 38 38 #include <async.h> 39 39 #include <stdio.h> 40 #include <err .h>40 #include <errno.h> 41 41 42 42 #include <ipc/ipc.h> … … 52 52 int nil_module_start_standalone(async_client_conn_t client_connection) 53 53 { 54 ERROR_DECLARE; 54 ipcarg_t phonehash; 55 int rc; 55 56 56 57 async_set_client_connection(client_connection); 57 58 int net_phone = net_connect_module(); 58 ERROR_PROPAGATE(pm_init());59 59 60 ipcarg_t phonehash; 61 if (ERROR_OCCURRED(nil_initialize(net_phone)) || 62 ERROR_OCCURRED(REGISTER_ME(SERVICE_NILDUMMY, &phonehash))) { 63 pm_destroy(); 64 return ERROR_CODE; 65 } 60 rc = pm_init(); 61 if (rc != EOK) 62 return rc; 63 64 65 rc = nil_initialize(net_phone); 66 if (rc != EOK) 67 goto out; 68 69 rc = REGISTER_ME(SERVICE_NILDUMMY, &phonehash); 70 if (rc != EOK) 71 goto out; 66 72 67 73 async_manager(); 68 74 75 out: 69 76 pm_destroy(); 70 return EOK;77 return rc; 71 78 } 72 79 -
uspace/srv/net/tl/icmp/icmp.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup icmp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * ICMP module implementation. 35 * @see icmp.h 36 */ 34 * ICMP module implementation. 35 * @see icmp.h 36 */ 37 38 #include "icmp.h" 39 #include "icmp_module.h" 37 40 38 41 #include <async.h> … … 51 54 #include <byteorder.h> 52 55 #include <errno.h> 53 #include <err.h>54 56 55 57 #include <net/socket_codes.h> 56 58 #include <net/ip_protocols.h> 57 59 #include <net/inet.h> 58 59 60 #include <net/modules.h> 61 #include <net/icmp_api.h> 62 #include <net/icmp_codes.h> 63 #include <net/icmp_common.h> 64 60 65 #include <packet_client.h> 61 66 #include <packet_remote.h> 62 67 #include <net_checksum.h> 63 #include <net/icmp_api.h>64 68 #include <icmp_client.h> 65 #include <net/icmp_codes.h>66 #include <net/icmp_common.h>67 69 #include <icmp_interface.h> 68 70 #include <il_interface.h> … … 74 76 #include <icmp_header.h> 75 77 76 #include "icmp.h" 77 #include "icmp_module.h" 78 79 /** ICMP module name. 80 */ 78 /** ICMP module name. */ 81 79 #define NAME "ICMP protocol" 82 80 83 /** Default ICMP error reporting. 84 */ 81 /** Default ICMP error reporting. */ 85 82 #define NET_DEFAULT_ICMP_ERROR_REPORTING true 86 83 87 /** Default ICMP echo replying. 88 */ 84 /** Default ICMP echo replying. */ 89 85 #define NET_DEFAULT_ICMP_ECHO_REPLYING true 90 86 91 /** Original datagram length in bytes transfered to the error notification message. 87 /** Original datagram length in bytes transfered to the error notification 88 * message. 92 89 */ 93 90 #define ICMP_KEEP_LENGTH 8 94 91 95 /** Free identifier numbers pool start. 96 */ 92 /** Free identifier numbers pool start. */ 97 93 #define ICMP_FREE_IDS_START 1 98 94 99 /** Free identifier numbers pool end. 100 */ 95 /** Free identifier numbers pool end. */ 101 96 #define ICMP_FREE_IDS_END UINT16_MAX 102 97 103 98 /** Computes the ICMP datagram checksum. 104 * @param[in,out] header The ICMP datagram header. 105 * @param[in] length The total datagram length. 106 * @returns The computed checksum. 107 */ 108 #define ICMP_CHECKSUM(header, length) htons(ip_checksum((uint8_t *) (header), (length))) 109 110 /** An echo request datagrams pattern. 111 */ 112 #define ICMP_ECHO_TEXT "Hello from HelenOS." 99 * 100 * @param[in,out] header The ICMP datagram header. 101 * @param[in] length The total datagram length. 102 * @returns The computed checksum. 103 */ 104 #define ICMP_CHECKSUM(header, length) \ 105 htons(ip_checksum((uint8_t *) (header), (length))) 106 107 /** An echo request datagrams pattern. */ 108 #define ICMP_ECHO_TEXT "Hello from HelenOS." 113 109 114 110 /** Computes an ICMP reply data key. 115 * @param[in] id The message identifier. 116 * @param[in] sequence The message sequence number. 117 * @returns The computed ICMP reply data key. 118 */ 119 #define ICMP_GET_REPLY_KEY(id, sequence) (((id) << 16) | (sequence &0xFFFF)) 120 121 /** Processes the received ICMP packet. 122 * Is used as an entry point from the underlying IP module. 123 * Releases the packet on error. 124 * @param device_id The device identifier. Ignored parameter. 125 * @param[in,out] packet The received packet. 126 * @param receiver The target service. Ignored parameter. 127 * @param[in] error The packet error reporting service. Prefixes the received packet. 128 * @returns EOK on success. 129 * @returns Other error codes as defined for the icmp_process_packet() function. 130 */ 131 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error); 132 133 /** Processes the received ICMP packet. 134 * Notifies the destination socket application. 135 * @param[in,out] packet The received packet. 136 * @param[in] error The packet error reporting service. Prefixes the received packet. 137 * @returns EOK on success. 138 * @returns EINVAL if the packet is not valid. 139 * @returns EINVAL if the stored packet address is not the an_addr_t. 140 * @returns EINVAL if the packet does not contain any data. 141 * @returns NO_DATA if the packet content is shorter than the user datagram header. 142 * @returns ENOMEM if there is not enough memory left. 143 * @returns EADDRNOTAVAIL if the destination socket does not exist. 144 * @returns Other error codes as defined for the ip_client_process_packet() function. 145 */ 146 int icmp_process_packet(packet_t packet, services_t error); 147 148 /** Processes the client messages. 149 * Remembers the assigned identifier and sequence numbers. 150 * Runs until the client module disconnects. 151 * @param[in] callid The message identifier. 152 * @param[in] call The message parameters. 153 * @returns EOK. 154 * @see icmp_interface.h 155 * @see icmp_api.h 156 */ 157 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 158 159 /** Processes the generic client messages. 160 * @param[in] call The message parameters. 161 * @returns EOK on success. 162 * @returns ENOTSUP if the message is not known. 163 * @returns Other error codes as defined for the packet_translate() function. 164 * @returns Other error codes as defined for the icmp_destination_unreachable_msg() function. 165 * @returns Other error codes as defined for the icmp_source_quench_msg() function. 166 * @returns Other error codes as defined for the icmp_time_exceeded_msg() function. 167 * @returns Other error codes as defined for the icmp_parameter_problem_msg() function. 168 * @see icmp_interface.h 169 */ 170 int icmp_process_message(ipc_call_t * call); 111 * 112 * @param[in] id The message identifier. 113 * @param[in] sequence The message sequence number. 114 * @returns The computed ICMP reply data key. 115 */ 116 #define ICMP_GET_REPLY_KEY(id, sequence) \ 117 (((id) << 16) | (sequence & 0xFFFF)) 118 119 120 /** ICMP global data. */ 121 icmp_globals_t icmp_globals; 122 123 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t); 124 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t); 171 125 172 126 /** Releases the packet and returns the result. 173 * @param[in] packet The packet queue to be released. 174 * @param[in] result The result to be returned. 175 * @returns The result parameter. 176 */ 177 int icmp_release_and_return(packet_t packet, int result); 127 * 128 * @param[in] packet The packet queue to be released. 129 * @param[in] result The result to be returned. 130 * @returns The result parameter. 131 */ 132 static int icmp_release_and_return(packet_t packet, int result) 133 { 134 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 135 return result; 136 } 137 138 /** Sends the ICMP message. 139 * 140 * Sets the message type and code and computes the checksum. 141 * Error messages are sent only if allowed in the configuration. 142 * Releases the packet on errors. 143 * 144 * @param[in] type The message type. 145 * @param[in] code The message code. 146 * @param[in] packet The message packet to be sent. 147 * @param[in] header The ICMP header. 148 * @param[in] error The error service to be announced. Should be 149 * SERVICE_ICMP or zero. 150 * @param[in] ttl The time to live. 151 * @param[in] tos The type of service. 152 * @param[in] dont_fragment The value indicating whether the datagram must not 153 * be fragmented. Is used as a MTU discovery. 154 * @returns EOK on success. 155 * @returns EPERM if the error message is not allowed. 156 */ 157 static int 158 icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, 159 icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, 160 int dont_fragment) 161 { 162 int rc; 163 164 // do not send an error if disabled 165 if (error && !icmp_globals.error_reporting) 166 return icmp_release_and_return(packet, EPERM); 167 168 header->type = type; 169 header->code = code; 170 header->checksum = 0; 171 header->checksum = ICMP_CHECKSUM(header, 172 packet_get_data_length(packet)); 173 174 rc = ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, 175 dont_fragment, 0); 176 if (rc != EOK) 177 return icmp_release_and_return(packet, rc); 178 179 return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, 180 error); 181 } 182 183 /** Prepares the ICMP error packet. 184 * 185 * Truncates the original packet if longer than ICMP_KEEP_LENGTH bytes. 186 * Prefixes and returns the ICMP header. 187 * 188 * @param[in,out] packet The original packet. 189 * @returns The prefixed ICMP header. 190 * @returns NULL on errors. 191 */ 192 static icmp_header_ref icmp_prepare_packet(packet_t packet) 193 { 194 icmp_header_ref header; 195 size_t header_length; 196 size_t total_length; 197 198 total_length = packet_get_data_length(packet); 199 if (total_length <= 0) 200 return NULL; 201 202 header_length = ip_client_header_length(packet); 203 if (header_length <= 0) 204 return NULL; 205 206 // truncate if longer than 64 bits (without the IP header) 207 if ((total_length > header_length + ICMP_KEEP_LENGTH) && 208 (packet_trim(packet, 0, 209 total_length - header_length - ICMP_KEEP_LENGTH) != EOK)) { 210 return NULL; 211 } 212 213 header = PACKET_PREFIX(packet, icmp_header_t); 214 if (!header) 215 return NULL; 216 217 bzero(header, sizeof(*header)); 218 return header; 219 } 178 220 179 221 /** Requests an echo message. 180 * Sends a packet with specified parameters to the target host and waits for the reply upto the given timeout. 181 * Blocks the caller until the reply or the timeout occurs. 182 * @param[in] id The message identifier. 183 * @param[in] sequence The message sequence parameter. 184 * @param[in] size The message data length in bytes. 185 * @param[in] timeout The timeout in miliseconds. 186 * @param[in] ttl The time to live. 187 * @param[in] tos The type of service. 188 * @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery. 189 * @param[in] addr The target host address. 190 * @param[in] addrlen The torget host address length. 191 * @returns ICMP_ECHO on success. 192 * @returns ETIMEOUT if the reply has not arrived before the timeout. 193 * @returns ICMP type of the received error notification. 194 * @returns EINVAL if the addrlen parameter is less or equal to zero (<=0). 195 * @returns ENOMEM if there is not enough memory left. 196 * @returns EPARTY if there was an internal error. 197 */ 198 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen); 199 200 /** Prepares the ICMP error packet. 201 * Truncates the original packet if longer than ICMP_KEEP_LENGTH bytes. 202 * Prefixes and returns the ICMP header. 203 * @param[in,out] packet The original packet. 204 * @returns The prefixed ICMP header. 205 * @returns NULL on errors. 206 */ 207 icmp_header_ref icmp_prepare_packet(packet_t packet); 208 209 /** Sends the ICMP message. 210 * Sets the message type and code and computes the checksum. 211 * Error messages are sent only if allowed in the configuration. 212 * Releases the packet on errors. 213 * @param[in] type The message type. 214 * @param[in] code The message code. 215 * @param[in] packet The message packet to be sent. 216 * @param[in] header The ICMP header. 217 * @param[in] error The error service to be announced. Should be SERVICE_ICMP or zero (0). 218 * @param[in] ttl The time to live. 219 * @param[in] tos The type of service. 220 * @param[in] dont_fragment The value indicating whether the datagram must not be fragmented. Is used as a MTU discovery. 221 * @returns EOK on success. 222 * @returns EPERM if the error message is not allowed. 223 */ 224 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment); 225 226 /** Tries to set the pending reply result as the received message type. 227 * If the reply data is not present, the reply timed out and the other fibril 228 * is already awake. 229 * Releases the packet. 230 * @param[in] packet The received reply message. 231 * @param[in] header The ICMP message header. 232 * @param[in] type The received reply message type. 233 * @param[in] code The received reply message code. 234 * @returns EOK. 235 */ 236 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code); 237 238 /** Assigns a new identifier for the connection. 239 * Fills the echo data parameter with the assigned values. 240 * @param[in,out] echo_data The echo data to be bound. 241 * @returns Index of the inserted echo data. 242 * @returns EBADMEM if the echo_data parameter is NULL. 243 * @returns ENOTCONN if no free identifier have been found. 244 */ 245 int icmp_bind_free_id(icmp_echo_ref echo_data); 246 247 /** ICMP global data. 248 */ 249 icmp_globals_t icmp_globals; 250 251 INT_MAP_IMPLEMENT(icmp_replies, icmp_reply_t); 252 253 INT_MAP_IMPLEMENT(icmp_echo_data, icmp_echo_t); 254 255 int icmp_echo_msg(int icmp_phone, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 256 icmp_echo_ref echo_data; 257 int res; 258 259 fibril_rwlock_write_lock(&icmp_globals.lock); 260 // use the phone as the echo data index 261 echo_data = icmp_echo_data_find(&icmp_globals.echo_data, icmp_phone); 262 if(! echo_data){ 263 res = ENOENT; 264 }else{ 265 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, size, timeout, ttl, tos, dont_fragment, addr, addrlen); 266 if(echo_data->sequence_number < UINT16_MAX){ 267 ++ echo_data->sequence_number; 268 }else{ 269 echo_data->sequence_number = 0; 270 } 271 } 272 fibril_rwlock_write_unlock(&icmp_globals.lock); 273 return res; 274 } 275 276 int icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, const struct sockaddr * addr, socklen_t addrlen){ 277 ERROR_DECLARE; 278 222 * 223 * Sends a packet with specified parameters to the target host and waits for 224 * the reply upto the given timeout. 225 * Blocks the caller until the reply or the timeout occurs. 226 * 227 * @param[in] id The message identifier. 228 * @param[in] sequence The message sequence parameter. 229 * @param[in] size The message data length in bytes. 230 * @param[in] timeout The timeout in miliseconds. 231 * @param[in] ttl The time to live. 232 * @param[in] tos The type of service. 233 * @param[in] dont_fragment The value indicating whether the datagram must not 234 * be fragmented. Is used as a MTU discovery. 235 * @param[in] addr The target host address. 236 * @param[in] addrlen The torget host address length. 237 * @returns ICMP_ECHO on success. 238 * @returns ETIMEOUT if the reply has not arrived before the 239 * timeout. 240 * @returns ICMP type of the received error notification. 241 * @returns EINVAL if the addrlen parameter is less or equal to 242 * zero. 243 * @returns ENOMEM if there is not enough memory left. 244 * @returns EPARTY if there was an internal error. 245 */ 246 static int 247 icmp_echo(icmp_param_t id, icmp_param_t sequence, size_t size, 248 mseconds_t timeout, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, 249 const struct sockaddr * addr, socklen_t addrlen) 250 { 279 251 icmp_header_ref header; 280 252 packet_t packet; 281 253 size_t length; 282 uint8_t * 254 uint8_t *data; 283 255 icmp_reply_ref reply; 284 256 int reply_key; 285 int result;286 257 int index; 287 288 if(addrlen <= 0){ 258 int rc; 259 260 if (addrlen <= 0) 289 261 return EINVAL; 290 } 262 291 263 length = (size_t) addrlen; 292 264 // TODO do not ask all the time 293 ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension)); 294 packet = packet_get_4_remote(icmp_globals.net_phone, size, icmp_globals.packet_dimension.addr_len, ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, icmp_globals.packet_dimension.suffix); 295 if(! packet){ 265 rc = ip_packet_size_req(icmp_globals.ip_phone, -1, 266 &icmp_globals.packet_dimension); 267 if (rc != EOK) 268 return rc; 269 270 packet = packet_get_4_remote(icmp_globals.net_phone, size, 271 icmp_globals.packet_dimension.addr_len, 272 ICMP_HEADER_SIZE + icmp_globals.packet_dimension.prefix, 273 icmp_globals.packet_dimension.suffix); 274 if (!packet) 296 275 return ENOMEM; 297 }298 276 299 277 // prepare the requesting packet 300 278 // set the destination address 301 if(ERROR_OCCURRED(packet_set_addr(packet, NULL, (const uint8_t *) addr, length))){ 302 return icmp_release_and_return(packet, ERROR_CODE); 303 } 279 rc = packet_set_addr(packet, NULL, (const uint8_t *) addr, length); 280 if (rc != EOK) 281 return icmp_release_and_return(packet, rc); 282 304 283 // allocate space in the packet 305 284 data = (uint8_t *) packet_suffix(packet, size); 306 if (! data){285 if (!data) 307 286 return icmp_release_and_return(packet, ENOMEM); 308 } 287 309 288 // fill the data 310 289 length = 0; 311 while (size > length + sizeof(ICMP_ECHO_TEXT)){290 while (size > length + sizeof(ICMP_ECHO_TEXT)) { 312 291 memcpy(data + length, ICMP_ECHO_TEXT, sizeof(ICMP_ECHO_TEXT)); 313 292 length += sizeof(ICMP_ECHO_TEXT); 314 293 } 315 294 memcpy(data + length, ICMP_ECHO_TEXT, size - length); 295 316 296 // prefix the header 317 297 header = PACKET_PREFIX(packet, icmp_header_t); 318 if (! header){298 if (!header) 319 299 return icmp_release_and_return(packet, ENOMEM); 320 } 300 321 301 bzero(header, sizeof(*header)); 322 302 header->un.echo.identifier = id; … … 325 305 // prepare the reply structure 326 306 reply = malloc(sizeof(*reply)); 327 if (! reply){307 if (!reply) 328 308 return icmp_release_and_return(packet, ENOMEM); 329 } 309 330 310 fibril_mutex_initialize(&reply->mutex); 331 311 fibril_mutex_lock(&reply->mutex); 332 312 fibril_condvar_initialize(&reply->condvar); 333 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 313 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, 314 header->un.echo.sequence_number); 334 315 index = icmp_replies_add(&icmp_globals.replies, reply_key, reply); 335 if (index < 0){316 if (index < 0) { 336 317 free(reply); 337 318 return icmp_release_and_return(packet, index); … … 342 323 343 324 // send the request 344 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, dont_fragment); 325 icmp_send_packet(ICMP_ECHO, 0, packet, header, 0, ttl, tos, 326 dont_fragment); 345 327 346 328 // wait for the reply 347 329 // timeout in microseconds 348 if(ERROR_OCCURRED(fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, timeout * 1000))){ 349 result = ERROR_CODE; 350 }else{ 351 // read the result 352 result = reply->result; 353 } 330 rc = fibril_condvar_wait_timeout(&reply->condvar, &reply->mutex, 331 timeout * 1000); 332 if (rc == EOK) 333 rc = reply->result; 354 334 355 335 // drop the reply mutex before locking the globals again … … 359 339 // destroy the reply structure 360 340 icmp_replies_exclude_index(&icmp_globals.replies, index); 361 return result; 362 } 363 364 int icmp_destination_unreachable_msg(int icmp_phone, icmp_code_t code, icmp_param_t mtu, packet_t packet){ 341 342 return rc; 343 } 344 345 static int 346 icmp_destination_unreachable_msg_local(int icmp_phone, icmp_code_t code, 347 icmp_param_t mtu, packet_t packet) 348 { 365 349 icmp_header_ref header; 366 350 367 351 header = icmp_prepare_packet(packet); 368 if (! header){352 if (!header) 369 353 return icmp_release_and_return(packet, ENOMEM); 370 } 371 if (mtu){354 355 if (mtu) 372 356 header->un.frag.mtu = mtu; 373 } 374 return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, SERVICE_ICMP, 0, 0, 0); 375 } 376 377 int icmp_source_quench_msg(int icmp_phone, packet_t packet){ 357 358 return icmp_send_packet(ICMP_DEST_UNREACH, code, packet, header, 359 SERVICE_ICMP, 0, 0, 0); 360 } 361 362 static int icmp_source_quench_msg_local(int icmp_phone, packet_t packet) 363 { 378 364 icmp_header_ref header; 379 365 380 366 header = icmp_prepare_packet(packet); 381 if (! header){367 if (!header) 382 368 return icmp_release_and_return(packet, ENOMEM); 383 } 384 return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, SERVICE_ICMP, 0, 0, 0); 385 } 386 387 int icmp_time_exceeded_msg(int icmp_phone, icmp_code_t code, packet_t packet){ 369 370 return icmp_send_packet(ICMP_SOURCE_QUENCH, 0, packet, header, 371 SERVICE_ICMP, 0, 0, 0); 372 } 373 374 static int 375 icmp_time_exceeded_msg_local(int icmp_phone, icmp_code_t code, packet_t packet) 376 { 388 377 icmp_header_ref header; 389 378 390 379 header = icmp_prepare_packet(packet); 391 if (! header){380 if (!header) 392 381 return icmp_release_and_return(packet, ENOMEM); 393 } 394 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, SERVICE_ICMP, 0, 0, 0); 395 } 396 397 int icmp_parameter_problem_msg(int icmp_phone, icmp_code_t code, icmp_param_t pointer, packet_t packet){ 382 383 return icmp_send_packet(ICMP_TIME_EXCEEDED, code, packet, header, 384 SERVICE_ICMP, 0, 0, 0); 385 } 386 387 static int 388 icmp_parameter_problem_msg_local(int icmp_phone, icmp_code_t code, 389 icmp_param_t pointer, packet_t packet) 390 { 398 391 icmp_header_ref header; 399 392 400 393 header = icmp_prepare_packet(packet); 401 if (! header){394 if (!header) 402 395 return icmp_release_and_return(packet, ENOMEM); 403 } 396 404 397 header->un.param.pointer = pointer; 405 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, SERVICE_ICMP, 0, 0, 0); 406 } 407 408 icmp_header_ref icmp_prepare_packet(packet_t packet){ 409 icmp_header_ref header; 410 size_t header_length; 411 size_t total_length; 412 413 total_length = packet_get_data_length(packet); 414 if(total_length <= 0){ 415 return NULL; 416 } 417 header_length = ip_client_header_length(packet); 418 if(header_length <= 0){ 419 return NULL; 420 } 421 // truncate if longer than 64 bits (without the IP header) 422 if((total_length > header_length + ICMP_KEEP_LENGTH) 423 && (packet_trim(packet, 0, total_length - header_length - ICMP_KEEP_LENGTH) != EOK)){ 424 return NULL; 425 } 426 header = PACKET_PREFIX(packet, icmp_header_t); 427 if(! header){ 428 return NULL; 429 } 430 bzero(header, sizeof(*header)); 431 return header; 432 } 433 434 int icmp_send_packet(icmp_type_t type, icmp_code_t code, packet_t packet, icmp_header_ref header, services_t error, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment){ 435 ERROR_DECLARE; 436 437 // do not send an error if disabled 438 if(error && (! icmp_globals.error_reporting)){ 439 return icmp_release_and_return(packet, EPERM); 440 } 441 header->type = type; 442 header->code = code; 443 header->checksum = 0; 444 header->checksum = ICMP_CHECKSUM(header, packet_get_data_length(packet)); 445 if(ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_ICMP, ttl, tos, dont_fragment, 0))){ 446 return icmp_release_and_return(packet, ERROR_CODE); 447 } 448 return ip_send_msg(icmp_globals.ip_phone, -1, packet, SERVICE_ICMP, error); 449 } 450 451 int icmp_initialize(async_client_conn_t client_connection){ 452 ERROR_DECLARE; 453 454 measured_string_t names[] = {{str_dup("ICMP_ERROR_REPORTING"), 20}, {str_dup("ICMP_ECHO_REPLYING"), 18}}; 398 return icmp_send_packet(ICMP_PARAMETERPROB, code, packet, header, 399 SERVICE_ICMP, 0, 0, 0); 400 } 401 402 /** Initializes the ICMP module. 403 * 404 * @param[in] client_connection The client connection processing function. The 405 * module skeleton propagates its own one. 406 * @returns EOK on success. 407 * @returns ENOMEM if there is not enough memory left. 408 */ 409 int icmp_initialize(async_client_conn_t client_connection) 410 { 411 measured_string_t names[] = { 412 { 413 (char *) "ICMP_ERROR_REPORTING", 414 20 415 }, 416 { 417 (char *) "ICMP_ECHO_REPLYING", 418 18 419 } 420 }; 455 421 measured_string_ref configuration; 456 422 size_t count = sizeof(names) / sizeof(measured_string_t); 457 char * data; 423 char *data; 424 int rc; 458 425 459 426 fibril_rwlock_initialize(&icmp_globals.lock); … … 461 428 icmp_replies_initialize(&icmp_globals.replies); 462 429 icmp_echo_data_initialize(&icmp_globals.echo_data); 463 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, SERVICE_ICMP, client_connection); 464 if(icmp_globals.ip_phone < 0){ 430 431 icmp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_ICMP, 432 SERVICE_ICMP, client_connection); 433 if (icmp_globals.ip_phone < 0) { 434 fibril_rwlock_write_unlock(&icmp_globals.lock); 465 435 return icmp_globals.ip_phone; 466 436 } 467 ERROR_PROPAGATE(ip_packet_size_req(icmp_globals.ip_phone, -1, &icmp_globals.packet_dimension)); 437 438 rc = ip_packet_size_req(icmp_globals.ip_phone, -1, 439 &icmp_globals.packet_dimension); 440 if (rc != EOK) { 441 fibril_rwlock_write_unlock(&icmp_globals.lock); 442 return rc; 443 } 444 468 445 icmp_globals.packet_dimension.prefix += ICMP_HEADER_SIZE; 469 446 icmp_globals.packet_dimension.content -= ICMP_HEADER_SIZE; 470 // get configuration 447 471 448 icmp_globals.error_reporting = NET_DEFAULT_ICMP_ERROR_REPORTING; 472 449 icmp_globals.echo_replying = NET_DEFAULT_ICMP_ECHO_REPLYING; 450 451 // get configuration 473 452 configuration = &names[0]; 474 ERROR_PROPAGATE(net_get_conf_req(icmp_globals.net_phone, &configuration, count, &data)); 475 if(configuration){ 476 if(configuration[0].value){ 477 icmp_globals.error_reporting = (configuration[0].value[0] == 'y'); 453 rc = net_get_conf_req(icmp_globals.net_phone, &configuration, count, 454 &data); 455 if (rc != EOK) { 456 fibril_rwlock_write_unlock(&icmp_globals.lock); 457 return rc; 458 } 459 460 if (configuration) { 461 if (configuration[0].value) { 462 icmp_globals.error_reporting = 463 (configuration[0].value[0] == 'y'); 478 464 } 479 if(configuration[1].value){ 480 icmp_globals.echo_replying = (configuration[1].value[0] == 'y'); 465 if (configuration[1].value) { 466 icmp_globals.echo_replying = 467 (configuration[1].value[0] == 'y'); 481 468 } 482 469 net_free_settings(configuration, data); 483 470 } 471 484 472 fibril_rwlock_write_unlock(&icmp_globals.lock); 485 473 return EOK; 486 474 } 487 475 488 int icmp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, services_t error){ 489 ERROR_DECLARE; 490 491 if(ERROR_OCCURRED(icmp_process_packet(packet, error))){ 492 return icmp_release_and_return(packet, ERROR_CODE); 493 } 494 495 return EOK; 496 } 497 498 int icmp_process_packet(packet_t packet, services_t error){ 499 ERROR_DECLARE; 500 476 /** Tries to set the pending reply result as the received message type. 477 * 478 * If the reply data is not present, the reply timed out and the other fibril 479 * is already awake. 480 * Releases the packet. 481 * 482 * @param[in] packet The received reply message. 483 * @param[in] header The ICMP message header. 484 * @param[in] type The received reply message type. 485 * @param[in] code The received reply message code. 486 */ 487 static void 488 icmp_process_echo_reply(packet_t packet, icmp_header_ref header, 489 icmp_type_t type, icmp_code_t code) 490 { 491 int reply_key; 492 icmp_reply_ref reply; 493 494 // compute the reply key 495 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, 496 header->un.echo.sequence_number); 497 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 498 499 fibril_rwlock_write_lock(&icmp_globals.lock); 500 // find the pending reply 501 reply = icmp_replies_find(&icmp_globals.replies, reply_key); 502 if (reply) { 503 reply->result = type; 504 fibril_condvar_signal(&reply->condvar); 505 } 506 fibril_rwlock_write_unlock(&icmp_globals.lock); 507 } 508 509 /** Processes the received ICMP packet. 510 * 511 * Notifies the destination socket application. 512 * 513 * @param[in,out] packet The received packet. 514 * @param[in] error The packet error reporting service. Prefixes the 515 * received packet. 516 * @returns EOK on success. 517 * @returns EINVAL if the packet is not valid. 518 * @returns EINVAL if the stored packet address is not the an_addr_t. 519 * @returns EINVAL if the packet does not contain any data. 520 * @returns NO_DATA if the packet content is shorter than the user 521 * datagram header. 522 * @returns ENOMEM if there is not enough memory left. 523 * @returns EADDRNOTAVAIL if the destination socket does not exist. 524 * @returns Other error codes as defined for the 525 * ip_client_process_packet() function. 526 */ 527 static int icmp_process_packet(packet_t packet, services_t error) 528 { 501 529 size_t length; 502 uint8_t * 530 uint8_t *src; 503 531 int addrlen; 504 532 int result; 505 void * 533 void *data; 506 534 icmp_header_ref header; 507 535 icmp_type_t type; 508 536 icmp_code_t code; 509 510 if(error){ 511 switch(error){ 512 case SERVICE_ICMP: 513 // process error 514 result = icmp_client_process_packet(packet, &type, &code, NULL, NULL); 515 if(result < 0){ 516 return result; 517 } 518 length = (size_t) result; 519 // remove the error header 520 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 521 break; 522 default: 523 return ENOTSUP; 524 } 525 } 537 int rc; 538 539 switch (error) { 540 case SERVICE_NONE: 541 break; 542 case SERVICE_ICMP: 543 // process error 544 result = icmp_client_process_packet(packet, &type, &code, NULL, 545 NULL); 546 if (result < 0) 547 return result; 548 length = (size_t) result; 549 // remove the error header 550 rc = packet_trim(packet, length, 0); 551 if (rc != EOK) 552 return rc; 553 break; 554 default: 555 return ENOTSUP; 556 } 557 526 558 // get rid of the ip header 527 559 length = ip_client_header_length(packet); 528 ERROR_PROPAGATE(packet_trim(packet, length, 0)); 560 rc = packet_trim(packet, length, 0); 561 if (rc != EOK) 562 return rc; 529 563 530 564 length = packet_get_data_length(packet); 531 if (length <= 0){565 if (length <= 0) 532 566 return EINVAL; 533 } 534 if (length < ICMP_HEADER_SIZE){567 568 if (length < ICMP_HEADER_SIZE) 535 569 return EINVAL; 536 } 570 537 571 data = packet_get_data(packet); 538 if (! data){572 if (!data) 539 573 return EINVAL; 540 } 574 541 575 // get icmp header 542 576 header = (icmp_header_ref) data; 543 // checksum 544 if (header->checksum){545 while (ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO){577 578 if (header->checksum) { 579 while (ICMP_CHECKSUM(header, length) != IP_CHECKSUM_ZERO) { 546 580 // set the original message type on error notification 547 581 // type swap observed in Qemu 548 if (error){549 switch (header->type){550 551 552 582 if (error) { 583 switch (header->type) { 584 case ICMP_ECHOREPLY: 585 header->type = ICMP_ECHO; 586 continue; 553 587 } 554 588 } … … 556 590 } 557 591 } 558 switch(header->type){ 559 case ICMP_ECHOREPLY: 560 if(error){ 561 return icmp_process_echo_reply(packet, header, type, code); 562 }else{ 563 return icmp_process_echo_reply(packet, header, ICMP_ECHO, 0); 592 593 switch (header->type) { 594 case ICMP_ECHOREPLY: 595 if (error) 596 icmp_process_echo_reply(packet, header, type, code); 597 else 598 icmp_process_echo_reply(packet, header, ICMP_ECHO, 0); 599 600 return EOK; 601 602 case ICMP_ECHO: 603 if (error) { 604 icmp_process_echo_reply(packet, header, type, code); 605 return EOK; 606 } 607 608 // do not send a reply if disabled 609 if (icmp_globals.echo_replying) { 610 addrlen = packet_get_addr(packet, &src, NULL); 611 612 // set both addresses to the source one (avoids the 613 // source address deletion before setting the 614 // destination one) 615 if ((addrlen > 0) && (packet_set_addr(packet, src, src, 616 (size_t) addrlen) == EOK)) { 617 // send the reply 618 icmp_send_packet(ICMP_ECHOREPLY, 0, packet, 619 header, 0, 0, 0, 0); 620 return EOK; 564 621 } 565 case ICMP_ECHO: 566 if(error){ 567 return icmp_process_echo_reply(packet, header, type, code); 568 // do not send a reply if disabled 569 }else if(icmp_globals.echo_replying){ 570 addrlen = packet_get_addr(packet, &src, NULL); 571 if((addrlen > 0) 572 // set both addresses to the source one (avoids the source address deletion before setting the destination one) 573 && (packet_set_addr(packet, src, src, (size_t) addrlen) == EOK)){ 574 // send the reply 575 icmp_send_packet(ICMP_ECHOREPLY, 0, packet, header, 0, 0, 0, 0); 576 return EOK; 577 }else{ 578 return EINVAL; 622 623 return EINVAL; 624 } 625 626 return EPERM; 627 628 case ICMP_DEST_UNREACH: 629 case ICMP_SOURCE_QUENCH: 630 case ICMP_REDIRECT: 631 case ICMP_ALTERNATE_ADDR: 632 case ICMP_ROUTER_ADV: 633 case ICMP_ROUTER_SOL: 634 case ICMP_TIME_EXCEEDED: 635 case ICMP_PARAMETERPROB: 636 case ICMP_CONVERSION_ERROR: 637 case ICMP_REDIRECT_MOBILE: 638 case ICMP_SKIP: 639 case ICMP_PHOTURIS: 640 ip_received_error_msg(icmp_globals.ip_phone, -1, packet, 641 SERVICE_IP, SERVICE_ICMP); 642 return EOK; 643 644 default: 645 return ENOTSUP; 646 } 647 } 648 649 /** Processes the received ICMP packet. 650 * 651 * Is used as an entry point from the underlying IP module. 652 * Releases the packet on error. 653 * 654 * @param device_id The device identifier. Ignored parameter. 655 * @param[in,out] packet The received packet. 656 * @param receiver The target service. Ignored parameter. 657 * @param[in] error The packet error reporting service. Prefixes the 658 * received packet. 659 * @returns EOK on success. 660 * @returns Other error codes as defined for the 661 * icmp_process_packet() function. 662 */ 663 static int 664 icmp_received_msg_local(device_id_t device_id, packet_t packet, 665 services_t receiver, services_t error) 666 { 667 int rc; 668 669 rc = icmp_process_packet(packet, error); 670 if (rc != EOK) 671 return icmp_release_and_return(packet, rc); 672 673 return EOK; 674 } 675 676 /** Processes the generic client messages. 677 * 678 * @param[in] call The message parameters. 679 * @returns EOK on success. 680 * @returns ENOTSUP if the message is not known. 681 * @returns Other error codes as defined for the packet_translate() 682 * function. 683 * @returns Other error codes as defined for the 684 * icmp_destination_unreachable_msg_local() function. 685 * @returns Other error codes as defined for the 686 * icmp_source_quench_msg_local() function. 687 * @returns Other error codes as defined for the 688 * icmp_time_exceeded_msg_local() function. 689 * @returns Other error codes as defined for the 690 * icmp_parameter_problem_msg_local() function. 691 * 692 * @see icmp_interface.h 693 */ 694 static int icmp_process_message(ipc_call_t *call) 695 { 696 packet_t packet; 697 int rc; 698 699 switch (IPC_GET_METHOD(*call)) { 700 case NET_ICMP_DEST_UNREACH: 701 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 702 IPC_GET_PACKET(call)); 703 if (rc != EOK) 704 return rc; 705 return icmp_destination_unreachable_msg_local(0, 706 ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet); 707 case NET_ICMP_SOURCE_QUENCH: 708 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 709 IPC_GET_PACKET(call)); 710 if (rc != EOK) 711 return rc; 712 return icmp_source_quench_msg_local(0, packet); 713 case NET_ICMP_TIME_EXCEEDED: 714 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 715 IPC_GET_PACKET(call)); 716 if (rc != EOK) 717 return rc; 718 return icmp_time_exceeded_msg_local(0, ICMP_GET_CODE(call), 719 packet); 720 case NET_ICMP_PARAMETERPROB: 721 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 722 IPC_GET_PACKET(call)); 723 if (rc != EOK) 724 return rc; 725 return icmp_parameter_problem_msg_local(0, ICMP_GET_CODE(call), 726 ICMP_GET_POINTER(call), packet); 727 default: 728 return ENOTSUP; 729 } 730 } 731 732 /** Assigns a new identifier for the connection. 733 * 734 * Fills the echo data parameter with the assigned values. 735 * 736 * @param[in,out] echo_data The echo data to be bound. 737 * @returns Index of the inserted echo data. 738 * @returns EBADMEM if the echo_data parameter is NULL. 739 * @returns ENOTCONN if no free identifier have been found. 740 */ 741 static int icmp_bind_free_id(icmp_echo_ref echo_data) 742 { 743 icmp_param_t index; 744 745 if (!echo_data) 746 return EBADMEM; 747 748 // from the last used one 749 index = icmp_globals.last_used_id; 750 do { 751 index++; 752 // til the range end 753 if (index >= ICMP_FREE_IDS_END) { 754 // start from the range beginning 755 index = ICMP_FREE_IDS_START - 1; 756 do { 757 index++; 758 // til the last used one 759 if (index >= icmp_globals.last_used_id) { 760 // none found 761 return ENOTCONN; 579 762 } 580 }else{ 581 return EPERM; 582 } 583 case ICMP_DEST_UNREACH: 584 case ICMP_SOURCE_QUENCH: 585 case ICMP_REDIRECT: 586 case ICMP_ALTERNATE_ADDR: 587 case ICMP_ROUTER_ADV: 588 case ICMP_ROUTER_SOL: 589 case ICMP_TIME_EXCEEDED: 590 case ICMP_PARAMETERPROB: 591 case ICMP_CONVERSION_ERROR: 592 case ICMP_REDIRECT_MOBILE: 593 case ICMP_SKIP: 594 case ICMP_PHOTURIS: 595 ip_received_error_msg(icmp_globals.ip_phone, -1, packet, SERVICE_IP, SERVICE_ICMP); 596 return EOK; 597 default: 598 return ENOTSUP; 599 } 600 } 601 602 int icmp_process_echo_reply(packet_t packet, icmp_header_ref header, icmp_type_t type, icmp_code_t code){ 603 int reply_key; 604 icmp_reply_ref reply; 605 606 // compute the reply key 607 reply_key = ICMP_GET_REPLY_KEY(header->un.echo.identifier, header->un.echo.sequence_number); 608 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 609 // lock the globals 610 fibril_rwlock_write_lock(&icmp_globals.lock); 611 // find the pending reply 612 reply = icmp_replies_find(&icmp_globals.replies, reply_key); 613 if(reply){ 614 // set the result 615 reply->result = type; 616 // notify the waiting fibril 617 fibril_condvar_signal(&reply->condvar); 618 } 619 fibril_rwlock_write_unlock(&icmp_globals.lock); 620 return EOK; 621 } 622 623 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 624 ERROR_DECLARE; 625 626 packet_t packet; 627 628 *answer_count = 0; 629 switch(IPC_GET_METHOD(*call)){ 630 case NET_TL_RECEIVED: 631 if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 632 ERROR_CODE = icmp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_ICMP, IPC_GET_ERROR(call)); 633 } 634 return ERROR_CODE; 635 case NET_ICMP_INIT: 636 return icmp_process_client_messages(callid, * call); 637 default: 638 return icmp_process_message(call); 639 } 640 return ENOTSUP; 641 } 642 643 int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call){ 644 ERROR_DECLARE; 645 763 } while(icmp_echo_data_find(&icmp_globals.echo_data, 764 index) != NULL); 765 766 // found, break immediately 767 break; 768 } 769 } while (icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 770 771 echo_data->identifier = index; 772 echo_data->sequence_number = 0; 773 774 return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data); 775 } 776 777 /** Processes the client messages. 778 * 779 * Remembers the assigned identifier and sequence numbers. 780 * Runs until the client module disconnects. 781 * 782 * @param[in] callid The message identifier. 783 * @param[in] call The message parameters. 784 * @returns EOK. 785 * 786 * @see icmp_interface.h 787 * @see icmp_api.h 788 */ 789 static int icmp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 790 { 646 791 bool keep_on_going = true; 647 // fibril_rwlock_t lock;648 792 ipc_call_t answer; 649 793 int answer_count; 650 794 size_t length; 651 struct sockaddr * 795 struct sockaddr *addr; 652 796 ipc_callid_t data_callid; 653 797 icmp_echo_ref echo_data; 654 int r es;798 int rc = EOK; 655 799 656 800 /* … … 658 802 * - Answer the first NET_ICMP_INIT call. 659 803 */ 660 res = EOK;661 804 answer_count = 0; 662 805 663 // fibril_rwlock_initialize(&lock);664 665 806 echo_data = (icmp_echo_ref) malloc(sizeof(*echo_data)); 666 if (! echo_data){807 if (!echo_data) 667 808 return ENOMEM; 668 }669 809 670 810 // assign a new identifier 671 811 fibril_rwlock_write_lock(&icmp_globals.lock); 672 r es= icmp_bind_free_id(echo_data);812 rc = icmp_bind_free_id(echo_data); 673 813 fibril_rwlock_write_unlock(&icmp_globals.lock); 674 if (res < 0){814 if (rc < 0) { 675 815 free(echo_data); 676 return res; 677 } 678 679 while(keep_on_going){ 680 816 return rc; 817 } 818 819 while (keep_on_going) { 681 820 // answer the call 682 answer_call(callid, r es, &answer, answer_count);821 answer_call(callid, rc, &answer, answer_count); 683 822 684 823 // refresh data … … 689 828 690 829 // process the call 691 switch(IPC_GET_METHOD(call)){ 692 case IPC_M_PHONE_HUNGUP: 693 keep_on_going = false; 694 res = EHANGUP; 830 switch (IPC_GET_METHOD(call)) { 831 case IPC_M_PHONE_HUNGUP: 832 keep_on_going = false; 833 rc = EHANGUP; 834 break; 835 836 case NET_ICMP_ECHO: 837 if (!async_data_write_receive(&data_callid, &length)) { 838 rc = EINVAL; 695 839 break; 696 case NET_ICMP_ECHO: 697 // fibril_rwlock_write_lock(&lock); 698 if(! async_data_write_receive(&data_callid, &length)){ 699 res = EINVAL; 700 }else{ 701 addr = malloc(length); 702 if(! addr){ 703 res = ENOMEM; 704 }else{ 705 if(! ERROR_OCCURRED(async_data_write_finalize(data_callid, addr, length))){ 706 fibril_rwlock_write_lock(&icmp_globals.lock); 707 res = icmp_echo(echo_data->identifier, echo_data->sequence_number, ICMP_GET_SIZE(call), ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), addr, (socklen_t) length); 708 fibril_rwlock_write_unlock(&icmp_globals.lock); 709 free(addr); 710 if(echo_data->sequence_number < UINT16_MAX){ 711 ++ echo_data->sequence_number; 712 }else{ 713 echo_data->sequence_number = 0; 714 } 715 }else{ 716 res = ERROR_CODE; 717 } 718 } 719 } 720 // fibril_rwlock_write_unlock(&lock); 840 } 841 842 addr = malloc(length); 843 if (!addr) { 844 rc = ENOMEM; 721 845 break; 722 default: 723 res = icmp_process_message(&call); 846 } 847 848 rc = async_data_write_finalize(data_callid, addr, 849 length); 850 if (rc != EOK) { 851 free(addr); 852 break; 853 } 854 855 fibril_rwlock_write_lock(&icmp_globals.lock); 856 rc = icmp_echo(echo_data->identifier, 857 echo_data->sequence_number, ICMP_GET_SIZE(call), 858 ICMP_GET_TIMEOUT(call), ICMP_GET_TTL(call), 859 ICMP_GET_TOS(call), ICMP_GET_DONT_FRAGMENT(call), 860 addr, (socklen_t) length); 861 fibril_rwlock_write_unlock(&icmp_globals.lock); 862 863 free(addr); 864 865 if (echo_data->sequence_number < UINT16_MAX) 866 echo_data->sequence_number++; 867 else 868 echo_data->sequence_number = 0; 869 870 break; 871 872 default: 873 rc = icmp_process_message(&call); 724 874 } 875 725 876 } 726 877 … … 729 880 icmp_echo_data_exclude(&icmp_globals.echo_data, echo_data->identifier); 730 881 fibril_rwlock_write_unlock(&icmp_globals.lock); 731 return res; 732 } 733 734 int icmp_process_message(ipc_call_t * call){ 735 ERROR_DECLARE; 736 882 883 return rc; 884 } 885 886 /** Processes the ICMP message. 887 * 888 * @param[in] callid The message identifier. 889 * @param[in] call The message parameters. 890 * @param[out] answer The message answer parameters. 891 * @param[out] answer_count The last parameter for the actual answer in the 892 * answer parameter. 893 * @returns EOK on success. 894 * @returns ENOTSUP if the message is not known. 895 * 896 * @see icmp_interface.h 897 * @see IS_NET_ICMP_MESSAGE() 898 */ 899 int 900 icmp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 901 ipc_call_t *answer, int *answer_count) 902 { 737 903 packet_t packet; 738 739 switch(IPC_GET_METHOD(*call)){ 740 case NET_ICMP_DEST_UNREACH: 741 if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 742 ERROR_CODE = icmp_destination_unreachable_msg(0, ICMP_GET_CODE(call), ICMP_GET_MTU(call), packet); 743 } 744 return ERROR_CODE; 745 case NET_ICMP_SOURCE_QUENCH: 746 if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 747 ERROR_CODE = icmp_source_quench_msg(0, packet); 748 } 749 return ERROR_CODE; 750 case NET_ICMP_TIME_EXCEEDED: 751 if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 752 ERROR_CODE = icmp_time_exceeded_msg(0, ICMP_GET_CODE(call), packet); 753 } 754 return ERROR_CODE; 755 case NET_ICMP_PARAMETERPROB: 756 if(! ERROR_OCCURRED(packet_translate_remote(icmp_globals.net_phone, &packet, IPC_GET_PACKET(call)))){ 757 ERROR_CODE = icmp_parameter_problem_msg(0, ICMP_GET_CODE(call), ICMP_GET_POINTER(call), packet); 758 } 759 return ERROR_CODE; 760 default: 761 return ENOTSUP; 762 } 763 } 764 765 int icmp_release_and_return(packet_t packet, int result){ 766 pq_release_remote(icmp_globals.net_phone, packet_get_id(packet)); 767 return result; 768 } 769 770 int icmp_bind_free_id(icmp_echo_ref echo_data){ 771 icmp_param_t index; 772 773 if(! echo_data){ 774 return EBADMEM; 775 } 776 // from the last used one 777 index = icmp_globals.last_used_id; 778 do{ 779 ++ index; 780 // til the range end 781 if(index >= ICMP_FREE_IDS_END){ 782 // start from the range beginning 783 index = ICMP_FREE_IDS_START - 1; 784 do{ 785 ++ index; 786 // til the last used one 787 if(index >= icmp_globals.last_used_id){ 788 // none found 789 return ENOTCONN; 790 } 791 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 792 // found, break immediately 793 break; 794 } 795 }while(icmp_echo_data_find(&icmp_globals.echo_data, index) != NULL); 796 echo_data->identifier = index; 797 echo_data->sequence_number = 0; 798 return icmp_echo_data_add(&icmp_globals.echo_data, index, echo_data); 799 } 904 int rc; 905 906 *answer_count = 0; 907 switch (IPC_GET_METHOD(*call)) { 908 case NET_TL_RECEIVED: 909 rc = packet_translate_remote(icmp_globals.net_phone, &packet, 910 IPC_GET_PACKET(call)); 911 if (rc != EOK) 912 return rc; 913 return icmp_received_msg_local(IPC_GET_DEVICE(call), packet, 914 SERVICE_ICMP, IPC_GET_ERROR(call)); 915 916 case NET_ICMP_INIT: 917 return icmp_process_client_messages(callid, * call); 918 919 default: 920 return icmp_process_message(call); 921 } 922 923 return ENOTSUP; 924 } 925 800 926 801 927 /** Default thread for new connections. 802 928 * 803 * 804 * 805 * 806 */ 807 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * 929 * @param[in] iid The initial message identifier. 930 * @param[in] icall The initial message call structure. 931 * 932 */ 933 static void tl_client_connection(ipc_callid_t iid, ipc_call_t *icall) 808 934 { 809 935 /* … … 813 939 ipc_answer_0(iid, EOK); 814 940 815 while (true) {941 while (true) { 816 942 ipc_call_t answer; 817 943 int answer_count; … … 828 954 &answer_count); 829 955 830 /* End if said to either by the message or the processing result */ 831 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)) 956 /* 957 * End if told to either by the message or the processing 958 * result. 959 */ 960 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || 961 (res == EHANGUP)) 832 962 return; 833 963 … … 839 969 /** Starts the module. 840 970 * 841 * @param argc The count of the command line arguments. Ignored parameter. 842 * @param argv The command line parameters. Ignored parameter. 843 * 844 * @returns EOK on success. 845 * @returns Other error codes as defined for each specific module start function. 846 * 971 * @returns EOK on success. 972 * @returns Other error codes as defined for each specific module 973 * start function. 847 974 */ 848 975 int main(int argc, char *argv[]) 849 976 { 850 ERROR_DECLARE;977 int rc; 851 978 852 979 /* Start the module */ 853 if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection))) 854 return ERROR_CODE; 855 856 return EOK; 980 rc = tl_module_start_standalone(tl_client_connection); 981 return rc; 857 982 } 858 983 859 984 /** @} 860 985 */ 986 -
uspace/srv/net/tl/icmp/icmp.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup icmp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * ICMP module. 35 35 */ 36 36 37 #ifndef __NET_ICMP_H__38 #define __NET_ICMP_H__37 #ifndef NET_ICMP_H_ 38 #define NET_ICMP_H_ 39 39 40 40 #include <fibril_synch.h> 41 41 42 42 #include <net/icmp_codes.h> 43 #include <net/packet.h> 43 44 #include <adt/int_map.h> 44 45 #include <icmp_header.h> 45 46 46 47 /** Type definition of the ICMP reply data. 47 * 48 * @see icmp_reply 48 49 */ 49 typedef struct icmp_reply 50 typedef struct icmp_reply icmp_reply_t; 50 51 51 52 /** Type definition of the ICMP reply data pointer. 52 * 53 * @see icmp_reply 53 54 */ 54 typedef icmp_reply_t * 55 typedef icmp_reply_t *icmp_reply_ref; 55 56 56 57 /** Type definition of the ICMP global data. 57 * 58 * @see icmp_globals 58 59 */ 59 typedef struct icmp_globals 60 typedef struct icmp_globals icmp_globals_t; 60 61 61 62 /** Pending replies map. 62 * Maps message identifiers to the pending replies. 63 * Sending fibril waits for its associated reply event. 64 * Receiving fibril sets the associated reply with the return value and signals the event. 63 * 64 * Maps message identifiers to the pending replies. 65 * Sending fibril waits for its associated reply event. 66 * Receiving fibril sets the associated reply with the return value and signals 67 * the event. 65 68 */ 66 69 INT_MAP_DECLARE(icmp_replies, icmp_reply_t); 67 70 68 71 /** Echo specific data map. 69 * The identifier is used in the future semi-remote calls instead of the ICMP phone. 72 * 73 * The identifier is used in the future semi-remote calls instead of the ICMP 74 * phone. 70 75 */ 71 76 INT_MAP_DECLARE(icmp_echo_data, icmp_echo_t); 72 77 73 /** ICMP reply data. 74 */ 75 struct icmp_reply{ 76 /** Reply result. 77 */ 78 /** ICMP reply data. */ 79 struct icmp_reply { 80 /** Reply result. */ 78 81 int result; 79 /** Safety lock. 80 */ 82 /** Safety lock. */ 81 83 fibril_mutex_t mutex; 82 /** Received or timeouted reply signaling. 83 */ 84 /** Received or timeouted reply signaling. */ 84 85 fibril_condvar_t condvar; 85 86 }; 86 87 87 /** ICMP global data. 88 */ 89 struct icmp_globals{ 90 /** IP module phone. 91 */ 88 /** ICMP global data. */ 89 struct icmp_globals { 90 /** IP module phone. */ 92 91 int ip_phone; 93 /** Packet dimension. 94 */ 92 /** Packet dimension. */ 95 93 packet_dimension_t packet_dimension; 96 /** Networking module phone. 97 */ 94 /** Networking module phone. */ 98 95 int net_phone; 99 /** Indicates whether ICMP error reporting is enabled. 100 */ 96 /** Indicates whether ICMP error reporting is enabled. */ 101 97 int error_reporting; 102 /** Indicates whether ICMP echo replying (ping) is enabled. 103 */ 98 /** Indicates whether ICMP echo replying (ping) is enabled. */ 104 99 int echo_replying; 105 /** The last used identifier number. 106 */ 100 /** The last used identifier number. */ 107 101 icmp_param_t last_used_id; 108 /** The budled modules assigned echo specific data. 109 */ 102 /** The budled modules assigned echo specific data. */ 110 103 icmp_echo_data_t echo_data; 111 /** Echo timeout locks. 112 */ 104 /** Echo timeout locks. */ 113 105 icmp_replies_t replies; 114 /** Safety lock. 115 */ 106 /** Safety lock. */ 116 107 fibril_rwlock_t lock; 117 108 }; … … 121 112 /** @} 122 113 */ 123 -
uspace/srv/net/tl/icmp/icmp_module.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup icmp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 36 * 37 * 34 * ICMP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 38 38 */ 39 40 #include "icmp.h" 41 #include "icmp_module.h" 39 42 40 43 #include <async.h> 41 44 #include <stdio.h> 42 #include <err .h>45 #include <errno.h> 43 46 #include <ipc/ipc.h> 44 47 #include <ipc/services.h> … … 47 50 #include <net/packet.h> 48 51 #include <net_interface.h> 52 49 53 #include <tl_local.h> 50 54 51 #include "icmp.h" 52 #include "icmp_module.h" 55 /** ICMP module global data. */ 56 extern icmp_globals_t icmp_globals; 53 57 54 /** ICMP module global data. 55 */ 56 extern icmp_globals_t icmp_globals; 57 58 /** Starts the ICMP module. 59 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop. 60 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 61 * @returns EOK on successful module termination. 62 * @returns Other error codes as defined for the arp_initialize() function. 63 * @returns Other error codes as defined for the REGISTER_ME() macro function. 64 */ 65 int tl_module_start_standalone(async_client_conn_t client_connection){ 66 ERROR_DECLARE; 67 58 int tl_module_start_standalone(async_client_conn_t client_connection) 59 { 68 60 ipcarg_t phonehash; 61 int rc; 69 62 70 63 async_set_client_connection(client_connection); 71 64 icmp_globals.net_phone = net_connect_module(); 72 if (icmp_globals.net_phone < 0){65 if (icmp_globals.net_phone < 0) 73 66 return icmp_globals.net_phone; 74 } 75 ERROR_PROPAGATE(pm_init()); 76 if(ERROR_OCCURRED(icmp_initialize(client_connection)) 77 || ERROR_OCCURRED(REGISTER_ME(SERVICE_ICMP, &phonehash))){ 78 pm_destroy(); 79 return ERROR_CODE; 80 } 67 68 rc = pm_init(); 69 if (rc != EOK) 70 return rc; 71 72 rc = icmp_initialize(client_connection); 73 if (rc != EOK) 74 goto out; 75 76 rc = REGISTER_ME(SERVICE_ICMP, &phonehash); 77 if (rc != EOK) 78 goto out; 81 79 82 80 async_manager(); 83 81 82 out: 84 83 pm_destroy(); 85 return EOK;84 return rc; 86 85 } 87 86 88 /** Processes the ICMP message. 89 * @param[in] callid The message identifier. 90 * @param[in] call The message parameters. 91 * @param[out] answer The message answer parameters. 92 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 93 * @returns EOK on success. 94 * @returns Other error codes as defined for the icmp_message() function. 95 */ 96 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 87 int 88 tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 89 ipc_call_t *answer, int *answer_count) 90 { 97 91 return icmp_message_standalone(callid, call, answer, answer_count); 98 92 } -
uspace/srv/net/tl/icmp/icmp_module.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup icmp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * ICMP module functions. 35 * The functions are used as ICMP module entry points. 36 36 */ 37 37 38 #ifndef __NET_ICMP_MODULE_H__39 #define __NET_ICMP_MODULE_H__38 #ifndef NET_ICMP_MODULE_H_ 39 #define NET_ICMP_MODULE_H_ 40 40 41 41 #include <async.h> 42 42 #include <ipc/ipc.h> 43 43 44 /** Initializes the ICMP module. 45 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 46 * @returns EOK on success. 47 * @returns ENOMEM if there is not enough memory left. 48 */ 49 int icmp_initialize(async_client_conn_t client_connection); 50 51 /** Processes the ICMP message. 52 * @param[in] callid The message identifier. 53 * @param[in] call The message parameters. 54 * @param[out] answer The message answer parameters. 55 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 56 * @returns EOK on success. 57 * @returns ENOTSUP if the message is not known. 58 * @see icmp_interface.h 59 * @see IS_NET_ICMP_MESSAGE() 60 */ 61 int icmp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 44 extern int icmp_initialize(async_client_conn_t); 45 extern int icmp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 62 47 63 48 #endif -
uspace/srv/net/tl/tcp/tcp.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * TCP module implementation. 35 * @see tcp.h 36 36 */ 37 38 #include "tcp.h" 39 #include "tcp_header.h" 40 #include "tcp_module.h" 37 41 38 42 #include <assert.h> … … 43 47 #include <stdio.h> 44 48 #include <errno.h> 45 #include <err.h>46 49 47 50 #include <ipc/ipc.h> … … 72 75 #include <tl_interface.h> 73 76 74 #include "tcp.h"75 #include "tcp_header.h"76 #include "tcp_module.h"77 78 77 /** TCP module name. */ 79 78 #define NAME "TCP protocol" … … 110 109 111 110 /** Returns a value indicating whether the value is in the interval respecting 112 * 111 * the possible overflow. 113 112 * 114 * The high end and/or the value may overflow, be lower than the low value. 115 * @param[in] lower The last value before the interval. 116 * @param[in] value The value to be checked. 117 * @param[in] higher_equal The last value in the interval. 113 * The high end and/or the value may overflow, be lower than the low value. 114 * 115 * @param[in] lower The last value before the interval. 116 * @param[in] value The value to be checked. 117 * @param[in] higher_equal The last value in the interval. 118 118 */ 119 119 #define IS_IN_INTERVAL_OVERFLOW(lower, value, higher_equal) \ … … 165 165 }; 166 166 167 /** Releases the packet and returns the result. 168 * @param[in] packet The packet queue to be released. 169 * @param[in] result The result to be returned. 170 * @return The result parameter. 171 */ 172 int tcp_release_and_return(packet_t packet, int result); 173 174 void tcp_prepare_operation_header(socket_core_ref socket, 175 tcp_socket_data_ref socket_data, tcp_header_ref header, int synchronize, 176 int finalize); 177 int tcp_prepare_timeout(int (*timeout_function)(void *tcp_timeout_t), 178 socket_core_ref socket, tcp_socket_data_ref socket_data, 179 size_t sequence_number, tcp_socket_state_t state, suseconds_t timeout, 180 int globals_read_only); 181 void tcp_free_socket_data(socket_core_ref socket); 182 183 int tcp_timeout(void *data); 184 185 int tcp_release_after_timeout(void *data); 186 187 int tcp_process_packet(device_id_t device_id, packet_t packet, 188 services_t error); 189 int tcp_connect_core(socket_core_ref socket, socket_cores_ref local_sockets, 190 struct sockaddr *addr, socklen_t addrlen); 191 int tcp_queue_prepare_packet(socket_core_ref socket, 192 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length); 193 int tcp_queue_packet(socket_core_ref socket, tcp_socket_data_ref socket_data, 194 packet_t packet, size_t data_length); 195 packet_t tcp_get_packets_to_send(socket_core_ref socket, 196 tcp_socket_data_ref socket_data); 197 void tcp_send_packets(device_id_t device_id, packet_t packet); 198 199 void tcp_process_acknowledgement(socket_core_ref socket, 200 tcp_socket_data_ref socket_data, tcp_header_ref header); 201 packet_t tcp_send_prepare_packet(socket_core_ref socket, 202 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 203 size_t sequence_number); 204 packet_t tcp_prepare_copy(socket_core_ref socket, 205 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length, 206 size_t sequence_number); 207 void tcp_retransmit_packet(socket_core_ref socket, 208 tcp_socket_data_ref socket_data, size_t sequence_number); 209 int tcp_create_notification_packet(packet_t * packet, socket_core_ref socket, 210 tcp_socket_data_ref socket_data, int synchronize, int finalize); 211 void tcp_refresh_socket_data(tcp_socket_data_ref socket_data); 212 213 void tcp_initialize_socket_data(tcp_socket_data_ref socket_data); 214 215 int tcp_process_listen(socket_core_ref listening_socket, 216 tcp_socket_data_ref listening_socket_data, tcp_header_ref header, 217 packet_t packet, struct sockaddr *src, struct sockaddr *dest, 218 size_t addrlen); 219 int tcp_process_syn_sent(socket_core_ref socket, 220 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 221 int tcp_process_syn_received(socket_core_ref socket, 222 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet); 223 int tcp_process_established(socket_core_ref socket, 224 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet, 225 int fragments, size_t total_length); 226 int tcp_queue_received_packet(socket_core_ref socket, 227 tcp_socket_data_ref socket_data, packet_t packet, int fragments, 228 size_t total_length); 229 230 int tcp_received_msg(device_id_t device_id, packet_t packet, 231 services_t receiver, services_t error); 232 int tcp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 233 234 int tcp_listen_message(socket_cores_ref local_sockets, int socket_id, 235 int backlog); 236 int tcp_connect_message(socket_cores_ref local_sockets, int socket_id, 237 struct sockaddr *addr, socklen_t addrlen); 238 int tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, 239 int flags, size_t * addrlen); 240 int tcp_send_message(socket_cores_ref local_sockets, int socket_id, 241 int fragments, size_t * data_fragment_size, int flags); 242 int tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 243 int new_socket_id, size_t * data_fragment_size, size_t * addrlen); 244 int tcp_close_message(socket_cores_ref local_sockets, int socket_id); 167 static int tcp_release_and_return(packet_t, int); 168 static void tcp_prepare_operation_header(socket_core_ref, tcp_socket_data_ref, 169 tcp_header_ref, int synchronize, int); 170 static int tcp_prepare_timeout(int (*)(void *), socket_core_ref, 171 tcp_socket_data_ref, size_t, tcp_socket_state_t, suseconds_t, int); 172 static void tcp_free_socket_data(socket_core_ref); 173 174 static int tcp_timeout(void *); 175 176 static int tcp_release_after_timeout(void *); 177 178 static int tcp_process_packet(device_id_t, packet_t, services_t); 179 static int tcp_connect_core(socket_core_ref, socket_cores_ref, 180 struct sockaddr *, socklen_t); 181 static int tcp_queue_prepare_packet(socket_core_ref, tcp_socket_data_ref, 182 packet_t, size_t); 183 static int tcp_queue_packet(socket_core_ref, tcp_socket_data_ref, packet_t, 184 size_t); 185 static packet_t tcp_get_packets_to_send(socket_core_ref, tcp_socket_data_ref); 186 static void tcp_send_packets(device_id_t, packet_t); 187 188 static void tcp_process_acknowledgement(socket_core_ref, tcp_socket_data_ref, 189 tcp_header_ref); 190 static packet_t tcp_send_prepare_packet(socket_core_ref, tcp_socket_data_ref, 191 packet_t, size_t, size_t); 192 static packet_t tcp_prepare_copy(socket_core_ref, tcp_socket_data_ref, packet_t, 193 size_t, size_t); 194 /* static */ void tcp_retransmit_packet(socket_core_ref, tcp_socket_data_ref, 195 size_t); 196 static int tcp_create_notification_packet(packet_t *, socket_core_ref, 197 tcp_socket_data_ref, int, int); 198 static void tcp_refresh_socket_data(tcp_socket_data_ref); 199 200 static void tcp_initialize_socket_data(tcp_socket_data_ref); 201 202 static int tcp_process_listen(socket_core_ref, tcp_socket_data_ref, 203 tcp_header_ref, packet_t, struct sockaddr *, struct sockaddr *, size_t); 204 static int tcp_process_syn_sent(socket_core_ref, tcp_socket_data_ref, 205 tcp_header_ref, packet_t); 206 static int tcp_process_syn_received(socket_core_ref, tcp_socket_data_ref, 207 tcp_header_ref, packet_t); 208 static int tcp_process_established(socket_core_ref, tcp_socket_data_ref, 209 tcp_header_ref, packet_t, int, size_t); 210 static int tcp_queue_received_packet(socket_core_ref, tcp_socket_data_ref, 211 packet_t, int, size_t); 212 213 static int tcp_received_msg(device_id_t, packet_t, services_t, services_t); 214 static int tcp_process_client_messages(ipc_callid_t, ipc_call_t); 215 216 static int tcp_listen_message(socket_cores_ref, int, int); 217 static int tcp_connect_message(socket_cores_ref, int, struct sockaddr *, 218 socklen_t); 219 static int tcp_recvfrom_message(socket_cores_ref, int, int, size_t *); 220 static int tcp_send_message(socket_cores_ref, int, int, size_t *, int); 221 static int tcp_accept_message(socket_cores_ref, int, int, size_t *, size_t *); 222 static int tcp_close_message(socket_cores_ref, int); 245 223 246 224 /** TCP global data. */ 247 225 tcp_globals_t tcp_globals; 248 226 227 /** Initializes the TCP module. 228 * 229 * @param[in] client_connection The client connection processing function. The 230 * module skeleton propagates its own one. 231 * @returns EOK on success. 232 * @returns ENOMEM if there is not enough memory left. 233 */ 249 234 int tcp_initialize(async_client_conn_t client_connection) 250 235 { 251 ERROR_DECLARE;236 int rc; 252 237 253 238 assert(client_connection); … … 260 245 tcp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_TCP, 261 246 SERVICE_TCP, client_connection); 262 if (tcp_globals.ip_phone < 0) 247 if (tcp_globals.ip_phone < 0) { 248 fibril_rwlock_write_unlock(&tcp_globals.lock); 263 249 return tcp_globals.ip_phone; 250 } 264 251 265 ERROR_PROPAGATE(socket_ports_initialize(&tcp_globals.sockets)); 266 if (ERROR_OCCURRED(packet_dimensions_initialize( 267 &tcp_globals.dimensions))) { 252 rc = socket_ports_initialize(&tcp_globals.sockets); 253 if (rc != EOK) 254 goto out; 255 256 rc = packet_dimensions_initialize(&tcp_globals.dimensions); 257 if (rc != EOK) { 268 258 socket_ports_destroy(&tcp_globals.sockets); 269 return ERROR_CODE;259 goto out; 270 260 } 271 261 272 262 tcp_globals.last_used_port = TCP_FREE_PORTS_START - 1; 263 264 out: 273 265 fibril_rwlock_write_unlock(&tcp_globals.lock); 274 275 return EOK; 266 return rc; 276 267 } 277 268 … … 280 271 services_t error) 281 272 { 282 ERROR_DECLARE;273 int rc; 283 274 284 275 if (receiver != SERVICE_TCP) … … 286 277 287 278 fibril_rwlock_write_lock(&tcp_globals.lock); 288 if (ERROR_OCCURRED(tcp_process_packet(device_id, packet, error))) 279 rc = tcp_process_packet(device_id, packet, error); 280 if (rc != EOK) 289 281 fibril_rwlock_write_unlock(&tcp_globals.lock); 290 282 291 printf("receive %d \n", ERROR_CODE);292 293 return ERROR_CODE;283 printf("receive %d \n", rc); 284 285 return rc; 294 286 } 295 287 296 288 int tcp_process_packet(device_id_t device_id, packet_t packet, services_t error) 297 289 { 298 ERROR_DECLARE;299 300 290 size_t length; 301 291 size_t offset; … … 313 303 struct sockaddr *dest; 314 304 size_t addrlen; 315 316 if (error) { 317 switch (error) { 318 case SERVICE_ICMP: 319 // process error 320 result = icmp_client_process_packet(packet, &type, 321 &code, NULL, NULL); 322 if (result < 0) 323 return tcp_release_and_return(packet, result); 324 325 length = (size_t) result; 326 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) { 327 return tcp_release_and_return(packet, 328 ERROR_CODE); 329 } 330 break; 331 332 default: 333 return tcp_release_and_return(packet, ENOTSUP); 334 } 305 int rc; 306 307 switch (error) { 308 case SERVICE_NONE: 309 break; 310 case SERVICE_ICMP: 311 // process error 312 result = icmp_client_process_packet(packet, &type, &code, NULL, 313 NULL); 314 if (result < 0) 315 return tcp_release_and_return(packet, result); 316 317 length = (size_t) result; 318 rc = packet_trim(packet, length, 0); 319 if (rc != EOK) 320 return tcp_release_and_return(packet, rc); 321 break; 322 default: 323 return tcp_release_and_return(packet, ENOTSUP); 335 324 } 336 325 … … 350 339 351 340 // trim all but TCP header 352 if (ERROR_OCCURRED(packet_trim(packet, offset, 0))) 353 return tcp_release_and_return(packet, ERROR_CODE); 341 rc = packet_trim(packet, offset, 0); 342 if (rc != EOK) 343 return tcp_release_and_return(packet, rc); 354 344 355 345 // get tcp header … … 367 357 addrlen = (size_t) result; 368 358 369 if (ERROR_OCCURRED(tl_set_address_port(src, addrlen,370 ntohs(header->source_port))))371 return tcp_release_and_return(packet, ERROR_CODE);359 rc = tl_set_address_port(src, addrlen, ntohs(header->source_port)); 360 if (rc != EOK) 361 return tcp_release_and_return(packet, rc); 372 362 373 363 // find the destination socket … … 379 369 ntohs(header->destination_port), SOCKET_MAP_KEY_LISTENING, 380 370 0); 381 if (!socket) {382 if (tl_prepare_icmp_packet(tcp_globals.net_phone,383 tcp_globals.icmp_phone, packet, error) == EOK) {384 icmp_destination_unreachable_msg(385 tcp_globals.icmp_phone, ICMP_PORT_UNREACH,386 387 388 389 390 } 371 } 372 if (!socket) { 373 if (tl_prepare_icmp_packet(tcp_globals.net_phone, 374 tcp_globals.icmp_phone, packet, error) == EOK) { 375 icmp_destination_unreachable_msg(tcp_globals.icmp_phone, 376 ICMP_PORT_UNREACH, 0, packet); 377 } 378 return EADDRNOTAVAIL; 379 } 380 391 381 printf("socket id %d\n", socket->socket_id); 392 382 socket_data = (tcp_socket_data_ref) socket->specific_data; … … 402 392 total_length = 0; 403 393 do { 404 ++fragments;394 fragments++; 405 395 length = packet_get_data_length(next_packet); 406 396 if (length <= 0) … … 421 411 422 412 if (error) 423 goto error;413 goto has_error_service; 424 414 425 415 if (socket_data->state == TCP_SOCKET_LISTEN) { 426 427 416 if (socket_data->pseudo_header) { 428 417 free(socket_data->pseudo_header); … … 431 420 } 432 421 433 if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_TCP, src, 434 addrlen, dest, addrlen, total_length, 435 &socket_data->pseudo_header, &socket_data->headerlen))) { 422 rc = ip_client_get_pseudo_header(IPPROTO_TCP, src, addrlen, 423 dest, addrlen, total_length, &socket_data->pseudo_header, 424 &socket_data->headerlen); 425 if (rc != EOK) { 436 426 fibril_rwlock_write_unlock(socket_data->local_lock); 437 return tcp_release_and_return(packet, ERROR_CODE); 438 } 439 440 } else if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length( 441 socket_data->pseudo_header, socket_data->headerlen, 442 total_length))) { 443 fibril_rwlock_write_unlock(socket_data->local_lock); 444 return tcp_release_and_return(packet, ERROR_CODE); 427 return tcp_release_and_return(packet, rc); 428 } 429 } else { 430 rc = ip_client_set_pseudo_header_data_length( 431 socket_data->pseudo_header, socket_data->headerlen, 432 total_length); 433 if (rc != EOK) { 434 fibril_rwlock_write_unlock(socket_data->local_lock); 435 return tcp_release_and_return(packet, rc); 436 } 445 437 } 446 438 … … 452 444 fibril_rwlock_write_unlock(socket_data->local_lock); 453 445 454 if (ERROR_NONE(tl_prepare_icmp_packet(tcp_globals.net_phone, 455 tcp_globals.icmp_phone, packet, error))) { 446 rc = tl_prepare_icmp_packet(tcp_globals.net_phone, 447 tcp_globals.icmp_phone, packet, error); 448 if (rc == EOK) { 456 449 // checksum error ICMP 457 450 icmp_parameter_problem_msg(tcp_globals.icmp_phone, … … 464 457 } 465 458 466 error:459 has_error_service: 467 460 fibril_rwlock_read_unlock(&tcp_globals.lock); 468 461 … … 470 463 switch (socket_data->state) { 471 464 case TCP_SOCKET_LISTEN: 472 ERROR_CODE = tcp_process_listen(socket, socket_data, header,473 packet,src, dest, addrlen);465 rc = tcp_process_listen(socket, socket_data, header, packet, 466 src, dest, addrlen); 474 467 break; 475 468 case TCP_SOCKET_SYN_RECEIVED: 476 ERROR_CODE = tcp_process_syn_received(socket, socket_data,477 header,packet);469 rc = tcp_process_syn_received(socket, socket_data, header, 470 packet); 478 471 break; 479 472 case TCP_SOCKET_SYN_SENT: 480 ERROR_CODE = tcp_process_syn_sent(socket, socket_data, header, 481 packet); 473 rc = tcp_process_syn_sent(socket, socket_data, header, packet); 482 474 break; 483 475 case TCP_SOCKET_FIN_WAIT_1: … … 490 482 // ack releasing the socket gets processed later 491 483 case TCP_SOCKET_ESTABLISHED: 492 ERROR_CODE = tcp_process_established(socket, socket_data,493 header,packet, fragments, total_length);484 rc = tcp_process_established(socket, socket_data, header, 485 packet, fragments, total_length); 494 486 break; 495 487 default: … … 497 489 } 498 490 499 if (ERROR_CODE != EOK) { 500 printf("process %d\n", ERROR_CODE); 491 if (rc != EOK) { 501 492 fibril_rwlock_write_unlock(socket_data->local_lock); 493 printf("process %d\n", rc); 502 494 } 503 495 … … 507 499 int 508 500 tcp_process_established(socket_core_ref socket, tcp_socket_data_ref socket_data, 509 tcp_header_ref header, packet_t packet, int fragments, 510 size_t total_length) 511 { 512 ERROR_DECLARE; 513 501 tcp_header_ref header, packet_t packet, int fragments, size_t total_length) 502 { 514 503 packet_t next_packet; 515 504 packet_t tmp_packet; … … 520 509 size_t offset; 521 510 uint32_t new_sequence_number; 511 int rc; 522 512 523 513 assert(socket); … … 560 550 } 561 551 562 if ((offset > 0) && (ERROR_OCCURRED(packet_trim(packet, 563 offset, 0)))) 564 return tcp_release_and_return(packet, ERROR_CODE); 552 if (offset > 0) { 553 rc = packet_trim(packet, offset, 0); 554 if (rc != EOK) 555 return tcp_release_and_return(packet, rc); 556 } 565 557 566 558 assert(new_sequence_number == socket_data->next_incoming); … … 594 586 if (length <= offset) 595 587 next_packet = pq_next(next_packet); 596 else if (ERROR_OCCURRED(packet_trim(next_packet, 0, 597 length - offset))) 598 return tcp_release_and_return(packet, 599 ERROR_CODE); 588 else { 589 rc = packet_trim(next_packet, 0, 590 length - offset)); 591 if (rc != EOK) 592 return tcp_release_and_return(packet, 593 rc); 594 } 600 595 offset -= length; 601 596 total_length -= length - offset; … … 622 617 // remove the header 623 618 total_length -= TCP_HEADER_LENGTH(header); 624 if (ERROR_OCCURRED(packet_trim(packet,625 TCP_HEADER_LENGTH(header), 0)))626 return tcp_release_and_return(packet, ERROR_CODE);619 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); 620 if (rc != EOK) 621 return tcp_release_and_return(packet, rc); 627 622 628 623 if (total_length) { 629 ERROR_PROPAGATE(tcp_queue_received_packet(socket, 630 socket_data, packet, fragments, total_length)); 624 rc = tcp_queue_received_packet(socket, socket_data, 625 packet, fragments, total_length); 626 if (rc != EOK) 627 return rc; 631 628 } else { 632 629 total_length = 1; … … 636 633 packet = socket_data->incoming; 637 634 while (packet) { 638 639 if (ERROR_OCCURRED(pq_get_order(socket_data->incoming, 640 &order, NULL))) { 635 rc = pq_get_order(socket_data->incoming, &order, NULL); 636 if (rc != EOK) { 641 637 // remove the corrupted packet 642 638 next_packet = pq_detach(packet); … … 675 671 socket_data->next_incoming) { 676 672 // queue received data 677 ERROR_PROPAGATE( 678 tcp_queue_received_packet(socket, 673 rc = tcp_queue_received_packet(socket, 679 674 socket_data, packet, 1, 680 packet_get_data_length(packet))); 675 packet_get_data_length(packet)); 676 if (rc != EOK) 677 return rc; 681 678 socket_data->next_incoming = 682 679 new_sequence_number; … … 684 681 continue; 685 682 // at least partly following data? 686 } else if (IS_IN_INTERVAL_OVERFLOW(687 sequence_number, socket_data->next_incoming,688 new_sequence_number)) {683 } 684 if (IS_IN_INTERVAL_OVERFLOW(sequence_number, 685 socket_data->next_incoming, new_sequence_number)) { 689 686 if (socket_data->next_incoming < 690 687 new_sequence_number) { … … 696 693 new_sequence_number; 697 694 } 698 if (ERROR_NONE(packet_trim(packet,699 length, 0))) {695 rc = packet_trim(packet,length, 0); 696 if (rc == EOK) { 700 697 // queue received data 701 ERROR_PROPAGATE( 702 tcp_queue_received_packet( 698 rc = tcp_queue_received_packet( 703 699 socket, socket_data, packet, 704 700 1, packet_get_data_length( 705 packet))); 701 packet)); 702 if (rc != EOK) 703 return rc; 706 704 socket_data->next_incoming = 707 705 new_sequence_number; … … 728 726 // remove the header 729 727 total_length -= TCP_HEADER_LENGTH(header); 730 if (ERROR_OCCURRED(packet_trim(packet,731 TCP_HEADER_LENGTH(header), 0)))732 return tcp_release_and_return(packet, ERROR_CODE);728 rc = packet_trim(packet, TCP_HEADER_LENGTH(header), 0); 729 if (rc != EOK) 730 return tcp_release_and_return(packet, rc); 733 731 734 732 next_packet = pq_detach(packet); 735 733 length = packet_get_data_length(packet); 736 if (ERROR_OCCURRED(pq_add(&socket_data->incoming, packet, 737 new_sequence_number, length))) { 734 rc = pq_add(&socket_data->incoming, packet, new_sequence_number, 735 length); 736 if (rc != EOK) { 738 737 // remove the corrupted packets 739 738 pq_release_remote(tcp_globals.net_phone, … … 746 745 tmp_packet = pq_detach(next_packet); 747 746 length = packet_get_data_length(next_packet); 748 if (ERROR_OCCURRED(pq_set_order(next_packet, 749 new_sequence_number, length)) || 750 ERROR_OCCURRED(pq_insert_after(packet, 751 next_packet))) { 747 748 rc = pq_set_order(next_packet, 749 new_sequence_number, length); 750 if (rc != EOK) { 751 pq_release_remote(tcp_globals.net_phone, 752 packet_get_id(next_packet)); 753 } 754 rc = pq_insert_after(packet, next_packet); 755 if (rc != EOK) { 752 756 pq_release_remote(tcp_globals.net_phone, 753 757 packet_get_id(next_packet)); … … 781 785 if (!packet) { 782 786 // create the notification packet 783 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, 784 socket_data, 0, 0)); 785 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, 786 packet, 1)); 787 rc = tcp_create_notification_packet(&packet, socket, 788 socket_data, 0, 0); 789 if (rc != EOK) 790 return rc; 791 rc = tcp_queue_prepare_packet(socket, socket_data, packet, 1); 792 if (rc != EOK) 793 return rc; 787 794 packet = tcp_send_prepare_packet(socket, socket_data, packet, 1, 788 795 socket_data->last_outgoing + 1); … … 802 809 size_t total_length) 803 810 { 804 ERROR_DECLARE;805 806 811 packet_dimension_ref packet_dimension; 812 int rc; 807 813 808 814 assert(socket); … … 814 820 815 821 // queue the received packet 816 if (ERROR_OCCURRED(dyn_fifo_push(&socket->received, 817 packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) || 818 ERROR_OCCURRED(tl_get_ip_packet_dimension(tcp_globals.ip_phone, 819 &tcp_globals.dimensions, socket_data->device_id, 820 &packet_dimension))) { 821 return tcp_release_and_return(packet, ERROR_CODE); 822 } 822 rc = dyn_fifo_push(&socket->received, packet_get_id(packet), 823 SOCKET_MAX_RECEIVED_SIZE); 824 if (rc != EOK) 825 return tcp_release_and_return(packet, rc); 826 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 827 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 828 if (rc != EOK) 829 return tcp_release_and_return(packet, rc); 823 830 824 831 // decrease the window size … … 839 846 tcp_header_ref header, packet_t packet) 840 847 { 841 ERROR_DECLARE;842 843 848 packet_t next_packet; 849 int rc; 844 850 845 851 assert(socket); … … 863 869 } 864 870 // trim if longer than the header 865 if ((packet_get_data_length(packet) > sizeof(*header)) && 866 ERROR_OCCURRED(packet_trim(packet, 0, 867 packet_get_data_length(packet) - sizeof(*header)))) { 868 return tcp_release_and_return(packet, ERROR_CODE); 871 if (packet_get_data_length(packet) > sizeof(*header)) { 872 rc = packet_trim(packet, 0, 873 packet_get_data_length(packet) - sizeof(*header)); 874 if (rc != EOK) 875 return tcp_release_and_return(packet, rc); 869 876 } 870 877 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); … … 895 902 size_t addrlen) 896 903 { 897 ERROR_DECLARE;898 899 904 packet_t next_packet; 900 905 socket_core_ref socket; … … 903 908 int listening_socket_id = listening_socket->socket_id; 904 909 int listening_port = listening_socket->port; 910 int rc; 905 911 906 912 assert(listening_socket); … … 932 938 memcpy(socket_data->addr, src, socket_data->addrlen); 933 939 socket_data->dest_port = ntohs(header->source_port); 934 if (ERROR_OCCURRED(tl_set_address_port(socket_data->addr, 935 socket_data->addrlen, socket_data->dest_port))) { 940 rc = tl_set_address_port(socket_data->addr, socket_data->addrlen, 941 socket_data->dest_port); 942 if (rc != EOK) { 936 943 free(socket_data->addr); 937 944 free(socket_data); 938 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 939 return ERROR_CODE; 945 return tcp_release_and_return(packet, rc); 940 946 } 941 947 942 948 // create a socket 943 949 socket_id = -1; 944 if (ERROR_OCCURRED(socket_create(socket_data->local_sockets, 945 listening_socket->phone, socket_data, &socket_id))) { 950 rc = socket_create(socket_data->local_sockets, listening_socket->phone, 951 socket_data, &socket_id); 952 if (rc != EOK) { 946 953 free(socket_data->addr); 947 954 free(socket_data); 948 return tcp_release_and_return(packet, ERROR_CODE);955 return tcp_release_and_return(packet, rc); 949 956 } 950 957 … … 961 968 listening_socket = socket_port_find(&tcp_globals.sockets, 962 969 listening_port, SOCKET_MAP_KEY_LISTENING, 0); 963 if ( (!listening_socket)||970 if (!listening_socket || 964 971 (listening_socket->socket_id != listening_socket_id)) { 965 972 fibril_rwlock_write_unlock(&tcp_globals.lock); … … 983 990 assert(socket_data); 984 991 985 ERROR_CODE = socket_port_add(&tcp_globals.sockets, listening_port,986 socket,(const char *) socket_data->addr, socket_data->addrlen);992 rc = socket_port_add(&tcp_globals.sockets, listening_port, socket, 993 (const char *) socket_data->addr, socket_data->addrlen); 987 994 assert(socket == socket_port_find(&tcp_globals.sockets, listening_port, 988 995 (const char *) socket_data->addr, socket_data->addrlen)); 989 996 990 // ERROR_CODE= socket_bind_free_port(&tcp_globals.sockets, socket,997 // rc = socket_bind_free_port(&tcp_globals.sockets, socket, 991 998 // TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 992 999 // tcp_globals.last_used_port); 993 1000 // tcp_globals.last_used_port = socket->port; 994 1001 fibril_rwlock_write_unlock(&tcp_globals.lock); 995 if ( ERROR_CODE!= EOK) {1002 if (rc != EOK) { 996 1003 socket_destroy(tcp_globals.net_phone, socket->socket_id, 997 1004 socket_data->local_sockets, &tcp_globals.sockets, 998 1005 tcp_free_socket_data); 999 return tcp_release_and_return(packet, ERROR_CODE);1006 return tcp_release_and_return(packet, rc); 1000 1007 } 1001 1008 … … 1011 1018 1012 1019 // trim if longer than the header 1013 if ((packet_get_data_length(packet) > sizeof(*header)) && 1014 ERROR_OCCURRED(packet_trim(packet, 0, 1015 packet_get_data_length(packet) - sizeof(*header)))) { 1020 if (packet_get_data_length(packet) > sizeof(*header)) { 1021 rc = packet_trim(packet, 0, 1022 packet_get_data_length(packet) - sizeof(*header)); 1023 if (rc != EOK) { 1024 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1025 socket_data->local_sockets, &tcp_globals.sockets, 1026 tcp_free_socket_data); 1027 return tcp_release_and_return(packet, rc); 1028 } 1029 } 1030 1031 tcp_prepare_operation_header(socket, socket_data, header, 1, 0); 1032 1033 rc = tcp_queue_packet(socket, socket_data, packet, 1); 1034 if (rc != EOK) { 1016 1035 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1017 1036 socket_data->local_sockets, &tcp_globals.sockets, 1018 1037 tcp_free_socket_data); 1019 return tcp_release_and_return(packet, ERROR_CODE); 1020 } 1021 1022 tcp_prepare_operation_header(socket, socket_data, header, 1, 0); 1023 1024 if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1))) { 1025 socket_destroy(tcp_globals.net_phone, socket->socket_id, 1026 socket_data->local_sockets, &tcp_globals.sockets, 1027 tcp_free_socket_data); 1028 return ERROR_CODE; 1038 return rc; 1029 1039 } 1030 1040 … … 1050 1060 tcp_socket_data_ref socket_data, tcp_header_ref header, packet_t packet) 1051 1061 { 1052 ERROR_DECLARE;1053 1054 1062 socket_core_ref listening_socket; 1055 1063 tcp_socket_data_ref listening_socket_data; 1064 int rc; 1056 1065 1057 1066 assert(socket); … … 1078 1087 1079 1088 // queue the received packet 1080 if (ERROR_NONE(dyn_fifo_push(&listening_socket->accepted, 1081 (-1 * socket->socket_id), 1082 listening_socket_data->backlog))) { 1083 1089 rc = dyn_fifo_push(&listening_socket->accepted, 1090 (-1 * socket->socket_id), listening_socket_data->backlog); 1091 if (rc == EOK) { 1084 1092 // notify the destination socket 1085 1093 async_msg_5(socket->phone, NET_SOCKET_ACCEPTED, … … 1096 1104 1097 1105 // create the notification packet 1098 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, 1099 socket_data, 0, 1)); 1106 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 1107 if (rc != EOK) 1108 return rc; 1100 1109 1101 1110 // send the packet 1102 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 1111 rc = tcp_queue_packet(socket, socket_data, packet, 1); 1112 if (rc != EOK) 1113 return rc; 1103 1114 1104 1115 // flush packets … … 1191 1202 if (number == socket_data->expected) { 1192 1203 // increase the counter 1193 ++socket_data->expected_count;1204 socket_data->expected_count++; 1194 1205 if (socket_data->expected_count == TCP_FAST_RETRANSMIT_COUNT) { 1195 1206 socket_data->expected_count = 1; … … 1200 1211 } 1201 1212 1202 int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 1203 ipc_call_t * answer, int *answer_count) 1204 { 1205 ERROR_DECLARE; 1206 1213 /** Processes the TCP message. 1214 * 1215 * @param[in] callid The message identifier. 1216 * @param[in] call The message parameters. 1217 * @param[out] answer The message answer parameters. 1218 * @param[out] answer_count The last parameter for the actual answer in the 1219 * answer parameter. 1220 * @returns EOK on success. 1221 * @returns ENOTSUP if the message is not known. 1222 * 1223 * @see tcp_interface.h 1224 * @see IS_NET_TCP_MESSAGE() 1225 */ 1226 int 1227 tcp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 1228 ipc_call_t *answer, int *answer_count) 1229 { 1207 1230 packet_t packet; 1231 int rc; 1208 1232 1209 1233 assert(call); … … 1214 1238 switch (IPC_GET_METHOD(*call)) { 1215 1239 case NET_TL_RECEIVED: 1216 //fibril_rwlock_read_lock(&tcp_globals.lock); 1217 if (ERROR_NONE(packet_translate_remote(tcp_globals.net_phone, 1218 &packet, IPC_GET_PACKET(call)))) { 1219 ERROR_CODE = tcp_received_msg(IPC_GET_DEVICE(call), 1220 packet, SERVICE_TCP, IPC_GET_ERROR(call)); 1221 } 1222 //fibril_rwlock_read_unlock(&tcp_globals.lock); 1223 return ERROR_CODE; 1224 1240 // fibril_rwlock_read_lock(&tcp_globals.lock); 1241 rc = packet_translate_remote(tcp_globals.net_phone, &packet, 1242 IPC_GET_PACKET(call)); 1243 if (rc != EOK) { 1244 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1245 return rc; 1246 } 1247 rc = tcp_received_msg(IPC_GET_DEVICE(call), packet, SERVICE_TCP, 1248 IPC_GET_ERROR(call)); 1249 // fibril_rwlock_read_unlock(&tcp_globals.lock); 1250 return rc; 1225 1251 case IPC_M_CONNECT_TO_ME: 1226 1252 return tcp_process_client_messages(callid, *call); … … 1521 1547 socket = socket_port_find(&tcp_globals.sockets, timeout->port, 1522 1548 timeout->key, timeout->key_length); 1523 if (! (socket && (socket->socket_id == timeout->socket_id)))1549 if (!socket || (socket->socket_id != timeout->socket_id)) 1524 1550 goto out; 1525 1551 … … 1532 1558 if (timeout->sequence_number) { 1533 1559 // increase the timeout counter; 1534 ++socket_data->timeout_count;1560 socket_data->timeout_count++; 1535 1561 if (socket_data->timeout_count == TCP_MAX_TIMEOUTS) { 1536 1562 // TODO release as connection lost … … 1667 1693 struct sockaddr *addr, socklen_t addrlen) 1668 1694 { 1669 ERROR_DECLARE;1670 1671 1695 socket_core_ref socket; 1696 int rc; 1672 1697 1673 1698 assert(local_sockets); … … 1680 1705 return ENOTSOCK; 1681 1706 1682 if (ERROR_OCCURRED(tcp_connect_core(socket, local_sockets, addr,1683 addrlen))) {1707 rc = tcp_connect_core(socket, local_sockets, addr, addrlen); 1708 if (rc != EOK) { 1684 1709 tcp_free_socket_data(socket); 1685 1710 // unbind if bound … … 1690 1715 } 1691 1716 } 1692 return ERROR_CODE;1717 return rc; 1693 1718 } 1694 1719 … … 1697 1722 struct sockaddr *addr, socklen_t addrlen) 1698 1723 { 1699 ERROR_DECLARE;1700 1701 1724 tcp_socket_data_ref socket_data; 1702 1725 packet_t packet; 1726 int rc; 1703 1727 1704 1728 assert(socket); … … 1716 1740 1717 1741 // get the destination port 1718 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, 1719 &socket_data->dest_port)); 1742 rc = tl_get_address_port(addr, addrlen, &socket_data->dest_port); 1743 if (rc != EOK) 1744 return rc; 1745 1720 1746 if (socket->port <= 0) { 1721 1747 // try to find a free port 1722 ERROR_PROPAGATE(socket_bind_free_port(&tcp_globals.sockets, 1723 socket, TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 1724 tcp_globals.last_used_port)); 1748 rc = socket_bind_free_port(&tcp_globals.sockets, socket, 1749 TCP_FREE_PORTS_START, TCP_FREE_PORTS_END, 1750 tcp_globals.last_used_port); 1751 if (rc != EOK) 1752 return rc; 1725 1753 // set the next port as the search starting port number 1726 1754 tcp_globals.last_used_port = socket->port; 1727 1755 } 1728 1756 1729 ERROR_PROPAGATE(ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP,1757 rc = ip_get_route_req(tcp_globals.ip_phone, IPPROTO_TCP, 1730 1758 addr, addrlen, &socket_data->device_id, 1731 &socket_data->pseudo_header, &socket_data->headerlen)); 1759 &socket_data->pseudo_header, &socket_data->headerlen); 1760 if (rc != EOK) 1761 return rc; 1732 1762 1733 1763 // create the notification packet 1734 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, 1735 socket_data, 1, 0)); 1764 rc = tcp_create_notification_packet(&packet, socket, socket_data, 1, 0); 1765 if (rc != EOK) 1766 return rc; 1736 1767 1737 1768 // unlock the globals and wait for an operation … … 1741 1772 socket_data->addrlen = addrlen; 1742 1773 // send the packet 1743 if (ERROR_OCCURRED(tcp_queue_packet(socket, socket_data, packet, 1)) || 1744 ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1745 0, TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false))) { 1746 1774 1775 if (((rc = tcp_queue_packet(socket, socket_data, packet, 1)) != EOK) || 1776 ((rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 0, 1777 TCP_SOCKET_INITIAL, NET_DEFAULT_TCP_INITIAL_TIMEOUT, false)) != 1778 EOK)) { 1747 1779 socket_data->addr = NULL; 1748 1780 socket_data->addrlen = 0; 1749 1781 fibril_rwlock_write_lock(&tcp_globals.lock); 1750 1751 1782 } else { 1752 1753 1783 packet = tcp_get_packets_to_send(socket, socket_data); 1754 1784 if (packet) { … … 1762 1792 fibril_condvar_wait(&socket_data->operation.condvar, 1763 1793 &socket_data->operation.mutex); 1764 ERROR_CODE= socket_data->operation.result;1765 if ( ERROR_CODE!= EOK) {1794 rc = socket_data->operation.result; 1795 if (rc != EOK) { 1766 1796 socket_data->addr = NULL; 1767 1797 socket_data->addrlen = 0; … … 1770 1800 socket_data->addr = NULL; 1771 1801 socket_data->addrlen = 0; 1772 ERROR_CODE= EINTR;1802 rc = EINTR; 1773 1803 } 1774 1804 } … … 1777 1807 1778 1808 // return the result 1779 return ERROR_CODE;1809 return rc; 1780 1810 } 1781 1811 … … 1784 1814 tcp_socket_data_ref socket_data, packet_t packet, size_t data_length) 1785 1815 { 1786 ERROR_DECLARE;1787 1788 1816 tcp_header_ref header; 1817 int rc; 1789 1818 1790 1819 assert(socket); … … 1801 1830 header->sequence_number = htonl(socket_data->next_outgoing); 1802 1831 1803 if (ERROR_OCCURRED(packet_set_addr(packet, NULL, 1804 (uint8_t *) socket_data->addr, socket_data->addrlen))) 1832 rc = packet_set_addr(packet, NULL, (uint8_t *) socket_data->addr, 1833 socket_data->addrlen); 1834 if (rc != EOK) 1805 1835 return tcp_release_and_return(packet, EINVAL); 1806 1836 … … 1816 1846 packet_t packet, size_t data_length) 1817 1847 { 1818 ERROR_DECLARE;1848 int rc; 1819 1849 1820 1850 assert(socket); … … 1822 1852 assert(socket->specific_data == socket_data); 1823 1853 1824 ERROR_PROPAGATE(tcp_queue_prepare_packet(socket, socket_data, packet, 1825 data_length)); 1826 1827 if (ERROR_OCCURRED(pq_add(&socket_data->outgoing, packet, 1828 socket_data->next_outgoing, data_length))) 1829 return tcp_release_and_return(packet, ERROR_CODE); 1854 rc = tcp_queue_prepare_packet(socket, socket_data, packet, data_length); 1855 if (rc != EOK) 1856 return rc; 1857 1858 rc = pq_add(&socket_data->outgoing, packet, socket_data->next_outgoing, 1859 data_length); 1860 if (rc != EOK) 1861 return tcp_release_and_return(packet, rc); 1830 1862 1831 1863 socket_data->next_outgoing += data_length; … … 1836 1868 tcp_get_packets_to_send(socket_core_ref socket, tcp_socket_data_ref socket_data) 1837 1869 { 1838 ERROR_DECLARE;1839 1840 1870 packet_t packet; 1841 1871 packet_t copy; … … 1843 1873 packet_t previous = NULL; 1844 1874 size_t data_length; 1875 int rc; 1845 1876 1846 1877 assert(socket); … … 1867 1898 if (!sending) { 1868 1899 sending = copy; 1869 } else if (ERROR_OCCURRED(pq_insert_after(previous, copy))) { 1870 pq_release_remote(tcp_globals.net_phone, 1871 packet_get_id(copy)); 1872 return sending; 1900 } else { 1901 rc = pq_insert_after(previous, copy); 1902 if (rc != EOK) { 1903 pq_release_remote(tcp_globals.net_phone, 1904 packet_get_id(copy)); 1905 return sending; 1906 } 1873 1907 } 1874 1908 … … 1876 1910 packet = pq_next(packet); 1877 1911 // overflow occurred ? 1878 if ( (!packet)&&1912 if (!packet && 1879 1913 (socket_data->last_outgoing > socket_data->next_outgoing)) { 1880 1914 printf("gpts overflow\n"); … … 1892 1926 packet_t packet, size_t data_length, size_t sequence_number) 1893 1927 { 1894 ERROR_DECLARE;1895 1896 1928 tcp_header_ref header; 1897 1929 uint32_t checksum; 1930 int rc; 1898 1931 1899 1932 assert(socket); … … 1902 1935 1903 1936 // adjust the pseudo header 1904 if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length(1905 socket_data-> pseudo_header, socket_data->headerlen,1906 packet_get_data_length(packet)))) {1937 rc = ip_client_set_pseudo_header_data_length(socket_data->pseudo_header, 1938 socket_data->headerlen, packet_get_data_length(packet)); 1939 if (rc != EOK) { 1907 1940 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1908 1941 return NULL; … … 1929 1962 checksum = compute_checksum(0, socket_data->pseudo_header, 1930 1963 socket_data->headerlen); 1931 checksum = compute_checksum(checksum, (uint8_t *) packet_get_data(packet), 1964 checksum = compute_checksum(checksum, 1965 (uint8_t *) packet_get_data(packet), 1932 1966 packet_get_data_length(packet)); 1933 1967 header->checksum = htons(flip_checksum(compact_checksum(checksum))); 1934 1968 1935 1969 // prepare the packet 1936 if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 1937 0, 0)) || ERROR_OCCURRED(tcp_prepare_timeout(tcp_timeout, socket, 1938 socket_data, sequence_number, socket_data->state, 1939 socket_data->timeout, true))) { 1970 rc = ip_client_prepare_packet(packet, IPPROTO_TCP, 0, 0, 0, 0); 1971 if (rc != EOK) { 1972 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1973 return NULL; 1974 } 1975 rc = tcp_prepare_timeout(tcp_timeout, socket, socket_data, 1976 sequence_number, socket_data->state, socket_data->timeout, true); 1977 if (rc != EOK) { 1940 1978 pq_release_remote(tcp_globals.net_phone, packet_get_id(packet)); 1941 1979 return NULL; … … 2044 2082 int 2045 2083 tcp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 2046 size_t * addrlen) 2047 { 2048 ERROR_DECLARE; 2049 2084 size_t *addrlen) 2085 { 2050 2086 socket_core_ref socket; 2051 2087 tcp_socket_data_ref socket_data; … … 2053 2089 packet_t packet; 2054 2090 size_t length; 2091 int rc; 2055 2092 2056 2093 assert(local_sockets); … … 2074 2111 // send the source address if desired 2075 2112 if (addrlen) { 2076 ERROR_PROPAGATE(data_reply(socket_data->addr, 2077 socket_data->addrlen)); 2113 rc = data_reply(socket_data->addr, socket_data->addrlen); 2114 if (rc != EOK) 2115 return rc; 2078 2116 *addrlen = socket_data->addrlen; 2079 2117 } … … 2084 2122 return NO_DATA; 2085 2123 2086 ERROR_PROPAGATE(packet_translate_remote(tcp_globals.net_phone, &packet, 2087 packet_id)); 2124 rc = packet_translate_remote(tcp_globals.net_phone, &packet, packet_id); 2125 if (rc != EOK) 2126 return rc; 2088 2127 2089 2128 // reply the packets 2090 ERROR_PROPAGATE(socket_reply_packets(packet, &length)); 2129 rc = socket_reply_packets(packet, &length); 2130 if (rc != EOK) 2131 return rc; 2091 2132 2092 2133 // release the packet … … 2099 2140 int 2100 2141 tcp_send_message(socket_cores_ref local_sockets, int socket_id, int fragments, 2101 size_t * data_fragment_size, int flags) 2102 { 2103 ERROR_DECLARE; 2104 2142 size_t *data_fragment_size, int flags) 2143 { 2105 2144 socket_core_ref socket; 2106 2145 tcp_socket_data_ref socket_data; … … 2111 2150 int index; 2112 2151 int result; 2152 int rc; 2113 2153 2114 2154 assert(local_sockets); … … 2131 2171 return ENOTCONN; 2132 2172 2133 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2134 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension)); 2173 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2174 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 2175 if (rc != EOK) 2176 return rc; 2135 2177 2136 2178 *data_fragment_size = … … 2138 2180 packet_dimension->content : socket_data->data_fragment_size); 2139 2181 2140 for (index = 0; index < fragments; ++index) {2182 for (index = 0; index < fragments; index++) { 2141 2183 // read the data fragment 2142 2184 result = tl_socket_read_packet_data(tcp_globals.net_phone, … … 2153 2195 2154 2196 tcp_prepare_operation_header(socket, socket_data, header, 0, 0); 2155 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 2156 0)); 2197 rc = tcp_queue_packet(socket, socket_data, packet, 0); 2198 if (rc != EOK) 2199 return rc; 2157 2200 } 2158 2201 … … 2173 2216 tcp_close_message(socket_cores_ref local_sockets, int socket_id) 2174 2217 { 2175 ERROR_DECLARE;2176 2177 2218 socket_core_ref socket; 2178 2219 tcp_socket_data_ref socket_data; 2179 2220 packet_t packet; 2221 int rc; 2180 2222 2181 2223 // find the socket … … 2202 2244 default: 2203 2245 // just destroy 2204 if (ERROR_NONE(socket_destroy(tcp_globals.net_phone, socket_id,2246 rc = socket_destroy(tcp_globals.net_phone, socket_id, 2205 2247 local_sockets, &tcp_globals.sockets, 2206 tcp_free_socket_data))) { 2248 tcp_free_socket_data); 2249 if (rc == EOK) { 2207 2250 fibril_rwlock_write_unlock(socket_data->local_lock); 2208 2251 fibril_rwlock_write_unlock(&tcp_globals.lock); 2209 2252 } 2210 return ERROR_CODE;2253 return rc; 2211 2254 } 2212 2255 … … 2215 2258 2216 2259 // create the notification packet 2217 ERROR_PROPAGATE(tcp_create_notification_packet(&packet, socket, 2218 socket_data, 0, 1)); 2260 rc = tcp_create_notification_packet(&packet, socket, socket_data, 0, 1); 2261 if (rc != EOK) 2262 return rc; 2219 2263 2220 2264 // send the packet 2221 ERROR_PROPAGATE(tcp_queue_packet(socket, socket_data, packet, 1)); 2265 rc = tcp_queue_packet(socket, socket_data, packet, 1); 2266 if (rc != EOK) 2267 return rc; 2222 2268 2223 2269 // flush packets … … 2235 2281 2236 2282 int 2237 tcp_create_notification_packet(packet_t * 2283 tcp_create_notification_packet(packet_t *packet, socket_core_ref socket, 2238 2284 tcp_socket_data_ref socket_data, int synchronize, int finalize) 2239 2285 { 2240 ERROR_DECLARE;2241 2242 2286 packet_dimension_ref packet_dimension; 2243 2287 tcp_header_ref header; 2288 int rc; 2244 2289 2245 2290 assert(packet); 2246 2291 2247 2292 // get the device packet dimension 2248 ERROR_PROPAGATE(tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2249 &tcp_globals.dimensions, socket_data->device_id, 2250 &packet_dimension)); 2293 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2294 &tcp_globals.dimensions, socket_data->device_id, &packet_dimension); 2295 if (rc != EOK) 2296 return rc; 2251 2297 2252 2298 // get a new packet … … 2271 2317 int 2272 2318 tcp_accept_message(socket_cores_ref local_sockets, int socket_id, 2273 int new_socket_id, size_t * data_fragment_size, size_t * addrlen) 2274 { 2275 ERROR_DECLARE; 2276 2319 int new_socket_id, size_t *data_fragment_size, size_t *addrlen) 2320 { 2277 2321 socket_core_ref accepted; 2278 2322 socket_core_ref socket; 2279 2323 tcp_socket_data_ref socket_data; 2280 2324 packet_dimension_ref packet_dimension; 2325 int rc; 2281 2326 2282 2327 assert(local_sockets); … … 2312 2357 // TODO can it be in another state? 2313 2358 if (socket_data->state == TCP_SOCKET_ESTABLISHED) { 2314 ERROR_PROPAGATE(data_reply(socket_data->addr, 2315 socket_data->addrlen)); 2316 ERROR_PROPAGATE(tl_get_ip_packet_dimension( 2317 tcp_globals.ip_phone, &tcp_globals.dimensions, 2318 socket_data->device_id, &packet_dimension)); 2359 rc = data_reply(socket_data->addr, 2360 socket_data->addrlen); 2361 if (rc != EOK) 2362 return rc; 2363 rc = tl_get_ip_packet_dimension(tcp_globals.ip_phone, 2364 &tcp_globals.dimensions, socket_data->device_id, 2365 &packet_dimension); 2366 if (rc != EOK) 2367 return rc; 2319 2368 *addrlen = socket_data->addrlen; 2320 2369 … … 2326 2375 2327 2376 if (new_socket_id > 0) { 2328 ERROR_PROPAGATE(socket_cores_update( 2329 local_sockets, accepted->socket_id, 2330 new_socket_id)); 2377 rc = socket_cores_update(local_sockets, 2378 accepted->socket_id, new_socket_id); 2379 if (rc != EOK) 2380 return rc; 2331 2381 accepted->socket_id = new_socket_id; 2332 2382 } … … 2373 2423 } 2374 2424 2425 /** Releases the packet and returns the result. 2426 * 2427 * @param[in] packet The packet queue to be released. 2428 * @param[in] result The result to be returned. 2429 * @return The result parameter. 2430 */ 2375 2431 int tcp_release_and_return(packet_t packet, int result) 2376 2432 { … … 2381 2437 /** Default thread for new connections. 2382 2438 * 2383 * @param[in] iidThe initial message identifier.2384 * @param[in] icallThe initial message call structure.2439 * @param[in] iid The initial message identifier. 2440 * @param[in] icall The initial message call structure. 2385 2441 * 2386 2442 */ … … 2397 2453 int answer_count; 2398 2454 2399 /* 2400 Clear the answer structure 2401 */ 2455 /* Clear the answer structure */ 2402 2456 refresh_answer(&answer, &answer_count); 2403 2457 2404 /* 2405 Fetch the next message 2406 */ 2458 /* Fetch the next message */ 2407 2459 ipc_call_t call; 2408 2460 ipc_callid_t callid = async_get_call(&call); 2409 2461 2410 /* 2411 Process the message 2412 */ 2462 /* Process the message */ 2413 2463 int res = tl_module_message_standalone(callid, &call, &answer, 2414 2464 &answer_count); 2415 2465 2416 2466 /* 2417 End if said to either by the message or the processing result 2467 * End if told to either by the message or the processing 2468 * result. 2418 2469 */ 2419 2470 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 2430 2481 /** Starts the module. 2431 2482 * 2432 * @param argc The count of the command line arguments. Ignored parameter. 2433 * @param argv The command line parameters. Ignored parameter. 2434 * 2435 * @returns EOK on success. 2436 * @returns Other error codes as defined for each specific module start function. 2437 * 2483 * @returns EOK on success. 2484 * @returns Other error codes as defined for each specific module 2485 * start function. 2438 2486 */ 2439 2487 int 2440 2488 main(int argc, char *argv[]) 2441 2489 { 2442 ERROR_DECLARE; 2443 2444 /* 2445 Start the module 2446 */ 2447 if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection))) 2448 return ERROR_CODE; 2449 2450 return EOK; 2490 int rc; 2491 2492 rc = tl_module_start_standalone(tl_client_connection); 2493 return rc; 2451 2494 } 2452 2495 -
uspace/srv/net/tl/tcp/tcp.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 */ 36 37 #ifndef __NET_TCP_H__38 #define __NET_TCP_H__34 * TCP module. 35 */ 36 37 #ifndef NET_TCP_H_ 38 #define NET_TCP_H_ 39 39 40 40 #include <fibril_synch.h> … … 46 46 47 47 /** Type definition of the TCP global data. 48 * 49 */ 50 typedef struct tcp_globals 48 * @see tcp_globals 49 */ 50 typedef struct tcp_globals tcp_globals_t; 51 51 52 52 /** Type definition of the TCP socket specific data. 53 * 54 */ 55 typedef struct tcp_socket_data 53 * @see tcp_socket_data 54 */ 55 typedef struct tcp_socket_data tcp_socket_data_t; 56 56 57 57 /** Type definition of the TCP socket specific data pointer. 58 * 59 */ 60 typedef tcp_socket_data_t * 58 * @see tcp_socket_data 59 */ 60 typedef tcp_socket_data_t *tcp_socket_data_ref; 61 61 62 62 /** Type definition of the TCP operation data. 63 * 64 */ 65 typedef struct tcp_operation 63 * @see tcp_operation 64 */ 65 typedef struct tcp_operation tcp_operation_t; 66 66 67 67 /** Type definition of the TCP operation data pointer. 68 * 69 */ 70 typedef tcp_operation_t * 68 * @see tcp_operation 69 */ 70 typedef tcp_operation_t *tcp_operation_ref; 71 71 72 72 /** TCP socket state type definition. 73 * @see tcp_socket_state 74 */ 75 typedef enum tcp_socket_state tcp_socket_state_t; 76 77 /** TCP socket state. 78 */ 79 enum tcp_socket_state{ 73 * @see tcp_socket_state 74 */ 75 typedef enum tcp_socket_state tcp_socket_state_t; 76 77 /** TCP socket state. */ 78 enum tcp_socket_state { 80 79 /** Initial. 81 * Not connected or bound. 80 * 81 * Not connected or bound. 82 82 */ 83 83 TCP_SOCKET_INITIAL, 84 84 85 /** Listening. 85 * Awaiting a connection request from another TCP layer. 86 * When SYN is received a new bound socket in the TCP_SOCKET_SYN_RECEIVED state should be created. 86 * 87 * Awaiting a connection request from another TCP layer. 88 * When SYN is received a new bound socket in the 89 * TCP_SOCKET_SYN_RECEIVED state should be created. 87 90 */ 88 91 TCP_SOCKET_LISTEN, 92 89 93 /** Connecting issued. 90 * A~SYN has been sent, and TCP is awaiting the response SYN. 91 * Should continue to the TCP_SOCKET_ESTABLISHED state. 94 * 95 * A SYN has been sent, and TCP is awaiting the response SYN. 96 * Should continue to the TCP_SOCKET_ESTABLISHED state. 92 97 */ 93 98 TCP_SOCKET_SYN_SENT, 99 94 100 /** Connecting received. 95 * A~SYN has been received, a~SYN has been sent, and TCP is awaiting an ACK. 96 * Should continue to the TCP_SOCKET_ESTABLISHED state. 101 * 102 * A SYN has been received, a SYN has been sent, and TCP is awaiting an 103 * ACK. Should continue to the TCP_SOCKET_ESTABLISHED state. 97 104 */ 98 105 TCP_SOCKET_SYN_RECEIVED, 106 99 107 /** Connected. 100 * The three-way handshake has been completed. 108 * 109 * The three-way handshake has been completed. 101 110 */ 102 111 TCP_SOCKET_ESTABLISHED, 112 103 113 /** Closing started. 104 * The local application has issued a~CLOSE. 105 * TCP has sent a~FIN, and is awaiting an ACK or a~FIN. 106 * Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is received. 107 * Should continue to the TCP_SOCKET_CLOSING state when a~FIN is received. 114 * 115 * The local application has issued a CLOSE. 116 * TCP has sent a FIN, and is awaiting an ACK or a FIN. 117 * Should continue to the TCP_SOCKET_FIN_WAIT_2 state when an ACK is 118 * received. 119 * Should continue to the TCP_SOCKET_CLOSING state when a FIN is 120 * received. 108 121 */ 109 122 TCP_SOCKET_FIN_WAIT_1, 123 110 124 /** Closing confirmed. 111 * A~FIN has been sent, and an ACK received. 112 * TCP is awaiting a~FIN from the remote TCP layer. 113 * Should continue to the TCP_SOCKET_CLOSING state. 125 * 126 * A FIN has been sent, and an ACK received. 127 * TCP is awaiting a~FIN from the remote TCP layer. 128 * Should continue to the TCP_SOCKET_CLOSING state. 114 129 */ 115 130 TCP_SOCKET_FIN_WAIT_2, 131 116 132 /** Closing. 117 * A FIN has been sent, a FIN has been received, and an ACK has been sent. 118 * TCP is awaiting an ACK for the FIN that was sent. 119 * Should continue to the TCP_SOCKET_TIME_WAIT state. 133 * 134 * A FIN has been sent, a FIN has been received, and an ACK has been 135 * sent. 136 * TCP is awaiting an ACK for the FIN that was sent. 137 * Should continue to the TCP_SOCKET_TIME_WAIT state. 120 138 */ 121 139 TCP_SOCKET_CLOSING, 140 122 141 /** Closing received. 123 * TCP has received a~FIN, and has sent an ACK. 124 * It is awaiting a~close request from the local application before sending a~FIN. 125 * Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state. 142 * 143 * TCP has received a FIN, and has sent an ACK. 144 * It is awaiting a close request from the local application before 145 * sending a FIN. 146 * Should continue to the TCP_SOCKET_SOCKET_LAST_ACK state. 126 147 */ 127 148 TCP_SOCKET_CLOSE_WAIT, 128 /** 129 * A~FIN has been received, and an ACK and a~FIN have been sent. 130 * TCP is awaiting an ACK. 131 * Should continue to the TCP_SOCKET_TIME_WAIT state. 149 150 /** 151 * A FIN has been received, and an ACK and a FIN have been sent. 152 * TCP is awaiting an ACK. 153 * Should continue to the TCP_SOCKET_TIME_WAIT state. 132 154 */ 133 155 TCP_SOCKET_LAST_ACK, 156 134 157 /** Closing finished. 135 * FINs have been received and ACK’d, and TCP is waiting two MSLs to remove the connection from the table. 158 * 159 * FINs have been received and ACK’d, and TCP is waiting two MSLs to 160 * remove the connection from the table. 136 161 */ 137 162 TCP_SOCKET_TIME_WAIT, 163 138 164 /** Closed. 139 * Imaginary, this indicates that a~connection has been removed from the connection table. 165 * 166 * Imaginary, this indicates that a connection has been removed from 167 * the connection table. 140 168 */ 141 169 TCP_SOCKET_CLOSED 142 170 }; 143 171 144 /** TCP operation data. 145 */ 146 struct tcp_operation{ 147 /** Operation result. 148 */ 172 /** TCP operation data. */ 173 struct tcp_operation { 174 /** Operation result. */ 149 175 int result; 150 /** Safety lock. 151 */ 176 /** Safety lock. */ 152 177 fibril_mutex_t mutex; 153 /** Operation result signaling. 154 */ 178 /** Operation result signaling. */ 155 179 fibril_condvar_t condvar; 156 180 }; 157 181 158 /** TCP socket specific data. 159 */ 160 struct tcp_socket_data{ 161 /** TCP socket state. 162 */ 182 /** TCP socket specific data. */ 183 struct tcp_socket_data { 184 /** TCP socket state. */ 163 185 tcp_socket_state_t state; 164 /** Data fragment size. 165 * Sending optimalization. 186 187 /** 188 * Data fragment size. 189 * Sending optimalization. 166 190 */ 167 191 size_t data_fragment_size; 168 /** Device identifier.169 */192 193 /** Device identifier. */ 170 194 device_id_t device_id; 171 /** Listening backlog. 172 * The maximal number of connected but not yet accepted sockets. 195 196 /** 197 * Listening backlog. 198 * The maximal number of connected but not yet accepted sockets. 173 199 */ 174 200 int backlog; 175 // /** Segment size. 176 // */ 177 // size_t segment_size; 178 /** Parent listening socket identifier. 179 * Set if this socket is an accepted one. 201 202 // /** Segment size. */ 203 // size_t segment_size; 204 205 /** 206 * Parent listening socket identifier. 207 * Set if this socket is an accepted one. 180 208 */ 181 209 int listening_socket_id; 182 /** Treshold size in bytes.183 */210 211 /** Treshold size in bytes. */ 184 212 size_t treshold; 185 /** Window size in bytes. 186 */ 213 /** Window size in bytes. */ 187 214 size_t window; 188 /** Acknowledgement timeout. 189 */ 215 /** Acknowledgement timeout. */ 190 216 suseconds_t timeout; 191 /** Last acknowledged byte. 192 */ 217 /** Last acknowledged byte. */ 193 218 uint32_t acknowledged; 194 /** Next incoming sequence number. 195 */ 219 /** Next incoming sequence number. */ 196 220 uint32_t next_incoming; 197 /** Incoming FIN. 198 */ 221 /** Incoming FIN. */ 199 222 uint32_t fin_incoming; 200 /** Next outgoing sequence number. 201 */ 223 /** Next outgoing sequence number. */ 202 224 uint32_t next_outgoing; 203 /** Last outgoing sequence number. 204 */ 225 /** Last outgoing sequence number. */ 205 226 uint32_t last_outgoing; 206 /** Outgoing FIN. 207 */ 227 /** Outgoing FIN. */ 208 228 uint32_t fin_outgoing; 209 /** Expected sequence number by the remote host. 210 * The sequence number the other host expects. 211 * The notification is sent only upon a packet reecival. 229 230 /** 231 * Expected sequence number by the remote host. 232 * The sequence number the other host expects. 233 * The notification is sent only upon a packet reecival. 212 234 */ 213 235 uint32_t expected; 214 /** Expected sequence number counter. 215 * Counts the number of received notifications for the same sequence number. 236 237 /** 238 * Expected sequence number counter. 239 * Counts the number of received notifications for the same sequence 240 * number. 216 241 */ 217 242 int expected_count; 243 218 244 /** Incoming packet queue. 219 * Packets are buffered until received in the right order. 220 * The packets are excluded after successfully read. 221 * Packets are sorted by their starting byte. 222 * Packets metric is set as their data length. 245 * 246 * Packets are buffered until received in the right order. 247 * The packets are excluded after successfully read. 248 * Packets are sorted by their starting byte. 249 * Packets metric is set as their data length. 223 250 */ 224 251 packet_t incoming; 252 225 253 /** Outgoing packet queue. 226 * Packets are buffered until acknowledged by the remote host in the right order. 227 * The packets are excluded after acknowledged. 228 * Packets are sorted by their starting byte. 229 * Packets metric is set as their data length. 254 * 255 * Packets are buffered until acknowledged by the remote host in the 256 * right order. 257 * The packets are excluded after acknowledged. 258 * Packets are sorted by their starting byte. 259 * Packets metric is set as their data length. 230 260 */ 231 261 packet_t outgoing; 232 /** IP pseudo header.233 */262 263 /** IP pseudo header. */ 234 264 void *pseudo_header; 235 /** IP pseudo header length. 236 */ 265 /** IP pseudo header length. */ 237 266 size_t headerlen; 238 /** Remote host address. 239 */ 240 struct sockaddr * addr; 241 /** Remote host address length. 242 */ 267 /** Remote host address. */ 268 struct sockaddr *addr; 269 /** Remote host address length. */ 243 270 socklen_t addrlen; 244 /** Remote host port. 245 */ 271 /** Remote host port. */ 246 272 uint16_t dest_port; 247 /** Parent local sockets. 248 */ 273 /** Parent local sockets. */ 249 274 socket_cores_ref local_sockets; 275 250 276 /** Local sockets safety lock. 251 * May be locked for writing while holding the global lock for reading when changing the local sockets only. 252 * The global lock may to be locked only before locking the local lock. 253 * The global lock may be locked more weakly than the local lock. 254 * The global lock may be released before releasing the local lock. 255 * @see tcp_globals:lock 256 */ 257 fibril_rwlock_t * local_lock; 258 /** Pending operation data. 259 */ 277 * 278 * May be locked for writing while holding the global lock for reading 279 * when changing the local sockets only. 280 * The global lock may be locked only before locking the local lock. 281 * The global lock may be locked more weakly than the local lock. 282 * The global lock may be released before releasing the local lock. 283 * @see tcp_globals:lock 284 */ 285 fibril_rwlock_t *local_lock; 286 287 /** Pending operation data. */ 260 288 tcp_operation_t operation; 261 /** Timeouts in a row counter. 262 * If TCP_MAX_TIMEOUTS is reached, the connection is lost. 289 290 /** 291 * Timeouts in a row counter. 292 * If TCP_MAX_TIMEOUTS is reached, the connection is lost. 263 293 */ 264 294 int timeout_count; 265 295 }; 266 296 267 /** TCP global data. 268 */ 269 struct tcp_globals{ 270 /** Networking module phone. 271 */ 297 /** TCP global data. */ 298 struct tcp_globals { 299 /** Networking module phone. */ 272 300 int net_phone; 273 /** IP module phone. 274 */ 301 /** IP module phone. */ 275 302 int ip_phone; 276 /** ICMP module phone. 277 */ 303 /** ICMP module phone. */ 278 304 int icmp_phone; 279 /** Last used free port. 280 */ 305 /** Last used free port. */ 281 306 int last_used_port; 282 /** Active sockets. 283 */ 307 /** Active sockets. */ 284 308 socket_ports_t sockets; 285 /** Device packet dimensions. 286 */ 309 /** Device packet dimensions. */ 287 310 packet_dimensions_t dimensions; 288 /** Safety lock. 289 * Write lock is used only for adding or removing socket ports. 311 312 /** 313 * Safety lock. 314 * Write lock is used only for adding or removing socket ports. 290 315 */ 291 316 fibril_rwlock_t lock; … … 296 321 /** @} 297 322 */ 298 -
uspace/srv/net/tl/tcp/tcp_header.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * Based on the RFC~793.34 * TCP header definition. 35 * Based on the RFC 793. 36 36 */ 37 37 38 #ifndef __NET_TCP_HEADER_H__39 #define __NET_TCP_HEADER_H__38 #ifndef NET_TCP_HEADER_H_ 39 #define NET_TCP_HEADER_H_ 40 40 41 41 #include <sys/types.h> 42 42 43 /** TCP header size in bytes. 44 */ 45 #define TCP_HEADER_SIZE sizeof(tcp_header_t) 43 /** TCP header size in bytes. */ 44 #define TCP_HEADER_SIZE sizeof(tcp_header_t) 46 45 47 46 /** Returns the actual TCP header length in bytes. 48 * 47 * @param[in] header The TCP packet header. 49 48 */ 50 #define TCP_HEADER_LENGTH(header) ((header)->header_length * 4 u)49 #define TCP_HEADER_LENGTH(header) ((header)->header_length * 4U) 51 50 52 51 /** Returns the TCP header length. 53 * 52 * @param[in] length The TCP header length in bytes. 54 53 */ 55 #define TCP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4u))54 #define TCP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4U)) 56 55 57 56 /** Type definition of the transmission datagram header. 58 * 57 * @see tcp_header 59 58 */ 60 typedef struct tcp_header 59 typedef struct tcp_header tcp_header_t; 61 60 62 61 /** Type definition of the transmission datagram header pointer. 63 * 62 * @see tcp_header 64 63 */ 65 typedef tcp_header_t * 64 typedef tcp_header_t *tcp_header_ref; 66 65 67 66 /** Type definition of the transmission datagram header option. 68 * 67 * @see tcp_option 69 68 */ 70 typedef struct tcp_option 69 typedef struct tcp_option tcp_option_t; 71 70 72 71 /** Type definition of the transmission datagram header option pointer. 73 * 72 * @see tcp_option 74 73 */ 75 typedef tcp_option_t * 74 typedef tcp_option_t *tcp_option_ref; 76 75 77 /** Type definition of the Maximum segment size TCP option. 78 * @see ... 79 */ 80 typedef struct tcp_max_segment_size_option tcp_max_segment_size_option_t; 76 /** Type definition of the Maximum segment size TCP option. */ 77 typedef struct tcp_max_segment_size_option tcp_max_segment_size_option_t; 81 78 82 79 /** Type definition of the Maximum segment size TCP option pointer. 83 * 80 * @see tcp_max_segment_size_option 84 81 */ 85 typedef tcp_max_segment_size_option_t * 82 typedef tcp_max_segment_size_option_t *tcp_max_segment_size_option_ref; 86 83 87 /** Transmission datagram header. 88 */ 89 struct tcp_header{ 90 /** The source port number. 91 */ 84 /** Transmission datagram header. */ 85 struct tcp_header { 92 86 uint16_t source_port; 93 /** The destination port number.94 */95 87 uint16_t destination_port; 96 /** The sequence number of the first data octet in this segment (except when SYN is present).97 * If SYN is present the sequence number is the initial sequence number (ISN) and the first data octet is ISN+1.98 */99 88 uint32_t sequence_number; 100 /** If the ACK control bit is set this field contains the value of the next sequence number the sender of the segment is expecting to receive.101 * Once a~connection is established this is always sent.102 * @see acknowledge103 */104 89 uint32_t acknowledgement_number; 90 105 91 #ifdef ARCH_IS_BIG_ENDIAN 106 /** The number of 32~bit words in the TCP Header.107 * This indicates where the data begins.108 * The TCP header (even one including options) is an integral number of 32~bits long.109 */110 92 uint8_t header_length:4; 111 /** Four bits reserved for future use.112 * Must be zero.113 */114 93 uint8_t reserved1:4; 115 94 #else 116 /** Four bits reserved for future use.117 * Must be zero.118 */119 95 uint8_t reserved1:4; 120 /** The number of 32~bit words in the TCP Header.121 * This indicates where the data begins.122 * The TCP header (even one including options) is an integral number of 32~bits long.123 */124 96 uint8_t header_length:4; 125 97 #endif 98 126 99 #ifdef ARCH_IS_BIG_ENDIAN 127 /** Two bits reserved for future use.128 * Must be zero.129 */130 100 uint8_t reserved2:2; 131 /** Urgent Pointer field significant.132 * @see tcp_header:urgent_pointer133 */134 101 uint8_t urgent:1; 135 /** Acknowledgment field significant136 * @see tcp_header:acknowledgement_number137 */138 102 uint8_t acknowledge:1; 139 /** Push function.140 */141 103 uint8_t push:1; 142 /** Reset the connection.143 */144 104 uint8_t reset:1; 145 /** Synchronize the sequence numbers.146 */147 105 uint8_t synchronize:1; 148 /** No more data from the sender.149 */150 106 uint8_t finalize:1; 151 107 #else 152 /** No more data from the sender.153 */154 108 uint8_t finalize:1; 155 /** Synchronize the sequence numbers.156 */157 109 uint8_t synchronize:1; 158 /** Reset the connection.159 */160 110 uint8_t reset:1; 161 /** Push function.162 */163 111 uint8_t push:1; 164 /** Acknowledgment field significant.165 * @see tcp_header:acknowledgement_number166 */167 112 uint8_t acknowledge:1; 168 /** Urgent Pointer field significant.169 * @see tcp_header:urgent_pointer170 */171 113 uint8_t urgent:1; 172 /** Two bits reserved for future use.173 * Must be zero.174 */175 114 uint8_t reserved2:2; 176 115 #endif 177 /** The number of data octets beginning with the one indicated in the acknowledgment field which the sender of this segment is willing to accept. 178 * @see tcp_header:acknowledge 179 */ 116 180 117 uint16_t window; 181 /** The checksum field is the 16~bit one's complement of the one's complement sum of all 16~bit words in the header and text.182 * If a~segment contains an odd number of header and text octets to be checksummed, the last octet is padded on the right with zeros to form a~16~bit word for checksum purposes.183 * The pad is not transmitted as part of the segment.184 * While computing the checksum, the checksum field itself is replaced with zeros.185 * The checksum also coves a~pseudo header conceptually.186 * The pseudo header conceptually prefixed to the TCP header contains the source address, the destination address, the protocol, and the TCP length.187 * This information gives protection against misrouted datagrams.188 * If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).189 */190 118 uint16_t checksum; 191 /** This field communicates the current value of the urgent pointer as a~positive offset from the sequence number in this segment.192 * The urgent pointer points to the sequence number of the octet following the urgent data.193 * This field is only be interpreted in segments with the URG control bit set.194 * @see tcp_header:urgent195 */196 119 uint16_t urgent_pointer; 197 120 } __attribute__ ((packed)); 198 121 199 /** Transmission datagram header option. 200 */ 201 struct tcp_option{ 202 /** Option type. 203 */ 122 /** Transmission datagram header option. */ 123 struct tcp_option { 124 /** Option type. */ 204 125 uint8_t type; 205 /** Option length. 206 */ 126 /** Option length. */ 207 127 uint8_t length; 208 128 }; 209 129 210 /** Maximum segment size TCP option. 211 */ 212 struct tcp_max_segment_size_option{ 130 /** Maximum segment size TCP option. */ 131 struct tcp_max_segment_size_option { 213 132 /** TCP option. 214 * 215 * 133 * @see TCPOPT_MAX_SEGMENT_SIZE 134 * @see TCPOPT_MAX_SEGMENT_SIZE_LENGTH 216 135 */ 217 136 tcp_option_t option; 218 /** Maximum segment size in bytes.219 */137 138 /** Maximum segment size in bytes. */ 220 139 uint16_t max_segment_size; 221 140 } __attribute__ ((packed)); -
uspace/srv/net/tl/tcp/tcp_module.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * TCP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 34 * TCP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * @see module.c 38 39 */ 40 41 #include "tcp.h" 42 #include "tcp_module.h" 39 43 40 44 #include <async.h> 41 45 #include <stdio.h> 42 #include <err .h>46 #include <errno.h> 43 47 #include <ipc/ipc.h> 44 48 #include <ipc/services.h> … … 46 50 #include <net/ip_protocols.h> 47 51 #include <net/modules.h> 48 49 52 #include <net/packet.h> 50 53 #include <net_interface.h> 54 51 55 #include <ip_interface.h> 52 56 #include <tl_local.h> 53 57 54 #include "tcp.h" 55 #include "tcp_module.h" 58 /** TCP module global data. */ 59 extern tcp_globals_t tcp_globals; 56 60 57 /** TCP module global data.58 */59 extern tcp_globals_t tcp_globals;60 61 /** Starts the TCP module.62 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop.63 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.64 * @returns EOK on successful module termination.65 * @returns Other error codes as defined for the tcp_initialize() function.66 * @returns Other error codes as defined for the REGISTER_ME() macro function.67 */68 61 int tl_module_start_standalone(async_client_conn_t client_connection) 69 62 { 70 ERROR_DECLARE; 71 63 ipcarg_t phonehash; 64 int rc; 65 72 66 async_set_client_connection(client_connection); 73 67 tcp_globals.net_phone = net_connect_module(); 74 ERROR_PROPAGATE(pm_init()); 75 76 ipcarg_t phonehash; 77 if (ERROR_OCCURRED(tcp_initialize(client_connection)) 78 || ERROR_OCCURRED(REGISTER_ME(SERVICE_TCP, &phonehash))) { 79 pm_destroy(); 80 return ERROR_CODE; 81 } 68 69 rc = pm_init(); 70 if (rc != EOK) 71 return rc; 72 73 rc = tcp_initialize(client_connection); 74 if (rc != EOK) 75 goto out; 76 77 rc = REGISTER_ME(SERVICE_TCP, &phonehash); 78 if (rc != EOK) 79 goto out; 82 80 83 81 async_manager(); 84 82 83 out: 85 84 pm_destroy(); 86 return EOK;85 return rc; 87 86 } 88 87 89 /** Processes the TCP message. 90 * @param[in] callid The message identifier. 91 * @param[in] call The message parameters. 92 * @param[out] answer The message answer parameters. 93 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 94 * @returns EOK on success. 95 * @returns Other error codes as defined for the tcp_message() function. 96 */ 97 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 88 int 89 tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 90 ipc_call_t *answer, int *answer_count) 91 { 98 92 return tcp_message_standalone(callid, call, answer, answer_count); 99 93 } -
uspace/srv/net/tl/tcp/tcp_module.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup tcp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * TCP module functions. 35 * The functions are used as TCP module entry points. 36 36 */ 37 37 38 #ifndef __NET_TCP_MODULE_H__39 #define __NET_TCP_MODULE_H__38 #ifndef NET_TCP_MODULE_H_ 39 #define NET_TCP_MODULE_H_ 40 40 41 41 #include <async.h> 42 42 #include <ipc/ipc.h> 43 43 44 /** Initializes the TCP module. 45 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 46 * @returns EOK on success. 47 * @returns ENOMEM if there is not enough memory left. 48 */ 49 extern int tcp_initialize(async_client_conn_t client_connection); 50 51 /** Processes the TCP message. 52 * @param[in] callid The message identifier. 53 * @param[in] call The message parameters. 54 * @param[out] answer The message answer parameters. 55 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 56 * @returns EOK on success. 57 * @returns ENOTSUP if the message is not known. 58 * @see tcp_interface.h 59 * @see IS_NET_TCP_MESSAGE() 60 */ 61 extern int tcp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 44 extern int tcp_initialize(async_client_conn_t); 45 extern int tcp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 62 47 63 48 #endif -
uspace/srv/net/tl/udp/udp.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * UDP module implementation. 35 * @see udp.h 36 */ 34 * UDP module implementation. 35 * @see udp.h 36 */ 37 38 #include "udp.h" 39 #include "udp_header.h" 40 #include "udp_module.h" 37 41 38 42 #include <async.h> … … 45 49 #include <ipc/tl.h> 46 50 #include <ipc/socket.h> 51 #include <adt/dynamic_fifo.h> 47 52 #include <errno.h> 48 #include <err.h>49 53 50 54 #include <net/socket_codes.h> … … 55 59 #include <net/modules.h> 56 60 57 #include <adt/dynamic_fifo.h>58 61 #include <packet_client.h> 59 62 #include <packet_remote.h> … … 69 72 #include <tl_interface.h> 70 73 71 #include "udp.h"72 #include "udp_header.h"73 #include "udp_module.h"74 75 74 /** UDP module name. */ 76 75 #define NAME "UDP protocol" … … 91 90 #define UDP_FREE_PORTS_END 65535 92 91 93 /** Processes the received UDP packet queue. 94 * 95 * Is used as an entry point from the underlying IP module. 96 * Locks the global lock and calls udp_process_packet() function. 97 * 98 * @param[in] device_id The receiving device identifier. 99 * @param[in,out] packet The received packet queue. 100 * @param receiver The target service. Ignored parameter. 101 * @param[in] error The packet error reporting service. Prefixes the 102 * received packet. 103 * @returns EOK on success. 104 * @returns Other error codes as defined for the 105 * udp_process_packet() function. 106 */ 107 int 108 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 109 services_t error); 110 111 /** Processes the received UDP packet queue. 112 * 113 * Notifies the destination socket application. 114 * Releases the packet on error or sends an ICMP error notification. 115 * 116 * @param[in] device_id The receiving device identifier. 117 * @param[in,out] packet The received packet queue. 118 * @param[in] error The packet error reporting service. Prefixes the 119 * received packet. 120 * @returns EOK on success. 121 * @returns EINVAL if the packet is not valid. 122 * @returns EINVAL if the stored packet address is not the 123 * an_addr_t. 124 * @returns EINVAL if the packet does not contain any data. 125 * @returns NO_DATA if the packet content is shorter than the user 126 * datagram header. 127 * @returns ENOMEM if there is not enough memory left. 128 * @returns EADDRNOTAVAIL if the destination socket does not exist. 129 * @returns Other error codes as defined for the 130 * ip_client_process_packet() function. 131 */ 132 int 133 udp_process_packet(device_id_t device_id, packet_t packet, services_t error); 134 135 /** Releases the packet and returns the result. 136 * 137 * @param[in] packet The packet queue to be released. 138 * @param[in] result The result to be returned. 139 * @return The result parameter. 140 */ 141 int udp_release_and_return(packet_t packet, int result); 142 143 /** @name Socket messages processing functions 144 */ 145 /*@{*/ 146 147 /** Processes the socket client messages. 148 * 149 * Runs until the client module disconnects. 150 * 151 * @param[in] callid The message identifier. 152 * @param[in] call The message parameters. 153 * @returns EOK on success. 154 * @see socket.h 155 */ 156 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call); 157 158 /** Sends data from the socket to the remote address. 159 * 160 * Binds the socket to a free port if not already connected/bound. 161 * Handles the NET_SOCKET_SENDTO message. 162 * Supports AF_INET and AF_INET6 address families. 163 * 164 * @param[in,out] local_sockets The application local sockets. 165 * @param[in] socket_id Socket identifier. 166 * @param[in] addr The destination address. 167 * @param[in] addrlen The address length. 168 * @param[in] fragments The number of data fragments. 169 * @param[out] data_fragment_size The data fragment size in bytes. 170 * @param[in] flags Various send flags. 171 * @returns EOK on success. 172 * @returns EAFNOTSUPPORT if the address family is not supported. 173 * @returns ENOTSOCK if the socket is not found. 174 * @returns EINVAL if the address is invalid. 175 * @returns ENOTCONN if the sending socket is not and cannot be 176 * bound. 177 * @returns ENOMEM if there is not enough memory left. 178 * @returns Other error codes as defined for the 179 * socket_read_packet_data() function. 180 * @returns Other error codes as defined for the 181 * ip_client_prepare_packet() function. 182 * @returns Other error codes as defined for the ip_send_msg() 183 * function. 184 */ 185 int 186 udp_sendto_message(socket_cores_ref local_sockets, int socket_id, 187 const struct sockaddr * addr, socklen_t addrlen, int fragments, 188 size_t * data_fragment_size, int flags); 189 190 /** Receives data to the socket. 191 * 192 * Handles the NET_SOCKET_RECVFROM message. 193 * Replies the source address as well. 194 * 195 * @param[in] local_sockets The application local sockets. 196 * @param[in] socket_id Socket identifier. 197 * @param[in] flags Various receive flags. 198 * @param[out] addrlen The source address length. 199 * @returns The number of bytes received. 200 * @returns ENOTSOCK if the socket is not found. 201 * @returns NO_DATA if there are no received packets or data. 202 * @returns ENOMEM if there is not enough memory left. 203 * @returns EINVAL if the received address is not an IP address. 204 * @returns Other error codes as defined for the packet_translate() 205 * function. 206 * @returns Other error codes as defined for the data_reply() 207 * function. 208 */ 209 int 210 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 211 size_t * addrlen); 212 213 /*@}*/ 214 215 /** UDP global data. 216 */ 92 /** UDP global data. */ 217 93 udp_globals_t udp_globals; 218 94 95 /** Initializes the UDP module. 96 * 97 * @param[in] client_connection The client connection processing function. The 98 * module skeleton propagates its own one. 99 * @returns EOK on success. 100 * @returns ENOMEM if there is not enough memory left. 101 */ 219 102 int udp_initialize(async_client_conn_t client_connection) 220 103 { 221 ERROR_DECLARE;222 223 104 measured_string_t names[] = { 224 105 { 225 str_dup("UDP_CHECKSUM_COMPUTING"),106 (char *) "UDP_CHECKSUM_COMPUTING", 226 107 22 227 108 }, 228 109 { 229 str_dup("UDP_AUTOBINDING"),110 (char *) "UDP_AUTOBINDING", 230 111 15 231 112 } … … 233 114 measured_string_ref configuration; 234 115 size_t count = sizeof(names) / sizeof(measured_string_t); 235 char * data; 116 char *data; 117 int rc; 236 118 237 119 fibril_rwlock_initialize(&udp_globals.lock); … … 240 122 udp_globals.icmp_phone = icmp_connect_module(SERVICE_ICMP, 241 123 ICMP_CONNECT_TIMEOUT); 124 242 125 udp_globals.ip_phone = ip_bind_service(SERVICE_IP, IPPROTO_UDP, 243 126 SERVICE_UDP, client_connection); 244 if (udp_globals.ip_phone < 0) 127 if (udp_globals.ip_phone < 0) { 128 fibril_rwlock_write_unlock(&udp_globals.lock); 245 129 return udp_globals.ip_phone; 130 } 246 131 247 132 // read default packet dimensions 248 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, 249 &udp_globals.packet_dimension)); 250 ERROR_PROPAGATE(socket_ports_initialize(&udp_globals.sockets)); 251 if (ERROR_OCCURRED(packet_dimensions_initialize( 252 &udp_globals.dimensions))) { 133 rc = ip_packet_size_req(udp_globals.ip_phone, -1, 134 &udp_globals.packet_dimension); 135 if (rc != EOK) { 136 fibril_rwlock_write_unlock(&udp_globals.lock); 137 return rc; 138 } 139 140 rc = socket_ports_initialize(&udp_globals.sockets); 141 if (rc != EOK) { 142 fibril_rwlock_write_unlock(&udp_globals.lock); 143 return rc; 144 } 145 146 rc = packet_dimensions_initialize(&udp_globals.dimensions); 147 if (rc != EOK) { 253 148 socket_ports_destroy(&udp_globals.sockets); 254 return ERROR_CODE; 255 } 149 fibril_rwlock_write_unlock(&udp_globals.lock); 150 return rc; 151 } 152 256 153 udp_globals.packet_dimension.prefix += sizeof(udp_header_t); 257 154 udp_globals.packet_dimension.content -= sizeof(udp_header_t); 258 155 udp_globals.last_used_port = UDP_FREE_PORTS_START - 1; 259 156 260 // get configuration261 157 udp_globals.checksum_computing = NET_DEFAULT_UDP_CHECKSUM_COMPUTING; 262 158 udp_globals.autobinding = NET_DEFAULT_UDP_AUTOBINDING; 159 160 // get configuration 263 161 configuration = &names[0]; 264 ERROR_PROPAGATE(net_get_conf_req(udp_globals.net_phone, &configuration, 265 count, &data)); 162 rc = net_get_conf_req(udp_globals.net_phone, &configuration, count, 163 &data); 164 if (rc != EOK) { 165 socket_ports_destroy(&udp_globals.sockets); 166 fibril_rwlock_write_unlock(&udp_globals.lock); 167 return rc; 168 } 169 266 170 if (configuration) { 267 171 if (configuration[0].value) … … 280 184 } 281 185 282 int 283 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 284 services_t error) 186 /** Releases the packet and returns the result. 187 * 188 * @param[in] packet The packet queue to be released. 189 * @param[in] result The result to be returned. 190 * @return The result parameter. 191 */ 192 static int udp_release_and_return(packet_t packet, int result) 285 193 { 286 int result; 287 288 fibril_rwlock_write_lock(&udp_globals.lock); 289 result = udp_process_packet(device_id, packet, error); 290 if (result != EOK) 291 fibril_rwlock_write_unlock(&udp_globals.lock); 292 194 pq_release_remote(udp_globals.net_phone, packet_get_id(packet)); 293 195 return result; 294 196 } 295 197 296 int udp_process_packet(device_id_t device_id, packet_t packet, services_t error) 198 /** Processes the received UDP packet queue. 199 * 200 * Notifies the destination socket application. 201 * Releases the packet on error or sends an ICMP error notification. 202 * 203 * @param[in] device_id The receiving device identifier. 204 * @param[in,out] packet The received packet queue. 205 * @param[in] error The packet error reporting service. Prefixes the 206 * received packet. 207 * @returns EOK on success. 208 * @returns EINVAL if the packet is not valid. 209 * @returns EINVAL if the stored packet address is not the 210 * an_addr_t. 211 * @returns EINVAL if the packet does not contain any data. 212 * @returns NO_DATA if the packet content is shorter than the user 213 * datagram header. 214 * @returns ENOMEM if there is not enough memory left. 215 * @returns EADDRNOTAVAIL if the destination socket does not exist. 216 * @returns Other error codes as defined for the 217 * ip_client_process_packet() function. 218 */ 219 static int 220 udp_process_packet(device_id_t device_id, packet_t packet, services_t error) 297 221 { 298 ERROR_DECLARE;299 300 222 size_t length; 301 223 size_t offset; … … 314 236 struct sockaddr *dest; 315 237 packet_dimension_ref packet_dimension; 316 317 if (error) { 318 switch (error) { 319 case SERVICE_ICMP: 320 // ignore error 321 // length = icmp_client_header_length(packet); 322 // process error 323 result = icmp_client_process_packet(packet, &type, 324 &code, NULL, NULL); 325 if (result < 0) 326 return udp_release_and_return(packet, result); 327 length = (size_t) result; 328 if (ERROR_OCCURRED(packet_trim(packet, length, 0))) 329 return udp_release_and_return(packet, 330 ERROR_CODE); 331 break; 332 default: 333 return udp_release_and_return(packet, ENOTSUP); 334 } 238 int rc; 239 240 switch (error) { 241 case SERVICE_NONE: 242 break; 243 case SERVICE_ICMP: 244 // ignore error 245 // length = icmp_client_header_length(packet); 246 // process error 247 result = icmp_client_process_packet(packet, &type, 248 &code, NULL, NULL); 249 if (result < 0) 250 return udp_release_and_return(packet, result); 251 length = (size_t) result; 252 rc = packet_trim(packet, length, 0); 253 if (rc != EOK) 254 return udp_release_and_return(packet, rc); 255 break; 256 default: 257 return udp_release_and_return(packet, ENOTSUP); 335 258 } 336 259 … … 348 271 349 272 // trim all but UDP header 350 if (ERROR_OCCURRED(packet_trim(packet, offset, 0))) 351 return udp_release_and_return(packet, ERROR_CODE); 273 rc = packet_trim(packet, offset, 0); 274 if (rc != EOK) 275 return udp_release_and_return(packet, rc); 352 276 353 277 // get udp header … … 374 298 375 299 // compute header checksum if set 376 if (header->checksum && (!error)) {300 if (header->checksum && !error) { 377 301 result = packet_get_addr(packet, (uint8_t **) &src, 378 302 (uint8_t **) &dest); 379 if (result <= 0)303 if (result <= 0) 380 304 return udp_release_and_return(packet, result); 381 382 if (ERROR_OCCURRED(ip_client_get_pseudo_header(IPPROTO_UDP,383 src, result, dest, result, total_length, &ip_header,384 &length))) {385 return udp_release_and_return(packet, ERROR_CODE);305 306 rc = ip_client_get_pseudo_header(IPPROTO_UDP, src, result, dest, 307 result, total_length, &ip_header, &length); 308 if (rc != EOK) { 309 return udp_release_and_return(packet, rc); 386 310 } else { 387 311 checksum = compute_checksum(0, ip_header, length); … … 396 320 397 321 do { 398 ++ fragments;322 fragments++; 399 323 length = packet_get_data_length(next_packet); 400 324 if (length <= 0) … … 402 326 403 327 if (total_length < length) { 404 if (ERROR_OCCURRED(packet_trim(next_packet, 0, 405 length - total_length))) { 406 return udp_release_and_return(packet, 407 ERROR_CODE); 408 } 328 rc = packet_trim(next_packet, 0, length - total_length); 329 if (rc != EOK) 330 return udp_release_and_return(packet, rc); 409 331 410 332 // add partial checksum if set … … 455 377 456 378 // queue the received packet 457 if (ERROR_OCCURRED(dyn_fifo_push(&socket->received, 458 packet_get_id(packet), SOCKET_MAX_RECEIVED_SIZE)) || 459 ERROR_OCCURRED(tl_get_ip_packet_dimension(udp_globals.ip_phone, 460 &udp_globals.dimensions, device_id, &packet_dimension))) { 461 return udp_release_and_return(packet, ERROR_CODE); 462 } 379 rc = dyn_fifo_push(&socket->received, packet_get_id(packet), 380 SOCKET_MAX_RECEIVED_SIZE); 381 if (rc != EOK) 382 return udp_release_and_return(packet, rc); 383 384 rc = tl_get_ip_packet_dimension(udp_globals.ip_phone, 385 &udp_globals.dimensions, device_id, &packet_dimension); 386 if (rc != EOK) 387 return udp_release_and_return(packet, rc); 463 388 464 389 // notify the destination socket … … 471 396 } 472 397 473 int 474 udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, 475 ipc_call_t * answer, int * answer_count) 398 /** Processes the received UDP packet queue. 399 * 400 * Is used as an entry point from the underlying IP module. 401 * Locks the global lock and calls udp_process_packet() function. 402 * 403 * @param[in] device_id The receiving device identifier. 404 * @param[in,out] packet The received packet queue. 405 * @param receiver The target service. Ignored parameter. 406 * @param[in] error The packet error reporting service. Prefixes the 407 * received packet. 408 * @returns EOK on success. 409 * @returns Other error codes as defined for the 410 * udp_process_packet() function. 411 */ 412 static int 413 udp_received_msg(device_id_t device_id, packet_t packet, services_t receiver, 414 services_t error) 476 415 { 477 ERROR_DECLARE; 478 416 int result; 417 418 fibril_rwlock_write_lock(&udp_globals.lock); 419 result = udp_process_packet(device_id, packet, error); 420 if (result != EOK) 421 fibril_rwlock_write_unlock(&udp_globals.lock); 422 423 return result; 424 } 425 426 /** Sends data from the socket to the remote address. 427 * 428 * Binds the socket to a free port if not already connected/bound. 429 * Handles the NET_SOCKET_SENDTO message. 430 * Supports AF_INET and AF_INET6 address families. 431 * 432 * @param[in,out] local_sockets The application local sockets. 433 * @param[in] socket_id Socket identifier. 434 * @param[in] addr The destination address. 435 * @param[in] addrlen The address length. 436 * @param[in] fragments The number of data fragments. 437 * @param[out] data_fragment_size The data fragment size in bytes. 438 * @param[in] flags Various send flags. 439 * @returns EOK on success. 440 * @returns EAFNOTSUPPORT if the address family is not supported. 441 * @returns ENOTSOCK if the socket is not found. 442 * @returns EINVAL if the address is invalid. 443 * @returns ENOTCONN if the sending socket is not and cannot be 444 * bound. 445 * @returns ENOMEM if there is not enough memory left. 446 * @returns Other error codes as defined for the 447 * socket_read_packet_data() function. 448 * @returns Other error codes as defined for the 449 * ip_client_prepare_packet() function. 450 * @returns Other error codes as defined for the ip_send_msg() 451 * function. 452 */ 453 static int 454 udp_sendto_message(socket_cores_ref local_sockets, int socket_id, 455 const struct sockaddr *addr, socklen_t addrlen, int fragments, 456 size_t *data_fragment_size, int flags) 457 { 458 socket_core_ref socket; 479 459 packet_t packet; 480 481 *answer_count = 0; 482 483 switch (IPC_GET_METHOD(*call)) { 484 case NET_TL_RECEIVED: 485 if (!ERROR_OCCURRED(packet_translate_remote( 486 udp_globals.net_phone, &packet, IPC_GET_PACKET(call)))) { 487 ERROR_CODE = udp_received_msg(IPC_GET_DEVICE(call), 488 packet, SERVICE_UDP, IPC_GET_ERROR(call)); 460 packet_t next_packet; 461 udp_header_ref header; 462 int index; 463 size_t total_length; 464 int result; 465 uint16_t dest_port; 466 uint32_t checksum; 467 void *ip_header; 468 size_t headerlen; 469 device_id_t device_id; 470 packet_dimension_ref packet_dimension; 471 int rc; 472 473 rc = tl_get_address_port(addr, addrlen, &dest_port); 474 if (rc != EOK) 475 return rc; 476 477 socket = socket_cores_find(local_sockets, socket_id); 478 if (!socket) 479 return ENOTSOCK; 480 481 if ((socket->port <= 0) && udp_globals.autobinding) { 482 // bind the socket to a random free port if not bound 483 rc = socket_bind_free_port(&udp_globals.sockets, socket, 484 UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 485 udp_globals.last_used_port); 486 if (rc != EOK) 487 return rc; 488 // set the next port as the search starting port number 489 udp_globals.last_used_port = socket->port; 490 } 491 492 if (udp_globals.checksum_computing) { 493 rc = ip_get_route_req(udp_globals.ip_phone, IPPROTO_UDP, addr, 494 addrlen, &device_id, &ip_header, &headerlen); 495 if (rc != EOK) 496 return rc; 497 // get the device packet dimension 498 // rc = tl_get_ip_packet_dimension(udp_globals.ip_phone, 499 // &udp_globals.dimensions, device_id, &packet_dimension); 500 // if (rc != EOK) 501 // return rc; 502 } 503 // } else { 504 // do not ask all the time 505 rc = ip_packet_size_req(udp_globals.ip_phone, -1, 506 &udp_globals.packet_dimension); 507 if (rc != EOK) 508 return rc; 509 packet_dimension = &udp_globals.packet_dimension; 510 // } 511 512 // read the first packet fragment 513 result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, 514 UDP_HEADER_SIZE, packet_dimension, addr, addrlen); 515 if (result < 0) 516 return result; 517 518 total_length = (size_t) result; 519 if (udp_globals.checksum_computing) 520 checksum = compute_checksum(0, packet_get_data(packet), 521 packet_get_data_length(packet)); 522 else 523 checksum = 0; 524 525 // prefix the udp header 526 header = PACKET_PREFIX(packet, udp_header_t); 527 if (!header) 528 return udp_release_and_return(packet, ENOMEM); 529 530 bzero(header, sizeof(*header)); 531 // read the rest of the packet fragments 532 for (index = 1; index < fragments; index++) { 533 result = tl_socket_read_packet_data(udp_globals.net_phone, 534 &next_packet, 0, packet_dimension, addr, addrlen); 535 if (result < 0) 536 return udp_release_and_return(packet, result); 537 538 rc = pq_add(&packet, next_packet, index, 0); 539 if (rc != EOK) 540 return udp_release_and_return(packet, rc); 541 542 total_length += (size_t) result; 543 if (udp_globals.checksum_computing) { 544 checksum = compute_checksum(checksum, 545 packet_get_data(next_packet), 546 packet_get_data_length(next_packet)); 489 547 } 490 return ERROR_CODE; 548 } 549 550 // set the udp header 551 header->source_port = htons((socket->port > 0) ? socket->port : 0); 552 header->destination_port = htons(dest_port); 553 header->total_length = htons(total_length + sizeof(*header)); 554 header->checksum = 0; 555 if (udp_globals.checksum_computing) { 556 // update the pseudo header 557 rc = ip_client_set_pseudo_header_data_length(ip_header, 558 headerlen, total_length + UDP_HEADER_SIZE); 559 if (rc != EOK) { 560 free(ip_header); 561 return udp_release_and_return(packet, rc); 562 } 563 564 // finish the checksum computation 565 checksum = compute_checksum(checksum, ip_header, headerlen); 566 checksum = compute_checksum(checksum, (uint8_t *) header, 567 sizeof(*header)); 568 header->checksum = 569 htons(flip_checksum(compact_checksum(checksum))); 570 free(ip_header); 571 } else { 572 device_id = DEVICE_INVALID_ID; 573 } 574 575 // prepare the first packet fragment 576 rc = ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 0, 0); 577 if (rc != EOK) 578 return udp_release_and_return(packet, rc); 579 580 /* Release the UDP global lock on success. */ 581 fibril_rwlock_write_unlock(&udp_globals.lock); 582 583 // send the packet 584 ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0); 585 586 return EOK; 587 } 588 589 /** Receives data to the socket. 590 * 591 * Handles the NET_SOCKET_RECVFROM message. 592 * Replies the source address as well. 593 * 594 * @param[in] local_sockets The application local sockets. 595 * @param[in] socket_id Socket identifier. 596 * @param[in] flags Various receive flags. 597 * @param[out] addrlen The source address length. 598 * @returns The number of bytes received. 599 * @returns ENOTSOCK if the socket is not found. 600 * @returns NO_DATA if there are no received packets or data. 601 * @returns ENOMEM if there is not enough memory left. 602 * @returns EINVAL if the received address is not an IP address. 603 * @returns Other error codes as defined for the packet_translate() 604 * function. 605 * @returns Other error codes as defined for the data_reply() 606 * function. 607 */ 608 static int 609 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags, 610 size_t *addrlen) 611 { 612 socket_core_ref socket; 613 int packet_id; 614 packet_t packet; 615 udp_header_ref header; 616 struct sockaddr *addr; 617 size_t length; 618 uint8_t *data; 619 int result; 620 int rc; 621 622 // find the socket 623 socket = socket_cores_find(local_sockets, socket_id); 624 if (!socket) 625 return ENOTSOCK; 626 627 // get the next received packet 628 packet_id = dyn_fifo_value(&socket->received); 629 if (packet_id < 0) 630 return NO_DATA; 491 631 492 case IPC_M_CONNECT_TO_ME: 493 return udp_process_client_messages(callid, * call); 494 } 495 496 return ENOTSUP; 632 rc = packet_translate_remote(udp_globals.net_phone, &packet, packet_id); 633 if (rc != EOK) { 634 (void) dyn_fifo_pop(&socket->received); 635 return rc; 636 } 637 638 // get udp header 639 data = packet_get_data(packet); 640 if (!data) { 641 (void) dyn_fifo_pop(&socket->received); 642 return udp_release_and_return(packet, NO_DATA); 643 } 644 header = (udp_header_ref) data; 645 646 // set the source address port 647 result = packet_get_addr(packet, (uint8_t **) &addr, NULL); 648 rc = tl_set_address_port(addr, result, ntohs(header->source_port)); 649 if (rc != EOK) { 650 (void) dyn_fifo_pop(&socket->received); 651 return udp_release_and_return(packet, rc); 652 } 653 *addrlen = (size_t) result; 654 655 // send the source address 656 rc = data_reply(addr, *addrlen); 657 switch (rc) { 658 case EOK: 659 break; 660 case EOVERFLOW: 661 return rc; 662 default: 663 (void) dyn_fifo_pop(&socket->received); 664 return udp_release_and_return(packet, rc); 665 } 666 667 // trim the header 668 rc = packet_trim(packet, UDP_HEADER_SIZE, 0); 669 if (rc != EOK) { 670 (void) dyn_fifo_pop(&socket->received); 671 return udp_release_and_return(packet, rc); 672 } 673 674 // reply the packets 675 rc = socket_reply_packets(packet, &length); 676 switch (rc) { 677 case EOK: 678 break; 679 case EOVERFLOW: 680 return rc; 681 default: 682 (void) dyn_fifo_pop(&socket->received); 683 return udp_release_and_return(packet, rc); 684 } 685 686 (void) dyn_fifo_pop(&socket->received); 687 688 // release the packet and return the total length 689 return udp_release_and_return(packet, (int) length); 497 690 } 498 691 499 int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 692 /** Processes the socket client messages. 693 * 694 * Runs until the client module disconnects. 695 * 696 * @param[in] callid The message identifier. 697 * @param[in] call The message parameters. 698 * @returns EOK on success. 699 * 700 * @see socket.h 701 */ 702 static int udp_process_client_messages(ipc_callid_t callid, ipc_call_t call) 500 703 { 501 704 int res; … … 638 841 } 639 842 843 /** Processes the UDP message. 844 * 845 * @param[in] callid The message identifier. 846 * @param[in] call The message parameters. 847 * @param[out] answer The message answer parameters. 848 * @param[out] answer_count The last parameter for the actual answer in the 849 * answer parameter. 850 * @returns EOK on success. 851 * @returns ENOTSUP if the message is not known. 852 * 853 * @see udp_interface.h 854 * @see IS_NET_UDP_MESSAGE() 855 */ 640 856 int 641 udp_sendto_message(socket_cores_ref local_sockets, int socket_id, 642 const struct sockaddr *addr, socklen_t addrlen, int fragments, 643 size_t *data_fragment_size, int flags) 857 udp_message_standalone(ipc_callid_t callid, ipc_call_t *call, 858 ipc_call_t *answer, int *answer_count) 644 859 { 645 ERROR_DECLARE;646 647 socket_core_ref socket;648 860 packet_t packet; 649 packet_t next_packet; 650 udp_header_ref header; 651 int index; 652 size_t total_length; 653 int result; 654 uint16_t dest_port; 655 uint32_t checksum; 656 void *ip_header; 657 size_t headerlen; 658 device_id_t device_id; 659 packet_dimension_ref packet_dimension; 660 661 ERROR_PROPAGATE(tl_get_address_port(addr, addrlen, &dest_port)); 662 663 socket = socket_cores_find(local_sockets, socket_id); 664 if (!socket) 665 return ENOTSOCK; 666 667 if ((socket->port <= 0) && udp_globals.autobinding) { 668 // bind the socket to a random free port if not bound 669 // do { 670 // try to find a free port 671 // fibril_rwlock_read_unlock(&udp_globals.lock); 672 // fibril_rwlock_write_lock(&udp_globals.lock); 673 // might be changed in the meantime 674 // if (socket->port <= 0) { 675 if (ERROR_OCCURRED(socket_bind_free_port( 676 &udp_globals.sockets, socket, 677 UDP_FREE_PORTS_START, UDP_FREE_PORTS_END, 678 udp_globals.last_used_port))) { 679 // fibril_rwlock_write_unlock( 680 // &udp_globals.lock); 681 // fibril_rwlock_read_lock( 682 // &udp_globals.lock); 683 return ERROR_CODE; 684 } 685 // set the next port as the search starting port 686 // number 687 udp_globals.last_used_port = socket->port; 688 // } 689 // fibril_rwlock_write_unlock(&udp_globals.lock); 690 // fibril_rwlock_read_lock(&udp_globals.lock); 691 // might be changed in the meantime 692 // } while (socket->port <= 0); 693 } 694 695 if (udp_globals.checksum_computing) { 696 if (ERROR_OCCURRED(ip_get_route_req(udp_globals.ip_phone, 697 IPPROTO_UDP, addr, addrlen, &device_id, &ip_header, 698 &headerlen))) { 699 return udp_release_and_return(packet, ERROR_CODE); 700 } 701 // get the device packet dimension 702 // ERROR_PROPAGATE(tl_get_ip_packet_dimension(udp_globals.ip_phone, 703 // &udp_globals.dimensions, device_id, &packet_dimension)); 704 } 705 // } else { 706 // do not ask all the time 707 ERROR_PROPAGATE(ip_packet_size_req(udp_globals.ip_phone, -1, 708 &udp_globals.packet_dimension)); 709 packet_dimension = &udp_globals.packet_dimension; 710 // } 711 712 // read the first packet fragment 713 result = tl_socket_read_packet_data(udp_globals.net_phone, &packet, 714 UDP_HEADER_SIZE, packet_dimension, addr, addrlen); 715 if (result < 0) 716 return result; 717 718 total_length = (size_t) result; 719 if (udp_globals.checksum_computing) 720 checksum = compute_checksum(0, packet_get_data(packet), 721 packet_get_data_length(packet)); 722 else 723 checksum = 0; 724 725 // prefix the udp header 726 header = PACKET_PREFIX(packet, udp_header_t); 727 if(! header) 728 return udp_release_and_return(packet, ENOMEM); 729 730 bzero(header, sizeof(*header)); 731 // read the rest of the packet fragments 732 for (index = 1; index < fragments; ++ index) { 733 result = tl_socket_read_packet_data(udp_globals.net_phone, 734 &next_packet, 0, packet_dimension, addr, addrlen); 735 if (result < 0) 736 return udp_release_and_return(packet, result); 737 738 if (ERROR_OCCURRED(pq_add(&packet, next_packet, index, 0))) 739 return udp_release_and_return(packet, ERROR_CODE); 740 741 total_length += (size_t) result; 742 if (udp_globals.checksum_computing) { 743 checksum = compute_checksum(checksum, 744 packet_get_data(next_packet), 745 packet_get_data_length(next_packet)); 746 } 747 } 748 749 // set the udp header 750 header->source_port = htons((socket->port > 0) ? socket->port : 0); 751 header->destination_port = htons(dest_port); 752 header->total_length = htons(total_length + sizeof(*header)); 753 header->checksum = 0; 754 if (udp_globals.checksum_computing) { 755 // update the pseudo header 756 if (ERROR_OCCURRED(ip_client_set_pseudo_header_data_length( 757 ip_header, headerlen, total_length + UDP_HEADER_SIZE))) { 758 free(ip_header); 759 return udp_release_and_return(packet, ERROR_CODE); 760 } 761 762 // finish the checksum computation 763 checksum = compute_checksum(checksum, ip_header, headerlen); 764 checksum = compute_checksum(checksum, (uint8_t *) header, 765 sizeof(*header)); 766 header->checksum = 767 htons(flip_checksum(compact_checksum(checksum))); 768 free(ip_header); 769 } else { 770 device_id = DEVICE_INVALID_ID; 771 } 772 773 // prepare the first packet fragment 774 if (ERROR_OCCURRED(ip_client_prepare_packet(packet, IPPROTO_UDP, 0, 0, 775 0, 0))) { 776 return udp_release_and_return(packet, ERROR_CODE); 777 } 778 779 // send the packet 780 fibril_rwlock_write_unlock(&udp_globals.lock); 781 ip_send_msg(udp_globals.ip_phone, device_id, packet, SERVICE_UDP, 0); 782 783 return EOK; 861 int rc; 862 863 *answer_count = 0; 864 865 switch (IPC_GET_METHOD(*call)) { 866 case NET_TL_RECEIVED: 867 rc = packet_translate_remote(udp_globals.net_phone, &packet, 868 IPC_GET_PACKET(call)); 869 if (rc != EOK) 870 return rc; 871 return udp_received_msg(IPC_GET_DEVICE(call), packet, 872 SERVICE_UDP, IPC_GET_ERROR(call)); 873 case IPC_M_CONNECT_TO_ME: 874 return udp_process_client_messages(callid, * call); 875 } 876 877 return ENOTSUP; 784 878 } 785 879 786 int787 udp_recvfrom_message(socket_cores_ref local_sockets, int socket_id, int flags,788 size_t *addrlen)789 {790 ERROR_DECLARE;791 792 socket_core_ref socket;793 int packet_id;794 packet_t packet;795 udp_header_ref header;796 struct sockaddr *addr;797 size_t length;798 uint8_t *data;799 int result;800 801 // find the socket802 socket = socket_cores_find(local_sockets, socket_id);803 if (!socket)804 return ENOTSOCK;805 806 // get the next received packet807 packet_id = dyn_fifo_value(&socket->received);808 if (packet_id < 0)809 return NO_DATA;810 811 ERROR_PROPAGATE(packet_translate_remote(udp_globals.net_phone, &packet,812 packet_id));813 814 // get udp header815 data = packet_get_data(packet);816 if (!data) {817 pq_release_remote(udp_globals.net_phone, packet_id);818 return NO_DATA;819 }820 header = (udp_header_ref) data;821 822 // set the source address port823 result = packet_get_addr(packet, (uint8_t **) &addr, NULL);824 if (ERROR_OCCURRED(tl_set_address_port(addr, result,825 ntohs(header->source_port)))) {826 pq_release_remote(udp_globals.net_phone, packet_id);827 return ERROR_CODE;828 }829 *addrlen = (size_t) result;830 831 // send the source address832 ERROR_PROPAGATE(data_reply(addr, * addrlen));833 834 // trim the header835 ERROR_PROPAGATE(packet_trim(packet, UDP_HEADER_SIZE, 0));836 837 // reply the packets838 ERROR_PROPAGATE(socket_reply_packets(packet, &length));839 840 // release the packet841 dyn_fifo_pop(&socket->received);842 pq_release_remote(udp_globals.net_phone, packet_get_id(packet));843 844 // return the total length845 return (int) length;846 }847 848 int udp_release_and_return(packet_t packet, int result)849 {850 pq_release_remote(udp_globals.net_phone, packet_get_id(packet));851 return result;852 }853 854 880 /** Default thread for new connections. 855 881 * 856 * @param[in] iid The initial message identifier. 857 * @param[in] icall The initial message call structure. 858 * 882 * @param[in] iid The initial message identifier. 883 * @param[in] icall The initial message call structure. 859 884 */ 860 885 static void tl_client_connection(ipc_callid_t iid, ipc_call_t * icall) … … 882 907 883 908 /* 884 * End if said to either by the message or the processing result 909 * End if told to either by the message or the processing 910 * result. 885 911 */ 886 912 if ((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || … … 895 921 /** Starts the module. 896 922 * 897 * @param argc The count of the command line arguments. Ignored 898 * parameter. 899 * @param argv The command line parameters. Ignored parameter. 900 * 901 * @returns EOK on success. 902 * @returns Other error codes as defined for each specific module 923 * @returns EOK on success. 924 * @returns Other error codes as defined for each specific module 903 925 * start function. 904 926 */ 905 927 int main(int argc, char *argv[]) 906 928 { 907 ERROR_DECLARE;929 int rc; 908 930 909 931 /* Start the module */ 910 if (ERROR_OCCURRED(tl_module_start_standalone(tl_client_connection))) 911 return ERROR_CODE; 912 913 return EOK; 932 rc = tl_module_start_standalone(tl_client_connection); 933 return rc; 914 934 } 915 935 -
uspace/srv/net/tl/udp/udp.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 34 * UDP module. 35 35 */ 36 36 37 #ifndef __NET_UDP_H__38 #define __NET_UDP_H__37 #ifndef NET_UDP_H_ 38 #define NET_UDP_H_ 39 39 40 40 #include <fibril_synch.h> … … 43 43 44 44 /** Type definition of the UDP global data. 45 * 45 * @see udp_globals 46 46 */ 47 typedef struct udp_globals 47 typedef struct udp_globals udp_globals_t; 48 48 49 /** UDP global data. 50 */ 51 struct udp_globals{ 52 /** Networking module phone. 53 */ 49 /** UDP global data. */ 50 struct udp_globals { 51 /** Networking module phone. */ 54 52 int net_phone; 55 /** IP module phone. 56 */ 53 /** IP module phone. */ 57 54 int ip_phone; 58 /** ICMP module phone. 59 */ 55 /** ICMP module phone. */ 60 56 int icmp_phone; 61 /** Packet dimension. 62 */ 57 /** Packet dimension. */ 63 58 packet_dimension_t packet_dimension; 64 /** Indicates whether UDP checksum computing is enabled. 65 */ 59 /** Indicates whether UDP checksum computing is enabled. */ 66 60 int checksum_computing; 67 /** Indicates whether UDP autobnding on send is enabled. 68 */ 61 /** Indicates whether UDP autobnding on send is enabled. */ 69 62 int autobinding; 70 /** Last used free port. 71 */ 63 /** Last used free port. */ 72 64 int last_used_port; 73 /** Active sockets. 74 */ 65 /** Active sockets. */ 75 66 socket_ports_t sockets; 76 /** Device packet dimensions. 77 */ 67 /** Device packet dimensions. */ 78 68 packet_dimensions_t dimensions; 79 /** Safety lock. 80 */ 69 /** Safety lock. */ 81 70 fibril_rwlock_t lock; 82 71 }; … … 86 75 /** @} 87 76 */ 88 -
uspace/srv/net/tl/udp/udp_header.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * Based on the RFC~768.34 * UDP header definition. 35 * Based on the RFC 768. 36 36 */ 37 37 38 #ifndef __NET_UDP_HEADER_H__39 #define __NET_UDP_HEADER_H__38 #ifndef NET_UDP_HEADER_H_ 39 #define NET_UDP_HEADER_H_ 40 40 41 41 #include <sys/types.h> 42 42 43 /** UDP header size in bytes. 44 */ 45 #define UDP_HEADER_SIZE sizeof(udp_header_t) 43 /** UDP header size in bytes. */ 44 #define UDP_HEADER_SIZE sizeof(udp_header_t) 46 45 47 46 /** Type definition of the user datagram header. 48 * 47 * @see udp_header 49 48 */ 50 typedef struct udp_header 49 typedef struct udp_header udp_header_t; 51 50 52 51 /** Type definition of the user datagram header pointer. 53 * 52 * @see udp_header 54 53 */ 55 typedef udp_header_t * 54 typedef udp_header_t *udp_header_ref; 56 55 57 /** User datagram header. 58 */ 59 struct udp_header{ 60 /** Source Port is an optional field, when meaningful, it indicates the port of the sending process, and may be assumed to be the port to which a reply should be addressed in the absence of any other information. 61 * If not used, a value of zero is inserted. 62 */ 56 /** User datagram header. */ 57 struct udp_header { 63 58 uint16_t source_port; 64 /** Destination port has a meaning within the context of a particular internet destination address.65 */66 59 uint16_t destination_port; 67 /** Length is the length in octets of this user datagram including this header and the data.68 * This means the minimum value of the length is eight.69 */70 60 uint16_t total_length; 71 /** Checksum is the 16-bit one's complement of the one's complement sum of a pseudo header of information from the IP header, the UDP header, and the data, padded with zero octets at the end (if necessary) to make a multiple of two octets.72 * The pseudo header conceptually prefixed to the UDP header contains the source address, the destination address, the protocol, and the UDP length.73 * This information gives protection against misrouted datagrams.74 * If the computed checksum is zero, it is transmitted as all ones (the equivalent in one's complement arithmetic).75 * An all zero transmitted checksum value means that the transmitter generated no checksum (for debugging or for higher level protocols that don't care).76 */77 61 uint16_t checksum; 78 62 } __attribute__ ((packed)); -
uspace/srv/net/tl/udp/udp_module.c
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * UDP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry points. 37 * @see module.c 34 * UDP standalone module implementation. 35 * Contains skeleton module functions mapping. 36 * The functions are used by the module skeleton as module specific entry 37 * points. 38 * @see module.c 38 39 */ 40 41 #include "udp.h" 42 #include "udp_module.h" 39 43 40 44 #include <async.h> 41 45 #include <stdio.h> 42 #include <err .h>46 #include <errno.h> 43 47 #include <ipc/ipc.h> 44 48 #include <ipc/services.h> … … 46 50 #include <net/modules.h> 47 51 #include <net/packet.h> 52 48 53 #include <net_interface.h> 49 54 #include <tl_local.h> 50 55 51 #include "udp.h" 52 #include "udp_module.h" 56 /** UDP module global data. */ 57 extern udp_globals_t udp_globals; 53 58 54 /** UDP module global data. 55 */ 56 extern udp_globals_t udp_globals; 57 58 /** Starts the UDP module. 59 * Initializes the client connection serving function, initializes the module, registers the module service and starts the async manager, processing IPC messages in an infinite loop. 60 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 61 * @returns EOK on successful module termination. 62 * @returns Other error codes as defined for the udp_initialize() function. 63 * @returns Other error codes as defined for the REGISTER_ME() macro function. 64 */ 65 int tl_module_start_standalone(async_client_conn_t client_connection){ 66 ERROR_DECLARE; 67 59 int tl_module_start_standalone(async_client_conn_t client_connection) 60 { 68 61 ipcarg_t phonehash; 62 int rc; 69 63 70 64 async_set_client_connection(client_connection); 71 65 udp_globals.net_phone = net_connect_module(); 72 if (udp_globals.net_phone < 0){66 if (udp_globals.net_phone < 0) 73 67 return udp_globals.net_phone; 74 } 75 ERROR_PROPAGATE(pm_init()); 76 if(ERROR_OCCURRED(udp_initialize(client_connection)) 77 || ERROR_OCCURRED(REGISTER_ME(SERVICE_UDP, &phonehash))){ 78 pm_destroy(); 79 return ERROR_CODE; 80 } 68 69 rc = pm_init(); 70 if (rc != EOK) 71 return EOK; 72 73 rc = udp_initialize(client_connection); 74 if (rc != EOK) 75 goto out; 76 77 rc = REGISTER_ME(SERVICE_UDP, &phonehash); 78 if (rc != EOK) 79 goto out; 81 80 82 81 async_manager(); 83 82 83 out: 84 84 pm_destroy(); 85 return EOK;85 return rc; 86 86 } 87 87 88 /** Processes the UDP message. 89 * @param[in] callid The message identifier. 90 * @param[in] call The message parameters. 91 * @param[out] answer The message answer parameters. 92 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 93 * @returns EOK on success. 94 * @returns Other error codes as defined for the udp_message() function. 95 */ 96 int tl_module_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 88 int 89 tl_module_message_standalone(ipc_callid_t callid, ipc_call_t *call, 90 ipc_call_t *answer, int *answer_count) 91 { 97 92 return udp_message_standalone(callid, call, answer, answer_count); 98 93 } -
uspace/srv/net/tl/udp/udp_module.h
rd70a463 rb40bfac 28 28 29 29 /** @addtogroup udp 30 * 30 * @{ 31 31 */ 32 32 33 33 /** @file 34 * 35 * 34 * UDP module functions. 35 * The functions are used as UDP module entry points. 36 36 */ 37 37 38 #ifndef __NET_UDP_MODULE_H__39 #define __NET_UDP_MODULE_H__38 #ifndef NET_UDP_MODULE_H_ 39 #define NET_UDP_MODULE_H_ 40 40 41 41 #include <async.h> 42 42 #include <ipc/ipc.h> 43 43 44 /** Initializes the UDP module. 45 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 46 * @returns EOK on success. 47 * @returns ENOMEM if there is not enough memory left. 48 */ 49 extern int udp_initialize(async_client_conn_t client_connection); 50 51 /** Processes the UDP message. 52 * @param[in] callid The message identifier. 53 * @param[in] call The message parameters. 54 * @param[out] answer The message answer parameters. 55 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 56 * @returns EOK on success. 57 * @returns ENOTSUP if the message is not known. 58 * @see udp_interface.h 59 * @see IS_NET_UDP_MESSAGE() 60 */ 61 extern int udp_message_standalone(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 44 extern int udp_initialize(async_client_conn_t); 45 extern int udp_message_standalone(ipc_callid_t, ipc_call_t *, ipc_call_t *, 46 int *); 62 47 63 48 #endif -
uspace/srv/taskmon/taskmon.c
rd70a463 rb40bfac 50 50 static void fault_event(ipc_callid_t callid, ipc_call_t *call) 51 51 { 52 const char *argv[6];53 52 const char *fname; 54 char *dump_fname;55 53 char *s_taskid; 56 const char **s;54 int rc; 57 55 58 56 task_id_t taskid; … … 67 65 } 68 66 67 printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread); 68 69 fname = "/app/taskdump"; 70 71 #ifdef CONFIG_WRITE_CORE_FILES 72 char *dump_fname; 73 69 74 if (asprintf(&dump_fname, "/data/core%" PRIuTASKID, taskid) < 0) { 70 75 printf("Memory allocation failed.\n"); … … 72 77 } 73 78 74 printf(NAME ": Task %" PRIuTASKID " fault in thread %p.\n", taskid, thread); 75 76 #ifdef CONFIG_WRITE_CORE_FILES 77 argv[0] = "/app/taskdump"; 78 argv[1] = "-c"; 79 argv[2] = dump_fname; 80 argv[3] = "-t"; 81 argv[4] = s_taskid; 82 argv[5] = NULL; 79 printf(NAME ": Executing %s -c %s -t %s\n", dump_fname, s_taskid); 80 rc = task_spawnl(NULL, fname, fname, "-c", dump_fname, "-t", s_taskid, 81 NULL); 83 82 #else 84 argv[0] = "/app/taskdump"; 85 argv[1] = "-t"; 86 argv[2] = s_taskid; 87 argv[3] = NULL; 83 printf(NAME ": Executing %s -t %s\n", s_taskid); 84 rc = task_spawnl(NULL, fname, fname, "-t", s_taskid, NULL); 88 85 #endif 89 fname = argv[0]; 90 91 printf(NAME ": Executing"); 92 93 s = argv; 94 while (*s != NULL) { 95 printf(" %s", *s); 96 ++s; 86 if (rc != EOK) { 87 printf("%s: Error spawning %s (%s).\n", NAME, fname, 88 str_error(rc)); 97 89 } 98 putchar('\n');99 100 int err;101 if (!task_spawn(fname, argv, &err))102 printf("%s: Error spawning %s (%s).\n", NAME, fname,103 str_error(err));104 90 } 105 91
Note:
See TracChangeset
for help on using the changeset viewer.