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