⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 net.c

📁 Embeded bootloader (rrload by ridgerun) for TI linux based platform v5.36
💻 C
字号:
/* * File: net.c * * This is an implementation exposing the net.h interface and providing the * UDP and IP levels of a network stack. It depends on an external module to * supply the underlying ethernet level. * * See Also *   net.h, ether.h * * Copyright (C) 2002 RidgeRun, Inc. * Author: RidgeRun, Inc  <skranz@ridgerun.com> * *  This program is free software; you can redistribute  it and/or modify it *  under  the terms of  the GNU General  Public License as published by the *  Free Software Foundation;  either version 2 of the  License, or (at your *  option) any later version. * *  THIS  SOFTWARE  IS  PROVIDED  ``AS  IS''  AND   ANY  EXPRESS  OR IMPLIED *  WARRANTIES,   INCLUDING, BUT NOT  LIMITED  TO, THE IMPLIED WARRANTIES OF *  MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.  IN *  NO  EVENT  SHALL   THE AUTHOR  BE    LIABLE FOR ANY   DIRECT,  INDIRECT, *  INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT *  NOT LIMITED   TO, PROCUREMENT OF  SUBSTITUTE GOODS  OR SERVICES; LOSS OF *  USE, DATA,  OR PROFITS; OR  BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON *  ANY THEORY OF LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT *  (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF *  THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * *  You should have received a copy of the  GNU General Public License along *  with this program; if not, write  to the Free Software Foundation, Inc., *  675 Mass Ave, Cambridge, MA 02139, USA. * * Please report all bugs/problems to the author or <support@dsplinux.net> * * key: RRGPLCR (do not remove) * */#include "types.h"#include "io.h"#include "util.h"#include "net.h"#include "ether.h"/****************************** Routine: Description:   Return 16-bit ones compliment of 16-bit ones compliment sum   Return value is converted to network byte order if necessary. ******************************/static unsigned short ip_chksum(unsigned short *iphdr, int num_bytes){  // Algorithm as per page 72,  "Internetworking With TCP/IP (2nd edition, vol 2)"  // Algorithm as per page 100, "Internetworking With TCP/IP (3rd edition, vol 1)"  //   unsigned long sum;  int nwords = num_bytes >> 1;  for (sum=0; nwords>0; nwords--) {    sum += ntohs(*iphdr);    iphdr++;  }  sum = (sum >> 16) + (sum & 0xffff); /* add in carry */  sum += (sum >> 16);                 /* maybe one more */  sum = ~sum;  sum = htons((unsigned short)sum);  return sum;}/****************************** Routine: Description: ******************************/static void ip_submit(submit_mode mode,         // in                      char *device_IP,          // in                      char *server_IP,          // in                      char *device_MAC,         // in, can be NULL only if our chipset has built in MAC.                      char *server_MAC,         // in, can be NULL only if our net stack has ARP.                      void *datagram,           // in/out                      unsigned short *num_bytes)// in/out{  ip_hdr_t *ipdatagram;  unsigned short ip_len;  unsigned long dev_IP;  unsigned long serv_IP;  switch(mode) {    case SEND:    case RECV:    case SEND_AND_GET_REPLY:      // --Stage One--      // Add the IP header and submit resulting datagram to ether layer.      // Recall that the client has provided the space for us to      // back the pointer up like this and add our header.      ipdatagram = (ip_hdr_t *)(datagram - sizeof(ip_hdr_t));      dev_IP  = util_IPstr_to_num(device_IP);      serv_IP = util_IPstr_to_num(server_IP);      // Fields, page 98, "Internetworking With TCP/IP (3rd edition, vol 1)"      ipdatagram->vers_hlen = 0x45;      ipdatagram->serv_type = 0x00;      ip_len = sizeof(ip_hdr_t) + *num_bytes;      ipdatagram->tot_len = htons(ip_len);      ipdatagram->ident = htons(0x0000);      ipdatagram->flags_fragoffset = htons(0x4000);      ipdatagram->timetolive = 0xFF;      ipdatagram->protocol = 0x11; // UDP code; as per /etc/protocols list.      ipdatagram->hdr_chksum = 0x0000;      ipdatagram->src_IP_addr  = htonl(dev_IP);      ipdatagram->dest_IP_addr = htonl(serv_IP);      ipdatagram->hdr_chksum = ip_chksum((unsigned short *)ipdatagram, sizeof(ip_hdr_t));      // util_printf("ip_submit: submitting frame 0x%X\n",ipdatagram); // *revisit-skranz* temp. //     ether_submit(mode,               // in //                  device_MAC,         // in //                  server_MAC,         // in //                  (void *)ipdatagram, // in/out //                  &ip_len);           // in/out      break;    case FLUSH:      // flush the net channel of any pending data.//      ether_submit(FLUSH,device_MAC,server_MAC,NULL,NULL);      break;    default:      SYSTEM_FATAL("Logic Error");      break;  }  switch(mode) {    case RECV:    case SEND_AND_GET_REPLY:      {        unsigned long d_IP;        if (ip_len < sizeof(ip_hdr_t)) {          // must of had some ehter errors. Upper level to address.          util_printf("num_bytes being set to zero\n"); // *debug* temp.          *num_bytes = 0;          return;        }        // Okay, *ipdatagram now contains the IP datagram which was        // recieved from the remote server. Any previous contents we        // had there have been overwritten. The dest_IP contained        // within now represents the machine the remote server has        // addressed this IP datagram to. Hopefully it matches our        // IP; e.g. our device_IP        d_IP = ntohl(ipdatagram->dest_IP_addr);        if (d_IP == dev_IP) {          // --Stage Two--          // Great, all done, *datagram now holds the newly received datagram,          // (minus the IP header) now we'll compute the length and hand it          // up to the UDP level above.          *num_bytes = ntohs(ipdatagram->tot_len) - sizeof(ip_hdr_t);        }        else {          // What? we just recieved something from a remote host which          // was destinted for some other IP than ours. Was this an ARP          // broadcast? possible some other form of broadcast? At any rate          // discard this datagram and cycle back down the network stack          // to get its contents replaced with the data we are expecting.          // (recursive call).          // util_printf("disregarding IP msg from 0x%x\n",d_IP); // *revisit-skranz* temp.          // util_printf("ip_submit2: submitting frame 0x%X\n",datagram); // *revisit-skranz* temp.          ip_submit(RECV,       // in                    device_IP,  // in                    server_IP,  // in                    device_MAC, // in                    server_MAC, // in                    datagram,   // in, discard and replace.                    num_bytes); // in        }      }      break;    default:      break;  }    }/****************************** Routine: Description:    See net.h for more info. ******************************/void udp_submit(submit_mode mode,           // in                unsigned short src_port,    // in (local device port number).                unsigned short dest_port,   // in (remote server port number).                char *device_IP,            // in                char *server_IP,            // in                char *device_MAC,           // in, can be NULL only if our chipset has built in MAC.                char *server_MAC,           // in, can be NULL only if our net stack has ARP.                void *datagram,             // in/out                unsigned short *num_bytes,  // in/out                unsigned short *reply_port) // out.{  udp_hdr_t *udatagram;  unsigned short u_len;  switch(mode) {    case SEND:    case RECV:    case SEND_AND_GET_REPLY:      // --Stage One--      // Add the UDP header and submit resulting datagram to IP layer.      // Recall that the client has provided the space for us to      // back the pointer up like this and add our header.      udatagram = (udp_hdr_t *)(datagram - sizeof(udp_hdr_t));      udatagram->src_port = htons(src_port);      udatagram->dest_port = htons(dest_port);      u_len = sizeof(udp_hdr_t) + *num_bytes;      udatagram->tot_len = htons(u_len);      udatagram->chksum = 0x0000; // Checksum optional. zero indicates not using it.                                  // page 182, "Internetworking With TCP/IP (3rd edition, vol 1)"      // util_printf("udp_submit: submitting frame 0x%X\n",udatagram); // *revisit-skranz* temp.      ip_submit(mode,              // in                device_IP,         // in                server_IP,         // in                device_MAC,        // in, can be NULL only if our chipset has built in MAC.                server_MAC,        // in, can be NULL only if our net stack has ARP.                (void *)udatagram, // in/out                &u_len);           // in      break;    case FLUSH:      // flush the net channel of any pending data.      ip_submit(FLUSH,      // in                device_IP,  // in                server_IP,  // in                device_MAC, // in, can be NULL only if our chipset has built in MAC.                server_MAC, // in, can be NULL only if our net stack has ARP.                NULL,       // in                NULL);      // in      break;    default:      SYSTEM_FATAL("Logic Error");      break;  }  switch(mode) {    case RECV:    case SEND_AND_GET_REPLY:      {        unsigned short dev_port;        if (u_len < sizeof(udp_hdr_t)) {          // must of had some ehter errors. Upper level to address.          util_printf("num_bytes being set to zero\n"); // *debug* temp.          *num_bytes = 0;          return;        }        // Okay, *udatagram now contains the UDP datagram which was        // recieved from the remote server. Any previous contents we        // had there have been overwritten. The dest_port contained        // within now represents the port the remote server has addressed        // this UDP datagram to. Hopefully it matches the port we        // sent from; e.g., our src_port.        dev_port = ntohs(udatagram->dest_port);        *reply_port = ntohs(udatagram->src_port);        if (dev_port == src_port) {          // --Stage Two--          // Great, all done, *datagram now holds the newly received datagram,          // (minus the UDP header) now we'll compute the length and hand it          // up to the application level above.          *num_bytes = ntohs(udatagram->tot_len) - sizeof(udp_hdr_t);        }        else {          // What? we just recieved something from a remote host which          // was destinted for some other port than the one we are          // interested in. Therefore, discard this datagram and cycle          // back down the network stack to get its contents replaced with          // the data we are expecting. (recursive call).          // util_printf("udp: disregarding port msg from 0x%x\n",dev_port); // *revisit-skranz* temp.          // util_printf("udp_submit2: submitting frame 0x%X\n",datagram); // *revisit-skranz* temp.          udp_submit(RECV,        // in                     src_port,    // in                     dest_port,   // in                     device_IP,   // in                     server_IP,   // in                     device_MAC,  // in                     server_MAC,  // in                     datagram,    // in, discard and replace.                     num_bytes,   // in,                     reply_port); // out        }      }      break;    default:      break;  }    }/****************************** Routine: Description:    See net.h for more info. ******************************/void net_init(void){}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -