source: edk_user_repository/WARP/sw_services/WARPxilnet_v3_03_a/src/xilnet_ip.c

Last change on this file was 3725, checked in by welsh, 10 years ago

Update to allow nodes to receive packets from 10.0.X.255 when the node's IP address has not been configured.

File size: 6.7 KB
Line 
1////////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2004 Xilinx, Inc.  All rights reserved.
3//
4// Xilinx, Inc.
5// XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS" AS A
6// COURTESY TO YOU.  BY PROVIDING THIS DESIGN, CODE, OR INFORMATION AS
7// ONE POSSIBLE   IMPLEMENTATION OF THIS FEATURE, APPLICATION OR
8// STANDARD, XILINX IS MAKING NO REPRESENTATION THAT THIS IMPLEMENTATION
9// IS FREE FROM ANY CLAIMS OF INFRINGEMENT, AND YOU ARE RESPONSIBLE
10// FOR OBTAINING ANY RIGHTS YOU MAY REQUIRE FOR YOUR IMPLEMENTATION.
11// XILINX EXPRESSLY DISCLAIMS ANY WARRANTY WHATSOEVER WITH RESPECT TO
12// THE ADEQUACY OF THE IMPLEMENTATION, INCLUDING BUT NOT LIMITED TO
13// ANY WARRANTIES OR REPRESENTATIONS THAT THIS IMPLEMENTATION IS FREE
14// FROM CLAIMS OF INFRINGEMENT, IMPLIED WARRANTIES OF MERCHANTABILITY
15// AND FITNESS FOR A PARTICULAR PURPOSE.
16//
17// File   : ip.c
18// Date   : 2002, March 20.
19// Author : Sathya Thammanur
20// Company: Xilinx
21// Group  : Emerging Software Technologies
22//
23// Summary:
24// IP layer specific functions
25//
26// $Id: ip.c,v 1.2.8.6 2005/11/15 23:41:10 salindac Exp $
27//
28////////////////////////////////////////////////////////////////////////////////
29
30////////////////////////////////////////////////////////////////////////////////
31// see copyright.txt for Rice University/Mango Communications modifications
32////////////////////////////////////////////////////////////////////////////////
33
34#include <xilnet_xilsock.h>
35
36
37/*
38 * initialize xilnet ip address
39 */
40void xilnet_ip_init(unsigned char* addr, unsigned int eth_dev_num) {
41    int k = 0;
42    int j;
43    int sum = 0;
44
45    for (j = 0; j < 3; j++) {
46
47        // parse input for dotted decimal notation of ip address
48        while(addr[k] != '.') {
49            sum = sum * 10 + addr[k] - 48;
50            k++;
51        }
52
53        k++; // move over the dot
54        eth_device[eth_dev_num].node_ip_addr[j] = (unsigned char) sum;
55        sum = 0;
56    }
57
58    // read last byte of ip address
59    while (addr[k] != '\0') {
60        sum = sum * 10 + addr[k] - 48;
61        k++;
62    }
63    eth_device[eth_dev_num].node_ip_addr[3] = (unsigned char) sum;
64}
65
66
67/*
68 * ip datagram handler:
69 * checks for the source ip address and calls the corr protocol handler
70 * no checksum calc is done to detect any errors
71 */
72
73int xilnet_ip(unsigned char*buf, int len, unsigned int eth_dev_num) {
74
75    int iplen = 0;
76    struct xilnet_ip_hdr *iph = (struct xilnet_ip_hdr *) (buf+ETH_HDR_LEN);
77
78#ifdef _DEBUG_
79    xil_printf("BEGIN xilnet_ip(): \n");
80    xil_printf("  Packet IP Address: %d.%d.%d.%d \n", (buf+ETH_HDR_LEN)[IP_DADDR_BASE],   (buf+ETH_HDR_LEN)[IP_DADDR_BASE+1],
81                                                      (buf+ETH_HDR_LEN)[IP_DADDR_BASE+2], (buf+ETH_HDR_LEN)[IP_DADDR_BASE+3]);
82    xil_printf("  Device IP Address: %d.%d.%d.%d \n", eth_device[eth_dev_num].node_ip_addr[0], eth_device[eth_dev_num].node_ip_addr[1],
83                                                      eth_device[eth_dev_num].node_ip_addr[2], eth_device[eth_dev_num].node_ip_addr[3]);
84#endif
85
86    unsigned char * ip_hdr  = (unsigned char *) buf + ETH_HDR_LEN;
87    unsigned char addr_pass = 0;
88
89    // If the node has not been initialized (ie address is 10.0.0.0)   
90    if ( eth_device[eth_dev_num].node_ip_addr[3] == 0 ) {
91
92        // Accept broadcast packets from 10.0.X.255
93        if ( ip_hdr[IP_DADDR_BASE]   == eth_device[eth_dev_num].node_ip_addr[0] &&
94             ip_hdr[IP_DADDR_BASE+1] == eth_device[eth_dev_num].node_ip_addr[1] &&
95             ip_hdr[IP_DADDR_BASE+3] == 255 ) {
96
97             addr_pass = 1;
98        }
99    } else {
100        // Accept unicast packets and broadcast packets on the given subnet
101        if ( ip_hdr[IP_DADDR_BASE]   == eth_device[eth_dev_num].node_ip_addr[0] &&
102             ip_hdr[IP_DADDR_BASE+1] == eth_device[eth_dev_num].node_ip_addr[1] &&
103             ip_hdr[IP_DADDR_BASE+2] == eth_device[eth_dev_num].node_ip_addr[2] &&
104            (ip_hdr[IP_DADDR_BASE+3] == eth_device[eth_dev_num].node_ip_addr[3] || ip_hdr[IP_DADDR_BASE+3] == 255 )) {
105
106            addr_pass = 1;
107        }
108    }
109
110    if (addr_pass == 1) {
111
112        // update hw addr table
113        xilnet_eth_update_hw_tbl(buf, ETH_PROTO_IP, eth_dev_num);
114
115        iplen = (unsigned short)( ((((unsigned short)buf[ETH_HDR_LEN+2]) << 8) & 0xFF00) +
116                                   (((unsigned short)buf[ETH_HDR_LEN+3]) & 0x00FF) );
117
118#ifdef _DEBUG_
119    xil_printf("  IP protocol: %d \n", iph->prot);
120#endif
121
122    // call corr protocol handler with the ip datagram
123        switch (iph->prot) {
124            case IP_PROTO_UDP:
125                return (xilnet_udp(buf+ETH_HDR_LEN, iplen, eth_dev_num));
126            break;
127            case IP_PROTO_TCP:
128                xil_printf("Error:  Xilnet does not support TCP \n");
129                return 0;
130            break;
131            case IP_PROTO_ICMP:
132                return (xilnet_icmp(buf+ETH_HDR_LEN, iplen, eth_dev_num));
133            break;
134            default:
135                xil_printf("Error:  unknown IP protocol \n");
136                return 0;
137            break;
138        }
139    }
140
141#ifdef _DEBUG_
142    xil_printf("END xilnet_ip(): \n");
143#endif
144
145    return 0;
146}
147
148
149/*
150 * xilnet_ip_header: fills in the ip header for proto
151 */
152int ip_id_cnt = 0;
153
154void xilnet_ip_header(unsigned char* buf, int len, int proto, unsigned char *peer_ip_addr, unsigned int eth_dev_num) {
155
156   struct xilnet_ip_hdr *iph = (struct xilnet_ip_hdr*) buf;
157
158#ifdef _DEBUG_
159   xil_printf("In xilnet_ip_header(): \n");
160#endif
161
162   buf[0]               = IP_VERSION << 4;
163   buf[0]              |= IP_HDR_LEN;
164   iph->tos             = IP_TOS;
165   iph->total_len       = Xil_Htons(len);
166   iph->ident           = Xil_Htons(ip_id_cnt++);
167   iph->frag_off        = Xil_Htons(IP_FRAG_OFF);
168   iph->ttl             = IP_TTL;
169   iph->prot            = proto;
170   iph->check_sum       = 0;
171   buf[IP_SADDR_BASE]   = eth_device[eth_dev_num].node_ip_addr[0];
172   buf[IP_SADDR_BASE+1] = eth_device[eth_dev_num].node_ip_addr[1];
173   buf[IP_SADDR_BASE+2] = eth_device[eth_dev_num].node_ip_addr[2];
174   buf[IP_SADDR_BASE+3] = eth_device[eth_dev_num].node_ip_addr[3];
175   buf[IP_DADDR_BASE]   = peer_ip_addr[0];
176   buf[IP_DADDR_BASE+1] = peer_ip_addr[1];
177   buf[IP_DADDR_BASE+2] = peer_ip_addr[2];
178   buf[IP_DADDR_BASE+3] = peer_ip_addr[3];
179   iph->check_sum = Xil_Htons(xilnet_ip_calc_chksum(buf, IP_HDR_LEN*4));
180
181}
182
183
184/*
185 * xilnet_ip_calc_chksum: compute checksum for ip header
186 */
187
188unsigned short xilnet_ip_calc_chksum(unsigned char* buf, int len) {
189
190   unsigned int sum = 0;
191   unsigned short w16 = 0;
192   int i;
193
194   for (i = 0; i < len; i = i + 2) {
195      w16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0x00FF);
196      sum = sum + (unsigned int) w16;
197   }
198
199   while (sum >> 16)
200      sum = (sum & 0xFFFF) + (sum >> 16);
201
202   return (unsigned short) (~sum);
203}
Note: See TracBrowser for help on using the repository browser.