Browse Source

Fixed whitespaces; updated UDP code

tags/v0.9.3
Nikhil Chandru Rao 18 years ago
parent
commit
a6c6b3d739
2 changed files with 181 additions and 130 deletions
  1. 13
    14
      src/include/gpxe/udp.h
  2. 168
    116
      src/net/udp.c

+ 13
- 14
src/include/gpxe/udp.h View File

@@ -18,7 +18,6 @@
18 18
  * UDP constants
19 19
  */
20 20
 
21
-#define UDP_HLEN    	8
22 21
 #define UDP_MAX_HLEN	72
23 22
 #define UDP_MAX_TXPKB	ETH_MAX_MTU
24 23
 #define UDP_MIN_TXPKB	ETH_ZLEN
@@ -29,10 +28,10 @@ typedef uint16_t port_t;
29 28
  * A UDP header
30 29
  */
31 30
 struct udp_header {
32
-        port_t source_port;
33
-        port_t dest_port;
34
-        uint16_t len;
35
-        uint16_t chksum;
31
+	port_t source_port;
32
+	port_t dest_port;
33
+	uint16_t len;
34
+	uint16_t chksum;
36 35
 };
37 36
 
38 37
 struct udp_connection;
@@ -59,15 +58,15 @@ struct udp_operations {
59 58
  */
60 59
 struct udp_connection {
61 60
        /** Address of the remote end of the connection */
62
-        struct sockaddr sin;
63
-        /** Local port on which the connection receives packets */
64
-        port_t local_port;
65
-        /** Transmit buffer */
66
-        struct pk_buff *tx_pkb;
67
-        /** List of registered connections */
68
-        struct list_head list;
69
-        /** Operations table for this connection */
70
-        struct udp_operations *udp_op;
61
+	struct sockaddr sin;
62
+	/** Local port on which the connection receives packets */
63
+	port_t local_port;
64
+	/** Transmit buffer */
65
+	struct pk_buff *tx_pkb;
66
+	/** List of registered connections */
67
+	struct list_head list;
68
+	/** Operations table for this connection */
69
+	struct udp_operations *udp_op;
71 70
 };
72 71
 
73 72
 /**

+ 168
- 116
src/net/udp.c View File

@@ -17,7 +17,40 @@
17 17
  * UDP protocol
18 18
  */
19 19
 
20
-void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest );
20
+static inline void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest ) {
21
+	memcpy ( dest, source, sizeof ( *dest ) );
22
+}
23
+
24
+static inline uint16_t dest_port ( struct sockaddr *sock, uint16_t *dest ) {
25
+	switch ( sock->sa_family ) {
26
+	case AF_INET:
27
+		dest = &sock->sin.sin_port;
28
+		break;
29
+	case AF_INET6:
30
+		dest = &sock->sin6.sin6_port;
31
+		break;
32
+	default:
33
+		DBG ( "Network family %d not supported\n", sock->sa_family );
34
+		return -EAFNOSUPPORT;
35
+	}
36
+	return 0;
37
+}
38
+
39
+/**
40
+ * Dump the UDP header
41
+ *
42
+ * @v udphdr	UDP header
43
+ */
44
+void udp_dump ( struct udp_header *udphdr ) {
45
+
46
+	/* Print UDP header for debugging */
47
+	DBG ( "UDP header at %#x + %d\n", udphdr, sizeof ( *udphdr ) );
48
+	DBG ( "\tSource Port = %d\n", ntohs ( udphdr->source_port ) );
49
+	DBG ( "\tDestination Port = %d\n", ntohs ( udphdr->dest_port ) );
50
+	DBG ( "\tLength = %d\n", ntohs ( udphdr->len ) );
51
+	DBG ( "\tChecksum = %d\n", ntohs ( udphdr->chksum ) );
52
+	DBG ( "\tChecksum located at %#x\n", &udphdr->chksum );
53
+}
21 54
 
22 55
 /**
23 56
  * Open a UDP connection
@@ -28,10 +61,11 @@ void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest );
28 61
  * This function stores the socket address within the connection
29 62
  */
30 63
 void udp_connect ( struct udp_connection *conn, struct sockaddr *peer ) {
31
-        copy_sockaddr ( peer, &conn->sin );
32
-        /**
33
-         * Not sure if this should add the connection to udp_conns; If it does, uncomment the following code
34
-         */
64
+	copy_sockaddr ( peer, &conn->sin );
65
+
66
+	/* Not sure if this should add the connection to udp_conns; If it does,
67
+	 * uncomment the following code
68
+	 */
35 69
 //	list_add ( &conn->list, &udp_conns );
36 70
 }
37 71
 
