1/* ********************************************************************* 2 * Broadcom Common Firmware Environment (CFE) 3 * 4 * Top-level API to network File: net_api.c 5 * 6 * This routine contains the highest-level API to the network 7 * routines. The global handle to the network state is right here. 8 * 9 * Author: Mitch Lichtenberg (mpl@broadcom.com) 10 * 11 ********************************************************************* 12 * 13 * Copyright 2000,2001,2002,2003 14 * Broadcom Corporation. All rights reserved. 15 * 16 * This software is furnished under license and may be used and 17 * copied only in accordance with the following terms and 18 * conditions. Subject to these conditions, you may download, 19 * copy, install, use, modify and distribute modified or unmodified 20 * copies of this software in source and/or binary form. No title 21 * or ownership is transferred hereby. 22 * 23 * 1) Any source code used, modified or distributed must reproduce 24 * and retain this copyright notice and list of conditions 25 * as they appear in the source file. 26 * 27 * 2) No right is granted to use any trade name, trademark, or 28 * logo of Broadcom Corporation. The "Broadcom Corporation" 29 * name may not be used to endorse or promote products derived 30 * from this software without the prior written permission of 31 * Broadcom Corporation. 32 * 33 * 3) THIS SOFTWARE IS PROVIDED "AS-IS" AND ANY EXPRESS OR 34 * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO, ANY IMPLIED 35 * WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR 36 * PURPOSE, OR NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT 37 * SHALL BROADCOM BE LIABLE FOR ANY DAMAGES WHATSOEVER, AND IN 38 * PARTICULAR, BROADCOM SHALL NOT BE LIABLE FOR DIRECT, INDIRECT, 39 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 40 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE 41 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR 42 * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 43 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR 44 * TORT (INCLUDING NEGLIGENCE OR OTHERWISE), EVEN IF ADVISED OF 45 * THE POSSIBILITY OF SUCH DAMAGE. 46 ********************************************************************* */ 47 48 49#include "bsp_config.h" 50 51#include "lib_types.h" 52#include "lib_string.h" 53#include "lib_queue.h" 54#include "lib_malloc.h" 55#include "lib_printf.h" 56 57#include "cfe_iocb.h" 58#include "cfe_devfuncs.h" 59#include "cfe_ioctl.h" 60#include "cfe_timer.h" 61 62#include "cfe_error.h" 63 64#include "net_ebuf.h" 65#include "net_ether.h" 66 67#include "cfe_timer.h" 68 69#include "net_ip.h" 70#include "net_ip_internal.h" 71#include "net_api.h" 72 73#include "env_subr.h" 74 75#if CFG_TCP 76#include "net_tcp.h" 77#endif 78 79#if CFG_HTTP 80#include "net_http.h" 81#endif 82 83/* ********************************************************************* 84 * Structures 85 ********************************************************************* */ 86 87/* 88 * Net context. All the soft context structures of all the 89 * layers of the network stack are bundled here. There's only one 90 * of these in the system when the network is active. 91 */ 92 93typedef struct net_ctx_s { 94 /* Global info */ 95 int64_t timer; 96 97 /* device name */ 98 char *devname; 99 100 /* Run-time info for IP interface */ 101 ip_info_t *ipinfo; 102 103 /* Info for Ethernet interface */ 104 ether_info_t *ethinfo; 105 106 /* Info specific to UDP */ 107 udp_info_t *udpinfo; 108 109 /* Info specific to ICMP */ 110 icmp_info_t *icmpinfo; 111 112#if CFG_TCP 113 /* Info specific to TCP */ 114 tcp_info_t *tcpinfo; 115#endif 116#if CFG_HTTP 117 /* Info specific to HTTP */ 118 http_info_t *httpinfo; 119#endif 120} net_ctx_t; 121 122 123/* ********************************************************************* 124 * Globals 125 ********************************************************************* */ 126 127static net_ctx_t *netctx = NULL; 128 129 130/* ********************************************************************* 131 * UDP INTERFACE 132 ********************************************************************* */ 133 134/* ********************************************************************* 135 * udp_alloc() 136 * 137 * Allocate an ebuf with fields reserved for the UDP layer. 138 * 139 * Input parameters: 140 * nothing 141 * 142 * Return value: 143 * pointer to ebuf, or NULL if no EBUFs are available 144 ********************************************************************* */ 145 146ebuf_t *udp_alloc(void) 147{ 148 if (!netctx) return NULL; 149 return _udp_alloc(netctx->udpinfo); 150} 151 152/* ********************************************************************* 153 * udp_free(buf) 154 * 155 * Return an ebuf to the pool. The ebuf was presumably allocated 156 * via udp_alloc() first. 157 * 158 * Input parameters: 159 * buf - ebuf to return to the pool 160 * 161 * Return value: 162 * nothing 163 ********************************************************************* */ 164void udp_free(ebuf_t *buf) 165{ 166 if (!netctx) return; 167 _udp_free(netctx->udpinfo,buf); 168} 169 170/* ********************************************************************* 171 * udp_socket(port) 172 * 173 * Open a UDP socket. Once open, datagrams sent on the socket will 174 * go to the specified port number. You can change the port later 175 * using the "udp_connect" function. 176 * 177 * Input parameters: 178 * port - port number 179 * 180 * Return value: 181 * UDP port handle, or -1 if no ports are available. 182 ********************************************************************* */ 183 184int udp_socket(uint16_t port) 185{ 186 if (!netctx) return -1; 187 188 return _udp_socket(netctx->udpinfo,port); 189} 190 191/* ********************************************************************* 192 * udp_close(sock) 193 * 194 * Close a udp socket. You pass this handle returned from a previous 195 * call to udp_open. 196 * 197 * Input parameters: 198 * handle - UDP port handle, from udp_open() 199 * 200 * Return value: 201 * nothing 202 ********************************************************************* */ 203 204void udp_close(int portnum) 205{ 206 if (!netctx) return; 207 208 _udp_close(netctx->udpinfo,portnum); 209} 210 211 212/* ********************************************************************* 213 * udp_send(s,buf,dest) 214 * 215 * Send a datagram to the specified destination address. The 216 * source and destination UDP port numbers are taken from the 217 * values passed to earlier calls to udp_open, udp_bind, and 218 * udp_connect. 219 * 220 * Input parameters: 221 * s - socket handle, from udp_open 222 * buf - ebuf to send (allocated via udp_alloc) 223 * dest - pointer to 4-byte destination IP address 224 * 225 * Return value: 226 * 0 if ok 227 * <0 if an error occured. 228 ********************************************************************* */ 229 230int udp_send(int s,ebuf_t *buf,uint8_t *dest) 231{ 232 if (!netctx) return -1; 233 234 return _udp_send(netctx->udpinfo,s,buf,dest); 235} 236 237/* ********************************************************************* 238 * udp_bind(s,port) 239 * 240 * Re-"bind" the specified udp socket to a new source port. 241 * This changes the source port number that will be transmitted 242 * in subsequent calls to udp_send() 243 * 244 * Input parameters: 245 * s - socket handle 246 * port - new port number 247 * 248 * Return value: 249 * 0 if ok, else error code 250 ********************************************************************* */ 251 252int udp_bind(int s,uint16_t port) 253{ 254 if (!netctx) return -1; 255 256 return _udp_bind(netctx->udpinfo,s,port); 257} 258 259 260/* ********************************************************************* 261 * udp_connect(s,port) 262 * 263 * Set the port number to be used in the destination port field 264 * for subsequent calls to udp_send(). 265 * 266 * Input parameters: 267 * s - udp socket handle 268 * port - new destination port number 269 * 270 * Return value: 271 * 0 if ok, else error code 272 ********************************************************************* */ 273 274int udp_connect(int s,uint16_t port) 275{ 276 if (!netctx) return -1; 277 278 return _udp_connect(netctx->udpinfo,s,port); 279} 280 281/* ********************************************************************* 282 * udp_recv(s) 283 * 284 * Return the next packet from the receive queue for this port. 285 * If no packets are available, NULL is returned. 286 * 287 * Input parameters: 288 * s - udp port handle 289 * 290 * Return value: 291 * ebuf (if a packet is available) 292 * NULL (no packet available) 293 ********************************************************************* */ 294 295ebuf_t *udp_recv(int s) 296{ 297 if (!netctx) return NULL; 298 299 return _udp_recv(netctx->udpinfo,s); 300} 301 302 303/* ********************************************************************* 304 * udp_recv_with_timeout(s,ticks) 305 * 306 * Return the next packet from the receive queue for this socket, 307 * waiting for one to arrive if there are none available. 308 * 309 * Input parameters: 310 * s - udp socket handle 311 * ticks - number of ticks to wait 312 * 313 * Return value: 314 * ebuf (if a packet is available) 315 * NULL (no packet available after timeout) 316 ********************************************************************* */ 317 318ebuf_t *udp_recv_with_timeout(int s,int ticks) 319{ 320 ebuf_t *buf = NULL; 321 int64_t timer; 322 323 if (!netctx) return NULL; 324 325 TIMER_SET(timer,ticks); 326 327 while (!TIMER_EXPIRED(timer)) { 328 POLL(); 329 buf = _udp_recv(netctx->udpinfo,s); 330 if (buf) break; 331 } 332 333 return buf; 334} 335 336 337 338#if CFG_TCP 339/* ********************************************************************* 340 * TCP INTERFACE 341 ********************************************************************* */ 342 343 344/* ********************************************************************* 345 * tcp_socket() 346 * 347 * Create a new TCP port. 348 * 349 * Input parameters: 350 * nothing. 351 * 352 * Return value: 353 * TCP port handle, or <0 if no ports are available. 354 ********************************************************************* */ 355 356int tcp_socket(void) 357{ 358 if (!netctx) return -1; 359 360 return _tcp_socket(netctx->tcpinfo); 361} 362 363/* ********************************************************************* 364 * tcp_connect(handle,dest,port) 365 * 366 * Connect to a remote TCP destination. 367 * 368 * Input parameters: 369 * handle - returned from tcp_create 370 * dest - destination IP address 371 * port - destination port number 372 * 373 * Return value: 374 * 0 if ok 375 * else error code 376 ********************************************************************* */ 377 378int tcp_connect(int s,uint8_t *dest,uint16_t port) 379{ 380 int res; 381 unsigned int flags; 382 int connflag; 383 384 if (!netctx) return -1; 385 386 /* 387 * Get socket's blocking status 388 * If nonblocking, just call the tcp stack 389 * and return what it returns. 390 */ 391 392 res = _tcp_getflags(netctx->tcpinfo,s,&flags); 393 if (res < 0) return res; 394 395 if (flags & TCPFLG_NBIO) { 396 return _tcp_connect(netctx->tcpinfo,s,dest,port); 397 } 398 399 /* 400 * Otherwise, call connect and poll till the status 401 * changes. We want to see a transition to the 402 * CONNECTED state, so we loop while we see "CONNECTING" 403 * and return a status based on what it changes to. 404 */ 405 406 res = _tcp_connect(netctx->tcpinfo,s,dest,port); 407 if (res < 0) return res; 408 connflag = TCPSTATUS_NOTCONN; 409 410 for (;;) { 411 POLL(); 412 413 res = _tcp_status(netctx->tcpinfo,s,&connflag,NULL,NULL); 414 if (res < 0) break; 415 416 if (connflag == TCPSTATUS_CONNECTING) continue; 417 break; 418 } 419 420 if (connflag != TCPSTATUS_CONNECTED) return CFE_ERR_NOTCONN; 421 422 return res; 423} 424 425/* ********************************************************************* 426 * tcp_close(s) 427 * 428 * Disconnect a connection (cleanly) 429 * 430 * Input parameters: 431 * s - handle from tcp_create 432 * 433 * Return value: 434 * 0 if ok 435 * else error 436 ********************************************************************* */ 437 438int tcp_close(int s) 439{ 440 if (!netctx) return -1; 441 442 return _tcp_close(netctx->tcpinfo,s); 443} 444 445 446 447/* ********************************************************************* 448 * tcp_send(s,buf,len) 449 * 450 * Send a buffer to the other TCP, buffering as much data as 451 * will fit in the send buffer. 452 * 453 * Input parameters: 454 * s - port handle, from tcp_open 455 * buf - buffer pointer 456 * len - length of buffer to send 457 * 458 * Return value: 459 * >=0 if ok (number of bytes sent) 460 * <0 if an error occured. 461 ********************************************************************* */ 462 463int tcp_send(int s,uint8_t *buf,int len) 464{ 465 int flags; 466 int res; 467 int total = 0; 468 469 if (!netctx) return -1; 470 471 /* 472 * Get socket's blocking status 473 * If nonblocking, just call the tcp stack 474 * and return what it returns. 475 */ 476 477 res = _tcp_getflags(netctx->tcpinfo,s,&flags); 478 if (res < 0) return res; 479 480 if (flags & TCPFLG_NBIO) { 481 return _tcp_send(netctx->tcpinfo,s,buf,len); 482 } 483 484 /* 485 * The first time we'll check the return code for an 486 * error so we can pass up the failure. 487 */ 488 489 res = _tcp_send(netctx->tcpinfo,s,buf,len); 490 if (res < 0) return res; 491 492 buf += res; 493 len -= res; 494 total += res; 495 496 while (len > 0) { 497 /* 498 * Give the TCP stack and devices a chance to run 499 */ 500 501 POLL(); 502 503 /* 504 * Try to send some more. If we get an error, get out. 505 * otherwise, keep going till all the data is gone. 506 */ 507 508 res = _tcp_send(netctx->tcpinfo,s,buf,len); 509 if (res < 0) break; 510 buf += res; 511 len -= res; 512 total += res; 513 } 514 515 /* 516 * If we sent nothing and have an error, return the error. 517 * Otherwise return the amount of data we sent. 518 */ 519 if ((total == 0) && (res < 0)) return res; 520 else return total; 521} 522 523/* ********************************************************************* 524 * tcp_recv(s,buf,len) 525 * 526 * Receive data from the remote TCP session 527 * 528 * Input parameters: 529 * s - port handle, from tcp_open 530 * buf - buffer pointer 531 * len - length of buffer to send 532 * 533 * Return value: 534 * >=0 if ok (number of bytes received) 535 * <0 if an error occured. 536 ********************************************************************* */ 537 538int tcp_recv(int s,uint8_t *buf,int len) 539{ 540 int flags; 541 int res; 542 int total = 0; 543 544 if (!netctx) return -1; 545 546 /* 547 * Get socket's blocking status 548 * If nonblocking, just call the tcp stack 549 * and return what it returns. 550 */ 551 552 res = _tcp_getflags(netctx->tcpinfo,s,&flags); 553 if (res < 0) return res; 554 555 if (flags & TCPFLG_NBIO) { 556 return _tcp_recv(netctx->tcpinfo,s,buf,len); 557 } 558 559 /* 560 * The first time we'll check the return code for an 561 * error so we can pass up the failure. 562 */ 563 564 res = _tcp_recv(netctx->tcpinfo,s,buf,len); 565 if (res < 0) return res; 566 567 buf += res; 568 len -= res; 569 total += res; 570 571 while (len > 0) { 572 /* 573 * Give the TCP stack and devices a chance to run 574 */ 575 576 POLL(); 577 578 /* 579 * Try to receive some more. If we get an error, get out. 580 * otherwise, keep going till all the data is gone. 581 */ 582 583 res = _tcp_recv(netctx->tcpinfo,s,buf,len); 584 if (res < 0) break; 585 586 if (res == 0) { 587 _tcp_status(netctx->tcpinfo,s,&flags,NULL,NULL); 588 if (flags != TCPSTATUS_CONNECTED) { 589 res = CFE_ERR_NOTCONN; 590 break; 591 } 592 } 593 594 buf += res; 595 len -= res; 596 total += res; 597 } 598 599 /* 600 * If we sent received and have an error, return the error. 601 * Otherwise return the amount of data we sent. 602 */ 603 if ((total == 0) && (res < 0)) return res; 604 else return total; 605 606} 607 608/* ********************************************************************* 609 * tcp_bind(s,port) 610 * 611 * Re-"bind" the specified tcp port handle to a new source port. 612 * 613 * Used for listening sockets. 614 * 615 * Input parameters: 616 * s - port handle 617 * port - new port number 618 * 619 * Return value: 620 * 0 if ok, else error code 621 ********************************************************************* */ 622 623int tcp_bind(int s,uint16_t port) 624{ 625 if (!netctx) return -1; 626 627 return _tcp_bind(netctx->tcpinfo,s,port); 628} 629 630/* ********************************************************************* 631 * tcp_peeraddr(s,addr,port) 632 * 633 * Return the address of the remote peer. 634 * 635 * Input parameters: 636 * s - port handle 637 * addr - points to 4-byte buffer to receive IP address 638 * port - points to uint16 to receive port number 639 * 640 * Return value: 641 * 0 if ok, else error code 642 ********************************************************************* */ 643 644int tcp_peeraddr(int s,uint8_t *addr,uint16_t *port) 645{ 646 if (!netctx) return -1; 647 648 return _tcp_peeraddr(netctx->tcpinfo,s,addr,port); 649} 650 651/* ********************************************************************* 652 * tcp_setflags(s,addr,flags) 653 * 654 * Set per-socket flags (nodelay, etc.) 655 * 656 * Input parameters: 657 * s - port handle 658 * flags - flags for this socket 659 * 660 * Return value: 661 * 0 if ok, else error code 662 ********************************************************************* */ 663 664int tcp_setflags(int s,unsigned int flags) 665{ 666 if (!netctx) return -1; 667 668 return _tcp_setflags(netctx->tcpinfo,s,flags); 669} 670 671/* ********************************************************************* 672 * tcp_getflags(s,addr,flags) 673 * 674 * Get per-socket flags (nodelay, etc.) 675 * 676 * Input parameters: 677 * s - port handle 678 * flags - flags for this socket 679 * 680 * Return value: 681 * 0 if ok, else error code 682 ********************************************************************* */ 683 684int tcp_getflags(int s,unsigned int *flags) 685{ 686 if (!netctx) return -1; 687 688 return _tcp_getflags(netctx->tcpinfo,s,flags); 689} 690 691 692/* ********************************************************************* 693 * tcp_listen(s) 694 * 695 * Set the socket into "listen" mode. 696 * 697 * Input parameters: 698 * s - port handle 699 * port - port # to listen on 700 * 701 * Return value: 702 * 0 if ok 703 * else error 704 ********************************************************************* */ 705 706int tcp_listen(int s,uint16_t port) 707{ 708 if (!netctx) return -1; 709 710 return _tcp_listen(netctx->tcpinfo,s,port); 711} 712 713/* ********************************************************************* 714 * tcp_status(s,connflag,rxready,rxeof) 715 * 716 * Return the TCP connection's status 717 * 718 * Input parameters: 719 * s - port handle 720 * connflag - points to flag to receive connected status 721 * rxready - returns # of bytes ready to receive 722 * rxeof - returns TRUE if we've been FINed. 723 * 724 * Return value: 725 * 0 if ok 726 * else error 727 ********************************************************************* */ 728 729int tcp_status(int s,int *connflag,int *rxready,int *rxeof) 730{ 731 if (!netctx) return -1; 732 733 return _tcp_status(netctx->tcpinfo,s,connflag,rxready,rxeof); 734} 735 736/* ********************************************************************* 737 * tcp_debug(s,arg) 738 * 739 * Call the debug routine in the tcp stack. 740 * 741 * Input parameters: 742 * s - socket handle 743 * arg - passed to debug routine 744 * 745 * Return value: 746 * return value from debug routine 747 ********************************************************************* */ 748 749int tcp_debug(int s,int arg) 750{ 751 if (!netctx) return -1; 752 return _tcp_debug(netctx->tcpinfo,s,arg); 753} 754 755#endif 756 757/* ********************************************************************* 758 * ARP FUNCTIONS 759 ********************************************************************* */ 760 761 762/* ********************************************************************* 763 * arp_add(destip,desthw) 764 * 765 * Add a permanent entry to the ARP table. This entry will 766 * persist until deleted or the interface is deactivated. 767 * This may cause a stale entry to be deleted if the table is full 768 * 769 * Input parameters: 770 * destip - pointer to 4-byte destination IP address 771 * desthw - pointer to 6-byte destination hardware address 772 * 773 * Return value: 774 * nothing 775 ********************************************************************* */ 776 777void arp_add(uint8_t *destip,uint8_t *desthw) 778{ 779 if (netctx) _arp_add(netctx->ipinfo,destip,desthw); 780} 781 782/* ********************************************************************* 783 * arp_lookup(destip) 784 * 785 * Look up the hardware address for an IP address. 786 * 787 * Input parameters: 788 * destip - pointer to 4-byte IP address 789 * 790 * Return value: 791 * pointer to 6-byte hardware address, or NULL if there are 792 * no matching entries in the table. 793 ********************************************************************* */ 794 795uint8_t *arp_lookup(uint8_t *destip) 796{ 797 if (!netctx) return NULL; 798 return _arp_lookup(netctx->ipinfo,destip); 799} 800 801 802/* ********************************************************************* 803 * arp_enumerate(entrynum,ipaddr,hwaddr) 804 * 805 * Return an entry from the ARP table. 806 * 807 * Input parameters: 808 * entrynum - entry number to return, starting with zero 809 * ipaddr - pointer to 4 bytes to receive IP address 810 * hwaddr - pointer to 6 bytes to receive hardware address 811 * 812 * Return value: 813 * 0 if ok 814 * else error code 815 ********************************************************************* */ 816 817int arp_enumerate(int entrynum,uint8_t *ipaddr,uint8_t *hwaddr) 818{ 819 if (!netctx) return -1; 820 return _arp_enumerate(netctx->ipinfo,entrynum,ipaddr,hwaddr); 821} 822 823/* ********************************************************************* 824 * arp_delete(ipaddr) 825 * 826 * Delete an entry from the ARP table. 827 * 828 * Input parameters: 829 * ipaddr - pointer to 4-byte IP address 830 * 831 * Return value: 832 * 0 if ok 833 * else error code 834 ********************************************************************* */ 835 836int arp_delete(uint8_t *ipaddr) 837{ 838 if (!netctx) return -1; 839 return _arp_delete(netctx->ipinfo,ipaddr); 840} 841 842/* ********************************************************************* 843 * ICMP FUNCTIONS 844 ********************************************************************* */ 845 846/* ********************************************************************* 847 * icmp_ping(dest,seq,len) 848 * 849 * Ping a remote host, transmitting the ICMP_ECHO message and 850 * waiting for the corresponding ICMP_ECHO_REPLY. 851 * 852 * Input parameters: 853 * dest - pointer to 4-byte destination IP address 854 * seq - sequence number to put in to the ICMP packet 855 * len - length of data to place in ICMP packet 856 * 857 * Return value: 858 * 0 if ok (remote host responded) 859 * else error code 860 ********************************************************************* */ 861 862int icmp_ping(uint8_t *dest,int seq,int len) 863{ 864 if (!netctx) return -1; 865 return _icmp_ping(netctx->icmpinfo,dest,seq,len); 866} 867 868/* ********************************************************************* 869 * INIT/CONFIG FUNCTIONS 870 ********************************************************************* */ 871 872/* ********************************************************************* 873 * net_getparam(param) 874 * 875 * Return a parameter from the current IP configuration. This is 876 * the main call to set the IP address, netmask, gateway, 877 * name server, host name, etc. 878 * 879 * Input parameters: 880 * param - parameter number (see net_api.h) 881 * 882 * Return value: 883 * pointer to value of parameter, or NULL if parameter 884 * ID is invalid 885 ********************************************************************* */ 886 887uint8_t *net_getparam(int param) 888{ 889 if (!netctx) return NULL; 890 if (param == NET_DEVNAME) return (uint8_t *) netctx->devname; 891 return _ip_getparam(netctx->ipinfo,param); 892 893} 894 895/* ********************************************************************* 896 * net_setparam(param,ptr) 897 * 898 * Set the value of an IP configuration parameter 899 * 900 * Input parameters: 901 * param - parameter number (see net_api.h) 902 * ptr - pointer to parameter's new value 903 * 904 * Return value: 905 * 0 if ok 906 * else error code 907 ********************************************************************* */ 908 909int net_setparam(int param,uint8_t *ptr) 910{ 911 if (!netctx) return NULL; 912 return _ip_setparam(netctx->ipinfo,param,ptr); 913} 914 915/* ********************************************************************* 916 * net_poll() 917 * 918 * Process background tasks for the network stack, maintaining 919 * the ARP table, receive queues, etc. 920 * 921 * Input parameters: 922 * nothing 923 * 924 * Return value: 925 * nothing 926 ********************************************************************* */ 927 928static void net_poll(void *arg) 929{ 930 if (netctx) { 931 eth_poll(netctx->ethinfo); 932 if (TIMER_EXPIRED(netctx->timer)) { 933 _ip_timer_tick(netctx->ipinfo); 934#if CFG_SIM 935 TIMER_SET(netctx->timer,CFE_HZ/10); 936#else 937 TIMER_SET(netctx->timer,CFE_HZ); 938#endif /* CFG_SIM */ 939 } 940 } 941} 942 943/* ********************************************************************* 944 * net_init(devname) 945 * 946 * Initialize the network interface. This is the main call, once 947 * completed you should call net_setparam to set up the network 948 * addresses and stuff. 949 * 950 * Input parameters: 951 * devname - CFE device name for network device 952 * 953 * Return value: 954 * 0 if ok 955 * else error code 956 ********************************************************************* */ 957 958int net_init(char *devname) 959{ 960 net_ctx_t *ctx; 961 962 if (netctx) net_uninit(); 963 964 ctx = KMALLOC(sizeof(net_ctx_t),0); 965 966 if (!ctx) return -1; 967 968 ctx->devname = strdup(devname); 969 970 ctx->ethinfo = eth_init(devname); 971 if (ctx->ethinfo == NULL) { 972 return -1; 973 } 974 975 ctx->ipinfo = _ip_init(ctx->ethinfo); 976 if (ctx->ipinfo == NULL) { 977 eth_uninit(ctx->ethinfo); 978 return -1; 979 } 980 981 ctx->udpinfo = _udp_init(ctx->ipinfo,ctx->ipinfo); 982 if (ctx->udpinfo == NULL) { 983 _ip_uninit(ctx->ipinfo); 984 eth_uninit(ctx->ethinfo); 985 return -1; 986 } 987 988 ctx->icmpinfo = _icmp_init(ctx->ipinfo); 989 if (ctx->icmpinfo == NULL) { 990 _udp_uninit(ctx->udpinfo); 991 _ip_uninit(ctx->ipinfo); 992 eth_uninit(ctx->ethinfo); 993 return -1; 994 } 995 996 cfe_bg_add(net_poll,ctx); 997#if CFG_SIM 998 TIMER_SET(ctx->timer,CFE_HZ/10); 999#else 1000 TIMER_SET(ctx->timer,CFE_HZ); 1001#endif /* CFG_SIM */ 1002 1003#if CFG_TCP 1004 ctx->tcpinfo = _tcp_init(ctx->ipinfo,ctx->ipinfo); 1005 cfe_bg_add(_tcp_poll,ctx->tcpinfo); 1006#endif 1007 1008#if CFG_HTTP 1009 ctx->httpinfo = _tcphttp_init(ctx->ipinfo,ctx->ipinfo); 1010#endif 1011 netctx = ctx; 1012 1013 return 0; 1014} 1015 1016 1017/* ********************************************************************* 1018 * net_uninit() 1019 * 1020 * Uninitialize the network, deallocating all resources allocated 1021 * to the network and closing all open device handles 1022 * 1023 * Input parameters: 1024 * nothing 1025 * 1026 * Return value: 1027 * nothing 1028 ********************************************************************* */ 1029 1030void net_uninit(void) 1031{ 1032 if (netctx) { 1033#if CFG_TCP 1034 cfe_bg_remove(_tcp_poll); 1035 _tcp_uninit(netctx->tcpinfo); 1036#endif 1037#if CFG_HTTP 1038 _tcphttp_uninit(netctx->httpinfo); 1039#endif 1040 TIMER_CLEAR(netctx->timer); 1041 _icmp_uninit(netctx->icmpinfo); 1042 _udp_uninit(netctx->udpinfo); 1043 _ip_uninit(netctx->ipinfo); 1044 eth_uninit(netctx->ethinfo); 1045 KFREE(netctx->devname); 1046 KFREE(netctx); 1047 netctx = NULL; 1048 cfe_bg_remove(net_poll); 1049 } 1050} 1051 1052 1053/* ********************************************************************* 1054 * net_setnetvars() 1055 * 1056 * Set environment variables related to the network. 1057 * 1058 * Input parameters: 1059 * nothing 1060 * 1061 * Return value: 1062 * nothing 1063 ********************************************************************* */ 1064 1065void net_setnetvars(void) 1066{ 1067 char *x; 1068 uint8_t *addr; 1069 char str[60]; 1070 1071 /* Clear out all the environment variables */ 1072 env_delenv("NET_DEVICE"); 1073 env_delenv("NET_IPADDR"); 1074 env_delenv("NET_NETMASK"); 1075 env_delenv("NET_GATEWAY"); 1076 env_delenv("NET_NAMESERVER"); 1077 env_delenv("NET_DOMAIN"); 1078 1079 x = (char *) net_getparam(NET_DEVNAME); 1080 if (!x) { 1081 return; 1082 } 1083 1084 x = (char *) net_getparam(NET_DEVNAME); 1085 if (x) env_setenv("NET_DEVICE",x,ENV_FLG_BUILTIN); 1086 1087 x = (char *) net_getparam(NET_DOMAIN); 1088 if (x) env_setenv("NET_DOMAIN",x,ENV_FLG_BUILTIN); 1089 1090 addr = net_getparam(NET_IPADDR); 1091 if (addr) { 1092 xsprintf(str,"%I",addr); 1093 env_setenv("NET_IPADDR",str,ENV_FLG_BUILTIN); 1094 } 1095 1096 addr = net_getparam(NET_NETMASK); 1097 if (addr) { 1098 xsprintf(str,"%I",addr); 1099 env_setenv("NET_NETMASK",str,ENV_FLG_BUILTIN); 1100 } 1101 1102 addr = net_getparam(NET_GATEWAY); 1103 if (addr) { 1104 xsprintf(str,"%I",addr); 1105 env_setenv("NET_GATEWAY",str,ENV_FLG_BUILTIN); 1106 } 1107 1108 addr = net_getparam(NET_NAMESERVER); 1109 if (addr) { 1110 xsprintf(str,"%I",addr); 1111 env_setenv("NET_NAMESERVER",str,ENV_FLG_BUILTIN); 1112 } 1113 1114} 1115