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

Last change on this file was 1930, checked in by murphpo, 11 years ago

Fixed src vs. dst port in UDP responses

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   : 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
37struct xilnet_udp_conn xilnet_udp_conns[MAX_UDP_CONNS];
38unsigned char isudpinit = 0;
39
40/*
41 * udp packet handler
42 * "buf" is a IP datagram
43 * currently, this fn just checks for the src port and returns
44 * there is only one udp conn available. multiple conns has to have
45 * more support from high level applns for handling packets for diff conns.
46 */
47
48int xilnet_udp(unsigned char* buf, int len) {
49
50   int i;
51   struct xilnet_udp_hdr *udph = (struct xilnet_udp_hdr*) (buf+IP_HDR_LEN*4);
52   struct xilnet_udp_conn *curr_conn = NULL;
53   pktSrcInfo pktInfo;
54
55   // check for an open conn
56   for (i = 0; i < MAX_UDP_CONNS; i++) {
57      if (xilnet_udp_conns[i].state != UDP_CONN_CLOSED) {
58         // match a conn
59         if ( (xilnet_udp_conns[i].src_port == Xil_Ntohs(udph->dst_port))) {
60            curr_conn = (xilnet_udp_conns + i);
61            // update the conn with the dst ip only the first time
62            xilnet_udp_conns[i].dst_port = Xil_Ntohs(udph->src_port);
63            xilnet_udp_conns[i].dst_ip[0] = buf[IP_SADDR_BASE];
64            xilnet_udp_conns[i].dst_ip[1] = buf[IP_SADDR_BASE+1];
65            xilnet_udp_conns[i].dst_ip[2] = buf[IP_SADDR_BASE+2];
66            xilnet_udp_conns[i].dst_ip[3] = buf[IP_SADDR_BASE+3];
67
68            //            xilnet_udp_conns[i].state = UDP_CONN_ESTABLISHED;
69            break;
70         }
71      }
72   }
73   // write data onto the socket of the found conn
74   if (curr_conn) {
75      buf = buf + (IP_HDR_LEN*4) + UDP_HDR_LEN;
76      xilsock_sockets[curr_conn->fd].recvbuf.buf = buf;
77      xilsock_sockets[curr_conn->fd].recvbuf.size = len - (IP_HDR_LEN*4) - UDP_HDR_LEN;
78
79      pktInfo.destPort = curr_conn->dst_port;
80      pktInfo.srcPort = curr_conn->src_port;
81
82      //xil_printf("pktInfo.destPort: %d, pktInfo.srcPort: %d\n", pktInfo.destPort, pktInfo.srcPort);
83     
84
85      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]));
86
87      //xil_printf(" pktInfo.srcIPAddr = %d.%d.%d.%d\n",( pktInfo.srcIPAddr>>24)&0xFF,( pktInfo.srcIPAddr>>16)&0xFF,( pktInfo.srcIPAddr>>8)&0xFF,( pktInfo.srcIPAddr)&0xFF);
88
89      curr_conn->rxCallback(buf,len - (IP_HDR_LEN*4) - UDP_HDR_LEN, &pktInfo);
90
91      return (len - (IP_HDR_LEN*4) - UDP_HDR_LEN);
92   }
93   
94   return 0;
95   
96}
97
98
99/*
100 * udp_header: fills the udp header for the packet to be sent
101 */
102
103void xilnet_udp_header(struct xilnet_udp_conn *conn, unsigned char* buf, int len) {
104   
105   struct xilnet_udp_hdr *udph = (struct xilnet_udp_hdr*) buf;
106   
107   udph->src_port = Xil_Htons(conn->src_port);
108   udph->dst_port = Xil_Htons(conn->dst_port);
109   udph->udp_len = Xil_Htons(len);
110   udph->check_sum = 0;
111   udph->check_sum = Xil_Htons(xilnet_udp_tcp_calc_chksum(buf, len, node_ip_addr, conn->dst_ip, IP_PROTO_UDP));
112}
113
114
115/*
116 * xilnet_udp_tcp_calc_chksum: Calculate UDP checksum
117 */
118unsigned short xilnet_udp_tcp_calc_chksum(unsigned char *buf, int buflen, unsigned char *saddr,
119                                        unsigned char *daddr, unsigned short protocol) {
120   unsigned int sum = 0;
121   unsigned short w16 = 0;
122   unsigned short proto = protocol;
123   short pad = 0;
124   int i = 0;
125 
126   //check if udp/tcp datagram needs padding
127   if (buflen %2) {
128      pad = 1; 
129      buf[buflen+1] = 0;
130   }
131   // get the 16bit sum for udp/tcp datagram
132   for (i = 0; i < buflen+pad; i = i + 2) {
133      w16 = ((buf[i] << 8) & 0xFF00) + (buf[i+1] & 0xFF);
134      sum = sum + (unsigned int) w16;   
135   }   
136   // add the src and dst ip address
137   for (i = 0; i < 4; i = i + 2) {
138      w16 = ((saddr[i] << 8) & 0xFF00) + (saddr[i+1] & 0xFF);
139      sum = sum + (unsigned int) w16;   
140   }
141   
142   for (i = 0; i < 4; i = i + 2) {
143      w16 = ((daddr[i] << 8) & 0xFF00) + (daddr[i+1] & 0x00FF);
144      sum = sum + (unsigned int) w16;   
145   }
146   // add proto and udplength to sum
147   sum = sum + proto + buflen;
148
149   while (sum >> 16)
150      sum = (sum & 0xFFFF) + (sum >> 16);   
151   
152   return ((unsigned short)(~sum)); 
153} 
154
155
156/******************************
157 * udp connection management **
158 ******************************/
159
160/*
161 * initialise all udp conns so that all the states are CLOSED
162 */
163
164void xilnet_udp_init_conns() {
165   
166   int i;
167
168   for (i = 0; i < MAX_UDP_CONNS; i++) {
169      xilnet_udp_conns[i].state = UDP_CONN_CLOSED;
170   }
171   
172}
173
174
175/*
176 * open a udp conn:
177 * opens a new udp conn and changes state to OPEN
178 * returns connection index if able to open else -1 if not possible
179 */
180
181int xilnet_udp_open_conn(unsigned short port,void (*callback) ()) {
182   
183   int i;
184   
185   if (!isudpinit) {
186      xilnet_udp_init_conns();
187      isudpinit = 1; 
188   }
189   
190   for (i = 0; i < MAX_UDP_CONNS; i++) {
191      if (xilnet_udp_conns[i].state == UDP_CONN_CLOSED)
192         break;
193   }
194   
195   if (i < MAX_UDP_CONNS) {
196      xilnet_udp_conns[i].src_port = port;
197      xilnet_udp_conns[i].state = UDP_CONN_OPEN;
198      xilnet_udp_conns[i].rxCallback = callback;
199      return i;
200   }
201   
202   return -1;
203   
204}
205
206
207/* close a udp conn:
208 * closes a udp conn by changing state to CLOSED
209 * returns 1 if able to close else return -1
210 */
211
212int xilnet_udp_close_conn(struct xilnet_udp_conn *conn) {
213   
214   int i;
215
216   for (i = 0; i < MAX_UDP_CONNS; i++) {
217      if ( (xilnet_udp_conns+i) == conn) {
218         xilnet_udp_conns[i].state = UDP_CONN_CLOSED;
219         return 1;
220      }
221   }
222   
223   return -1;
224}
225
Note: See TracBrowser for help on using the repository browser.