@@ -42,11 +76,11 @@ void udp_connect ( struct udp_connection *conn, struct sockaddr *peer ) {
42 76
  * @v udp_op	UDP operations
43 77
  */
44 78
 void udp_init ( struct udp_connection *conn, struct udp_operations *udp_op ) {
45
-        conn->local_port = 0;
46
-        conn->tx_pkb = NULL;
47
-        if ( udp_op != NULL ) {
48
-                conn->udp_op = udp_op;
49
-        }
79
+	conn->local_port = 0;
80
+	conn->tx_pkb = NULL;
81
+	if ( udp_op != NULL ) {
82
+		conn->udp_op = udp_op;
83
+	}
50 84
 }
51 85
 
52 86
 /**
@@ -59,12 +93,12 @@ void udp_init ( struct udp_connection *conn, struct udp_operations *udp_op ) {
59 93
  * Allocate "len" amount of space in the transmit buffer
60 94
  */
61 95
 int udp_buf_alloc ( struct udp_connection *conn, size_t len ) {
62
-        if ( conn->tx_pkb != NULL ) {
63
-                free_pkb ( conn->tx_pkb );
64
-                conn->tx_pkb = NULL;
65
-        }
66
-        conn->tx_pkb = alloc_pkb ( len < UDP_MIN_TXPKB ? UDP_MIN_TXPKB : len );
67
-        return !conn ? -ENOMEM : 0;
96
+	if ( conn->tx_pkb != NULL ) {
97
+		free_pkb ( conn->tx_pkb );
98
+		conn->tx_pkb = NULL;
99
+	}
100
+	conn->tx_pkb = alloc_pkb ( len < UDP_MIN_TXPKB ? UDP_MIN_TXPKB : len );
101
+	return !conn ? -ENOMEM : 0;
68 102
 }
69 103
 
70 104
 /**
@@ -74,45 +108,47 @@ int udp_buf_alloc ( struct udp_connection *conn, size_t len ) {
74 108
  * @v data      Data to send
75 109
  * @v len       Length of data
76 110
  *
77
- * This function fills up the UDP headers and sends the data. Discover the network protocol to
78
- * use through the sa_family field in the destination socket address.
111
+ * This function fills up the UDP headers and sends the data. Discover the
112
+ * network protocol through the sa_family field in the destination socket
113
+ * address.
79 114
  */
80 115
 int udp_send ( struct udp_connection *conn, const void *data, size_t len ) {
81
-       	struct udp_header *udphdr;              /* UDP header */
82
-        struct sockaddr *sock = &conn->sin;     /* Destination sockaddr */
83
-        int rc;
84
-
85
-        /* Copy data into packet buffer if necessary */
86
-        if ( data != conn->tx_pkb->data ) {
87
-                /* Allocate a buffer */
88
-                if ( ( rc = udp_buf_alloc ( conn, len + UDP_MAX_HLEN ) ) != 0 ) {
89
-                        DBG ( "Error allocating buffer" );
90
-                        return rc;
91
-                }
92
-
93
-                /* Reserve space for the headers and copy contents */
94
-                pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
95
-                memcpy ( pkb_put ( conn->tx_pkb, len ), data, len );
96
-        }
97
-
98
-        /* Add the UDP header */
99
-        udphdr = pkb_push ( conn->tx_pkb, UDP_HLEN );
100
-        if ( sock->sa_family == AF_INET )
101
-                udphdr->dest_port = sock->sin.sin_port;
102
-        else
103
-                udphdr->dest_port = sock->sin6.sin6_port;
104
-        udphdr->source_port = conn->local_port;
105
-        udphdr->len = htons ( pkb_len ( conn->tx_pkb ) );
106
-        udphdr->chksum = calc_chksum ( udphdr, UDP_HLEN );
107
-
108
-        /* Print UDP header for debugging */
109
-        DBG ( "UDP header at %#x + %d\n", udphdr, UDP_HDR_LEN  );
110
-        DBG ( "\tSource Port = %d\n", udphdr->source_port );
111
-        DBG ( "\tDestination Port = %d\n", udphdr->dest_port );
112
-        DBG ( "\tLength = %d\n", udphdr->len );
113
-        DBG ( "\tChecksum = %d\n", udphdr->chksum );
114
-        DBG ( "\tChecksum located at %#x\n", &udphdr->chksum );
116
+       	struct udp_header *udphdr;		/* UDP header */
117
+	struct sockaddr *sock = &conn->sin;	/* Destination sockaddr */
118
+	uint16_t *dest;
119
+	int rc;
120
+
121
+	/* Copy data into packet buffer, if necessary */
122
+	if ( data != conn->tx_pkb->data ) {
123
+		/* Allocate space for data and lower layer headers */
124
+		if ( ( rc = udp_buf_alloc ( conn, len + UDP_MAX_HLEN ) ) != 0 ) {
125
+			DBG ( "Error allocating buffer" );
126
+			return rc;
127
+		}
128
+
129
+		/* Reserve space for the headers and copy contents */
130
+		pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
131
+		memcpy ( pkb_put ( conn->tx_pkb, len ), data, len );
132
+	}
115 133
 
134
+	/*
135
+	 * Add the UDP header
136
+	 *
137
+	 * Covert all 16- and 32- bit integers into network btye order before
138
+	 * sending it over the network
139
+	 */
140
+	udphdr = pkb_push ( conn->tx_pkb, sizeof ( *udphdr ) );
141
+	if ( (rc = dest_port ( sock, dest ) ) != 0 ) {
142
+		return rc;
143
+	}
144
+	udphdr->dest_port = htons ( *dest );
145
+	udphdr->source_port = htons ( conn->local_port );
146
+	udphdr->len = htons ( pkb_len ( conn->tx_pkb ) );
147
+	udphdr->chksum = htons ( calc_chksum ( udphdr, sizeof ( *udphdr ) ) );
148
+
149
+	udp_dump ( udphdr );
150
+
151
+	/* Send it to the next layer for processing */
116 152
 	return trans_tx ( conn->tx_pkb, IP_UDP, sock );
117 153
 }
118 154
 
@@ -125,13 +161,13 @@ int udp_send ( struct udp_connection *conn, const void *data, size_t len ) {
125 161
  * @v len       Length of data
126 162
  */
127 163
 int udp_sendto ( struct udp_connection *conn, struct sockaddr *peer,
128
-                        const void *data, size_t len ) {
129
-        struct sockaddr tempsock;
130
-        copy_sockaddr ( &conn->sin, &tempsock );
131
-        copy_sockaddr ( peer, &conn->sin );
132
-        int rc = udp_send ( conn, data, len );
133
-        copy_sockaddr ( &tempsock, &conn->sin );
134
-        return rc;
164
+		 const void *data, size_t len ) {
165
+	struct sockaddr tempsock;
166
+	copy_sockaddr ( &conn->sin, &tempsock );
167
+	copy_sockaddr ( peer, &conn->sin );
168
+	int rc = udp_send ( conn, data, len );
169
+	copy_sockaddr ( &tempsock, &conn->sin );
170
+	return rc;
135 171
 }
136 172
 
137 173
 /**
@@ -140,7 +176,7 @@ int udp_sendto ( struct udp_connection *conn, struct sockaddr *peer,
140 176
  * @v conn      UDP connection
141 177
  */
142 178
 void udp_close ( struct udp_connection *conn ) {
143
-        list_del ( &conn->list );
179
+	list_del ( &conn->list );
144 180
 }
145 181
 
146 182
 /**
@@ -152,74 +188,90 @@ void udp_close ( struct udp_connection *conn ) {
152 188
  * This does not support the 0 port option correctly yet
153 189
  */
154 190
 int udp_open ( struct udp_connection *conn, uint16_t local_port ) {
155
-        struct udp_connection *connr;
156
-        uint16_t min_port = 0xffff;
157
-        list_for_each_entry ( connr, &udp_conns, list ) {
158
-                if ( connr->local_port == local_port ) {
159
-                        return -EISCONN; /* CHECK THE ERROR NUMBER */
160
-                }
161
-                if ( min_port > connr->local_port ) {
162
-                        min_port = connr->local_port;
163
-                }
164
-        }
165
-        conn->local_port = local_port == 0 ? min_port > 1024 ? 1024 : min_port + 1 : local_port; // FAULTY!!!
166
-        list_add ( &conn->list, &udp_conns );
167
-        return 0;
191
+	struct udp_connection *connr;
192
+	uint16_t min_port = 0xffff;
193
+
194
+	/* Iterate through udp_conns to see if local_port is available */
195
+	list_for_each_entry ( connr, &udp_conns, list ) {
196
+		if ( connr->local_port == local_port ) {
197
+			return -EISCONN;
198
+		}
199
+		if ( min_port > connr->local_port ) {
200
+			min_port = connr->local_port;
201
+		}
202
+	}
203
+	/* This code is buggy. I will update it soon :) */
204
+	conn->local_port = local_port == 0 ? min_port > 1024 ? 1024 :
205
+						min_port + 1 : local_port;
206
+
207
+	/* Add the connection to the list of listening connections */
208
+	list_add ( &conn->list, &udp_conns );
209
+	return 0;
168 210
 }
169 211
 
170 212
 /**
171 213
  * Process a received packet
172 214
  *
173
- * @v pkb               Packet buffer
215
+ * @v pkb	       Packet buffer
174 216
  * @v src_net_addr      Source network address
175 217
  * @v dest_net_addr     Destination network address
176 218
  */
177 219
 void udp_rx ( struct pk_buff *pkb, struct in_addr *src_net_addr __unused,
178
-                        struct in_addr *dest_net_addr __unused ) {
179
-        struct udp_header *udphdr = pkb->data;
180
-        struct udp_connection *conn;
181
-
182
-        /* todo: Compute and verify checksum */
183
-
184
-        /* Print UDP header for debugging */
185
-        DBG ( "UDP header at %#x + %d\n", udphdr, UDP_HDR_LEN  );
186
-        DBG ( "\tSource Port = %d\n", udphdr->source_port );
187
-        DBG ( "\tDestination Port = %d\n", udphdr->dest_port );
188
-        DBG ( "\tLength = %d\n", udphdr->len );
189
-        DBG ( "\tChecksum = %d\n", udphdr->chksum );
190
-        DBG ( "\tChecksum located at %#x\n", &udphdr->chksum );
191
-
192
-        /* Demux the connection */
193
-        list_for_each_entry ( conn, &udp_conns, list ) {
194
-                if ( conn->local_port == udphdr->dest_port ) {
195
-                        goto conn;
196
-                }
197
-        }
198
-        return;
199
-
200
-        conn:
201
-        /** Strip off the UDP header */
202
-        pkb_pull ( pkb, UDP_HLEN );
203
-
204
-        /** Allocate max possible buffer space to the tx buffer */
205
-        conn->tx_pkb = alloc_pkb ( UDP_MAX_TXPKB );
206
-        pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
207
-
208
-        /** Call the application's callback */
209
-        conn->udp_op->newdata ( conn, pkb->data, ntohs ( udphdr->len ) - UDP_HLEN  );
220
+			struct in_addr *dest_net_addr __unused ) {
221
+	struct udp_header *udphdr = pkb->data;
222
+	struct udp_connection *conn;
223
+	uint16_t ulen;
224
+	uint16_t chksum;
225
+
226
+	udp_dump ( udphdr );
227
+
228
+	/* Validate the packet and the UDP length */
229
+	if ( pkb_len ( pkb ) < sizeof ( *udphdr ) ) {
230
+		DBG ( "UDP packet too short (%d bytes)\n",
231
+		      pkb_len ( pkb ) );
232
+		return;
233
+	}
234
+
235
+	ulen = ntohs ( udphdr->len );
236
+	if ( ulen != pkb_len ( pkb ) ) {
237
+		DBG ( "Inconsistent UDP packet length (%d bytes)\n",
238
+		      pkb_len ( pkb ) );
239
+		return;
240
+	}
241
+
242
+	/* Verify the checksum */
243
+	chksum = calc_chksum ( pkb->data, pkb_len ( pkb ) );
244
+	if ( chksum != 0xffff ) {
245
+		DBG ( "Bad checksum %d\n", chksum );
246
+		return;
247
+	}
248
+
249
+	/* Todo: Check if it is a broadcast or multicast address */
250
+
251
+	/* Demux the connection */
252
+	list_for_each_entry ( conn, &udp_conns, list ) {
253
+		if ( conn->local_port == ntohs ( udphdr->dest_port ) ) {
254
+			goto conn;
255
+		}
256
+	}
257
+	return;
258
+
259
+	conn:
260
+	/** Strip off the UDP header */
261
+	pkb_pull ( pkb, sizeof ( *udphdr ) );
262
+
263
+	/** Allocate max possible buffer space to the tx buffer */
264
+	conn->tx_pkb = alloc_pkb ( UDP_MAX_TXPKB );
265
+	pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
266
+
267
+	/** Call the application's callback */
268
+	conn->udp_op->newdata ( conn, pkb->data, ulen - sizeof ( *udphdr ) );
210 269
 }
211 270
 
212 271
 struct trans_protocol udp_protocol  = {
213
-        .name = "UDP",
214
-        .rx = udp_rx,
215
-        .trans_proto = IP_UDP,
272
+	.name = "UDP",
273
+	.rx = udp_rx,
274
+	.trans_proto = IP_UDP,
216 275
 };
217 276
 
218 277
 TRANS_PROTOCOL ( udp_protocol );
219
-
220
-/**
221
- * Internal functions
222
- */
223
-void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest ) {
224
-        memcpy ( dest, source, sizeof ( struct sockaddr ) );
225
-}

Loading…
Cancel
Save