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

Last change on this file was 2229, checked in by welsh, 11 years ago

Added WARPxilnet version 3.03.a

File size: 8.1 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   : udp.c
18// Date   : 2002, March 20.
19// Author : Sathya Thammanur
20// Company: Xilinx
21// Group  : Emerging Software Technologies
22//
23// Summary:
24// UDP layer specific functions
25//
26// $Id: udp.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#include <stdio.h>
36
37
38/*
39 * udp packet handler
40 * "buf" is a IP datagram
41 * currently, this fn just checks for the src port and returns
42 * there is only one udp conn available. multiple conns has to have
43 * more support from high level applns for handling packets for diff conns.
44 */
45
46int xilnet_udp(unsigned char* buf, int len, unsigned int eth_dev_num) {
47
48    int i;
49    struct xilsock_socket  *sockets   = (struct xilsock_socket  *)eth_device[eth_dev_num].xilsock_sockets;
50    struct xilnet_udp_hdr  *udph      = (struct xilnet_udp_hdr  *)(buf+IP_HDR_LEN*4);
51    struct xilnet_udp_conn *conns     = (struct xilnet_udp_conn *)eth_device[eth_dev_num].xilnet_udp_conns;
52    struct xilnet_udp_conn *curr_conn = NULL;
53    pktSrcInfo pktInfo;
54
55#ifdef _DEBUG_
56    xil_printf("BEGIN xilnet_udp(): \n");
57#endif
58
59    // check for an open conn
60    for (i = 0; i < XILNET_MAX_UDP_CONNS; i++) {
61        if (conns[i].state != UDP_CONN_CLOSED) {
62            // match a conn
63            if ( (conns[i].src_port == Xil_Ntohs(udph->dst_port))) {
64                curr_conn = (conns + i);
65
66                // update the conn with the dst ip only the first time
67                conns[i].dst_port = Xil_Ntohs(udph->src_port);
68                conns[i].dst_ip[0] = buf[IP_SADDR_BASE];
69                conns[i].dst_ip[1] = buf[IP_SADDR_BASE+1];
70                conns[i].dst_ip[2] = buf[IP_SADDR_BASE+2];
71                conns[i].dst_ip[3] = buf[IP_SADDR_BASE+3];
72                break;
73            }
74        }
75    }
76    // write data onto the socket of the found conn
77    if (curr_conn) {
78        buf = buf + (IP_HDR_LEN*4) + UDP_HDR_LEN;
79        sockets[curr_conn->fd].recvbuf.buf  = buf;
80        sockets[curr_conn->fd].recvbuf.size = len - (IP_HDR_LEN*4) - UDP_HDR_LEN;
81
82        pktInfo.destPort = curr_conn->dst_port;
83        pktInfo.srcPort  = curr_conn->src_port;
84
85#ifdef _DEBUG_
86        xil_printf("  pktInfo.destPort: %d, pktInfo.srcPort: %d\n", pktInfo.destPort, pktInfo.srcPort);
87#endif
88
89        pktInfo.srcIPAddr = (u32)((curr_conn->dst_ip[0]<<24)+(curr_conn->dst_ip[1]<<16)+(curr_conn->dst_ip[2]<<8)+(curr_conn->dst_ip[3]));
90
91#ifdef _DEBUG_
92        xil_printf("  pktInfo.srcIPAddr = %d.%d.%d.%d\n",( pktInfo.srcIPAddr>>24)&0xFF,( pktInfo.srcIPAddr>>16)&0xFF,( pktInfo.srcIPAddr>>8)&0xFF,( pktInfo.srcIPAddr)&0xFF);
93#endif
94
95        curr_conn->rxCallback(buf,len - (IP_HDR_LEN*4) - UDP_HDR_LEN, &pktInfo, eth_dev_num);
96
97        return (len - (IP_HDR_LEN*4) - UDP_HDR_LEN);
98    }  else {
99#ifdef _DEBUG_
100    xil_printf("  No socket connection found %d : \n", Xil_Ntohs(udph->dst_port) );
101    xil_printf("  Current connections are:  \n");
102    for (i = 0; i < XILNET_MAX_UDP_CONNS; i++) {
103        if (conns[i].state != UDP_CONN_CLOSED) {
104            xil_printf("    UDP conn[%d] = %d \n", i, conns[i].src_port);
105        }
106    }
107#endif
108    }
109
110#ifdef _DEBUG_
111    xil_printf("END xilnet_udp(): \n");
112#endif
113
114   return 0;
115}
116
117
118/*
119 * udp_header: fills the udp header for the packet to be sent
120 */
121
122void xilnet_udp_header(struct xilnet_udp_conn *conn, unsigned char* buf, int len, unsigned int eth_dev_num) {
123   
124   struct xilnet_udp_hdr *udph = (struct xilnet_udp_hdr*) buf;
125   
126   udph->src_port  = Xil_Htons(conn->src_port);
127   udph->dst_port  = Xil_Htons(conn->dst_port);
128   udph->udp_len   = Xil_Htons(len);
129   udph->check_sum = 0;
130   
131   // NOTE:  Currently, we are not computing the checksum on the UDP packets.  This is primarly due to the long
132   // compute time (~1ms @ 160 MHz).  It is ok to not compute the checksum since we are using IPv4 (which has its
133   // own checksum calculation) and we are only using local networks.
134   //   
135   // udph->check_sum = Xil_Htons(xilnet_udp_tcp_calc_chksum(buf, len, eth_device[eth_dev_num].node_ip_addr, conn->dst_ip, IP_PROTO_UDP));
136}
137
138
139/*
140 * xilnet_udp_tcp_calc_chksum: Calculate UDP checksum
141 */
142unsigned short xilnet_udp_tcp_calc_chksum(unsigned char *buf, int buflen, unsigned char *saddr,
143                                          unsigned char *daddr, unsigned short protocol) {
144   unsigned int   sum   = 0;
145   unsigned short w16   = 0;
146   unsigned short proto = protocol;
147   short          pad   = 0;
148   int            i     = 0;
149 
150   //check if udp/tcp datagram needs padding
151   if (buflen %2) {
152      pad = 1; 
153      buf[buflen+1] = 0;
154   }
155   // get the 16bit sum for udp/tcp datagram
156   for (i = 0; i < buflen+pad; i = i + 2) {
157      w16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF);
158      sum = sum + (unsigned int) w16;   
159   }
160   
161   // add the src and dst ip address
162   for (i = 0; i < 4; i = i + 2) {
163      w16 = ((saddr[i] << 8) & 0xFF00) + (saddr[i+1] & 0xFF);
164      sum = sum + (unsigned int) w16;   
165   }
166   
167   for (i = 0; i < 4; i = i + 2) {
168      w16 = ((daddr[i] << 8) & 0xFF00) + (daddr[i+1] & 0x00FF);
169      sum = sum + (unsigned int) w16;   
170   }
171   // add proto and udplength to sum
172   sum = sum + proto + buflen;
173
174   while (sum >> 16)
175      sum = (sum & 0xFFFF) + (sum >> 16);   
176   
177   return ((unsigned short)(~sum)); 
178} 
179
180
181/******************************
182 * udp connection management **
183 ******************************/
184
185/*
186 * initialize all udp conns so that all the states are CLOSED
187 */
188
189void xilnet_udp_init_conns(unsigned int eth_dev_num) {
190   
191    int i;
192    struct xilnet_udp_conn *conns = (struct xilnet_udp_conn *)eth_device[eth_dev_num].xilnet_udp_conns;
193
194    for (i = 0; i < XILNET_MAX_UDP_CONNS; i++) {
195        conns[i].state = UDP_CONN_CLOSED;
196    }
197}
198
199
200/*
201 * open a udp conn:
202 * opens a new udp conn and changes state to OPEN
203 * returns connection index if able to open else -1 if not possible
204 */
205
206int xilnet_udp_open_conn(unsigned short port, void (*callback) (), unsigned int eth_dev_num) {
207   
208    int i;
209    struct xilnet_udp_conn *conns = (struct xilnet_udp_conn *)eth_device[eth_dev_num].xilnet_udp_conns;
210   
211    if (!eth_device[eth_dev_num].is_udp_init) {
212        xilnet_udp_init_conns(eth_dev_num);
213        eth_device[eth_dev_num].is_udp_init = 1;
214    }
215   
216    for (i = 0; i < XILNET_MAX_UDP_CONNS; i++) {
217        if (conns[i].state == UDP_CONN_CLOSED)
218            break;
219    }
220   
221    if (i < XILNET_MAX_UDP_CONNS) {
222        conns[i].src_port = port;
223        conns[i].state = UDP_CONN_OPEN;
224        conns[i].rxCallback = callback;
225        return i;
226    }
227   
228    return -1;
229}
230
231
232/* close a udp conn:
233 * closes a udp conn by changing state to CLOSED
234 * returns 1 if able to close else return -1
235 */
236
237int xilnet_udp_close_conn(struct xilnet_udp_conn *conn, unsigned int eth_dev_num) {
238   
239   int i;
240    struct xilnet_udp_conn *conns = (struct xilnet_udp_conn *)eth_device[eth_dev_num].xilnet_udp_conns;
241
242   for (i = 0; i < XILNET_MAX_UDP_CONNS; i++) {
243      if ( (conns+i) == conn) {
244         conns[i].state = UDP_CONN_CLOSED;
245         return 1;
246      }
247   }
248   
249   return -1;
250}
251
Note: See TracBrowser for help on using the repository browser.