?? net.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 + -