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

Last change on this file was 1749, checked in by chunter, 12 years ago

Updated copyright information and improved handling of broadcast IP address

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