Changeset 60ab6c3 in mainline
- Timestamp:
- 2010-03-10T05:46:54Z (15 years ago)
- Branches:
- lfn, master, serial, ticket/834-toolchain-update, topic/msim-upgrade, topic/simplify-dev-export
- Children:
- 5782081
- Parents:
- 71b00dcc (diff), b48ebd19 (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/srv/net
- Files:
-
- 2 added
- 46 edited
Legend:
- Unmodified
- Added
- Removed
-
uspace/srv/net/Doxyfile
r71b00dcc r60ab6c3 6 6 DOXYFILE_ENCODING = UTF-8 7 7 PROJECT_NAME = "Networking and TCP/IP stack for HelenOS system" 8 PROJECT_NUMBER = " Master thesis 2009"8 PROJECT_NUMBER = "" 9 9 OUTPUT_DIRECTORY = doc/ 10 10 CREATE_SUBDIRS = YES -
uspace/srv/net/Makefile
r71b00dcc r60ab6c3 29 29 include ../../../Makefile.config 30 30 31 DIRS = \ 31 # keep netif drivers before nil modules 32 # in order to support networking architectures build 33 34 ifeq ($(CONFIG_NETIF_DP8390),y) 35 DIRS = netif/dp8390 36 else 37 DIRS = 38 endif 39 40 DIRS += \ 32 41 netif/lo \ 33 42 nil/eth \ … … 47 56 tl/udp \ 48 57 tl/tcp \ 49 50 ifeq ($(CONFIG_NETIF_DP8390),y)51 DIRS += netif/dp839052 endif53 58 54 59 DIRS_ALL = $(DIRS) $(DIRS_MODULAR) -
uspace/srv/net/app/echo/echo.c
r71b00dcc r60ab6c3 55 55 #define NAME "Echo" 56 56 57 /** Prints the application help. 58 */ 59 void echo_print_help(void); 60 57 61 /** Module entry point. 58 62 * Reads command line parameters and starts listenning. … … 62 66 */ 63 67 int main(int argc, char * argv[]); 64 65 /** Prints the application help.66 */67 void echo_print_help(void);68 69 /** Translates the character string to the protocol family number.70 * @param[in] name The protocol family name.71 * @returns The corresponding protocol family number.72 * @returns EPFNOSUPPORTED if the protocol family is not supported.73 */74 int echo_parse_protocol_family(const char * name);75 76 /** Translates the character string to the socket type number.77 * @param[in] name The socket type name.78 * @returns The corresponding socket type number.79 * @returns ESOCKNOSUPPORTED if the socket type is not supported.80 */81 int echo_parse_socket_type(const char * name);82 68 83 69 void echo_print_help(void){ … … 115 101 } 116 102 117 int echo_parse_protocol_family(const char * name){118 if(str_lcmp(name, "PF_INET", 7) == 0){119 return PF_INET;120 }else if(str_lcmp(name, "PF_INET6", 8) == 0){121 return PF_INET6;122 }123 return EPFNOSUPPORT;124 }125 126 int echo_parse_socket_type(const char * name){127 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){128 return SOCK_DGRAM;129 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){130 return SOCK_STREAM;131 }132 return ESOCKTNOSUPPORT;133 }134 135 103 int main(int argc, char * argv[]){ 136 104 ERROR_DECLARE; … … 138 106 size_t size = 1024; 139 107 int verbose = 0; 140 char * reply 141 sock_type_t type 108 char * reply = NULL; 109 sock_type_t type = SOCK_DGRAM; 142 110 int count = -1; 143 111 int family = PF_INET; 144 uint16_t port 112 uint16_t port = 7; 145 113 int backlog = 3; 146 114 147 socklen_t max_length = sizeof(struct sockaddr_in6);115 socklen_t max_length = sizeof(struct sockaddr_in6); 148 116 uint8_t address_data[max_length]; 149 struct sockaddr * address = (struct sockaddr *) address_data;117 struct sockaddr * address = (struct sockaddr *) address_data; 150 118 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 151 119 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; … … 155 123 int socket_id; 156 124 int listening_id; 157 char * 125 char * data; 158 126 size_t length; 159 127 int index; … … 161 129 int value; 162 130 131 // print the program label 163 132 printf("Task %d - ", task_get_id()); 164 133 printf("%s\n", NAME); 165 134 135 // parse the command line arguments 166 136 for(index = 1; index < argc; ++ index){ 167 137 if(argv[index][0] == '-'){ … … 174 144 break; 175 145 case 'f': 176 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, echo_parse_protocol_family));146 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 177 147 break; 178 148 case 'h': … … 192 162 break; 193 163 case 't': 194 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, echo_parse_socket_type));164 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 0, parse_socket_type)); 195 165 type = (sock_type_t) value; 196 166 break; … … 198 168 verbose = 1; 199 169 break; 170 // long options with the double minus sign ('-') 200 171 case '-': 201 172 if(str_lcmp(argv[index] + 2, "backlog=", 6) == 0){ … … 204 175 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "message count", 8)); 205 176 }else if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 206 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, echo_parse_protocol_family));177 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 207 178 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 208 179 echo_print_help(); … … 217 188 size = (value >= 0) ? (size_t) value : 0; 218 189 }else if(str_lcmp(argv[index] + 2, "type=", 5) == 0){ 219 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, echo_parse_socket_type));190 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &value, "socket type", 7, parse_socket_type)); 220 191 type = (sock_type_t) value; 221 192 }else if(str_lcmp(argv[index] + 2, "verbose", 8) == 0){ … … 239 210 } 240 211 212 // check the buffer size 241 213 if(size <= 0){ 242 214 fprintf(stderr, "Receive size too small (%d). Using 1024 bytes instead.\n", size); 243 215 size = 1024; 244 216 } 245 // size plus t erminating null (\0)217 // size plus the terminating null (\0) 246 218 data = (char *) malloc(size + 1); 247 219 if(! data){ … … 250 222 } 251 223 224 // set the reply size if set 252 225 reply_length = reply ? str_length(reply) : 0; 253 226 254 listening_id = socket(family, type, 0); 255 if(listening_id < 0){ 256 socket_print_error(stderr, listening_id, "Socket create: ", "\n"); 257 return listening_id; 258 } 259 227 // prepare the address buffer 260 228 bzero(address_data, max_length); 261 229 switch(family){ … … 275 243 } 276 244 245 // get a listening socket 277 246 listening_id = socket(family, type, 0); 278 247 if(listening_id < 0){ … … 281 250 } 282 251 252 // if the stream socket is used 283 253 if(type == SOCK_STREAM){ 254 // check the backlog 284 255 if(backlog <= 0){ 285 256 fprintf(stderr, "Accepted sockets queue size too small (%d). Using 3 instead.\n", size); 286 257 backlog = 3; 287 258 } 259 // set the backlog 288 260 if(ERROR_OCCURRED(listen(listening_id, backlog))){ 289 261 socket_print_error(stderr, ERROR_CODE, "Socket listen: ", "\n"); … … 292 264 } 293 265 266 // bind the listenning socket 294 267 if(ERROR_OCCURRED(bind(listening_id, address, addrlen))){ 295 268 socket_print_error(stderr, ERROR_CODE, "Socket bind: ", "\n"); … … 303 276 socket_id = listening_id; 304 277 278 // do count times 279 // or indefinitely if set to a negative value 305 280 while(count){ 281 306 282 addrlen = max_length; 307 283 if(type == SOCK_STREAM){ 284 // acceept a socket if the stream socket is used 308 285 socket_id = accept(listening_id, address, &addrlen); 309 286 if(socket_id <= 0){ … … 315 292 } 316 293 } 294 295 // if the datagram socket is used or the stream socked was accepted 317 296 if(socket_id > 0){ 297 298 // receive an echo request 318 299 value = recvfrom(socket_id, data, size, 0, address, &addrlen); 319 300 if(value < 0){ … … 322 303 length = (size_t) value; 323 304 if(verbose){ 305 // print the header 306 307 // get the source port and prepare the address buffer 324 308 address_start = NULL; 325 309 switch(address->sa_family){ … … 335 319 fprintf(stderr, "Address family %d (0x%X) is not supported.\n", address->sa_family); 336 320 } 321 // parse the source address 337 322 if(address_start){ 338 323 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ … … 344 329 } 345 330 } 331 332 // answer the request either with the static reply or the original data 346 333 if(ERROR_OCCURRED(sendto(socket_id, reply ? reply : data, reply ? reply_length : length, 0, address, addrlen))){ 347 334 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 348 335 } 349 } 336 337 } 338 339 // close the accepted stream socket 350 340 if(type == SOCK_STREAM){ 351 341 if(ERROR_OCCURRED(closesocket(socket_id))){ … … 353 343 } 354 344 } 355 } 345 346 } 347 348 // decrease the count if positive 356 349 if(count > 0){ 357 350 -- count; … … 366 359 } 367 360 361 // close the listenning socket 368 362 if(ERROR_OCCURRED(closesocket(listening_id))){ 369 363 socket_print_error(stderr, ERROR_CODE, "Close socket: ", "\n"); -
uspace/srv/net/app/nettest1/Makefile
r71b00dcc r60ab6c3 40 40 SOURCES = \ 41 41 $(NAME).c \ 42 $(NET_BASE)app/nettest.c \ 42 43 $(NET_BASE)app/parse.c \ 43 44 $(NET_BASE)app/print_error.c -
uspace/srv/net/app/nettest1/nettest1.c
r71b00dcc r60ab6c3 48 48 #include "../../err.h" 49 49 50 #include "../nettest.h" 50 51 #include "../parse.h" 51 52 #include "../print_error.h" … … 69 70 /** Prints the application help. 70 71 */ 71 void print_help(void); 72 73 /** Translates the character string to the protocol family number. 74 * @param[in] name The protocol family name. 75 * @returns The corresponding protocol family number. 76 * @returns EPFNOSUPPORTED if the protocol family is not supported. 77 */ 78 int parse_protocol_family(const char * name); 79 80 /** Translates the character string to the socket type number. 81 * @param[in] name The socket type name. 82 * @returns The corresponding socket type number. 83 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 84 */ 85 int parse_socket_type(const char * name); 72 void nettest1_print_help(void); 86 73 87 74 /** Refreshes the data. … … 90 77 * @param[in] size The data block size in bytes. 91 78 */ 92 void refresh_data(char * data, size_t size); 93 94 /** Creates new sockets. 95 * @param[in] verbose A value indicating whether to print out verbose information. 96 * @param[out] socket_ids A field to store the socket identifiers. 97 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 98 * @param[in] family The socket address family. 99 * @param[in] type The socket type. 100 * @returns EOK on success. 101 * @returns Other error codes as defined for the socket() function. 102 */ 103 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type); 104 105 /** Closes sockets. 106 * @param[in] verbose A value indicating whether to print out verbose information. 107 * @param[in] socket_ids A field of stored socket identifiers. 108 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 109 * @returns EOK on success. 110 * @returns Other error codes as defined for the closesocket() function. 111 */ 112 int sockets_close(int verbose, int * socket_ids, int sockets); 113 114 /** Connects sockets. 115 * @param[in] verbose A value indicating whether to print out verbose information. 116 * @param[in] socket_ids A field of stored socket identifiers. 117 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 118 * @param[in] address The destination host address to connect to. 119 * @param[in] addrlen The length of the destination address in bytes. 120 * @returns EOK on success. 121 * @returns Other error codes as defined for the connect() function. 122 */ 123 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen); 124 125 /** Sends data via sockets. 126 * @param[in] verbose A value indicating whether to print out verbose information. 127 * @param[in] socket_ids A field of stored socket identifiers. 128 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 129 * @param[in] address The destination host address to send data to. 130 * @param[in] addrlen The length of the destination address in bytes. 131 * @param[in] data The data to be sent. 132 * @param[in] size The data size in bytes. 133 * @param[in] messages The number of datagrams per socket to be sent. 134 * @returns EOK on success. 135 * @returns Other error codes as defined for the sendto() function. 136 */ 137 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages); 138 139 /** Receives data via sockets. 140 * @param[in] verbose A value indicating whether to print out verbose information. 141 * @param[in] socket_ids A field of stored socket identifiers. 142 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 143 * @param[in] address The source host address of received datagrams. 144 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 145 * @param[out] data The received data. 146 * @param[in] size The maximum data size in bytes. 147 * @param[in] messages The number of datagrams per socket to be received. 148 * @returns EOK on success. 149 * @returns Other error codes as defined for the recvfrom() function. 150 */ 151 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 152 153 /** Sends and receives data via sockets. 154 * Each datagram is sent and a reply read consequently. 155 * The next datagram is sent after the reply is received. 156 * @param[in] verbose A value indicating whether to print out verbose information. 157 * @param[in] socket_ids A field of stored socket identifiers. 158 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 159 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 160 * @param[in] addrlen The length of the destination address in bytes. 161 * @param[in,out] data The data to be sent. The received data are set instead. 162 * @param[in] size The data size in bytes. 163 * @param[in] messages The number of datagrams per socket to be received. 164 * @returns EOK on success. 165 * @returns Other error codes as defined for the recvfrom() function. 166 */ 167 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 168 169 /** Prints a mark. 170 * If the index is a multiple of ten, a different mark is printed. 171 * @param[in] index The index of the mark to be printed. 172 */ 173 void print_mark(int index); 174 175 void print_help(void){ 176 printf( 177 "Network Networking test 1 aplication - sockets\n" \ 178 "Usage: echo [options] numeric_address\n" \ 179 "Where options are:\n" \ 180 "-f protocol_family | --family=protocol_family\n" \ 181 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 182 "\n" \ 183 "-h | --help\n" \ 184 "\tShow this application help.\n" 185 "\n" \ 186 "-m count | --messages=count\n" \ 187 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 188 "\n" \ 189 "-n sockets | --sockets=count\n" \ 190 "\tThe number of sockets to use. The default is 10.\n" \ 191 "\n" \ 192 "-p port_number | --port=port_number\n" \ 193 "\tThe port number the application should send messages to. The default is 7.\n" \ 194 "\n" \ 195 "-s packet_size | --size=packet_size\n" \ 196 "\tThe packet data size the application sends. The default is 28 bytes.\n" \ 197 "\n" \ 198 "-v | --verbose\n" \ 199 "\tShow all output messages.\n" 200 ); 201 } 202 203 int parse_protocol_family(const char * name){ 204 if(str_lcmp(name, "PF_INET", 7) == 0){ 205 return PF_INET; 206 }else if(str_lcmp(name, "PF_INET6", 8) == 0){ 207 return PF_INET6; 208 } 209 return EPFNOSUPPORT; 210 } 211 212 int parse_socket_type(const char * name){ 213 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){ 214 return SOCK_DGRAM; 215 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){ 216 return SOCK_STREAM; 217 } 218 return ESOCKTNOSUPPORT; 219 } 220 221 void refresh_data(char * data, size_t size){ 222 size_t length; 223 224 // fill the data 225 length = 0; 226 while(size > length + sizeof(NETTEST1_TEXT) - 1){ 227 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1); 228 length += sizeof(NETTEST1_TEXT) - 1; 229 } 230 memcpy(data + length, NETTEST1_TEXT, size - length); 231 data[size] = '\0'; 232 } 233 234 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){ 235 int index; 236 237 if(verbose){ 238 printf("Create\t"); 239 } 240 fflush(stdout); 241 for(index = 0; index < sockets; ++ index){ 242 socket_ids[index] = socket(family, type, 0); 243 if(socket_ids[index] < 0){ 244 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 245 socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n"); 246 return socket_ids[index]; 247 } 248 if(verbose){ 249 print_mark(index); 250 } 251 } 252 return EOK; 253 } 254 255 int sockets_close(int verbose, int * socket_ids, int sockets){ 256 ERROR_DECLARE; 257 258 int index; 259 260 if(verbose){ 261 printf("\tClose\t"); 262 } 263 fflush(stdout); 264 for(index = 0; index < sockets; ++ index){ 265 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){ 266 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 267 socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n"); 268 return ERROR_CODE; 269 } 270 if(verbose){ 271 print_mark(index); 272 } 273 } 274 return EOK; 275 } 276 277 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){ 278 ERROR_DECLARE; 279 280 int index; 281 282 if(verbose){ 283 printf("\tConnect\t"); 284 } 285 fflush(stdout); 286 for(index = 0; index < sockets; ++ index){ 287 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){ 288 socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n"); 289 return ERROR_CODE; 290 } 291 if(verbose){ 292 print_mark(index); 293 } 294 } 295 return EOK; 296 } 297 298 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){ 299 ERROR_DECLARE; 300 301 int index; 302 int message; 303 304 if(verbose){ 305 printf("\tSendto\t"); 306 } 307 fflush(stdout); 308 for(index = 0; index < sockets; ++ index){ 309 for(message = 0; message < messages; ++ message){ 310 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){ 311 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 312 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 313 return ERROR_CODE; 314 } 315 } 316 if(verbose){ 317 print_mark(index); 318 } 319 } 320 return EOK; 321 } 322 323 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 324 int value; 325 int index; 326 int message; 327 328 if(verbose){ 329 printf("\tRecvfrom\t"); 330 } 331 fflush(stdout); 332 for(index = 0; index < sockets; ++ index){ 333 for(message = 0; message < messages; ++ message){ 334 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 335 if(value < 0){ 336 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 337 socket_print_error(stderr, value, "Socket receive: ", "\n"); 338 return value; 339 } 340 } 341 if(verbose){ 342 print_mark(index); 343 } 344 } 345 return EOK; 346 } 347 348 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 349 ERROR_DECLARE; 350 351 int value; 352 int index; 353 int message; 354 355 if(verbose){ 356 printf("\tSendto and recvfrom\t"); 357 } 358 fflush(stdout); 359 for(index = 0; index < sockets; ++ index){ 360 for(message = 0; message < messages; ++ message){ 361 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){ 362 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 363 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 364 return ERROR_CODE; 365 } 366 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 367 if(value < 0){ 368 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 369 socket_print_error(stderr, value, "Socket receive: ", "\n"); 370 return value; 371 } 372 } 373 if(verbose){ 374 print_mark(index); 375 } 376 } 377 return EOK; 378 } 379 380 void print_mark(int index){ 381 if((index + 1) % 10){ 382 printf("*"); 383 }else{ 384 printf("|"); 385 } 386 fflush(stdout); 387 } 79 void nettest1_refresh_data(char * data, size_t size); 388 80 389 81 int main(int argc, char * argv[]){ … … 392 84 size_t size = 27; 393 85 int verbose = 0; 394 sock_type_t type 86 sock_type_t type = SOCK_DGRAM; 395 87 int sockets = 10; 396 88 int messages = 10; 397 89 int family = PF_INET; 398 uint16_t port 399 400 socklen_t max_length = sizeof(struct sockaddr_in6);90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 401 93 uint8_t address_data[max_length]; 402 struct sockaddr * address = (struct sockaddr *) address_data;94 struct sockaddr * address = (struct sockaddr *) address_data; 403 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 404 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 405 97 socklen_t addrlen; 406 // char 98 // char address_string[INET6_ADDRSTRLEN]; 407 99 uint8_t * address_start; 408 100 409 101 int * socket_ids; 410 char * 102 char * data; 411 103 int value; 412 104 int index; … … 414 106 struct timeval time_after; 415 107 108 // print the program label 416 109 printf("Task %d - ", task_get_id()); 417 110 printf("%s\n", NAME); 418 111 419 if(argc <= 1){ 420 print_help(); 421 return EINVAL; 422 } 423 424 for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){ 112 // parse the command line arguments 113 // stop before the last argument if it does not start with the minus sign ('-') 114 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 115 // options should start with the minus sign ('-') 425 116 if(argv[index][0] == '-'){ 426 117 switch(argv[index][1]){ 118 // short options with only one letter 427 119 case 'f': 428 120 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 429 121 break; 430 122 case 'h': 431 print_help();123 nettest1_print_help(); 432 124 return EOK; 433 125 break; … … 453 145 verbose = 1; 454 146 break; 147 // long options with the double minus sign ('-') 455 148 case '-': 456 149 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 457 150 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 458 151 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 459 print_help();152 nettest1_print_help(); 460 153 return EOK; 461 154 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ … … 473 166 }else{ 474 167 print_unrecognized(index, argv[index] + 2); 475 print_help();168 nettest1_print_help(); 476 169 return EINVAL; 477 170 } … … 479 172 default: 480 173 print_unrecognized(index, argv[index] + 1); 481 print_help();174 nettest1_print_help(); 482 175 return EINVAL; 483 176 } 484 177 }else{ 485 178 print_unrecognized(index, argv[index]); 486 print_help();179 nettest1_print_help(); 487 180 return EINVAL; 488 181 } 489 182 } 490 183 184 // if not before the last argument containing the address 185 if(index >= argc){ 186 printf("Command line error: missing address\n"); 187 nettest1_print_help(); 188 return EINVAL; 189 } 190 191 // prepare the address buffer 491 192 bzero(address_data, max_length); 492 193 switch(family){ … … 508 209 } 509 210 211 // parse the last argument which should contain the address 510 212 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 511 213 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 513 215 } 514 216 217 // check the buffer size 515 218 if(size <= 0){ 516 219 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 517 220 size = 1024; 518 221 } 519 // size plus terminating null (\0) 222 223 // prepare the buffer 224 // size plus the terminating null (\0) 520 225 data = (char *) malloc(size + 1); 521 226 if(! data){ … … 523 228 return ENOMEM; 524 229 } 525 refresh_data(data, size); 526 230 nettest1_refresh_data(data, size); 231 232 // check the socket count 527 233 if(sockets <= 0){ 528 234 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 529 235 sockets = 2; 530 236 } 531 // count plus terminating null (\0) 237 238 // prepare the socket buffer 239 // count plus the terminating null (\0) 532 240 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 533 241 if(! socket_ids){ … … 673 381 } 674 382 383 void nettest1_print_help(void){ 384 printf( 385 "Network Networking test 1 aplication - sockets\n" \ 386 "Usage: echo [options] numeric_address\n" \ 387 "Where options are:\n" \ 388 "-f protocol_family | --family=protocol_family\n" \ 389 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 390 "\n" \ 391 "-h | --help\n" \ 392 "\tShow this application help.\n" 393 "\n" \ 394 "-m count | --messages=count\n" \ 395 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 396 "\n" \ 397 "-n sockets | --sockets=count\n" \ 398 "\tThe number of sockets to use. The default is 10.\n" \ 399 "\n" \ 400 "-p port_number | --port=port_number\n" \ 401 "\tThe port number the application should send messages to. The default is 7.\n" \ 402 "\n" \ 403 "-s packet_size | --size=packet_size\n" \ 404 "\tThe packet data size the application sends. The default is 28 bytes.\n" \ 405 "\n" \ 406 "-v | --verbose\n" \ 407 "\tShow all output messages.\n" 408 ); 409 } 410 411 void nettest1_refresh_data(char * data, size_t size){ 412 size_t length; 413 414 // fill the data 415 length = 0; 416 while(size > length + sizeof(NETTEST1_TEXT) - 1){ 417 memcpy(data + length, NETTEST1_TEXT, sizeof(NETTEST1_TEXT) - 1); 418 length += sizeof(NETTEST1_TEXT) - 1; 419 } 420 memcpy(data + length, NETTEST1_TEXT, size - length); 421 data[size] = '\0'; 422 } 423 675 424 /** @} 676 425 */ -
uspace/srv/net/app/nettest2/Makefile
r71b00dcc r60ab6c3 40 40 SOURCES = \ 41 41 $(NAME).c \ 42 $(NET_BASE)app/nettest.c \ 42 43 $(NET_BASE)app/parse.c \ 43 44 $(NET_BASE)app/print_error.c -
uspace/srv/net/app/nettest2/nettest2.c
r71b00dcc r60ab6c3 48 48 #include "../../err.h" 49 49 50 #include "../nettest.h" 50 51 #include "../parse.h" 51 52 #include "../print_error.h" … … 69 70 /** Prints the application help. 70 71 */ 71 void print_help(void); 72 73 /** Translates the character string to the protocol family number. 74 * @param[in] name The protocol family name. 75 * @returns The corresponding protocol family number. 76 * @returns EPFNOSUPPORTED if the protocol family is not supported. 77 */ 78 int parse_protocol_family(const char * name); 79 80 /** Translates the character string to the socket type number. 81 * @param[in] name The socket type name. 82 * @returns The corresponding socket type number. 83 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 84 */ 85 int parse_socket_type(const char * name); 72 void nettest2_print_help(void); 86 73 87 74 /** Refreshes the data. … … 90 77 * @param[in] size The data block size in bytes. 91 78 */ 92 void refresh_data(char * data, size_t size); 93 94 /** Creates new sockets. 95 * @param[in] verbose A value indicating whether to print out verbose information. 96 * @param[out] socket_ids A field to store the socket identifiers. 97 * @param[in] sockets The number of sockets to create. Should be at most the size of the field. 98 * @param[in] family The socket address family. 99 * @param[in] type The socket type. 100 * @returns EOK on success. 101 * @returns Other error codes as defined for the socket() function. 102 */ 103 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type); 104 105 /** Closes sockets. 106 * @param[in] verbose A value indicating whether to print out verbose information. 107 * @param[in] socket_ids A field of stored socket identifiers. 108 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 109 * @returns EOK on success. 110 * @returns Other error codes as defined for the closesocket() function. 111 */ 112 int sockets_close(int verbose, int * socket_ids, int sockets); 113 114 /** Connects sockets. 115 * @param[in] verbose A value indicating whether to print out verbose information. 116 * @param[in] socket_ids A field of stored socket identifiers. 117 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 118 * @param[in] address The destination host address to connect to. 119 * @param[in] addrlen The length of the destination address in bytes. 120 * @returns EOK on success. 121 * @returns Other error codes as defined for the connect() function. 122 */ 123 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen); 124 125 /** Sends data via sockets. 126 * @param[in] verbose A value indicating whether to print out verbose information. 127 * @param[in] socket_ids A field of stored socket identifiers. 128 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 129 * @param[in] address The destination host address to send data to. 130 * @param[in] addrlen The length of the destination address in bytes. 131 * @param[in] data The data to be sent. 132 * @param[in] size The data size in bytes. 133 * @param[in] messages The number of datagrams per socket to be sent. 134 * @returns EOK on success. 135 * @returns Other error codes as defined for the sendto() function. 136 */ 137 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages); 138 139 /** Receives data via sockets. 140 * @param[in] verbose A value indicating whether to print out verbose information. 141 * @param[in] socket_ids A field of stored socket identifiers. 142 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 143 * @param[in] address The source host address of received datagrams. 144 * @param[in,out] addrlen The maximum length of the source address in bytes. The actual size of the source address is set instead. 145 * @param[out] data The received data. 146 * @param[in] size The maximum data size in bytes. 147 * @param[in] messages The number of datagrams per socket to be received. 148 * @returns EOK on success. 149 * @returns Other error codes as defined for the recvfrom() function. 150 */ 151 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 152 153 /** Sends and receives data via sockets. 154 * Each datagram is sent and a reply read consequently. 155 * The next datagram is sent after the reply is received. 156 * @param[in] verbose A value indicating whether to print out verbose information. 157 * @param[in] socket_ids A field of stored socket identifiers. 158 * @param[in] sockets The number of sockets in the field. Should be at most the size of the field. 159 * @param[in,out] address The destination host address to send data to. The source host address of received datagrams is set instead. 160 * @param[in] addrlen The length of the destination address in bytes. 161 * @param[in,out] data The data to be sent. The received data are set instead. 162 * @param[in] size The data size in bytes. 163 * @param[in] messages The number of datagrams per socket to be received. 164 * @returns EOK on success. 165 * @returns Other error codes as defined for the recvfrom() function. 166 */ 167 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages); 168 169 /** Prints a mark. 170 * If the index is a multiple of ten, a different mark is printed. 171 * @param[in] index The index of the mark to be printed. 172 */ 173 void print_mark(int index); 174 175 void print_help(void){ 176 printf( 177 "Network Networking test 2 aplication - UDP transfer\n" \ 178 "Usage: echo [options] numeric_address\n" \ 179 "Where options are:\n" \ 180 "-f protocol_family | --family=protocol_family\n" \ 181 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 182 "\n" \ 183 "-h | --help\n" \ 184 "\tShow this application help.\n" 185 "\n" \ 186 "-m count | --messages=count\n" \ 187 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 188 "\n" \ 189 "-n sockets | --sockets=count\n" \ 190 "\tThe number of sockets to use. The default is 10.\n" \ 191 "\n" \ 192 "-p port_number | --port=port_number\n" \ 193 "\tThe port number the application should send messages to. The default is 7.\n" \ 194 "\n" \ 195 "-s packet_size | --size=packet_size\n" \ 196 "\tThe packet data size the application sends. The default is 29 bytes.\n" \ 197 "\n" \ 198 "-v | --verbose\n" \ 199 "\tShow all output messages.\n" 200 ); 201 } 202 203 int parse_protocol_family(const char * name){ 204 if(str_lcmp(name, "PF_INET", 7) == 0){ 205 return PF_INET; 206 }else if(str_lcmp(name, "PF_INET6", 8) == 0){ 207 return PF_INET6; 208 } 209 return EPFNOSUPPORT; 210 } 211 212 int parse_socket_type(const char * name){ 213 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){ 214 return SOCK_DGRAM; 215 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){ 216 return SOCK_STREAM; 217 } 218 return ESOCKTNOSUPPORT; 219 } 220 221 void refresh_data(char * data, size_t size){ 222 size_t length; 223 224 // fill the data 225 length = 0; 226 while(size > length + sizeof(NETTEST2_TEXT) - 1){ 227 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1); 228 length += sizeof(NETTEST2_TEXT) - 1; 229 } 230 memcpy(data + length, NETTEST2_TEXT, size - length); 231 data[size] = '\0'; 232 } 233 234 int sockets_create(int verbose, int * socket_ids, int sockets, int family, sock_type_t type){ 235 int index; 236 237 if(verbose){ 238 printf("Create\t"); 239 } 240 fflush(stdout); 241 for(index = 0; index < sockets; ++ index){ 242 socket_ids[index] = socket(family, type, 0); 243 if(socket_ids[index] < 0){ 244 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 245 socket_print_error(stderr, socket_ids[index], "Socket create: ", "\n"); 246 return socket_ids[index]; 247 } 248 if(verbose){ 249 print_mark(index); 250 } 251 } 252 return EOK; 253 } 254 255 int sockets_close(int verbose, int * socket_ids, int sockets){ 256 ERROR_DECLARE; 257 258 int index; 259 260 if(verbose){ 261 printf("\tClose\t"); 262 } 263 fflush(stdout); 264 for(index = 0; index < sockets; ++ index){ 265 if(ERROR_OCCURRED(closesocket(socket_ids[index]))){ 266 printf("Socket %d (%d) error:\n", index, socket_ids[index]); 267 socket_print_error(stderr, ERROR_CODE, "Socket close: ", "\n"); 268 return ERROR_CODE; 269 } 270 if(verbose){ 271 print_mark(index); 272 } 273 } 274 return EOK; 275 } 276 277 int sockets_connect(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen){ 278 ERROR_DECLARE; 279 280 int index; 281 282 if(verbose){ 283 printf("\tConnect\t"); 284 } 285 fflush(stdout); 286 for(index = 0; index < sockets; ++ index){ 287 if(ERROR_OCCURRED(connect(socket_ids[index], address, addrlen))){ 288 socket_print_error(stderr, ERROR_CODE, "Socket connect: ", "\n"); 289 return ERROR_CODE; 290 } 291 if(verbose){ 292 print_mark(index); 293 } 294 } 295 return EOK; 296 } 297 298 int sockets_sendto(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t addrlen, char * data, int size, int messages){ 299 ERROR_DECLARE; 300 301 int index; 302 int message; 303 304 if(verbose){ 305 printf("\tSendto\t"); 306 } 307 fflush(stdout); 308 for(index = 0; index < sockets; ++ index){ 309 for(message = 0; message < messages; ++ message){ 310 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, addrlen))){ 311 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 312 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 313 return ERROR_CODE; 314 } 315 } 316 if(verbose){ 317 print_mark(index); 318 } 319 } 320 return EOK; 321 } 322 323 int sockets_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 324 int value; 325 int index; 326 int message; 327 328 if(verbose){ 329 printf("\tRecvfrom\t"); 330 } 331 fflush(stdout); 332 for(index = 0; index < sockets; ++ index){ 333 for(message = 0; message < messages; ++ message){ 334 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 335 if(value < 0){ 336 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 337 socket_print_error(stderr, value, "Socket receive: ", "\n"); 338 return value; 339 } 340 } 341 if(verbose){ 342 print_mark(index); 343 } 344 } 345 return EOK; 346 } 347 348 int sockets_sendto_recvfrom(int verbose, int * socket_ids, int sockets, struct sockaddr * address, socklen_t * addrlen, char * data, int size, int messages){ 349 ERROR_DECLARE; 350 351 int value; 352 int index; 353 int message; 354 355 if(verbose){ 356 printf("\tSendto and recvfrom\t"); 357 } 358 fflush(stdout); 359 for(index = 0; index < sockets; ++ index){ 360 for(message = 0; message < messages; ++ message){ 361 if(ERROR_OCCURRED(sendto(socket_ids[index], data, size, 0, address, * addrlen))){ 362 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 363 socket_print_error(stderr, ERROR_CODE, "Socket send: ", "\n"); 364 return ERROR_CODE; 365 } 366 value = recvfrom(socket_ids[index], data, size, 0, address, addrlen); 367 if(value < 0){ 368 printf("Socket %d (%d), message %d error:\n", index, socket_ids[index], message); 369 socket_print_error(stderr, value, "Socket receive: ", "\n"); 370 return value; 371 } 372 } 373 if(verbose){ 374 print_mark(index); 375 } 376 } 377 return EOK; 378 } 379 380 void print_mark(int index){ 381 if((index + 1) % 10){ 382 printf("*"); 383 }else{ 384 printf("|"); 385 } 386 fflush(stdout); 387 } 79 void nettest2_refresh_data(char * data, size_t size); 388 80 389 81 int main(int argc, char * argv[]){ … … 392 84 size_t size = 28; 393 85 int verbose = 0; 394 sock_type_t type 86 sock_type_t type = SOCK_DGRAM; 395 87 int sockets = 10; 396 88 int messages = 10; 397 89 int family = PF_INET; 398 uint16_t port 399 400 socklen_t max_length = sizeof(struct sockaddr_in6);90 uint16_t port = 7; 91 92 socklen_t max_length = sizeof(struct sockaddr_in6); 401 93 uint8_t address_data[max_length]; 402 struct sockaddr * address = (struct sockaddr *) address_data;94 struct sockaddr * address = (struct sockaddr *) address_data; 403 95 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 404 96 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; 405 97 socklen_t addrlen; 406 // char 98 // char address_string[INET6_ADDRSTRLEN]; 407 99 uint8_t * address_start; 408 100 409 101 int * socket_ids; 410 char * 102 char * data; 411 103 int value; 412 104 int index; … … 417 109 printf("%s\n", NAME); 418 110 419 if(argc <= 1){ 420 print_help(); 421 return EINVAL; 422 } 423 424 for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){ 111 // parse the command line arguments 112 // stop before the last argument if it does not start with the minus sign ('-') 113 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 114 // options should start with the minus sign ('-') 425 115 if(argv[index][0] == '-'){ 426 116 switch(argv[index][1]){ 117 // short options with only one letter 427 118 case 'f': 428 119 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 0, parse_protocol_family)); 429 120 break; 430 121 case 'h': 431 print_help();122 nettest2_print_help(); 432 123 return EOK; 433 124 break; … … 453 144 verbose = 1; 454 145 break; 146 // long options with the double minus sign ('-') 455 147 case '-': 456 148 if(str_lcmp(argv[index] + 2, "family=", 7) == 0){ 457 149 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "protocol family", 9, parse_protocol_family)); 458 150 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 459 print_help();151 nettest2_print_help(); 460 152 return EOK; 461 153 }else if(str_lcmp(argv[index] + 2, "messages=", 6) == 0){ … … 473 165 }else{ 474 166 print_unrecognized(index, argv[index] + 2); 475 print_help();167 nettest2_print_help(); 476 168 return EINVAL; 477 169 } … … 479 171 default: 480 172 print_unrecognized(index, argv[index] + 1); 481 print_help();173 nettest2_print_help(); 482 174 return EINVAL; 483 175 } 484 176 }else{ 485 177 print_unrecognized(index, argv[index]); 486 print_help();178 nettest2_print_help(); 487 179 return EINVAL; 488 180 } 489 181 } 490 182 183 // if not before the last argument containing the address 184 if(index >= argc){ 185 printf("Command line error: missing address\n"); 186 nettest2_print_help(); 187 return EINVAL; 188 } 189 190 // prepare the address buffer 491 191 bzero(address_data, max_length); 492 192 switch(family){ … … 508 208 } 509 209 210 // parse the last argument which should contain the address 510 211 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 511 212 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 513 214 } 514 215 216 // check the buffer size 515 217 if(size <= 0){ 516 218 fprintf(stderr, "Data buffer size too small (%d). Using 1024 bytes instead.\n", size); 517 219 size = 1024; 518 220 } 221 222 // prepare the buffer 519 223 // size plus terminating null (\0) 520 224 data = (char *) malloc(size + 1); … … 523 227 return ENOMEM; 524 228 } 525 refresh_data(data, size); 526 229 nettest2_refresh_data(data, size); 230 231 // check the socket count 527 232 if(sockets <= 0){ 528 233 fprintf(stderr, "Socket count too small (%d). Using 2 instead.\n", sockets); 529 234 sockets = 2; 530 235 } 531 // count plus terminating null (\0) 236 237 // prepare the socket buffer 238 // count plus the terminating null (\0) 532 239 socket_ids = (int *) malloc(sizeof(int) * (sockets + 1)); 533 240 if(! socket_ids){ … … 597 304 } 598 305 306 void nettest2_print_help(void){ 307 printf( 308 "Network Networking test 2 aplication - UDP transfer\n" \ 309 "Usage: echo [options] numeric_address\n" \ 310 "Where options are:\n" \ 311 "-f protocol_family | --family=protocol_family\n" \ 312 "\tThe listenning socket protocol family. Only the PF_INET and PF_INET6 are supported.\n" 313 "\n" \ 314 "-h | --help\n" \ 315 "\tShow this application help.\n" 316 "\n" \ 317 "-m count | --messages=count\n" \ 318 "\tThe number of messages to send and receive per socket. The default is 10.\n" \ 319 "\n" \ 320 "-n sockets | --sockets=count\n" \ 321 "\tThe number of sockets to use. The default is 10.\n" \ 322 "\n" \ 323 "-p port_number | --port=port_number\n" \ 324 "\tThe port number the application should send messages to. The default is 7.\n" \ 325 "\n" \ 326 "-s packet_size | --size=packet_size\n" \ 327 "\tThe packet data size the application sends. The default is 29 bytes.\n" \ 328 "\n" \ 329 "-v | --verbose\n" \ 330 "\tShow all output messages.\n" 331 ); 332 } 333 334 void nettest2_refresh_data(char * data, size_t size){ 335 size_t length; 336 337 // fill the data 338 length = 0; 339 while(size > length + sizeof(NETTEST2_TEXT) - 1){ 340 memcpy(data + length, NETTEST2_TEXT, sizeof(NETTEST2_TEXT) - 1); 341 length += sizeof(NETTEST2_TEXT) - 1; 342 } 343 memcpy(data + length, NETTEST2_TEXT, size - length); 344 data[size] = '\0'; 345 } 346 599 347 /** @} 600 348 */ -
uspace/srv/net/app/parse.c
r71b00dcc r60ab6c3 38 38 #include <string.h> 39 39 40 #include "../include/socket.h" 41 40 42 #include "../err.h" 41 43 42 44 #include "parse.h" 45 46 int parse_address_family(const char * name){ 47 if(str_lcmp(name, "AF_INET", 7) == 0){ 48 return AF_INET; 49 }else if(str_lcmp(name, "AF_INET6", 8) == 0){ 50 return AF_INET6; 51 } 52 return EAFNOSUPPORT; 53 } 43 54 44 55 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset){ … … 61 72 } 62 73 63 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){64 if(offset){65 *value = argv[*index] + offset;66 }else if((*index) + 1 < argc){67 ++ (*index);68 *value = argv[*index];69 }else{70 fprintf(stderr, "Command line error: missing %s\n", name);71 return EINVAL;72 }73 return EOK;74 }75 76 74 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)){ 77 75 ERROR_DECLARE; … … 88 86 } 89 87 88 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset){ 89 if(offset){ 90 *value = argv[*index] + offset; 91 }else if((*index) + 1 < argc){ 92 ++ (*index); 93 *value = argv[*index]; 94 }else{ 95 fprintf(stderr, "Command line error: missing %s\n", name); 96 return EINVAL; 97 } 98 return EOK; 99 } 100 101 int parse_protocol_family(const char * name){ 102 if(str_lcmp(name, "PF_INET", 7) == 0){ 103 return PF_INET; 104 }else if(str_lcmp(name, "PF_INET6", 8) == 0){ 105 return PF_INET6; 106 } 107 return EPFNOSUPPORT; 108 } 109 110 int parse_socket_type(const char * name){ 111 if(str_lcmp(name, "SOCK_DGRAM", 11) == 0){ 112 return SOCK_DGRAM; 113 }else if(str_lcmp(name, "SOCK_STREAM", 12) == 0){ 114 return SOCK_STREAM; 115 } 116 return ESOCKTNOSUPPORT; 117 } 118 90 119 void print_unrecognized(int index, const char * parameter){ 91 fprintf(stderr, "Command line error - unrecognized parameter(%d: %s)\n", index, parameter);120 fprintf(stderr, "Command line error: unrecognized argument (%d: %s)\n", index, parameter); 92 121 } 93 122 -
uspace/srv/net/app/parse.h
r71b00dcc r60ab6c3 38 38 #define __NET_APP_PARSE__ 39 39 40 /** Prints the parameter unrecognized message and the application help. 41 * @param[in] index The index of the parameter. 42 * @param[in] parameter The parameter name. 40 #include "../include/socket.h" 41 42 /** Translates the character string to the address family number. 43 * @param[in] name The address family name. 44 * @returns The corresponding address family number. 45 * @returns EAFNOSUPPORTED if the address family is not supported. 43 46 */ 44 void print_unrecognized(int index, const char * parameter);47 int parse_address_family(const char * name); 45 48 46 49 /** Parses the next parameter as an integral number. … … 58 61 */ 59 62 int parse_parameter_int(int argc, char ** argv, int * index, int * value, const char * name, int offset); 60 61 /** Parses the next parameter as a character string.62 * The actual parameter is pointed by the index.63 * Uses the offseted actual parameter value if the offset is set or the next one if not.64 * Increments the actual index by the number of processed parameters.65 * @param[in] argc The total number of the parameters.66 * @param[in] argv The parameters.67 * @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters.68 * @param[out] value The parsed parameter value.69 * @param[in] name The parameter name to be printed on errors.70 * @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead.71 * @returns EOK on success.72 * @returns EINVAL if the parameter is missing.73 */74 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset);75 63 76 64 /** Parses the next named parameter as an integral number. … … 92 80 int parse_parameter_name_int(int argc, char ** argv, int * index, int * value, const char * name, int offset, int (*parse_value)(const char * value)); 93 81 82 /** Parses the next parameter as a character string. 83 * The actual parameter is pointed by the index. 84 * Uses the offseted actual parameter value if the offset is set or the next one if not. 85 * Increments the actual index by the number of processed parameters. 86 * @param[in] argc The total number of the parameters. 87 * @param[in] argv The parameters. 88 * @param[in,out] index The actual parameter index. The index is incremented by the number of processed parameters. 89 * @param[out] value The parsed parameter value. 90 * @param[in] name The parameter name to be printed on errors. 91 * @param[in] offset The value offset in the actual parameter. If not set, the next parameter is parsed instead. 92 * @returns EOK on success. 93 * @returns EINVAL if the parameter is missing. 94 */ 95 int parse_parameter_string(int argc, char ** argv, int * index, char ** value, const char * name, int offset); 96 97 /** Translates the character string to the protocol family number. 98 * @param[in] name The protocol family name. 99 * @returns The corresponding protocol family number. 100 * @returns EPFNOSUPPORTED if the protocol family is not supported. 101 */ 102 int parse_protocol_family(const char * name); 103 104 /** Translates the character string to the socket type number. 105 * @param[in] name The socket type name. 106 * @returns The corresponding socket type number. 107 * @returns ESOCKNOSUPPORTED if the socket type is not supported. 108 */ 109 int parse_socket_type(const char * name); 110 111 /** Prints the parameter unrecognized message and the application help. 112 * @param[in] index The index of the parameter. 113 * @param[in] parameter The parameter name. 114 */ 115 void print_unrecognized(int index, const char * parameter); 116 94 117 #endif 95 118 -
uspace/srv/net/app/ping/ping.c
r71b00dcc r60ab6c3 39 39 #include <task.h> 40 40 #include <time.h> 41 #include <ipc/ipc.h> 41 42 #include <ipc/services.h> 42 43 … … 67 68 /** Prints the application help. 68 69 */ 69 void print_help(void); 70 71 /** Translates the character string to the address family number. 72 * @param[in] name The address family name. 73 * @returns The corresponding address family number. 74 * @returns EAFNOSUPPORTED if the address family is not supported. 75 */ 76 int parse_address_family(const char * name); 77 78 void print_help(void){ 79 printf( 80 "Network Ping aplication\n" \ 81 "Usage: ping [options] numeric_address\n" \ 82 "Where options are:\n" \ 83 "\n" \ 84 "-c request_count | --count=request_count\n" \ 85 "\tThe number of packets the application sends. The default is three (3).\n" \ 86 "\n" \ 87 "--dont_fragment\n" \ 88 "\tDisable packet fragmentation.\n" 89 "\n" \ 90 "-f address_family | --family=address_family\n" \ 91 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" 92 "\n" \ 93 "-h | --help\n" \ 94 "\tShow this application help.\n" 95 "\n" \ 96 "-s packet_size | --size=packet_size\n" \ 97 "\tThe packet data size the application sends. The default is 38 bytes.\n" \ 98 "\n" \ 99 "-t timeout | --timeout=timeout\n" \ 100 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \ 101 "\n" \ 102 "--tos=tos\n" \ 103 "\tThe type of service to be used.\n" \ 104 "\n" \ 105 "--ttl=ttl\n" \ 106 "\tThe time to live to be used.\n" \ 107 "\n" \ 108 "-v | --verbose\n" \ 109 "\tShow all output messages.\n" 110 ); 111 } 112 113 int parse_address_family(const char * name){ 114 if(str_lcmp(name, "AF_INET", 7) == 0){ 115 return AF_INET; 116 }else if(str_lcmp(name, "AF_INET6", 8) == 0){ 117 return AF_INET6; 118 } 119 return EAFNOSUPPORT; 120 } 70 void ping_print_help(void); 121 71 122 72 int main(int argc, char * argv[]){ … … 126 76 int verbose = 0; 127 77 int dont_fragment = 0; 128 ip_ttl_t ttl 129 ip_tos_t tos 78 ip_ttl_t ttl = 0; 79 ip_tos_t tos = 0; 130 80 int count = 3; 131 suseconds_t timeout 81 suseconds_t timeout = 3000; 132 82 int family = AF_INET; 133 83 134 socklen_t max_length = sizeof(struct sockaddr_in6);84 socklen_t max_length = sizeof(struct sockaddr_in6); 135 85 uint8_t address_data[max_length]; 136 struct sockaddr * address = (struct sockaddr *) address_data;86 struct sockaddr * address = (struct sockaddr *) address_data; 137 87 struct sockaddr_in * address_in = (struct sockaddr_in *) address; 138 88 struct sockaddr_in6 * address_in6 = (struct sockaddr_in6 *) address; … … 147 97 int index; 148 98 99 // print the program label 149 100 printf("Task %d - ", task_get_id()); 150 101 printf("%s\n", NAME); 151 102 152 if(argc <= 1){ 153 print_help(); 154 return EINVAL; 155 } 156 157 for(index = 1; (index < argc - 1) || ((index == argc) && (argv[index][0] == '-')); ++ index){ 103 // parse the command line arguments 104 // stop before the last argument if it does not start with the minus sign ('-') 105 for(index = 1; (index < argc - 1) || ((index == argc - 1) && (argv[index][0] == '-')); ++ index){ 106 // options should start with the minus sign ('-') 158 107 if(argv[index][0] == '-'){ 159 108 switch(argv[index][1]){ 109 // short options with only one letter 160 110 case 'c': 161 111 ERROR_PROPAGATE(parse_parameter_int(argc, argv, &index, &count, "count", 0)); … … 165 115 break; 166 116 case 'h': 167 p rint_help();117 ping_print_help(); 168 118 return EOK; 169 119 break; … … 179 129 verbose = 1; 180 130 break; 131 // long options with the double minus sign ('-') 181 132 case '-': 182 133 if(str_lcmp(argv[index] + 2, "count=", 6) == 0){ … … 187 138 ERROR_PROPAGATE(parse_parameter_name_int(argc, argv, &index, &family, "address family", 9, parse_address_family)); 188 139 }else if(str_lcmp(argv[index] + 2, "help", 5) == 0){ 189 p rint_help();140 ping_print_help(); 190 141 return EOK; 191 142 }else if(str_lcmp(argv[index] + 2, "size=", 5) == 0){ … … 205 156 }else{ 206 157 print_unrecognized(index, argv[index] + 2); 207 p rint_help();158 ping_print_help(); 208 159 return EINVAL; 209 160 } … … 211 162 default: 212 163 print_unrecognized(index, argv[index] + 1); 213 p rint_help();164 ping_print_help(); 214 165 return EINVAL; 215 166 } 216 167 }else{ 217 168 print_unrecognized(index, argv[index]); 218 p rint_help();169 ping_print_help(); 219 170 return EINVAL; 220 171 } 221 172 } 222 173 174 // if not before the last argument containing the address 175 if(index >= argc){ 176 printf("Command line error: missing address\n"); 177 ping_print_help(); 178 return EINVAL; 179 } 180 181 // prepare the address buffer 223 182 bzero(address_data, max_length); 224 183 switch(family){ … … 238 197 } 239 198 199 // parse the last argument which should contain the address 240 200 if(ERROR_OCCURRED(inet_pton(family, argv[argc - 1], address_start))){ 241 201 fprintf(stderr, "Address parse error %d\n", ERROR_CODE); … … 243 203 } 244 204 205 // connect to the ICMP module 245 206 icmp_phone = icmp_connect_module(SERVICE_ICMP, ICMP_CONNECT_TIMEOUT); 246 207 if(icmp_phone < 0){ … … 249 210 } 250 211 212 // print the ping header 251 213 printf("PING %d bytes of data\n", size); 252 214 if(ERROR_OCCURRED(inet_ntop(address->sa_family, address_start, address_string, sizeof(address_string)))){ … … 256 218 } 257 219 220 // do count times 258 221 while(count > 0){ 222 223 // get the starting time 259 224 if(ERROR_OCCURRED(gettimeofday(&time_before, NULL))){ 260 225 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 226 // release the ICMP phone 227 ipc_hangup(icmp_phone); 261 228 return ERROR_CODE; 262 229 } 230 231 // request the ping 263 232 result = icmp_echo_msg(icmp_phone, size, timeout, ttl, tos, dont_fragment, address, addrlen); 233 234 // get the ending time 264 235 if(ERROR_OCCURRED(gettimeofday(&time_after, NULL))){ 265 236 fprintf(stderr, "Get time of day error %d\n", ERROR_CODE); 237 // release the ICMP phone 238 ipc_hangup(icmp_phone); 266 239 return ERROR_CODE; 267 240 } 241 242 // print the result 268 243 switch(result){ 269 244 case ICMP_ECHO: … … 283 258 } 284 259 260 // release the ICMP phone 261 ipc_hangup(icmp_phone); 262 285 263 return EOK; 286 264 } 287 265 266 void ping_print_help(void){ 267 printf( 268 "Network Ping aplication\n" \ 269 "Usage: ping [options] numeric_address\n" \ 270 "Where options are:\n" \ 271 "\n" \ 272 "-c request_count | --count=request_count\n" \ 273 "\tThe number of packets the application sends. The default is three (3).\n" \ 274 "\n" \ 275 "--dont_fragment\n" \ 276 "\tDisable packet fragmentation.\n" 277 "\n" \ 278 "-f address_family | --family=address_family\n" \ 279 "\tThe given address family. Only the AF_INET and AF_INET6 are supported.\n" 280 "\n" \ 281 "-h | --help\n" \ 282 "\tShow this application help.\n" 283 "\n" \ 284 "-s packet_size | --size=packet_size\n" \ 285 "\tThe packet data size the application sends. The default is 38 bytes.\n" \ 286 "\n" \ 287 "-t timeout | --timeout=timeout\n" \ 288 "\tThe number of miliseconds the application waits for a reply. The default is three thousands (3 000).\n" \ 289 "\n" \ 290 "--tos=tos\n" \ 291 "\tThe type of service to be used.\n" \ 292 "\n" \ 293 "--ttl=ttl\n" \ 294 "\tThe time to live to be used.\n" \ 295 "\n" \ 296 "-v | --verbose\n" \ 297 "\tShow all output messages.\n" 298 ); 299 } 300 288 301 /** @} 289 302 */ -
uspace/srv/net/app/print_error.c
r71b00dcc r60ab6c3 41 41 42 42 #include "print_error.h" 43 44 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){45 if(IS_ICMP_ERROR(error_code)){46 icmp_print_error(output, error_code, prefix, suffix);47 }else if(IS_SOCKET_ERROR(error_code)){48 socket_print_error(output, error_code, prefix, suffix);49 }50 }51 43 52 44 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ … … 101 93 } 102 94 95 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 96 if(IS_ICMP_ERROR(error_code)){ 97 icmp_print_error(output, error_code, prefix, suffix); 98 }else if(IS_SOCKET_ERROR(error_code)){ 99 socket_print_error(output, error_code, prefix, suffix); 100 } 101 } 102 103 103 void socket_print_error(FILE * output, int error_code, const char * prefix, const char * suffix){ 104 104 if(output){ -
uspace/srv/net/app/print_error.h
r71b00dcc r60ab6c3 50 50 #define IS_SOCKET_ERROR(error_code) ((error_code) < 0) 51 51 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 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 59 52 60 /** Prints the error description. 53 61 * Supports ICMP and socket error codes. … … 58 66 */ 59 67 void print_error(FILE * output, int error_code, const char * prefix, const char * suffix); 60 61 /** Prints the specific ICMP error description.62 * @param[in] output The description output stream. May be NULL.63 * @param[in] error_code The ICMP 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 void icmp_print_error(FILE * output, int error_code, const char * prefix, const char * suffix);68 68 69 69 /** Prints the specific socket error description. -
uspace/srv/net/cfg/modular/general
r71b00dcc r60ab6c3 3 3 IPV=4 4 4 IP_ROUTING=no 5 5 6 MTU=1500 7 6 8 ICMP_ERROR_REPORTING=yes 7 9 ICMP_ECHO_REPLYING=yes 10 8 11 UDP_CHECKSUM_COMPUTING=yes 9 12 UDP_AUTOBINDING=yes -
uspace/srv/net/cfg/module/general
r71b00dcc r60ab6c3 3 3 IPV=4 4 4 IP_ROUTING=no 5 5 6 MTU=1500 7 6 8 ICMP_ERROR_REPORTING=yes 7 9 ICMP_ECHO_REPLYING=yes 10 8 11 UDP_CHECKSUM_COMPUTING=yes 9 12 UDP_AUTOBINDING=yes -
uspace/srv/net/checksum.c
r71b00dcc r60ab6c3 47 47 #define CRC_DIVIDER_LE 0xEDB88320 48 48 49 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){ 50 size_t index; 49 uint16_t compact_checksum(uint32_t sum){ 50 // shorten to the 16 bits 51 while(sum >> 16){ 52 sum = (sum &0xFFFF) + (sum >> 16); 53 } 51 54 52 while(length >= 8){ 53 seed ^= (*data); 54 for(index = 0; index < 8; ++ index){ 55 if(seed &1){ 56 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 57 }else{ 58 seed >>= 1; 59 } 60 } 61 ++ data; 62 length -= 8; 63 } 64 if(length > 0){ 65 seed ^= (*data) >> (8 - length); 66 for(index = 0; index < length; ++ index){ 67 if(seed &1){ 68 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 69 }else{ 70 seed >>= 1; 71 } 72 } 73 length -= 8; 74 } 75 return seed; 76 } 77 78 uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){ 79 size_t index; 80 81 while(length >= 8){ 82 seed ^= (*data) << 24; 83 for(index = 0; index < 8; ++ index){ 84 if(seed &0x80000000){ 85 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 86 }else{ 87 seed <<= 1; 88 } 89 } 90 ++ data; 91 length -= 8; 92 } 93 if(length > 0){ 94 seed ^= ((*data) &(0xFF << (8 - length))) << 24; 95 for(index = 0; index < length; ++ index){ 96 if(seed &0x80000000){ 97 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 98 }else{ 99 seed <<= 1; 100 } 101 } 102 length -= 8; 103 } 104 return seed; 55 return (uint16_t) sum; 105 56 } 106 57 … … 121 72 } 122 73 123 uint16_t compact_checksum(uint32_t sum){ 124 // shorten to the 16 bits 125 while(sum >> 16){ 126 sum = (sum &0xFFFF) + (sum >> 16); 74 uint32_t compute_crc32_be(uint32_t seed, uint8_t * data, size_t length){ 75 size_t index; 76 77 // process full bytes 78 while(length >= 8){ 79 // add the data 80 seed ^= (*data) << 24; 81 // for each added bit 82 for(index = 0; index < 8; ++ index){ 83 // if the first bit is set 84 if(seed &0x80000000){ 85 // shift and divide the checksum 86 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 87 }else{ 88 // shift otherwise 89 seed <<= 1; 90 } 91 } 92 // move to the next byte 93 ++ data; 94 length -= 8; 127 95 } 128 96 129 return (uint16_t) sum; 97 // process the odd bits 98 if(length > 0){ 99 // add the data with zero padding 100 seed ^= ((*data) &(0xFF << (8 - length))) << 24; 101 // for each added bit 102 for(index = 0; index < length; ++ index){ 103 // if the first bit is set 104 if(seed &0x80000000){ 105 // shift and divide the checksum 106 seed = (seed << 1) ^ ((uint32_t) CRC_DIVIDER_BE); 107 }else{ 108 // shift otherwise 109 seed <<= 1; 110 } 111 } 112 } 113 114 return seed; 115 } 116 117 uint32_t compute_crc32_le(uint32_t seed, uint8_t * data, size_t length){ 118 size_t index; 119 120 // process full bytes 121 while(length >= 8){ 122 // add the data 123 seed ^= (*data); 124 // for each added bit 125 for(index = 0; index < 8; ++ index){ 126 // if the last bit is set 127 if(seed &1){ 128 // shift and divide the checksum 129 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 130 }else{ 131 // shift otherwise 132 seed >>= 1; 133 } 134 } 135 // move to the next byte 136 ++ data; 137 length -= 8; 138 } 139 140 // process the odd bits 141 if(length > 0){ 142 // add the data with zero padding 143 seed ^= (*data) >> (8 - length); 144 for(index = 0; index < length; ++ index){ 145 // if the last bit is set 146 if(seed &1){ 147 // shift and divide the checksum 148 seed = (seed >> 1) ^ ((uint32_t) CRC_DIVIDER_LE); 149 }else{ 150 // shift otherwise 151 seed >>= 1; 152 } 153 } 154 } 155 156 return seed; 130 157 } 131 158 … … 137 164 138 165 uint16_t ip_checksum(uint8_t * data, size_t length){ 166 // compute, compact and flip the data checksum 139 167 return flip_checksum(compact_checksum(compute_checksum(0, data, length))); 140 168 } -
uspace/srv/net/configuration.h
r71b00dcc r60ab6c3 46 46 /*@{*/ 47 47 48 /** Activates the measured strings self test.49 * The NET_SELF_TEST has to be activated.50 * @see measured_strings.h51 */52 #define NET_SELF_TEST_MEASURED_STRINGS 153 54 48 /** Activates the char map self test. 55 49 * The NET_SELF_TEST has to be activated. … … 57 51 */ 58 52 #define NET_SELF_TEST_CHAR_MAP 1 53 54 /** Activates the CRC computation self test. 55 * The NET_SELF_TEST has to be activated. 56 * @see crc.h 57 */ 58 #define NET_SELF_TEST_CRC 1 59 60 /** Activates the dynamic fifo self test. 61 * The NET_SELF_TEST has to be activated. 62 * @see dynamic_fifo.h 63 */ 64 #define NET_SELF_TEST_DYNAMIC_FIFO 1 65 66 /** Activates the generic char map self test. 67 * The NET_SELF_TEST has to be activated. 68 * @see generic_char_map.h 69 */ 70 #define NET_SELF_TEST_GENERIC_CHAR_MAP 1 71 72 /** Activates the generic field self test. 73 * The NET_SELF_TEST has to be activated. 74 * @see generic_field.h 75 */ 76 #define NET_SELF_TEST_GENERIC_FIELD 1 59 77 60 78 /** Activates the integral map self test. … … 64 82 #define NET_SELF_TEST_INT_MAP 1 65 83 66 /** Activates the generic fieldself test.84 /** Activates the measured strings self test. 67 85 * The NET_SELF_TEST has to be activated. 68 * @see generic_field.h86 * @see measured_strings.h 69 87 */ 70 #define NET_SELF_TEST_GENERIC_FIELD 1 71 72 /** Activates the generic char map self test. 73 * The NET_SELF_TEST has to be activated. 74 * @see generic_char_map.h 75 */ 76 #define NET_SELF_TEST_GENERIC_CHAR_MAP 1 77 78 /** Activates the CRC computation self test. 79 * The NET_SELF_TEST has to be activated. 80 * @see crc.h 81 */ 82 #define NET_SELF_TEST_CRC 1 83 84 /** Activates the dynamic fifo self test. 85 * The NET_SELF_TEST has to be activated. 86 * @see dynamic_fifo.h 87 */ 88 #define NET_SELF_TEST_DYNAMIC_FIFO 1 88 #define NET_SELF_TEST_MEASURED_STRINGS 1 89 89 90 90 /*@}*/ -
uspace/srv/net/err.h
r71b00dcc r60ab6c3 62 62 #ifdef CONFIG_DEBUG 63 63 64 #define ERROR_OCCURRED(value) (((ERROR_CODE = (value)) != EOK) && ({printf("error at %s:%d %d\n", __FILE__, __LINE__, ERROR_CODE); 1;})) 64 #define ERROR_OCCURRED(value) \ 65 (((ERROR_CODE = (value)) != EOK) \ 66 && ({printf("error at %s:%d %d\n", __FILE__, __LINE__, ERROR_CODE); 1;})) 65 67 66 68 #else -
uspace/srv/net/il/arp/arp.c
r71b00dcc r60ab6c3 73 73 arp_globals_t arp_globals; 74 74 75 /** Clears the device specific data. 76 * @param[in] device The device specific data. 77 */ 78 void arp_clear_device(arp_device_ref device); 79 75 80 /** Creates new protocol specific data. 76 81 * Allocates and returns the needed memory block as the proto parameter. … … 82 87 */ 83 88 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address); 84 85 /** Clears the device specific data.86 * @param[in] device The device specific data.87 */88 void arp_clear_device(arp_device_ref device);89 89 90 90 /** @name Message processing functions … … 105 105 int arp_device_message(device_id_t device_id, services_t service, services_t protocol, measured_string_ref address); 106 106 107 /** Returns the hardware address for the given protocol address. 108 * Sends the ARP request packet if the hardware address is not found in the cache. 107 /** Updates the device content length according to the new MTU value. 109 108 * @param[in] device_id The device identifier. 110 * @param[in] protocol The protocol service. 111 * @param[in] target The target protocol address. 112 * @returns The hardware address of the target. 113 * @returns NULL if the target parameter is NULL. 114 * @returns NULL if the device is not found. 115 * @returns NULL if the device packet is too small to send a request. 116 * @returns NULL if the hardware address is not found in the cache. 117 */ 118 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 109 * @param[in] mtu The new mtu value. 110 * @returns ENOENT if device is not found. 111 * @returns EOK on success. 112 */ 113 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 119 114 120 115 /** Processes the received ARP packet. … … 133 128 int arp_receive_message(device_id_t device_id, packet_t packet); 134 129 135 /** Updates the device content length according to the new MTU value. 130 /** Returns the hardware address for the given protocol address. 131 * Sends the ARP request packet if the hardware address is not found in the cache. 136 132 * @param[in] device_id The device identifier. 137 * @param[in] mtu The new mtu value. 138 * @returns ENOENT if device is not found. 139 * @returns EOK on success. 140 */ 141 int arp_mtu_changed_message(device_id_t device_id, size_t mtu); 133 * @param[in] protocol The protocol service. 134 * @param[in] target The target protocol address. 135 * @returns The hardware address of the target. 136 * @returns NULL if the target parameter is NULL. 137 * @returns NULL if the device is not found. 138 * @returns NULL if the device packet is too small to send a request. 139 * @returns NULL if the hardware address is not found in the cache. 140 */ 141 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target); 142 142 143 143 /*@}*/ … … 148 148 149 149 GENERIC_CHAR_MAP_IMPLEMENT(arp_addr, measured_string_t) 150 151 task_id_t arp_task_get_id(void){152 return task_get_id();153 }154 155 int arp_clear_device_req(int arp_phone, device_id_t device_id){156 arp_device_ref device;157 158 fibril_rwlock_write_lock(&arp_globals.lock);159 device = arp_cache_find(&arp_globals.cache, device_id);160 if(! device){161 fibril_rwlock_write_unlock(&arp_globals.lock);162 return ENOENT;163 }164 arp_clear_device(device);165 printf("Device %d cleared\n", device_id);166 fibril_rwlock_write_unlock(&arp_globals.lock);167 return EOK;168 }169 170 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){171 arp_device_ref device;172 arp_proto_ref proto;173 174 fibril_rwlock_write_lock(&arp_globals.lock);175 device = arp_cache_find(&arp_globals.cache, device_id);176 if(! device){177 fibril_rwlock_write_unlock(&arp_globals.lock);178 return ENOENT;179 }180 proto = arp_protos_find(&device->protos, protocol);181 if(! proto){182 fibril_rwlock_write_unlock(&arp_globals.lock);183 return ENOENT;184 }185 arp_addr_exclude(&proto->addresses, address->value, address->length);186 fibril_rwlock_write_unlock(&arp_globals.lock);187 return EOK;188 }189 150 190 151 int arp_clean_cache_req(int arp_phone){ … … 211 172 } 212 173 213 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 214 ERROR_DECLARE; 215 216 measured_string_ref tmp; 217 218 // copy the given address for exclusive use 219 tmp = measured_string_copy(address); 220 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 221 free(tmp->value); 222 free(tmp); 223 } 224 return ERROR_CODE; 225 } 226 227 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 228 measured_string_ref tmp; 229 230 fibril_rwlock_read_lock(&arp_globals.lock); 231 tmp = arp_translate_message(device_id, protocol, address); 232 if(tmp){ 233 *translation = measured_string_copy(tmp); 234 fibril_rwlock_read_unlock(&arp_globals.lock); 235 if(*translation){ 236 *data = (** translation).value; 237 return EOK; 238 }else{ 239 return ENOMEM; 240 } 241 }else{ 242 fibril_rwlock_read_unlock(&arp_globals.lock); 174 int arp_clear_address_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address){ 175 arp_device_ref device; 176 arp_proto_ref proto; 177 178 fibril_rwlock_write_lock(&arp_globals.lock); 179 device = arp_cache_find(&arp_globals.cache, device_id); 180 if(! device){ 181 fibril_rwlock_write_unlock(&arp_globals.lock); 243 182 return ENOENT; 244 183 } 245 } 246 247 int arp_initialize(async_client_conn_t client_connection){ 248 ERROR_DECLARE; 249 250 fibril_rwlock_initialize(&arp_globals.lock); 184 proto = arp_protos_find(&device->protos, protocol); 185 if(! proto){ 186 fibril_rwlock_write_unlock(&arp_globals.lock); 187 return ENOENT; 188 } 189 arp_addr_exclude(&proto->addresses, address->value, address->length); 190 fibril_rwlock_write_unlock(&arp_globals.lock); 191 return EOK; 192 } 193 194 void arp_clear_device(arp_device_ref device){ 195 int count; 196 arp_proto_ref proto; 197 198 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 199 proto = arp_protos_get_index(&device->protos, count); 200 if(proto){ 201 if(proto->addr){ 202 free(proto->addr); 203 } 204 if(proto->addr_data){ 205 free(proto->addr_data); 206 } 207 arp_addr_destroy(&proto->addresses); 208 } 209 } 210 arp_protos_clear(&device->protos); 211 } 212 213 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 214 arp_device_ref device; 215 251 216 fibril_rwlock_write_lock(&arp_globals.lock); 252 arp_globals.client_connection = client_connection; 253 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache)); 217 device = arp_cache_find(&arp_globals.cache, device_id); 218 if(! device){ 219 fibril_rwlock_write_unlock(&arp_globals.lock); 220 return ENOENT; 221 } 222 arp_clear_device(device); 223 printf("Device %d cleared\n", device_id); 254 224 fibril_rwlock_write_unlock(&arp_globals.lock); 255 225 return EOK; 256 226 } 257 227 258 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 259 ERROR_DECLARE; 260 261 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 262 if(!(*proto)){ 263 return ENOMEM; 264 } 265 (** proto).service = service; 266 (** proto).addr = address; 267 (** proto).addr_data = address->value; 268 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 269 free(*proto); 270 return ERROR_CODE; 228 int arp_connect_module(services_t service){ 229 if(service != SERVICE_ARP){ 230 return EINVAL; 271 231 } 272 232 return EOK; … … 383 343 } 384 344 385 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 386 arp_device_ref device; 387 arp_proto_ref proto; 388 measured_string_ref addr; 389 size_t length; 390 packet_t packet; 391 arp_header_ref header; 392 393 if(! target){ 394 return NULL; 395 } 396 device = arp_cache_find(&arp_globals.cache, device_id); 397 if(! device){ 398 return NULL; 399 } 400 proto = arp_protos_find(&device->protos, protocol); 401 if((! proto) || (proto->addr->length != target->length)){ 402 return NULL; 403 } 404 addr = arp_addr_find(&proto->addresses, target->value, target->length); 405 if(addr){ 406 return addr; 407 } 408 // ARP packet content size = header + (address + translation) * 2 409 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 410 if(length > device->packet_dimension.content){ 411 return NULL; 412 } 413 packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 414 if(! packet){ 415 return NULL; 416 } 417 header = (arp_header_ref) packet_suffix(packet, length); 418 if(! header){ 419 pq_release(arp_globals.net_phone, packet_get_id(packet)); 420 return NULL; 421 } 422 header->hardware = htons(device->hardware); 423 header->hardware_length = (uint8_t) device->addr->length; 424 header->protocol = htons(protocol_map(device->service, protocol)); 425 header->protocol_length = (uint8_t) proto->addr->length; 426 header->operation = htons(ARPOP_REQUEST); 427 length = sizeof(arp_header_t); 428 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 429 length += device->addr->length; 430 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 431 length += proto->addr->length; 432 bzero(((uint8_t *) header) + length, device->addr->length); 433 length += device->addr->length; 434 memcpy(((uint8_t *) header) + length, target->value, target->length); 435 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){ 436 pq_release(arp_globals.net_phone, packet_get_id(packet)); 437 return NULL; 438 } 439 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 440 return NULL; 441 } 442 443 int arp_receive_message(device_id_t device_id, packet_t packet){ 345 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 444 346 ERROR_DECLARE; 445 347 446 size_t length; 447 arp_header_ref header; 448 arp_device_ref device; 449 arp_proto_ref proto; 450 measured_string_ref hw_source; 451 uint8_t * src_hw; 452 uint8_t * src_proto; 453 uint8_t * des_hw; 454 uint8_t * des_proto; 455 456 length = packet_get_data_length(packet); 457 if(length <= sizeof(arp_header_t)){ 458 return EINVAL; 459 } 460 device = arp_cache_find(&arp_globals.cache, device_id); 461 if(! device){ 462 return ENOENT; 463 } 464 header = (arp_header_ref) packet_get_data(packet); 465 if((ntohs(header->hardware) != device->hardware) 466 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 467 return EINVAL; 468 } 469 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 470 if(! proto){ 471 return ENOENT; 472 } 473 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 474 src_proto = src_hw + header->hardware_length; 475 des_hw = src_proto + header->protocol_length; 476 des_proto = des_hw + header->hardware_length; 477 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 478 // exists? 479 if(hw_source){ 480 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 481 return EINVAL; 482 } 483 memcpy(hw_source->value, src_hw, hw_source->length); 484 } 485 // is my protocol address? 486 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 487 return EINVAL; 488 } 489 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 490 // not already upadted? 491 if(! hw_source){ 492 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 493 if(! hw_source){ 494 return ENOMEM; 495 } 496 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 497 } 498 if(ntohs(header->operation) == ARPOP_REQUEST){ 499 header->operation = htons(ARPOP_REPLY); 500 memcpy(des_proto, src_proto, header->protocol_length); 501 memcpy(src_proto, proto->addr->value, header->protocol_length); 502 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 503 memcpy(des_hw, hw_source->value, header->hardware_length); 504 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 505 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 506 return 1; 507 } 508 } 509 return EOK; 510 } 511 512 void arp_clear_device(arp_device_ref device){ 513 int count; 514 arp_proto_ref proto; 515 516 for(count = arp_protos_count(&device->protos) - 1; count >= 0; -- count){ 517 proto = arp_protos_get_index(&device->protos, count); 518 if(proto){ 519 if(proto->addr){ 520 free(proto->addr); 521 } 522 if(proto->addr_data){ 523 free(proto->addr_data); 524 } 525 arp_addr_destroy(&proto->addresses); 526 } 527 } 528 arp_protos_clear(&device->protos); 529 } 530 531 int arp_connect_module(services_t service){ 532 if(service != SERVICE_ARP){ 533 return EINVAL; 534 } 535 return EOK; 536 } 537 538 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 539 arp_device_ref device; 540 348 measured_string_ref tmp; 349 350 // copy the given address for exclusive use 351 tmp = measured_string_copy(address); 352 if(ERROR_OCCURRED(arp_device_message(device_id, netif, protocol, tmp))){ 353 free(tmp->value); 354 free(tmp); 355 } 356 return ERROR_CODE; 357 } 358 359 int arp_initialize(async_client_conn_t client_connection){ 360 ERROR_DECLARE; 361 362 fibril_rwlock_initialize(&arp_globals.lock); 541 363 fibril_rwlock_write_lock(&arp_globals.lock); 542 device = arp_cache_find(&arp_globals.cache, device_id); 543 if(! device){ 544 fibril_rwlock_write_unlock(&arp_globals.lock); 545 return ENOENT; 546 } 547 device->packet_dimension.content = mtu; 548 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 364 arp_globals.client_connection = client_connection; 365 ERROR_PROPAGATE(arp_cache_initialize(&arp_globals.cache)); 549 366 fibril_rwlock_write_unlock(&arp_globals.lock); 550 367 return EOK; … … 618 435 } 619 436 437 int arp_mtu_changed_message(device_id_t device_id, size_t mtu){ 438 arp_device_ref device; 439 440 fibril_rwlock_write_lock(&arp_globals.lock); 441 device = arp_cache_find(&arp_globals.cache, device_id); 442 if(! device){ 443 fibril_rwlock_write_unlock(&arp_globals.lock); 444 return ENOENT; 445 } 446 device->packet_dimension.content = mtu; 447 printf("arp - device %d changed mtu to %d\n\n", device_id, mtu); 448 fibril_rwlock_write_unlock(&arp_globals.lock); 449 return EOK; 450 } 451 452 int arp_proto_create(arp_proto_ref * proto, services_t service, measured_string_ref address){ 453 ERROR_DECLARE; 454 455 *proto = (arp_proto_ref) malloc(sizeof(arp_proto_t)); 456 if(!(*proto)){ 457 return ENOMEM; 458 } 459 (** proto).service = service; 460 (** proto).addr = address; 461 (** proto).addr_data = address->value; 462 if(ERROR_OCCURRED(arp_addr_initialize(&(** proto).addresses))){ 463 free(*proto); 464 return ERROR_CODE; 465 } 466 return EOK; 467 } 468 469 int arp_receive_message(device_id_t device_id, packet_t packet){ 470 ERROR_DECLARE; 471 472 size_t length; 473 arp_header_ref header; 474 arp_device_ref device; 475 arp_proto_ref proto; 476 measured_string_ref hw_source; 477 uint8_t * src_hw; 478 uint8_t * src_proto; 479 uint8_t * des_hw; 480 uint8_t * des_proto; 481 482 length = packet_get_data_length(packet); 483 if(length <= sizeof(arp_header_t)){ 484 return EINVAL; 485 } 486 device = arp_cache_find(&arp_globals.cache, device_id); 487 if(! device){ 488 return ENOENT; 489 } 490 header = (arp_header_ref) packet_get_data(packet); 491 if((ntohs(header->hardware) != device->hardware) 492 || (length < sizeof(arp_header_t) + header->hardware_length * 2u + header->protocol_length * 2u)){ 493 return EINVAL; 494 } 495 proto = arp_protos_find(&device->protos, protocol_unmap(device->service, ntohs(header->protocol))); 496 if(! proto){ 497 return ENOENT; 498 } 499 src_hw = ((uint8_t *) header) + sizeof(arp_header_t); 500 src_proto = src_hw + header->hardware_length; 501 des_hw = src_proto + header->protocol_length; 502 des_proto = des_hw + header->hardware_length; 503 hw_source = arp_addr_find(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length)); 504 // exists? 505 if(hw_source){ 506 if(hw_source->length != CONVERT_SIZE(uint8_t, char, header->hardware_length)){ 507 return EINVAL; 508 } 509 memcpy(hw_source->value, src_hw, hw_source->length); 510 } 511 // is my protocol address? 512 if(proto->addr->length != CONVERT_SIZE(uint8_t, char, header->protocol_length)){ 513 return EINVAL; 514 } 515 if(! str_lcmp(proto->addr->value, (char *) des_proto, proto->addr->length)){ 516 // not already upadted? 517 if(! hw_source){ 518 hw_source = measured_string_create_bulk((char *) src_hw, CONVERT_SIZE(uint8_t, char, header->hardware_length)); 519 if(! hw_source){ 520 return ENOMEM; 521 } 522 ERROR_PROPAGATE(arp_addr_add(&proto->addresses, (char *) src_proto, CONVERT_SIZE(uint8_t, char, header->protocol_length), hw_source)); 523 } 524 if(ntohs(header->operation) == ARPOP_REQUEST){ 525 header->operation = htons(ARPOP_REPLY); 526 memcpy(des_proto, src_proto, header->protocol_length); 527 memcpy(src_proto, proto->addr->value, header->protocol_length); 528 memcpy(src_hw, device->addr->value, device->packet_dimension.addr_len); 529 memcpy(des_hw, hw_source->value, header->hardware_length); 530 ERROR_PROPAGATE(packet_set_addr(packet, src_hw, des_hw, header->hardware_length)); 531 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 532 return 1; 533 } 534 } 535 return EOK; 536 } 537 538 task_id_t arp_task_get_id(void){ 539 return task_get_id(); 540 } 541 542 measured_string_ref arp_translate_message(device_id_t device_id, services_t protocol, measured_string_ref target){ 543 arp_device_ref device; 544 arp_proto_ref proto; 545 measured_string_ref addr; 546 size_t length; 547 packet_t packet; 548 arp_header_ref header; 549 550 if(! target){ 551 return NULL; 552 } 553 device = arp_cache_find(&arp_globals.cache, device_id); 554 if(! device){ 555 return NULL; 556 } 557 proto = arp_protos_find(&device->protos, protocol); 558 if((! proto) || (proto->addr->length != target->length)){ 559 return NULL; 560 } 561 addr = arp_addr_find(&proto->addresses, target->value, target->length); 562 if(addr){ 563 return addr; 564 } 565 // ARP packet content size = header + (address + translation) * 2 566 length = 8 + (CONVERT_SIZE(char, uint8_t, proto->addr->length) + CONVERT_SIZE(char, uint8_t, device->addr->length)) * 2; 567 if(length > device->packet_dimension.content){ 568 return NULL; 569 } 570 packet = packet_get_4(arp_globals.net_phone, device->packet_dimension.addr_len, device->packet_dimension.prefix, length, device->packet_dimension.suffix); 571 if(! packet){ 572 return NULL; 573 } 574 header = (arp_header_ref) packet_suffix(packet, length); 575 if(! header){ 576 pq_release(arp_globals.net_phone, packet_get_id(packet)); 577 return NULL; 578 } 579 header->hardware = htons(device->hardware); 580 header->hardware_length = (uint8_t) device->addr->length; 581 header->protocol = htons(protocol_map(device->service, protocol)); 582 header->protocol_length = (uint8_t) proto->addr->length; 583 header->operation = htons(ARPOP_REQUEST); 584 length = sizeof(arp_header_t); 585 memcpy(((uint8_t *) header) + length, device->addr->value, device->addr->length); 586 length += device->addr->length; 587 memcpy(((uint8_t *) header) + length, proto->addr->value, proto->addr->length); 588 length += proto->addr->length; 589 bzero(((uint8_t *) header) + length, device->addr->length); 590 length += device->addr->length; 591 memcpy(((uint8_t *) header) + length, target->value, target->length); 592 if(packet_set_addr(packet, (uint8_t *) device->addr->value, (uint8_t *) device->broadcast_addr->value, CONVERT_SIZE(char, uint8_t, device->addr->length)) != EOK){ 593 pq_release(arp_globals.net_phone, packet_get_id(packet)); 594 return NULL; 595 } 596 nil_send_msg(device->phone, device_id, packet, SERVICE_ARP); 597 return NULL; 598 } 599 600 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 601 measured_string_ref tmp; 602 603 fibril_rwlock_read_lock(&arp_globals.lock); 604 tmp = arp_translate_message(device_id, protocol, address); 605 if(tmp){ 606 *translation = measured_string_copy(tmp); 607 fibril_rwlock_read_unlock(&arp_globals.lock); 608 if(*translation){ 609 *data = (** translation).value; 610 return EOK; 611 }else{ 612 return ENOMEM; 613 } 614 }else{ 615 fibril_rwlock_read_unlock(&arp_globals.lock); 616 return ENOENT; 617 } 618 } 619 620 620 /** @} 621 621 */ -
uspace/srv/net/il/arp/arp.h
r71b00dcc r60ab6c3 51 51 52 52 53 /** Type definition of the ARP global data.54 * @see arp_globals55 */56 typedef struct arp_globals arp_globals_t;57 58 53 /** Type definition of the ARP device specific data. 59 54 * @see arp_device … … 66 61 typedef arp_device_t * arp_device_ref; 67 62 63 /** Type definition of the ARP global data. 64 * @see arp_globals 65 */ 66 typedef struct arp_globals arp_globals_t; 67 68 68 /** Type definition of the ARP protocol specific data. 69 69 * @see arp_proto … … 75 75 */ 76 76 typedef arp_proto_t * arp_proto_ref; 77 78 /** ARP address map. 79 * Translates addresses. 80 * @see generic_char_map.h 81 */ 82 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t) 77 83 78 84 /** ARP address cache. … … 88 94 INT_MAP_DECLARE(arp_protos, arp_proto_t) 89 95 90 /** ARP address map.91 * Translates addresses.92 * @see generic_char_map.h93 */94 GENERIC_CHAR_MAP_DECLARE(arp_addr, measured_string_t)95 96 96 /** ARP device specific data. 97 97 */ 98 98 struct arp_device{ 99 /** Device identifier.100 */101 device_id_t device_id;102 /** Hardware type.103 */104 hw_type_t hardware;105 /** Packet dimension.106 */107 packet_dimension_t packet_dimension;108 99 /** Actual device hardware address. 109 100 */ … … 118 109 */ 119 110 char * broadcast_data; 120 /** Device module service.111 /** Device identifier. 121 112 */ 122 services_t service; 113 device_id_t device_id; 114 /** Hardware type. 115 */ 116 hw_type_t hardware; 117 /** Packet dimension. 118 */ 119 packet_dimension_t packet_dimension; 123 120 /** Device module phone. 124 121 */ … … 128 125 */ 129 126 arp_protos_t protos; 127 /** Device module service. 128 */ 129 services_t service; 130 }; 131 132 /** ARP global data. 133 */ 134 struct arp_globals{ 135 /** ARP address cache. 136 */ 137 arp_cache_t cache; 138 /** The client connection processing function. 139 * The module skeleton propagates its own one. 140 */ 141 async_client_conn_t client_connection; 142 /** Networking module phone. 143 */ 144 int net_phone; 145 /** Safety lock. 146 */ 147 fibril_rwlock_t lock; 130 148 }; 131 149 … … 133 151 */ 134 152 struct arp_proto{ 135 /** Protocol service.136 */137 services_t service;138 153 /** Actual device protocol address. 139 154 */ … … 145 160 */ 146 161 arp_addr_t addresses; 147 }; 148 149 /** ARP global data. 150 */ 151 struct arp_globals{ 152 /** Networking module phone. 162 /** Protocol service. 153 163 */ 154 int net_phone; 155 /** Safety lock. 156 */ 157 fibril_rwlock_t lock; 158 /** ARP address cache. 159 */ 160 arp_cache_t cache; 161 /** The client connection processing function. 162 * The module skeleton propagates its own one. 163 */ 164 async_client_conn_t client_connection; 164 services_t service; 165 165 }; 166 166 -
uspace/srv/net/il/arp/arp_messages.h
r71b00dcc r60ab6c3 46 46 */ 47 47 typedef enum{ 48 /** New device message.49 * @see arp_ device_req()48 /** Clean cache message. 49 * @see arp_clean_cache() 50 50 */ 51 NET_ARP_ DEVICE = NET_ARP_FIRST,52 /** Address translationmessage.53 * @see arp_ translate_req()51 NET_ARP_CLEAN_CACHE = NET_ARP_FIRST, 52 /** Clear address cache message. 53 * @see arp_clear_address_msg() 54 54 */ 55 NET_ARP_ TRANSLATE,55 NET_ARP_CLEAR_ADDRESS, 56 56 /** Clear device cache message. 57 57 * @see arp_clear_device_req() 58 58 */ 59 59 NET_ARP_CLEAR_DEVICE, 60 /** Clear address cache message.61 * @see arp_ clear_address_msg()60 /** New device message. 61 * @see arp_device_req() 62 62 */ 63 NET_ARP_ CLEAR_ADDRESS,64 /** Clean cachemessage.65 * @see arp_ clean_cache()63 NET_ARP_DEVICE, 64 /** Address translation message. 65 * @see arp_translate_req() 66 66 */ 67 NET_ARP_ CLEAN_CACHE,67 NET_ARP_TRANSLATE 68 68 } arp_messages; 69 69 -
uspace/srv/net/il/arp/arp_module.c
r71b00dcc r60ab6c3 58 58 #define NAME "ARP protocol" 59 59 60 /** ARP module global data. 61 */ 62 extern arp_globals_t arp_globals; 63 64 /** Processes the ARP message. 65 * @param[in] callid The message identifier. 66 * @param[in] call The message parameters. 67 * @param[out] answer The message answer parameters. 68 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 69 * @returns EOK on success. 70 * @returns Other error codes as defined for the arp_message() function. 71 */ 72 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 73 60 74 /** Prints the module name. 61 75 * @see NAME … … 72 86 int module_start(async_client_conn_t client_connection); 73 87 74 /** Processes the ARP message. 75 * @param[in] callid The message identifier. 76 * @param[in] call The message parameters. 77 * @param[out] answer The message answer parameters. 78 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 79 * @returns EOK on success. 80 * @returns Other error codes as defined for the arp_message() function. 81 */ 82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 84 /** ARP module global data. 85 */ 86 extern arp_globals_t arp_globals; 88 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 89 return arp_message(callid, call, answer, answer_count); 90 } 87 91 88 92 void module_print_name(void){ … … 110 114 } 111 115 112 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){113 return arp_message(callid, call, answer, answer_count);114 }115 116 116 /** @} 117 117 */ -
uspace/srv/net/il/arp/arp_oc.h
r71b00dcc r60ab6c3 44 44 /** REQUEST operation code. 45 45 */ 46 #define ARPOP_REQUEST 146 #define ARPOP_REQUEST 1 47 47 48 48 /** REPLY operation code. 49 49 */ 50 #define ARPOP_REPLY 250 #define ARPOP_REPLY 2 51 51 52 52 /** Reverse request operation code. 53 53 */ 54 #define ARPOP_RREQUEST 354 #define ARPOP_RREQUEST 3 55 55 56 56 /** Reverse reply operation code. 57 57 */ 58 #define ARPOP_RREPLY 458 #define ARPOP_RREPLY 4 59 59 60 60 /** DRARP-Request operation code. 61 61 */ 62 #define ARPOP_DRARP_Request 562 #define ARPOP_DRARP_Request 5 63 63 64 64 /** DRARP-Reply operation code. 65 65 */ 66 #define ARPOP_DRARP_Reply 666 #define ARPOP_DRARP_Reply 6 67 67 68 68 /** DRARP-Error operation code. 69 69 */ 70 #define ARPOP_DRARP_Error 770 #define ARPOP_DRARP_Error 7 71 71 72 72 /** InARP-Request operation code. 73 73 */ 74 #define ARPOP_InREQUEST 874 #define ARPOP_InREQUEST 8 75 75 76 76 /** InARP-Reply operation code. 77 77 */ 78 #define ARPOP_InREPLY 978 #define ARPOP_InREPLY 9 79 79 80 80 /** ARP-NAK operation code. 81 81 */ 82 #define ARPOP_NAK 1082 #define ARPOP_NAK 10 83 83 84 84 /** MARS-Request operation code. 85 85 */ 86 #define ARPOP_MARS_Request 1186 #define ARPOP_MARS_Request 11 87 87 88 88 /** MARS-Multi operation code. 89 89 */ 90 #define ARPOP_MARS_Multi 1290 #define ARPOP_MARS_Multi 12 91 91 92 92 /** MARS-MServ operation code. 93 93 */ 94 #define ARPOP_MARS_MServ 1394 #define ARPOP_MARS_MServ 13 95 95 96 96 /** MARS-Join operation code. 97 97 */ 98 #define ARPOP_MARS_Join 1498 #define ARPOP_MARS_Join 14 99 99 100 100 /** MARS-Leave operation code. 101 101 */ 102 #define ARPOP_MARS_Leave 15102 #define ARPOP_MARS_Leave 15 103 103 104 104 /** MARS-NAK operation code. 105 105 */ 106 #define ARPOP_MARS_NAK 16106 #define ARPOP_MARS_NAK 16 107 107 108 108 /** MARS-Unserv operation code. 109 109 */ 110 #define ARPOP_MARS_Unserv 17110 #define ARPOP_MARS_Unserv 17 111 111 112 112 /** MARS-SJoin operation code. 113 113 */ 114 #define ARPOP_MARS_SJoin 18114 #define ARPOP_MARS_SJoin 18 115 115 116 116 /** MARS-SLeave operation code. 117 117 */ 118 #define ARPOP_MARS_SLeave 19118 #define ARPOP_MARS_SLeave 19 119 119 120 120 /** MARS-Grouplist-Request operation code. 121 121 */ 122 #define ARPOP_MARS_Grouplist_Request 122 #define ARPOP_MARS_Grouplist_Request 20 123 123 124 124 /** MARS-Grouplist-Reply operation code. … … 128 128 /** MARS-Redirect-Map operation code. 129 129 */ 130 #define ARPOP_MARS_Redirect_Map 22130 #define ARPOP_MARS_Redirect_Map 22 131 131 132 132 /** MAPOS-UNARP operation code. 133 133 */ 134 #define ARPOP_MAPOS_UNARP 23134 #define ARPOP_MAPOS_UNARP 23 135 135 136 136 /*@}*/ -
uspace/srv/net/il/arp/arp_remote.c
r71b00dcc r60ab6c3 52 52 #include "arp_messages.h" 53 53 54 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 55 aid_t message_id; 56 ipcarg_t result; 57 58 message_id = async_send_3(arp_phone, NET_ARP_DEVICE, (ipcarg_t) device_id, protocol, netif, NULL); 59 measured_strings_send(arp_phone, address, 1); 60 async_wait_for(message_id, &result); 61 return (int) result; 54 int arp_connect_module(services_t service){ 55 if(service != SERVICE_ARP){ 56 return EINVAL; 57 } 58 return connect_to_service(SERVICE_ARP); 62 59 } 63 60 64 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 65 return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data); 66 } 67 68 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 69 return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE, (ipcarg_t) device_id); 61 int arp_clean_cache_req(int arp_phone){ 62 return (int) async_req_0_0(arp_phone, NET_ARP_CLEAN_CACHE); 70 63 } 71 64 … … 80 73 } 81 74 82 int arp_clea n_cache_req(int arp_phone){83 return (int) async_req_ 0_0(arp_phone, NET_ARP_CLEAN_CACHE);75 int arp_clear_device_req(int arp_phone, device_id_t device_id){ 76 return (int) async_req_1_0(arp_phone, NET_ARP_CLEAR_DEVICE, (ipcarg_t) device_id); 84 77 } 85 78 86 int arp_connect_module(services_t service){ 87 if(service != SERVICE_ARP){ 88 return EINVAL; 89 } 90 return connect_to_service(SERVICE_ARP); 79 int arp_device_req(int arp_phone, device_id_t device_id, services_t protocol, services_t netif, measured_string_ref address){ 80 aid_t message_id; 81 ipcarg_t result; 82 83 message_id = async_send_3(arp_phone, NET_ARP_DEVICE, (ipcarg_t) device_id, protocol, netif, NULL); 84 measured_strings_send(arp_phone, address, 1); 85 async_wait_for(message_id, &result); 86 return (int) result; 91 87 } 92 88 … … 95 91 } 96 92 93 int arp_translate_req(int arp_phone, device_id_t device_id, services_t protocol, measured_string_ref address, measured_string_ref * translation, char ** data){ 94 return generic_translate_req(arp_phone, NET_ARP_TRANSLATE, device_id, protocol, address, 1, translation, data); 95 } 96 97 97 /** @} 98 98 */ -
uspace/srv/net/il/il_messages.h
r71b00dcc r60ab6c3 53 53 */ 54 54 NET_IL_DEVICE_STATE, 55 /** Device MTU changed message. 56 * @see il_mtu_changed_msg() 57 */ 58 NET_IL_MTU_CHANGED, 59 /** Packet size message. 60 * @see il_packet_size_req() 61 */ 62 NET_IL_PACKET_SPACE, 55 63 /** Packet received message. 56 64 * @see il_received_msg() … … 60 68 * @see il_send_msg() 61 69 */ 62 NET_IL_SEND, 63 /** Packet size message. 64 * @see il_packet_size_req() 65 */ 66 NET_IL_PACKET_SPACE, 67 /** Device MTU changed message. 68 * @see il_mtu_changed_msg() 69 */ 70 NET_IL_MTU_CHANGED 70 NET_IL_SEND 71 71 } il_messages; 72 72 … … 83 83 * @param[in] call The message call structure. 84 84 */ 85 #define IL_GET_SERVICE(call) 85 #define IL_GET_SERVICE(call) (services_t) IPC_GET_ARG2(*call) 86 86 87 87 /*@}*/ -
uspace/srv/net/il/ip/ip.h
r71b00dcc r60ab6c3 106 106 */ 107 107 struct ip_netif{ 108 /** Device identifier.109 */110 device_id_t device_id;111 /** Netif module service.112 */113 services_t service;114 /** Netif module phone.115 */116 int phone;117 108 /** ARP module. 118 109 * Assigned if using ARP. 119 110 */ 120 111 module_ref arp; 112 /** Broadcast address. 113 */ 114 in_addr_t broadcast; 115 /** Device identifier. 116 */ 117 device_id_t device_id; 118 /** Indicates whether using DHCP. 119 */ 120 int dhcp; 121 121 /** IP version. 122 122 */ 123 123 int ipv; 124 /** Indicates whether using DHCP. 125 */ 126 int dhcp; 124 /** Packet dimension. 125 */ 126 packet_dimension_t packet_dimension; 127 /** Netif module phone. 128 */ 129 int phone; 130 /** Routing table. 131 */ 132 ip_routes_t routes; 127 133 /** Indicates whether IP routing is enabled. 128 134 */ 129 135 int routing; 136 /** Netif module service. 137 */ 138 services_t service; 130 139 /** Device state. 131 140 */ 132 141 device_state_t state; 133 /** Broadcast address.134 */135 in_addr_t broadcast;136 /** Routing table.137 */138 ip_routes_t routes;139 /** Packet dimension.140 */141 packet_dimension_t packet_dimension;142 142 }; 143 143 … … 145 145 */ 146 146 struct ip_proto{ 147 /** Protocol module phone. 148 */ 149 int phone; 147 150 /** Protocol number. 148 151 */ 149 152 int protocol; 153 /** Protocol packet receiving function. 154 */ 155 tl_received_msg_t received_msg; 150 156 /** Protocol module service. 151 157 */ 152 158 services_t service; 153 /** Protocol module phone.154 */155 int phone;156 /** Protocol packet receiving function.157 */158 tl_received_msg_t received_msg;159 159 }; 160 160 … … 165 165 */ 166 166 in_addr_t address; 167 /** Target network mask.168 */169 in_addr_t netmask;170 167 /** Gateway. 171 168 */ … … 174 171 */ 175 172 ip_netif_ref netif; 173 /** Target network mask. 174 */ 175 in_addr_t netmask; 176 176 }; 177 177 … … 179 179 */ 180 180 struct ip_globals{ 181 /** Default client connection function for support modules. 182 */ 183 async_client_conn_t client_connection; 184 /** Default gateway. 185 */ 186 ip_route_t gateway; 187 /** Safety lock. 188 */ 189 fibril_rwlock_t lock; 190 /** Known support modules. 191 */ 192 modules_t modules; 181 193 /** Networking module phone. 182 194 */ … … 188 200 */ 189 201 fibril_rwlock_t netifs_lock; 202 /** Packet counter. 203 */ 204 uint16_t packet_counter; 190 205 /** Registered protocols. 191 206 */ … … 194 209 */ 195 210 fibril_rwlock_t protos_lock; 196 /** Default gateway.197 */198 ip_route_t gateway;199 /** Known support modules.200 */201 modules_t modules;202 /** Default client connection function for support modules.203 */204 async_client_conn_t client_connection;205 /** Packet counter.206 */207 uint16_t packet_counter;208 /** Safety lock.209 */210 fibril_rwlock_t lock;211 211 }; 212 212 -
uspace/srv/net/il/ip/ip_client.c
r71b00dcc r60ab6c3 48 48 #include "ip_header.h" 49 49 50 int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){51 ip_header_ref header;52 uint8_t * data;53 size_t padding;54 55 padding = ipopt_length % 4;56 if(padding){57 padding = 4 - padding;58 ipopt_length += padding;59 }60 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding);61 if(! data){62 return ENOMEM;63 }64 while(padding --){65 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP;66 }67 header = (ip_header_ref) data;68 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length);69 header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL;70 header->tos = tos;71 header->protocol = protocol;72 if(dont_fragment){73 header->flags = IPFLAG_DONT_FRAGMENT;74 }75 return EOK;76 }77 78 int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){79 ip_header_ref header;80 81 header = (ip_header_ref) packet_get_data(packet);82 if((! header)83 || (packet_get_data_length(packet) < sizeof(ip_header_t))){84 return ENOMEM;85 }86 if(protocol){87 *protocol = header->protocol;88 }89 if(ttl){90 *ttl = header->ttl;91 }92 if(tos){93 *tos = header->tos;94 }95 if(dont_fragment){96 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT;97 }98 if(ipopt_length){99 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t);100 return sizeof(ip_header_t);101 }else{102 return IP_HEADER_LENGTH(header);103 }104 }105 106 50 size_t ip_client_header_length(packet_t packet){ 107 51 ip_header_ref header; … … 113 57 } 114 58 return IP_HEADER_LENGTH(header); 115 }116 117 int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length){118 ipv4_pseudo_header_ref header_in;119 120 if(! header){121 return EBADMEM;122 }123 if(headerlen == sizeof(ipv4_pseudo_header_t)){124 header_in = (ipv4_pseudo_header_ref) header;125 header_in->data_length = htons(data_length);126 return EOK;127 }else{128 return EINVAL;129 }130 59 } 131 60 … … 140 69 return EINVAL; 141 70 } 71 142 72 switch(src->sa_family){ 143 73 case AF_INET: … … 171 101 } 172 102 103 int ip_client_prepare_packet(packet_t packet, ip_protocol_t protocol, ip_ttl_t ttl, ip_tos_t tos, int dont_fragment, size_t ipopt_length){ 104 ip_header_ref header; 105 uint8_t * data; 106 size_t padding; 107 108 // compute the padding if IP options are set 109 // multiple of 4 bytes 110 padding = ipopt_length % 4; 111 if(padding){ 112 padding = 4 - padding; 113 ipopt_length += padding; 114 } 115 116 // prefix the header 117 data = (uint8_t *) packet_prefix(packet, sizeof(ip_header_t) + padding); 118 if(! data){ 119 return ENOMEM; 120 } 121 122 // add the padding 123 while(padding --){ 124 data[sizeof(ip_header_t) + padding] = IPOPT_NOOP; 125 } 126 127 // set the header 128 header = (ip_header_ref) data; 129 header->header_length = IP_COMPUTE_HEADER_LENGTH(sizeof(ip_header_t) + ipopt_length); 130 header->ttl = (ttl ? ttl : IPDEFTTL); //(((ttl) <= MAXTTL) ? ttl : MAXTTL) : IPDEFTTL; 131 header->tos = tos; 132 header->protocol = protocol; 133 134 if(dont_fragment){ 135 header->flags = IPFLAG_DONT_FRAGMENT; 136 } 137 return EOK; 138 } 139 140 int ip_client_process_packet(packet_t packet, ip_protocol_t * protocol, ip_ttl_t * ttl, ip_tos_t * tos, int * dont_fragment, size_t * ipopt_length){ 141 ip_header_ref header; 142 143 header = (ip_header_ref) packet_get_data(packet); 144 if((! header) 145 || (packet_get_data_length(packet) < sizeof(ip_header_t))){ 146 return ENOMEM; 147 } 148 149 if(protocol){ 150 *protocol = header->protocol; 151 } 152 if(ttl){ 153 *ttl = header->ttl; 154 } 155 if(tos){ 156 *tos = header->tos; 157 } 158 if(dont_fragment){ 159 *dont_fragment = header->flags &IPFLAG_DONT_FRAGMENT; 160 } 161 if(ipopt_length){ 162 *ipopt_length = IP_HEADER_LENGTH(header) - sizeof(ip_header_t); 163 return sizeof(ip_header_t); 164 }else{ 165 return IP_HEADER_LENGTH(header); 166 } 167 } 168 169 int ip_client_set_pseudo_header_data_length(ip_pseudo_header_ref header, size_t headerlen, size_t data_length){ 170 ipv4_pseudo_header_ref header_in; 171 172 if(! header){ 173 return EBADMEM; 174 } 175 176 if(headerlen == sizeof(ipv4_pseudo_header_t)){ 177 header_in = (ipv4_pseudo_header_ref) header; 178 header_in->data_length = htons(data_length); 179 return EOK; 180 // TODO IPv6 181 }else{ 182 return EINVAL; 183 } 184 } 185 173 186 /** @} 174 187 */ -
uspace/srv/net/il/ip/ip_header.h
r71b00dcc r60ab6c3 42 42 #include <sys/types.h> 43 43 44 /** Returns the actual IP header length in bytes. 45 * @param[in] header The IP packet header. 46 */ 47 #define IP_HEADER_LENGTH(header) ((header)->header_length * 4u) 44 /** Returns the fragment offest high bits. 45 * @param[in] length The prefixed data total length. 46 */ 47 #define IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) ((((length) / 8u) &0x1F00) >> 8) 48 49 /** Returns the fragment offest low bits. 50 * @param[in] length The prefixed data total length. 51 */ 52 #define IP_COMPUTE_FRAGMENT_OFFSET_LOW(length) (((length) / 8u) &0xFF) 48 53 49 54 /** Returns the IP header length. … … 52 57 #define IP_COMPUTE_HEADER_LENGTH(length) ((uint8_t) ((length) / 4u)) 53 58 59 /** Returns the fragment offest. 60 * @param[in] header The IP packet header. 61 */ 62 #define IP_FRAGMENT_OFFSET(header) ((((header)->fragment_offset_high << 8) + (header)->fragment_offset_low) * 8u) 63 64 /** Returns the IP packet header checksum. 65 * @param[in] header The IP packet header. 66 */ 67 #define IP_HEADER_CHECKSUM(header) (htons(ip_checksum((uint8_t *)(header), IP_HEADER_LENGTH(header)))) 68 69 /** Returns the actual IP packet data length. 70 * @param[in] header The IP packet header. 71 */ 72 #define IP_HEADER_DATA_LENGTH(header) (IP_TOTAL_LENGTH(header) - IP_HEADER_LENGTH(header)) 73 74 /** Returns the actual IP header length in bytes. 75 * @param[in] header The IP packet header. 76 */ 77 #define IP_HEADER_LENGTH(header) ((header)->header_length * 4u) 78 54 79 /** Returns the actual IP packet total length. 55 80 * @param[in] header The IP packet header. … … 57 82 #define IP_TOTAL_LENGTH(header) ntohs((header)->total_length) 58 83 59 /** Returns the actual IP packet data length. 60 * @param[in] header The IP packet header. 61 */ 62 #define IP_HEADER_DATA_LENGTH(header) (IP_TOTAL_LENGTH(header) - IP_HEADER_LENGTH(header)) 63 64 /** Returns the IP packet header checksum. 65 * @param[in] header The IP packet header. 66 */ 67 #define IP_HEADER_CHECKSUM(header) (htons(ip_checksum((uint8_t *)(header), IP_HEADER_LENGTH(header)))) 68 69 /** Returns the fragment offest. 70 * @param[in] header The IP packet header. 71 */ 72 #define IP_FRAGMENT_OFFSET(header) ((((header)->fragment_offset_high << 8) + (header)->fragment_offset_low) * 8u) 73 74 /** Returns the fragment offest high bits. 75 * @param[in] length The prefixed data total length. 76 */ 77 #define IP_COMPUTE_FRAGMENT_OFFSET_HIGH(length) ((((length) / 8u) &0x1F00) >> 8) 78 79 /** Returns the fragment offest low bits. 80 * @param[in] length The prefixed data total length. 81 */ 82 #define IP_COMPUTE_FRAGMENT_OFFSET_LOW(length) (((length) / 8u) &0xFF) 84 /** @name IP flags definitions 85 */ 86 /*@{*/ 87 88 /** Fragment flag field shift. 89 */ 90 #define IPFLAG_FRAGMENT_SHIFT 1 91 92 /** Fragmented flag field shift. 93 */ 94 #define IPFLAG_FRAGMENTED_SHIFT 0 95 96 /** Don't fragment flag value. 97 * Permits the packet fragmentation. 98 */ 99 #define IPFLAG_DONT_FRAGMENT (0x1 << IPFLAG_FRAGMENT_SHIFT) 100 101 /** Last fragment flag value. 102 * Indicates the last packet fragment. 103 */ 104 #define IPFLAG_LAST_FRAGMENT (0x0 << IPFLAG_FRAGMENTED_SHIFT) 105 106 /** May fragment flag value. 107 * Allows the packet fragmentation. 108 */ 109 #define IPFLAG_MAY_FRAGMENT (0x0 << IPFLAG_FRAGMENT_SHIFT) 110 111 /** More fragments flag value. 112 * Indicates that more packet fragments follow. 113 */ 114 #define IPFLAG_MORE_FRAGMENTS (0x1 << IPFLAG_FRAGMENTED_SHIFT) 115 116 /*@}*/ 83 117 84 118 /** Type definition of the internet header. … … 91 125 */ 92 126 typedef ip_header_t * ip_header_ref; 127 128 /** Type definition of the internet option header. 129 * @see ip_header 130 */ 131 typedef struct ip_option ip_option_t; 132 133 /** Type definition of the internet option header pointer. 134 * @see ip_header 135 */ 136 typedef ip_option_t * ip_option_ref; 137 138 /** Type definition of the internet version 4 pseudo header. 139 * @see ipv4_pseudo_header 140 */ 141 typedef struct ipv4_pseudo_header ipv4_pseudo_header_t; 142 143 /** Type definition of the internet version 4 pseudo header pointer. 144 * @see ipv4_pseudo_header 145 */ 146 typedef ipv4_pseudo_header_t * ipv4_pseudo_header_ref; 93 147 94 148 /** Internet header. … … 171 225 } __attribute__ ((packed)); 172 226 173 /** Type definition of the internet option header.174 * @see ip_header175 */176 typedef struct ip_option ip_option_t;177 178 /** Type definition of the internet option header pointer.179 * @see ip_header180 */181 typedef ip_option_t * ip_option_ref;182 183 227 /** Internet option header. 184 228 * Only type field is always valid. … … 212 256 } __attribute__ ((packed)); 213 257 214 /** @name IP flags definitions215 */216 /*@{*/217 218 /** Fragment flag field shift.219 */220 #define IPFLAG_FRAGMENT_SHIFT 1221 222 /** Fragmented flag field shift.223 */224 #define IPFLAG_FRAGMENTED_SHIFT 0225 226 /** May fragment flag value.227 * Allows the packet fragmentation.228 */229 #define IPFLAG_MAY_FRAGMENT (0x0 << IPFLAG_FRAGMENT_SHIFT)230 231 /** Don't fragment flag value.232 * Permits the packet fragmentation.233 */234 #define IPFLAG_DONT_FRAGMENT (0x1 << IPFLAG_FRAGMENT_SHIFT)235 236 /** Last fragment flag value.237 * Indicates the last packet fragment.238 */239 #define IPFLAG_LAST_FRAGMENT (0x0 << IPFLAG_FRAGMENTED_SHIFT)240 241 /** More fragments flag value.242 * Indicates that more packet fragments follow.243 */244 #define IPFLAG_MORE_FRAGMENTS (0x1 << IPFLAG_FRAGMENTED_SHIFT)245 246 /*@}*/247 248 /** Type definition of the internet version 4 pseudo header.249 * @see ipv4_pseudo_header250 */251 typedef struct ipv4_pseudo_header ipv4_pseudo_header_t;252 253 /** Type definition of the internet version 4 pseudo header pointer.254 * @see ipv4_pseudo_header255 */256 typedef ipv4_pseudo_header_t * ipv4_pseudo_header_ref;257 258 258 /** Internet version 4 pseudo header. 259 259 */ -
uspace/srv/net/il/ip/ip_messages.h
r71b00dcc r60ab6c3 51 51 */ 52 52 NET_IP_ADD_ROUTE = NET_IP_FIRST, 53 /** Sets the default gateway.54 * @see ip_ set_default_gateway()53 /** Gets the actual route information. 54 * @see ip_get_route() 55 55 */ 56 NET_IP_ SET_GATEWAY,56 NET_IP_GET_ROUTE, 57 57 /** Processes the received error notification. 58 58 * @see ip_received_error_msg() 59 59 */ 60 60 NET_IP_RECEIVED_ERROR, 61 /** Gets the actual route information.62 * @see ip_ get_route()61 /** Sets the default gateway. 62 * @see ip_set_default_gateway() 63 63 */ 64 NET_IP_ GET_ROUTE64 NET_IP_SET_GATEWAY 65 65 } ip_messages; 66 66 … … 69 69 /*@{*/ 70 70 71 /** Returns the address message parameter. 72 * @param[in] call The message call structure. 73 */ 74 #define IP_GET_ADDRESS(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG3(*call); addr;}) 75 71 76 /** Returns the gateway message parameter. 72 77 * @param[in] call The message call structure. … … 74 79 #define IP_GET_GATEWAY(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG2(*call); addr;}) 75 80 76 /** Returns the address message parameter.77 * @param[ in] call The message callstructure.81 /** Sets the header length in the message answer. 82 * @param[out] answer The message answer structure. 78 83 */ 79 #define IP_ GET_ADDRESS(call) ({in_addr_t addr; addr.s_addr = IPC_GET_ARG3(*call); addr;})84 #define IP_SET_HEADERLEN(answer) ((size_t *) &IPC_GET_ARG2(*answer)) 80 85 81 86 /** Returns the network mask message parameter. … … 89 94 #define IP_GET_PROTOCOL(call) ((ip_protocol_t) IPC_GET_ARG1(*call)) 90 95 91 /** Sets the header length in the message answer.92 * @param[out] answer The message answer structure.93 */94 #define IP_SET_HEADERLEN(answer) ((size_t *) &IPC_GET_ARG2(*answer))95 96 96 /*@}*/ 97 97 -
uspace/srv/net/il/ip/ip_module.c
r71b00dcc r60ab6c3 58 58 #define NAME "IP protocol" 59 59 60 /** IP module global data. 61 */ 62 extern ip_globals_t ip_globals; 63 64 /** Processes the IP message. 65 * @param[in] callid The message identifier. 66 * @param[in] call The message parameters. 67 * @param[out] answer The message answer parameters. 68 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 69 * @returns EOK on success. 70 * @returns Other error codes as defined for the ip_message() function. 71 */ 72 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 73 60 74 /** Prints the module name. 61 75 * @see NAME … … 72 86 int module_start(async_client_conn_t client_connection); 73 87 74 /** Processes the IP message. 75 * @param[in] callid The message identifier. 76 * @param[in] call The message parameters. 77 * @param[out] answer The message answer parameters. 78 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 79 * @returns EOK on success. 80 * @returns Other error codes as defined for the ip_message() function. 81 */ 82 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 83 84 /** IP module global data. 85 */ 86 extern ip_globals_t ip_globals; 88 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){ 89 return ip_message(callid, call, answer, answer_count); 90 } 87 91 88 92 void module_print_name(void){ … … 110 114 } 111 115 112 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count){113 return ip_message(callid, call, answer, answer_count);114 }115 116 116 /** @} 117 117 */ -
uspace/srv/net/il/ip/ip_remote.c
r71b00dcc r60ab6c3 52 52 #include "ip_messages.h" 53 53 54 int ip_ device_req(int ip_phone, device_id_t device_id, services_t service){55 return generic_device_req(ip_phone, NET_IL_DEVICE, device_id, 0, service);54 int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){ 55 return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr, (ipcarg_t) address.s_addr, (ipcarg_t) netmask.s_addr); 56 56 } 57 57 58 int ip_ send_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){59 return generic_send_msg(ip_phone, NET_IL_SEND, device_id, packet_get_id(packet), sender, error);58 int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg){ 59 return (int) bind_service(service, (ipcarg_t) protocol, me, service, receiver); 60 60 } 61 61 … … 64 64 } 65 65 66 int ip_add_route_req(int ip_phone, device_id_t device_id, in_addr_t address, in_addr_t netmask, in_addr_t gateway){ 67 return (int) async_req_4_0(ip_phone, NET_IP_ADD_ROUTE, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr, (ipcarg_t) address.s_addr, (ipcarg_t) netmask.s_addr); 68 } 69 70 int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){ 71 return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr); 72 } 73 74 int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){ 75 return generic_packet_size_req(ip_phone, NET_IL_PACKET_SPACE, device_id, packet_dimension); 76 } 77 78 int ip_bind_service(services_t service, int protocol, services_t me, async_client_conn_t receiver, tl_received_msg_t tl_received_msg){ 79 return (int) bind_service(service, (ipcarg_t) protocol, me, service, receiver); 80 } 81 82 int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){ 83 return generic_received_msg(ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id(packet), target, error); 66 int ip_device_req(int ip_phone, device_id_t device_id, services_t service){ 67 return generic_device_req(ip_phone, NET_IL_DEVICE, device_id, 0, service); 84 68 } 85 69 … … 95 79 return EBADMEM; 96 80 } 81 97 82 *header = NULL; 98 83 message_id = async_send_1(ip_phone, NET_IP_GET_ROUTE, (ipcarg_t) protocol, &answer); … … 108 93 } 109 94 async_wait_for(message_id, &result); 95 110 96 if((result != EOK) && (*header)){ 111 97 free(*header); … … 116 102 } 117 103 104 int ip_packet_size_req(int ip_phone, device_id_t device_id, packet_dimension_ref packet_dimension){ 105 return generic_packet_size_req(ip_phone, NET_IL_PACKET_SPACE, device_id, packet_dimension); 106 } 107 108 int ip_received_error_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t target, services_t error){ 109 return generic_received_msg(ip_phone, NET_IP_RECEIVED_ERROR, device_id, packet_get_id(packet), target, error); 110 } 111 112 int ip_send_msg(int ip_phone, device_id_t device_id, packet_t packet, services_t sender, services_t error){ 113 return generic_send_msg(ip_phone, NET_IL_SEND, device_id, packet_get_id(packet), sender, error); 114 } 115 116 int ip_set_gateway_req(int ip_phone, device_id_t device_id, in_addr_t gateway){ 117 return (int) async_req_2_0(ip_phone, NET_IP_SET_GATEWAY, (ipcarg_t) device_id, (ipcarg_t) gateway.s_addr); 118 } 119 118 120 /** @} 119 121 */ -
uspace/srv/net/inet.c
r71b00dcc r60ab6c3 45 45 #include "include/socket_codes.h" 46 46 47 int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){ 48 if((! data) || (! address)){ 49 return EINVAL; 50 } 51 52 switch(family){ 53 case AF_INET: 54 // check the output buffer size 55 if(length < INET_ADDRSTRLEN){ 56 return ENOMEM; 57 } 58 // fill the buffer with the IPv4 address 59 snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", data[0], data[1], data[2], data[3]); 60 return EOK; 61 case AF_INET6: 62 // check the output buffer size 63 if(length < INET6_ADDRSTRLEN){ 64 return ENOMEM; 65 } 66 // fill the buffer with the IPv6 address 67 snprintf(address, length, "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]); 68 return EOK; 69 default: 70 return ENOTSUP; 71 } 72 } 73 47 74 int inet_pton(uint16_t family, const char * address, uint8_t * data){ 75 /** The base number of the values. 76 */ 77 int base; 78 /** The number of bytes per a section. 79 */ 80 size_t bytes; 81 /** The number of bytes of the address data. 82 */ 83 int count; 84 48 85 const char * next; 49 86 char * last; 50 87 int index; 51 int count;52 int base;53 size_t bytes;54 88 size_t shift; 55 89 unsigned long value; … … 58 92 return EINVAL; 59 93 } 94 95 // set the processing parameters 60 96 switch(family){ 61 97 case AF_INET: … … 72 108 return ENOTSUP; 73 109 } 110 111 // erase if no address 74 112 if(! address){ 75 113 bzero(data, count); 76 114 return ENOENT; 77 115 } 116 117 // process the string from the beginning 78 118 next = address; 79 119 index = 0; 80 120 do{ 121 // if the actual character is set 81 122 if(next && (*next)){ 123 124 // if not on the first character 82 125 if(index){ 126 // move to the next character 83 127 ++ next; 84 128 } 129 130 // parse the actual integral value 85 131 value = strtoul(next, &last, base); 132 // remember the last problematic character 133 // should be either '.' or ':' but is ignored to be more generic 86 134 next = last; 135 136 // fill the address data byte by byte 87 137 shift = bytes - 1; 88 138 do{ … … 91 141 value >>= 8; 92 142 }while(shift --); 143 93 144 index += bytes; 94 145 }else{ 146 // erase the rest of the address 95 147 bzero(data + index, count - index); 96 148 return EOK; 97 149 } 98 150 }while(index < count); 151 99 152 return EOK; 100 }101 102 int inet_ntop(uint16_t family, const uint8_t * data, char * address, size_t length){103 if((! data) || (! address)){104 return EINVAL;105 }106 switch(family){107 case AF_INET:108 if(length < INET_ADDRSTRLEN){109 return ENOMEM;110 }111 snprintf(address, length, "%hhu.%hhu.%hhu.%hhu", data[0], data[1], data[2], data[3]);112 return EOK;113 case AF_INET6:114 if(length < INET6_ADDRSTRLEN){115 return ENOMEM;116 }117 snprintf(address, length, "%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx:%hhx%hhx", data[0], data[1], data[2], data[3], data[4], data[5], data[6], data[7], data[8], data[9], data[10], data[11], data[12], data[13], data[14], data[15]);118 return EOK;119 default:120 return ENOTSUP;121 }122 153 } 123 154 -
uspace/srv/net/messages.h
r71b00dcc r60ab6c3 48 48 #include "structures/packet/packet.h" 49 49 50 /** @name Networking message counts51 */52 /*@{*/53 54 /** The number of network interface driver messages.55 */56 #define NET_NETIF_COUNT 657 58 /** The number of general networking messages.59 */60 #define NET_NET_COUNT 361 62 /** The number of network interface layer messages.63 */64 #define NET_NIL_COUNT 765 66 /** The number of Ethernet messages.67 */68 #define NET_ETH_COUNT 069 70 /** The number of inter-network messages.71 */72 #define NET_IL_COUNT 673 74 /** The number of IP messages.75 */76 #define NET_IP_COUNT 477 78 /** The number of ARP messages.79 */80 #define NET_ARP_COUNT 581 82 /** The number of ICMP messages.83 */84 #define NET_ICMP_COUNT 685 86 /** The number of transport layer messages.87 */88 #define NET_TL_COUNT 189 90 /** The number of UDP messages.91 */92 #define NET_UDP_COUNT 093 94 /** The number of TCP messages.95 */96 #define NET_TCP_COUNT 097 98 /** The number of packet management system messages.99 */100 #define NET_PACKET_COUNT 5101 102 /** The number of socket messages.103 */104 #define NET_SOCKET_COUNT 14105 106 /*@}*/107 108 /** @name Networking message intervals109 */110 /*@{*/111 112 /** The first networking message.113 */114 #define NET_FIRST 2000115 116 /** The first network interface layer message.117 */118 #define NET_NETIF_FIRST NET_FIRST119 120 /** The last network interface layer message.121 */122 #define NET_NETIF_LAST (NET_NETIF_FIRST + NET_NETIF_COUNT)123 124 /** The first general networking message.125 */126 #define NET_NET_FIRST (NET_NETIF_LAST + 0)127 128 /** The last general networking message.129 */130 #define NET_NET_LAST (NET_NET_FIRST + NET_NET_COUNT)131 132 /** The first network interface layer message.133 */134 #define NET_NIL_FIRST (NET_NET_LAST + 0)135 136 /** The last network interface layer message.137 */138 #define NET_NIL_LAST (NET_NIL_FIRST + NET_NIL_COUNT)139 140 /** The first Ethernet message.141 */142 #define NET_ETH_FIRST (NET_NIL_LAST + 0)143 144 /** The last Ethernet message.145 */146 #define NET_ETH_LAST (NET_ETH_FIRST + NET_ETH_COUNT)147 148 /** The first inter-network message.149 */150 #define NET_IL_FIRST (NET_ETH_LAST + 0)151 152 /** The last inter-network message.153 */154 #define NET_IL_LAST (NET_IL_FIRST + NET_IL_COUNT)155 156 /** The first IP message.157 */158 #define NET_IP_FIRST (NET_IL_LAST + 0)159 160 /** The last IP message.161 */162 #define NET_IP_LAST (NET_IP_FIRST + NET_IP_COUNT)163 164 /** The first ARP message.165 */166 #define NET_ARP_FIRST (NET_IP_LAST + 0)167 168 /** The last ARP message.169 */170 #define NET_ARP_LAST (NET_ARP_FIRST + NET_ARP_COUNT)171 172 /** The first ICMP message.173 */174 #define NET_ICMP_FIRST (NET_ARP_LAST + 0)175 176 /** The last ICMP message.177 */178 #define NET_ICMP_LAST (NET_ICMP_FIRST + NET_ICMP_COUNT)179 180 /** The first ICMP message.181 */182 #define NET_TL_FIRST (NET_ICMP_LAST + 0)183 184 /** The last ICMP message.185 */186 #define NET_TL_LAST (NET_TL_FIRST + NET_TL_COUNT)187 188 /** The first UDP message.189 */190 #define NET_UDP_FIRST (NET_TL_LAST + 0)191 192 /** The last UDP message.193 */194 #define NET_UDP_LAST (NET_UDP_FIRST + NET_UDP_COUNT)195 196 /** The first TCP message.197 */198 #define NET_TCP_FIRST (NET_UDP_LAST + 0)199 200 /** The last TCP message.201 */202 #define NET_TCP_LAST (NET_TCP_FIRST + NET_TCP_COUNT)203 204 /** The first socket message.205 */206 #define NET_SOCKET_FIRST (NET_TCP_LAST + 0)207 208 /** The last socket message.209 */210 #define NET_SOCKET_LAST (NET_SOCKET_FIRST + NET_SOCKET_COUNT)211 212 /** The first packet management system message.213 */214 #define NET_PACKET_FIRST (NET_SOCKET_LAST + 0)215 216 /** The last packet management system message.217 */218 #define NET_PACKET_LAST (NET_PACKET_FIRST + NET_PACKET_COUNT)219 220 /** The last networking message.221 */222 #define NET_LAST NET_PACKET_LAST223 224 /** The number of networking messages.225 */226 #define NET_COUNT (NET_LAST - NET_FIRST)227 228 50 /** Returns a value indicating whether the value is in the interval. 229 51 * @param[in] item The value to be checked. … … 233 55 #define IS_IN_INTERVAL(item, first_inclusive, last_exclusive) (((item) >= (first_inclusive)) && ((item) < (last_exclusive))) 234 56 57 /** @name Networking message counts 58 */ 59 /*@{*/ 60 61 /** The number of ARP messages. 62 */ 63 #define NET_ARP_COUNT 5 64 65 /** The number of Ethernet messages. 66 */ 67 #define NET_ETH_COUNT 0 68 69 /** The number of ICMP messages. 70 */ 71 #define NET_ICMP_COUNT 6 72 73 /** The number of inter-network messages. 74 */ 75 #define NET_IL_COUNT 6 76 77 /** The number of IP messages. 78 */ 79 #define NET_IP_COUNT 4 80 81 /** The number of general networking messages. 82 */ 83 #define NET_NET_COUNT 3 84 85 /** The number of network interface driver messages. 86 */ 87 #define NET_NETIF_COUNT 6 88 89 /** The number of network interface layer messages. 90 */ 91 #define NET_NIL_COUNT 7 92 93 /** The number of packet management system messages. 94 */ 95 #define NET_PACKET_COUNT 5 96 97 /** The number of socket messages. 98 */ 99 #define NET_SOCKET_COUNT 14 100 101 /** The number of TCP messages. 102 */ 103 #define NET_TCP_COUNT 0 104 105 /** The number of transport layer messages. 106 */ 107 #define NET_TL_COUNT 1 108 109 /** The number of UDP messages. 110 */ 111 #define NET_UDP_COUNT 0 112 113 /*@}*/ 114 115 /** @name Networking message intervals 116 */ 117 /*@{*/ 118 119 /** The first networking message. 120 */ 121 #define NET_FIRST 2000 122 123 /** The first network interface layer message. 124 */ 125 #define NET_NETIF_FIRST NET_FIRST 126 127 /** The last network interface layer message. 128 */ 129 #define NET_NETIF_LAST (NET_NETIF_FIRST + NET_NETIF_COUNT) 130 131 /** The first general networking message. 132 */ 133 #define NET_NET_FIRST (NET_NETIF_LAST + 0) 134 135 /** The last general networking message. 136 */ 137 #define NET_NET_LAST (NET_NET_FIRST + NET_NET_COUNT) 138 139 /** The first network interface layer message. 140 */ 141 #define NET_NIL_FIRST (NET_NET_LAST + 0) 142 143 /** The last network interface layer message. 144 */ 145 #define NET_NIL_LAST (NET_NIL_FIRST + NET_NIL_COUNT) 146 147 /** The first Ethernet message. 148 */ 149 #define NET_ETH_FIRST (NET_NIL_LAST + 0) 150 151 /** The last Ethernet message. 152 */ 153 #define NET_ETH_LAST (NET_ETH_FIRST + NET_ETH_COUNT) 154 155 /** The first inter-network message. 156 */ 157 #define NET_IL_FIRST (NET_ETH_LAST + 0) 158 159 /** The last inter-network message. 160 */ 161 #define NET_IL_LAST (NET_IL_FIRST + NET_IL_COUNT) 162 163 /** The first IP message. 164 */ 165 #define NET_IP_FIRST (NET_IL_LAST + 0) 166 167 /** The last IP message. 168 */ 169 #define NET_IP_LAST (NET_IP_FIRST + NET_IP_COUNT) 170 171 /** The first ARP message. 172 */ 173 #define NET_ARP_FIRST (NET_IP_LAST + 0) 174 175 /** The last ARP message. 176 */ 177 #define NET_ARP_LAST (NET_ARP_FIRST + NET_ARP_COUNT) 178 179 /** The first ICMP message. 180 */ 181 #define NET_ICMP_FIRST (NET_ARP_LAST + 0) 182 183 /** The last ICMP message. 184 */ 185 #define NET_ICMP_LAST (NET_ICMP_FIRST + NET_ICMP_COUNT) 186 187 /** The first ICMP message. 188 */ 189 #define NET_TL_FIRST (NET_ICMP_LAST + 0) 190 191 /** The last ICMP message. 192 */ 193 #define NET_TL_LAST (NET_TL_FIRST + NET_TL_COUNT) 194 195 /** The first UDP message. 196 */ 197 #define NET_UDP_FIRST (NET_TL_LAST + 0) 198 199 /** The last UDP message. 200 */ 201 #define NET_UDP_LAST (NET_UDP_FIRST + NET_UDP_COUNT) 202 203 /** The first TCP message. 204 */ 205 #define NET_TCP_FIRST (NET_UDP_LAST + 0) 206 207 /** The last TCP message. 208 */ 209 #define NET_TCP_LAST (NET_TCP_FIRST + NET_TCP_COUNT) 210 211 /** The first socket message. 212 */ 213 #define NET_SOCKET_FIRST (NET_TCP_LAST + 0) 214 215 /** The last socket message. 216 */ 217 #define NET_SOCKET_LAST (NET_SOCKET_FIRST + NET_SOCKET_COUNT) 218 219 /** The first packet management system message. 220 */ 221 #define NET_PACKET_FIRST (NET_SOCKET_LAST + 0) 222 223 /** The last packet management system message. 224 */ 225 #define NET_PACKET_LAST (NET_PACKET_FIRST + NET_PACKET_COUNT) 226 227 /** The last networking message. 228 */ 229 #define NET_LAST NET_PACKET_LAST 230 231 /** The number of networking messages. 232 */ 233 #define NET_COUNT (NET_LAST - NET_FIRST) 234 235 235 /** Returns a value indicating whether the IPC call is a generic networking message. 236 236 * @param[in] call The IPC call to be checked. … … 238 238 #define IS_NET_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_FIRST, NET_LAST) 239 239 240 /** Returns a value indicating whether the IPC call is an ARP message. 241 * @param[in] call The IPC call to be checked. 242 */ 243 #define IS_NET_ARP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ARP_FIRST, NET_ARP_LAST) 244 245 /** Returns a value indicating whether the IPC call is an Ethernet message. 246 * @param[in] call The IPC call to be checked. 247 */ 248 #define IS_NET_ETH_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ETH_FIRST, NET_ETH_LAST) 249 250 /** Returns a value indicating whether the IPC call is an ICMP message. 251 * @param[in] call The IPC call to be checked. 252 */ 253 #define IS_NET_ICMP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST) 254 255 /** Returns a value indicating whether the IPC call is an inter-network layer message. 256 * @param[in] call The IPC call to be checked. 257 */ 258 #define IS_NET_IL_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IL_FIRST, NET_IL_LAST) 259 260 /** Returns a value indicating whether the IPC call is an IP message. 261 * @param[in] call The IPC call to be checked. 262 */ 263 #define IS_NET_IP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IP_FIRST, NET_IP_LAST) 264 240 265 /** Returns a value indicating whether the IPC call is a generic networking message. 241 266 * @param[in] call The IPC call to be checked. … … 248 273 #define IS_NET_NIL_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_NIL_FIRST, NET_NIL_LAST) 249 274 250 /** Returns a value indicating whether the IPC call is an Ethernet message. 251 * @param[in] call The IPC call to be checked. 252 */ 253 #define IS_NET_ETH_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ETH_FIRST, NET_ETH_LAST) 254 255 /** Returns a value indicating whether the IPC call is an inter-network layer message. 256 * @param[in] call The IPC call to be checked. 257 */ 258 #define IS_NET_IL_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IL_FIRST, NET_IL_LAST) 259 260 /** Returns a value indicating whether the IPC call is an IP message. 261 * @param[in] call The IPC call to be checked. 262 */ 263 #define IS_NET_IP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_IP_FIRST, NET_IP_LAST) 264 265 /** Returns a value indicating whether the IPC call is an ARP message. 266 * @param[in] call The IPC call to be checked. 267 */ 268 #define IS_NET_ARP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ARP_FIRST, NET_ARP_LAST) 269 270 /** Returns a value indicating whether the IPC call is an ICMP message. 271 * @param[in] call The IPC call to be checked. 272 */ 273 #define IS_NET_ICMP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_ICMP_FIRST, NET_ICMP_LAST) 275 /** Returns a value indicating whether the IPC call is a packet manaagement system message. 276 * @param[in] call The IPC call to be checked. 277 */ 278 #define IS_NET_PACKET_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST) 279 280 /** Returns a value indicating whether the IPC call is a socket message. 281 * @param[in] call The IPC call to be checked. 282 */ 283 #define IS_NET_SOCKET_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST) 284 285 /** Returns a value indicating whether the IPC call is a TCP message. 286 * @param[in] call The IPC call to be checked. 287 */ 288 #define IS_NET_TCP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TCP_FIRST, NET_TCP_LAST) 274 289 275 290 /** Returns a value indicating whether the IPC call is a transport layer message. … … 283 298 #define IS_NET_UDP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_UDP_FIRST, NET_UDP_LAST) 284 299 285 /** Returns a value indicating whether the IPC call is a TCP message. 286 * @param[in] call The IPC call to be checked. 287 */ 288 #define IS_NET_TCP_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_TCP_FIRST, NET_TCP_LAST) 289 290 /** Returns a value indicating whether the IPC call is a socket message. 291 * @param[in] call The IPC call to be checked. 292 */ 293 #define IS_NET_SOCKET_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_SOCKET_FIRST, NET_SOCKET_LAST) 294 295 /** Returns a value indicating whether the IPC call is a packet manaagement system message. 296 * @param[in] call The IPC call to be checked. 297 */ 298 #define IS_NET_PACKET_MESSAGE(call) IS_IN_INTERVAL(IPC_GET_METHOD(*call), NET_PACKET_FIRST, NET_PACKET_LAST) 299 300 /*@}*/ 301 302 /** @name Networking specific message parameters definitions 303 */ 304 /*@{*/ 305 306 /** Returns the device identifier message parameter. 300 /*@}*/ 301 302 /** @name Networking specific message arguments definitions 303 */ 304 /*@{*/ 305 306 /** @name First arguments 307 */ 308 /*@{*/ 309 310 /** Returns the device identifier message argument. 307 311 * @param[in] call The message call structure. 308 312 */ 309 313 #define IPC_GET_DEVICE(call) (device_id_t) IPC_GET_ARG1(*call) 310 314 311 /** Returns the packet identifier message parameter. 315 /*@}*/ 316 317 /** @name Second arguments 318 */ 319 /*@{*/ 320 321 /** Returns the packet identifier message argument. 312 322 * @param[in] call The message call structure. 313 323 */ 314 324 #define IPC_GET_PACKET(call) (packet_id_t) IPC_GET_ARG2(*call) 315 325 316 /** Returns the count message parameter.326 /** Returns the count message argument. 317 327 * @param[in] call The message call structure. 318 328 */ 319 329 #define IPC_GET_COUNT(call) (size_t) IPC_GET_ARG2(*call) 320 330 321 /** Returns the device state message parameter.331 /** Returns the device state message argument. 322 332 * @param[in] call The message call structure. 323 333 */ 324 334 #define IPC_GET_STATE(call) (device_state_t) IPC_GET_ARG2(*call) 325 335 326 /** Returns the maximum transmission unit message parameter.336 /** Returns the maximum transmission unit message argument. 327 337 * @param[in] call The message call structure. 328 338 */ 329 339 #define IPC_GET_MTU(call) (size_t) IPC_GET_ARG2(*call) 330 340 331 /** Returns the device driver service message parameter. 341 /*@}*/ 342 343 /** @name Third arguments 344 */ 345 /*@{*/ 346 347 /** Returns the device driver service message argument. 332 348 * @param[in] call The message call structure. 333 349 */ 334 350 #define IPC_GET_SERVICE(call) (services_t) IPC_GET_ARG3(*call) 335 351 336 /** Returns the target service message parameter.352 /** Returns the target service message argument. 337 353 * @param[in] call The message call structure. 338 354 */ 339 355 #define IPC_GET_TARGET(call) (services_t) IPC_GET_ARG3(*call) 340 356 341 /** Returns the sender service message parameter.357 /** Returns the sender service message argument. 342 358 * @param[in] call The message call structure. 343 359 */ 344 360 #define IPC_GET_SENDER(call) (services_t) IPC_GET_ARG3(*call) 345 361 346 /** Returns the error service message parameter. 362 /*@}*/ 363 364 /** @name Fourth arguments 365 */ 366 /*@{*/ 367 368 /** Returns the error service message argument. 347 369 * @param[in] call The message call structure. 348 370 */ 349 371 #define IPC_GET_ERROR(call) (services_t) IPC_GET_ARG4(*call) 350 372 351 /** Returns the phone message parameter. 373 /*@}*/ 374 375 /** @name Fifth arguments 376 */ 377 /*@{*/ 378 379 /** Returns the phone message argument. 352 380 * @param[in] call The message call structure. 353 381 */ 354 382 #define IPC_GET_PHONE(call) (int) IPC_GET_ARG5(*call) 383 384 /*@}*/ 385 386 /** @name First answers 387 */ 388 /*@{*/ 355 389 356 390 /** Sets the device identifier in the message answer. … … 364 398 #define IPC_SET_ADDR(answer) ((size_t *) &IPC_GET_ARG1(*answer)) 365 399 400 /*@}*/ 401 402 /** @name Second answers 403 */ 404 /*@{*/ 405 366 406 /** Sets the minimum prefix size in the message answer. 367 407 * @param[out] answer The message answer structure. … … 369 409 #define IPC_SET_PREFIX(answer) ((size_t *) &IPC_GET_ARG2(*answer)) 370 410 411 /*@}*/ 412 413 /** @name Third answers 414 */ 415 /*@{*/ 416 371 417 /** Sets the maximum content size in the message answer. 372 418 * @param[out] answer The message answer structure. … … 374 420 #define IPC_SET_CONTENT(answer) ((size_t *) &IPC_GET_ARG3(*answer)) 375 421 422 /*@}*/ 423 424 /** @name Fourth answers 425 */ 426 /*@{*/ 427 376 428 /** Sets the minimum suffix size in the message answer. 377 429 * @param[out] answer The message answer structure. … … 380 432 381 433 /*@}*/ 434 435 /*@}*/ 436 437 /** Notifies the module about the device state change. 438 * @param[in] phone The service module phone. 439 * @param[in] message The service specific message. 440 * @param[in] device_id The device identifier. 441 * @param[in] state The new device state. 442 * @param[in] target The target module service. 443 * @returns EOK on success. 444 */ 445 static inline int generic_device_state_msg(int phone, int message, device_id_t device_id, int state, services_t target){ 446 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) state, target); 447 return EOK; 448 } 449 450 /** Notifies a module about the device. 451 * @param[in] phone The service module phone. 452 * @param[in] message The service specific message. 453 * @param[in] device_id The device identifier. 454 * @param[in] arg2 The second argument of the message. 455 * @param[in] service The device module service. 456 * @returns EOK on success. 457 * @returns Other error codes as defined for the specific service message. 458 */ 459 static inline int generic_device_req(int phone, int message, device_id_t device_id, int arg2, services_t service){ 460 return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) arg2, (ipcarg_t) service); 461 } 382 462 383 463 /** Returns the address. … … 399 479 return EBADMEM; 400 480 } 481 482 // request the address 401 483 message_id = async_send_1(phone, (ipcarg_t) message, (ipcarg_t) device_id, NULL); 402 484 string = measured_strings_return(phone, address, data, 1); 403 485 async_wait_for(message_id, &result); 486 487 // if not successful 404 488 if((string == EOK) && (result != EOK)){ 489 // clear the data 405 490 free(*address); 406 491 free(*data); 407 492 } 408 493 return (int) result; 494 } 495 496 /** Returns the device packet dimension for sending. 497 * @param[in] phone The service module phone. 498 * @param[in] message The service specific message. 499 * @param[in] device_id The device identifier. 500 * @param[out] packet_dimension The packet dimension. 501 * @returns EOK on success. 502 * @returns EBADMEM if the packet_dimension parameter is NULL. 503 * @returns Other error codes as defined for the specific service message. 504 */ 505 static inline int generic_packet_size_req(int phone, int message, device_id_t device_id, packet_dimension_ref packet_dimension){ 506 ipcarg_t result; 507 ipcarg_t prefix; 508 ipcarg_t content; 509 ipcarg_t suffix; 510 ipcarg_t addr_len; 511 512 if(! packet_dimension){ 513 return EBADMEM; 514 } 515 result = async_req_1_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix); 516 packet_dimension->prefix = (size_t) prefix; 517 packet_dimension->content = (size_t) content; 518 packet_dimension->suffix = (size_t) suffix; 519 packet_dimension->addr_len = (size_t) addr_len; 520 return (int) result; 521 } 522 523 /** Passes the packet queue to the module. 524 * @param[in] phone The service module phone. 525 * @param[in] message The service specific message. 526 * @param[in] device_id The device identifier. 527 * @param[in] packet_id The received packet or the received packet queue identifier. 528 * @param[in] target The target module service. 529 * @param[in] error The error module service. 530 * @returns EOK on success. 531 */ 532 static inline int generic_received_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target, services_t error){ 533 if(error){ 534 async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error); 535 }else{ 536 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target); 537 } 538 return EOK; 539 } 540 541 /** Sends the packet queue. 542 * @param[in] phone The service module phone. 543 * @param[in] message The service specific message. 544 * @param[in] device_id The device identifier. 545 * @param[in] packet_id The packet or the packet queue identifier. 546 * @param[in] sender The sending module service. 547 * @param[in] error The error module service. 548 * @returns EOK on success. 549 */ 550 static inline int generic_send_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender, services_t error){ 551 if(error){ 552 async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error); 553 }else{ 554 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender); 555 } 556 return EOK; 409 557 } 410 558 … … 436 584 return EBADMEM; 437 585 } 586 587 // request the translation 438 588 message_id = async_send_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) count, (ipcarg_t) service, NULL); 439 589 measured_strings_send(phone, configuration, count); 440 590 string = measured_strings_return(phone, translation, data, count); 441 591 async_wait_for(message_id, &result); 592 593 // if not successful 442 594 if((string == EOK) && (result != EOK)){ 595 // clear the data 443 596 free(*translation); 444 597 free(*data); 445 598 } 599 446 600 return (int) result; 447 601 } 448 602 449 /** Sends the packet queue.450 * @param[in] phone The service module phone.451 * @param[in] message The service specific message.452 * @param[in] device_id The device identifier.453 * @param[in] packet_id The packet or the packet queue identifier.454 * @param[in] sender The sending module service.455 * @param[in] error The error module service.456 * @returns EOK on success.457 */458 static inline int generic_send_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t sender, services_t error){459 if(error){460 async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender, (ipcarg_t) error);461 }else{462 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) sender);463 }464 return EOK;465 }466 467 /** Returns the device packet dimension for sending.468 * @param[in] phone The service module phone.469 * @param[in] message The service specific message.470 * @param[in] device_id The device identifier.471 * @param[out] packet_dimension The packet dimension.472 * @returns EOK on success.473 * @returns EBADMEM if the packet_dimension parameter is NULL.474 * @returns Other error codes as defined for the specific service message.475 */476 static inline int generic_packet_size_req(int phone, int message, device_id_t device_id, packet_dimension_ref packet_dimension){477 ipcarg_t result;478 ipcarg_t prefix;479 ipcarg_t content;480 ipcarg_t suffix;481 ipcarg_t addr_len;482 483 if(! packet_dimension){484 return EBADMEM;485 }486 result = async_req_1_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, &addr_len, &prefix, &content, &suffix);487 packet_dimension->prefix = (size_t) prefix;488 packet_dimension->content = (size_t) content;489 packet_dimension->suffix = (size_t) suffix;490 packet_dimension->addr_len = (size_t) addr_len;491 return (int) result;492 }493 494 /** Notifies the module about the device state change.495 * @param[in] phone The service module phone.496 * @param[in] message The service specific message.497 * @param[in] device_id The device identifier.498 * @param[in] state The new device state.499 * @param[in] target The target module service.500 * @returns EOK on success.501 */502 static inline int generic_device_state_msg(int phone, int message, device_id_t device_id, int state, services_t target){503 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) state, target);504 return EOK;505 }506 507 /** Passes the packet queue to the module.508 * @param[in] phone The service module phone.509 * @param[in] message The service specific message.510 * @param[in] device_id The device identifier.511 * @param[in] packet_id The received packet or the received packet queue identifier.512 * @param[in] target The target module service.513 * @param[in] error The error module service.514 * @returns EOK on success.515 */516 static inline int generic_received_msg(int phone, int message, device_id_t device_id, packet_id_t packet_id, services_t target, services_t error){517 if(error){518 async_msg_4(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target, (ipcarg_t) error);519 }else{520 async_msg_3(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) packet_id, (ipcarg_t) target);521 }522 return EOK;523 }524 525 /** Notifies a module about the device.526 * @param[in] phone The service module phone.527 * @param[in] message The service specific message.528 * @param[in] device_id The device identifier.529 * @param[in] arg2 The second argument of the message.530 * @param[in] service The device module service.531 * @returns EOK on success.532 * @returns Other error codes as defined for the specific service message.533 */534 static inline int generic_device_req(int phone, int message, device_id_t device_id, int arg2, services_t service){535 return (int) async_req_3_0(phone, (ipcarg_t) message, (ipcarg_t) device_id, (ipcarg_t) arg2, (ipcarg_t) service);536 }537 538 603 #endif 539 604 -
uspace/srv/net/module.c
r71b00dcc r60ab6c3 104 104 ipc_answer_0(iid, EOK); 105 105 106 // process additional messages 106 107 while(true){ 108 109 // clear the answer structure 107 110 refresh_answer(&answer, &answer_count); 108 111 112 // fetch the next message 109 113 callid = async_get_call(&call); 114 115 // process the message 110 116 res = module_message(callid, &call, &answer, &answer_count); 111 117 118 // end if said to either by the message or the processing result 112 119 if((IPC_GET_METHOD(call) == IPC_M_PHONE_HUNGUP) || (res == EHANGUP)){ 113 120 return; 114 121 } 115 122 123 // answer the message 116 124 answer_call(callid, res, &answer, answer_count); 117 125 } … … 121 129 ERROR_DECLARE; 122 130 131 // print the module label 123 132 printf("Task %d - ", task_get_id()); 124 133 module_print_name(); 125 134 printf("\n"); 135 136 // start the module 126 137 if(ERROR_OCCURRED(module_start(client_connection))){ 127 138 printf(" - ERROR %i\n", ERROR_CODE); 128 139 return ERROR_CODE; 129 140 } 141 130 142 return EOK; 131 143 } -
uspace/srv/net/modules.c
r71b00dcc r60ab6c3 51 51 52 52 void answer_call(ipc_callid_t callid, int result, ipc_call_t * answer, int answer_count){ 53 // choose the most efficient answer function 53 54 if(answer || (! answer_count)){ 54 55 switch(answer_count){ … … 86 87 ipcarg_t phonehash; 87 88 89 // connect to the needed service 88 90 phone = connect_to_service_timeout(need, timeout); 91 // if connected 89 92 if(phone >= 0){ 93 // request the bidirectional connection 90 94 if(ERROR_OCCURRED(ipc_connect_to_me(phone, arg1, arg2, arg3, &phonehash))){ 91 95 ipc_hangup(phone); … … 102 106 103 107 int connect_to_service_timeout(services_t need, suseconds_t timeout){ 104 if (timeout <= 0) 108 int phone; 109 110 // if no timeout is set 111 if (timeout <= 0){ 105 112 return async_connect_me_to_blocking(PHONE_NS, need, 0, 0); 106 113 } 114 107 115 while(true){ 108 int phone; 116 phone = async_connect_me_to(PHONE_NS, need, 0, 0); 117 if((phone >= 0) || (phone != ENOENT)){ 118 return phone; 119 } 109 120 110 phone = async_connect_me_to(PHONE_NS, need, 0, 0); 111 if((phone >= 0) || (phone != ENOENT)) 112 return phone; 113 114 timeout -= MODULE_WAIT_TIME; 121 // end if no time is left 115 122 if(timeout <= 0){ 116 123 return ETIMEOUT; 117 124 } 118 125 119 usleep(MODULE_WAIT_TIME); 126 // wait the minimum of the module wait time and the timeout 127 usleep((timeout <= MODULE_WAIT_TIME) ? timeout : MODULE_WAIT_TIME); 128 timeout -= MODULE_WAIT_TIME; 120 129 } 121 130 } … … 129 138 return EBADMEM; 130 139 } 140 141 // fetch the request 131 142 if(! async_data_write_receive(&callid, length)){ 132 143 return EINVAL; 133 144 } 145 146 // allocate the buffer 134 147 *data = malloc(*length); 135 148 if(!(*data)){ 136 149 return ENOMEM; 137 150 } 151 152 // fetch the data 138 153 if(ERROR_OCCURRED(async_data_write_finalize(callid, * data, * length))){ 139 154 free(data); … … 147 162 ipc_callid_t callid; 148 163 164 // fetch the request 149 165 if(! async_data_read_receive(&callid, &length)){ 150 166 return EINVAL; 151 167 } 168 169 // check the requested data size 152 170 if(length < data_length){ 153 171 async_data_read_finalize(callid, data, length); 154 172 return EOVERFLOW; 155 173 } 174 175 // send the data 156 176 return async_data_read_finalize(callid, data, data_length); 157 177 } 158 178 159 179 void refresh_answer(ipc_call_t * answer, int * answer_count){ 180 160 181 if(answer_count){ 161 182 *answer_count = 0; 162 183 } 184 163 185 if(answer){ 164 186 IPC_SET_RETVAL(*answer, 0); -
uspace/srv/net/net/net.c
r71b00dcc r60ab6c3 66 66 #include "net_messages.h" 67 67 68 /** File read buffer size. 69 */ 70 #define BUFFER_SIZE 256 71 68 72 /** Networking module name. 69 73 */ 70 74 #define NAME "Networking" 71 75 72 /** File read buffer size. 73 */ 74 #define BUFFER_SIZE 256 76 /** Networking module global data. 77 */ 78 net_globals_t net_globals; 79 80 /** Generates new system-unique device identifier. 81 * @returns The system-unique devic identifier. 82 */ 83 device_id_t generate_new_device_id(void); 75 84 76 85 /** Prints the module name. … … 88 97 int module_start(async_client_conn_t client_connection); 89 98 90 /** \todo 91 */ 92 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration); 99 /** Returns the configured values. 100 * The network interface configuration is searched first. 101 * @param[in] netif_conf The network interface configuration setting. 102 * @param[out] configuration The found configured values. 103 * @param[in] count The desired settings count. 104 * @param[out] data The found configuration settings data. 105 * @returns EOK. 106 */ 107 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data); 108 109 /** Initializes the networking module. 110 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 111 * @returns EOK on success. 112 * @returns ENOMEM if there is not enough memory left. 113 */ 114 int net_initialize(async_client_conn_t client_connection); 93 115 94 116 /** \todo … … 101 123 */ 102 124 int read_configuration(void); 125 126 /** \todo 127 */ 128 int read_configuration_file(const char * directory, const char * filename, measured_strings_ref configuration); 129 130 /** Reads the network interface specific configuration. 131 * @param[in] name The network interface name. 132 * @param[in,out] netif The network interface structure. 133 * @returns EOK on success. 134 * @returns Other error codes as defined for the add_configuration() function. 135 */ 136 int read_netif_configuration(const char * name, netif_ref netif); 103 137 104 138 /** Starts the network interface according to its configuration. … … 126 160 int startup(void); 127 161 128 /** Generates new system-unique device identifier. 129 * @returns The system-unique devic identifier. 130 */ 131 device_id_t generate_new_device_id(void); 132 133 /** Returns the configured values. 134 * The network interface configuration is searched first. 135 * @param[in] netif_conf The network interface configuration setting. 136 * @param[out] configuration The found configured values. 137 * @param[in] count The desired settings count. 138 * @param[out] data The found configuration settings data. 139 * @returns EOK. 140 */ 141 int net_get_conf(measured_strings_ref netif_conf, measured_string_ref configuration, size_t count, char ** data); 142 143 /** Initializes the networking module. 144 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 145 * @returns EOK on success. 146 * @returns ENOMEM if there is not enough memory left. 147 */ 148 int net_initialize(async_client_conn_t client_connection); 149 150 /** Reads the network interface specific configuration. 151 * @param[in] name The network interface name. 152 * @param[in,out] netif The network interface structure. 153 * @returns EOK on success. 154 * @returns Other error codes as defined for the add_configuration() function. 155 */ 156 int read_netif_configuration(const char * name, netif_ref netif); 157 158 /** Networking module global data. 159 */ 160 net_globals_t net_globals; 162 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t) 161 163 162 164 DEVICE_MAP_IMPLEMENT(netifs, netif_t) 163 165 164 GENERIC_CHAR_MAP_IMPLEMENT(measured_strings, measured_string_t) 166 int add_configuration(measured_strings_ref configuration, const char * name, const char * value){ 167 ERROR_DECLARE; 168 169 measured_string_ref setting; 170 171 setting = measured_string_create_bulk(value, 0); 172 if(! setting){ 173 return ENOMEM; 174 } 175 // add the configuration setting 176 if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){ 177 free(setting); 178 return ERROR_CODE; 179 } 180 return EOK; 181 } 182 183 device_id_t generate_new_device_id(void){ 184 return device_assign_devno(); 185 } 165 186 166 187 void module_print_name(void){ … … 187 208 } 188 209 189 int net_initialize(async_client_conn_t client_connection){ 190 ERROR_DECLARE; 191 192 netifs_initialize(&net_globals.netifs); 193 char_map_initialize(&net_globals.netif_names); 194 modules_initialize(&net_globals.modules); 195 measured_strings_initialize(&net_globals.configuration); 196 197 // TODO dynamic configuration 198 ERROR_PROPAGATE(read_configuration()); 199 200 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service)); 201 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service)); 202 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service)); 203 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service)); 204 205 // build specific initialization 206 return net_initialize_build(client_connection); 207 } 208 209 int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){ 210 netif_ref netif; 211 212 if(!(configuration && (count > 0))){ 213 return EINVAL; 214 } 215 netif = netifs_find(&net_globals.netifs, device_id); 216 if(netif){ 217 return net_get_conf(&netif->configuration, * configuration, count, data); 218 }else{ 219 return net_get_conf(NULL, * configuration, count, data); 220 } 221 } 222 223 int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){ 224 if(!(configuration && (count > 0))){ 225 return EINVAL; 226 } 227 return net_get_conf(NULL, * configuration, count, data); 210 int net_connect_module(services_t service){ 211 return EOK; 212 } 213 214 void net_free_settings(measured_string_ref settings, char * data){ 228 215 } 229 216 … … 235 222 *data = NULL; 236 223 } 224 237 225 for(index = 0; index < count; ++ index){ 238 226 setting = measured_strings_find(netif_conf, configuration[index].value, 0); … … 251 239 } 252 240 253 void net_free_settings(measured_string_ref settings, char * data){ 254 } 255 256 int net_connect_module(services_t service){ 257 return EOK; 241 int net_get_conf_req(int net_phone, measured_string_ref * configuration, size_t count, char ** data){ 242 if(!(configuration && (count > 0))){ 243 return EINVAL; 244 } 245 246 return net_get_conf(NULL, * configuration, count, data); 247 } 248 249 int net_get_device_conf_req(int net_phone, device_id_t device_id, measured_string_ref * configuration, size_t count, char ** data){ 250 netif_ref netif; 251 252 if(!(configuration && (count > 0))){ 253 return EINVAL; 254 } 255 256 netif = netifs_find(&net_globals.netifs, device_id); 257 if(netif){ 258 return net_get_conf(&netif->configuration, * configuration, count, data); 259 }else{ 260 return net_get_conf(NULL, * configuration, count, data); 261 } 262 } 263 264 int net_initialize(async_client_conn_t client_connection){ 265 ERROR_DECLARE; 266 267 netifs_initialize(&net_globals.netifs); 268 char_map_initialize(&net_globals.netif_names); 269 modules_initialize(&net_globals.modules); 270 measured_strings_initialize(&net_globals.configuration); 271 272 // TODO dynamic configuration 273 ERROR_PROPAGATE(read_configuration()); 274 275 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, LO_NAME, LO_FILENAME, SERVICE_LO, 0, connect_to_service)); 276 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, DP8390_NAME, DP8390_FILENAME, SERVICE_DP8390, 0, connect_to_service)); 277 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, ETHERNET_NAME, ETHERNET_FILENAME, SERVICE_ETHERNET, 0, connect_to_service)); 278 ERROR_PROPAGATE(add_module(NULL, &net_globals.modules, NILDUMMY_NAME, NILDUMMY_FILENAME, SERVICE_NILDUMMY, 0, connect_to_service)); 279 280 // build specific initialization 281 return net_initialize_build(client_connection); 258 282 } 259 283 … … 288 312 } 289 313 return ENOTSUP; 314 } 315 316 int parse_line(measured_strings_ref configuration, char * line){ 317 ERROR_DECLARE; 318 319 measured_string_ref setting; 320 char * name; 321 char * value; 322 323 // from the beginning 324 name = line; 325 326 // skip comments and blank lines 327 if((*name == '#') || (*name == '\0')){ 328 return EOK; 329 } 330 // skip spaces 331 while(isspace(*name)){ 332 ++ name; 333 } 334 335 // remember the name start 336 value = name; 337 // skip the name 338 while(isalnum(*value) || (*value == '_')){ 339 // make uppercase 340 // *value = toupper(*value); 341 ++ value; 342 } 343 344 if(*value == '='){ 345 // terminate the name 346 *value = '\0'; 347 }else{ 348 // terminate the name 349 *value = '\0'; 350 // skip until '=' 351 ++ value; 352 while((*value) && (*value != '=')){ 353 ++ value; 354 } 355 // not found? 356 if(*value != '='){ 357 return EINVAL; 358 } 359 } 360 361 ++ value; 362 // skip spaces 363 while(isspace(*value)){ 364 ++ value; 365 } 366 // create a bulk measured string till the end 367 setting = measured_string_create_bulk(value, 0); 368 if(! setting){ 369 return ENOMEM; 370 } 371 372 // add the configuration setting 373 if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){ 374 free(setting); 375 return ERROR_CODE; 376 } 377 return EOK; 378 } 379 380 int read_configuration(void){ 381 // read the general configuration file 382 return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, &net_globals.configuration); 290 383 } 291 384 … … 341 434 } 342 435 343 int parse_line(measured_strings_ref configuration, char * line){344 ERROR_DECLARE;345 346 measured_string_ref setting;347 char * name;348 char * value;349 350 // from the beginning351 name = line;352 353 // skip comments and blank lines354 if((*name == '#') || (*name == '\0')){355 return EOK;356 }357 // skip spaces358 while(isspace(*name)){359 ++ name;360 }361 362 // remember the name start363 value = name;364 // skip the name365 while(isalnum(*value) || (*value == '_')){366 // make uppercase367 // *value = toupper(*value);368 ++ value;369 }370 371 if(*value == '='){372 // terminate the name373 *value = '\0';374 }else{375 // terminate the name376 *value = '\0';377 // skip until '='378 ++ value;379 while((*value) && (*value != '=')){380 ++ value;381 }382 // not found?383 if(*value != '='){384 return EINVAL;385 }386 }387 388 ++ value;389 // skip spaces390 while(isspace(*value)){391 ++ value;392 }393 // create a bulk measured string till the end394 setting = measured_string_create_bulk(value, 0);395 if(! setting){396 return ENOMEM;397 }398 399 // add the configuration setting400 if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){401 free(setting);402 return ERROR_CODE;403 }404 return EOK;405 }406 407 int add_configuration(measured_strings_ref configuration, const char * name, const char * value){408 ERROR_DECLARE;409 410 measured_string_ref setting;411 412 setting = measured_string_create_bulk(value, 0);413 if(! setting){414 return ENOMEM;415 }416 // add the configuration setting417 if(ERROR_OCCURRED(measured_strings_add(configuration, name, 0, setting))){418 free(setting);419 return ERROR_CODE;420 }421 return EOK;422 }423 424 device_id_t generate_new_device_id(void){425 return device_assign_devno();426 }427 428 int read_configuration(void){429 // read the general configuration file430 return read_configuration_file(CONF_DIR, CONF_GENERAL_FILE, &net_globals.configuration);431 }432 433 436 int read_netif_configuration(const char * name, netif_ref netif){ 434 437 // read the netif configuration file … … 452 455 return EINVAL; 453 456 } 457 454 458 // optional network interface layer 455 459 setting = measured_strings_find(&netif->configuration, CONF_NIL, 0); … … 463 467 netif->nil = NULL; 464 468 } 469 465 470 // mandatory internet layer 466 471 setting = measured_strings_find(&netif->configuration, CONF_IL, 0); … … 470 475 return EINVAL; 471 476 } 472 // end of the static loopback initialization 473 // startup the loopback interface477 478 // hardware configuration 474 479 setting = measured_strings_find(&netif->configuration, CONF_IRQ, 0); 475 480 irq = setting ? strtol(setting->value, NULL, 10) : 0; … … 477 482 io = setting ? strtol(setting->value, NULL, 16) : 0; 478 483 ERROR_PROPAGATE(netif_probe_req(netif->driver->phone, netif->id, irq, io)); 484 485 // network interface layer startup 479 486 if(netif->nil){ 480 487 setting = measured_strings_find(&netif->configuration, CONF_MTU, 0); … … 488 495 internet_service = netif->driver->service; 489 496 } 497 498 // inter-network layer startup 490 499 switch(netif->il->service){ 491 500 case SERVICE_IP: … … 525 534 } 526 535 ERROR_PROPAGATE(measured_strings_initialize(&netif->configuration)); 536 527 537 // read configuration files 528 538 if(ERROR_OCCURRED(read_netif_configuration(conf_files[i], netif))){ … … 531 541 return ERROR_CODE; 532 542 } 543 533 544 // mandatory name 534 545 setting = measured_strings_find(&netif->configuration, CONF_NAME, 0); … … 540 551 } 541 552 netif->name = setting->value; 553 542 554 // add to the netifs map 543 555 index = netifs_add(&net_globals.netifs, netif->id, netif); … … 547 559 return index; 548 560 } 561 549 562 // add to the netif names map 550 563 if(ERROR_OCCURRED(char_map_add(&net_globals.netif_names, netif->name, 0, index)) … … 555 568 return ERROR_CODE; 556 569 } 570 557 571 // increment modules' usage 558 572 ++ netif->driver->usage; -
uspace/srv/net/net/net.h
r71b00dcc r60ab6c3 52 52 /*@{*/ 53 53 54 /** DP8390 network interface module full path filename. 55 */ 56 #define DP8390_FILENAME "/srv/dp8390" 57 58 /** DP8390 network interface module name. 59 */ 60 #define DP8390_NAME "dp8390" 61 62 /** Ethernet module full path filename. 63 */ 64 #define ETHERNET_FILENAME "/srv/eth" 65 66 /** Ethernet module name. 67 */ 68 #define ETHERNET_NAME "ethernet" 69 70 /** IP module full path filename. 71 */ 72 #define IP_FILENAME "/srv/ip" 73 74 /** IP module name. 75 */ 76 #define IP_NAME "ip" 77 78 /** Loopback network interface module full path filename. 79 */ 80 #define LO_FILENAME "/srv/lo" 81 54 82 /** Loopback network interface module name. 55 83 */ 56 84 #define LO_NAME "lo" 57 85 58 /** Loopback network interface module full path filename. 59 */ 60 #define LO_FILENAME "/srv/lo" 61 62 /** DP8390 network interface module name. 63 */ 64 #define DP8390_NAME "dp8390" 65 66 /** DP8390 network interface module full path filename. 67 */ 68 #define DP8390_FILENAME "/srv/dp8390" 86 /** Ethernet module full path filename. 87 */ 88 #define NILDUMMY_FILENAME "/srv/nildummy" 69 89 70 90 /** Ethernet module name. 71 91 */ 72 #define ETHERNET_NAME "ethernet"73 74 /** Ethernet module full path filename.75 */76 #define ETHERNET_FILENAME "/srv/eth"77 78 /** Ethernet module name.79 */80 92 #define NILDUMMY_NAME "nildummy" 81 93 82 /** Ethernet module full path filename.83 */84 #define NILDUMMY_FILENAME "/srv/nildummy"85 86 /** IP module name.87 */88 #define IP_NAME "ip"89 90 /** IP module full path filename.91 */92 #define IP_FILENAME "/srv/ip"93 94 94 /*@}*/ 95 95 … … 98 98 /*@{*/ 99 99 100 /** Internet protocol module name configuration label. 101 */ 102 #define CONF_IL "IL" 103 104 /** Device input/output address configuration label. 105 */ 106 #define CONF_IO "IO" 107 108 /** Interrupt number configuration label. 109 */ 110 #define CONF_IRQ "IRQ" 111 112 /** Maximum transmission unit configuration label. 113 */ 114 #define CONF_MTU "MTU" 115 100 116 /** Network interface name configuration label. 101 117 */ … … 110 126 #define CONF_NIL "NIL" 111 127 112 /** Internet protocol module name configuration label.113 */114 #define CONF_IL "IL"115 116 /** Interrupt number configuration label.117 */118 #define CONF_IRQ "IRQ"119 120 /** Device input/output address configuration label.121 */122 #define CONF_IO "IO"123 124 /** Maximum transmission unit configuration label.125 */126 #define CONF_MTU "MTU"127 128 128 /*@}*/ 129 129 … … 135 135 */ 136 136 #define CONF_GENERAL_FILE "general" 137 138 /** Type definition of the networking module global data. 139 * @see net_globals 140 */ 141 typedef struct net_globals net_globals_t; 137 142 138 143 /** Type definition of the network interface specific data. … … 146 151 typedef netif_t * netif_ref; 147 152 148 /** Type definition of the networking module global data. 149 * @see net_globals 150 */ 151 typedef struct net_globals net_globals_t; 153 /** Configuration settings. 154 * Maps setting names to the values. 155 * @see generic_char_map.h 156 */ 157 GENERIC_CHAR_MAP_DECLARE(measured_strings, measured_string_t) 152 158 153 159 /** Present network interfaces. … … 157 163 DEVICE_MAP_DECLARE(netifs, netif_t) 158 164 159 /** Configuration settings. 160 * Maps setting names to the values. 161 * @see generic_char_map.h 162 */ 163 GENERIC_CHAR_MAP_DECLARE(measured_strings, measured_string_t) 165 /** Networking module global variables. 166 */ 167 struct net_globals{ 168 /** Global configuration. 169 */ 170 measured_strings_t configuration; 171 /** Available modules. 172 */ 173 modules_t modules; 174 /** Network interface structure indices by names. 175 */ 176 char_map_t netif_names; 177 /** Present network interfaces. 178 */ 179 netifs_t netifs; 180 }; 164 181 165 182 /** Present network interface device. 166 183 */ 167 184 struct netif{ 185 /** Configuration. 186 */ 187 measured_strings_t configuration; 188 /** Serving network interface driver module index. 189 */ 190 module_ref driver; 168 191 /** System-unique network interface identifier. 169 192 */ 170 193 device_id_t id; 171 /** Serving network interface driver module index.172 */173 module_ref driver;174 /** Serving link layer module index.175 */176 module_ref nil;177 194 /** Serving internet layer module index. 178 195 */ … … 181 198 */ 182 199 char * name; 183 /** Configuration. 184 */ 185 measured_strings_t configuration; 186 }; 187 188 /** Networking module global variables. 189 */ 190 struct net_globals{ 191 /** Present network interfaces. 192 */ 193 netifs_t netifs; 194 /** Network interface structure indices by names. 195 */ 196 char_map_t netif_names; 197 /** Available modules. 198 */ 199 modules_t modules; 200 /** Global configuration. 201 */ 202 measured_strings_t configuration; 200 /** Serving link layer module index. 201 */ 202 module_ref nil; 203 203 }; 204 204 … … 211 211 */ 212 212 int add_configuration(measured_strings_ref configuration, const char * name, const char * value); 213 214 /** Processes the networking message.215 * @param[in] callid The message identifier.216 * @param[in] call The message parameters.217 * @param[out] answer The message answer parameters.218 * @param[out] answer_count The last parameter for the actual answer in the answer parameter.219 * @returns EOK on success.220 * @returns ENOTSUP if the message is not known.221 * @see net_interface.h222 * @see IS_NET_NET_MESSAGE()223 */224 int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count);225 226 /** Initializes the networking module for the chosen subsystem build type.227 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one.228 * @returns EOK on success.229 * @returns ENOMEM if there is not enough memory left.230 */231 int net_initialize_build(async_client_conn_t client_connection);232 213 233 214 /** Processes the module message. … … 243 224 int module_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 244 225 226 /** Initializes the networking module for the chosen subsystem build type. 227 * @param[in] client_connection The client connection processing function. The module skeleton propagates its own one. 228 * @returns EOK on success. 229 * @returns ENOMEM if there is not enough memory left. 230 */ 231 int net_initialize_build(async_client_conn_t client_connection); 232 233 /** Processes the networking message. 234 * @param[in] callid The message identifier. 235 * @param[in] call The message parameters. 236 * @param[out] answer The message answer parameters. 237 * @param[out] answer_count The last parameter for the actual answer in the answer parameter. 238 * @returns EOK on success. 239 * @returns ENOTSUP if the message is not known. 240 * @see net_interface.h 241 * @see IS_NET_NET_MESSAGE() 242 */ 243 int net_message(ipc_callid_t callid, ipc_call_t * call, ipc_call_t * answer, int * answer_count); 244 245 245 #endif 246 246 -
uspace/srv/net/net/net_bundle.c
r71b00dcc r60ab6c3 60 60 extern net_globals_t net_globals; 61 61 62 int net_initialize_build