summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/include/gpxe/tcpip_if.h2
-rw-r--r--src/include/gpxe/udp.h22
-rw-r--r--src/net/tcpip_if.c39
-rw-r--r--src/net/udp.c32
4 files changed, 62 insertions, 33 deletions
diff --git a/src/include/gpxe/tcpip_if.h b/src/include/gpxe/tcpip_if.h
index bac39699..ce095efa 100644
--- a/src/include/gpxe/tcpip_if.h
+++ b/src/include/gpxe/tcpip_if.h
@@ -83,7 +83,7 @@ extern void trans_rx ( struct pk_buff *pkb, uint8_t trans_proto,
extern int trans_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip,
struct sockaddr *dest );
-extern uint16_t calc_chksum ( void *data, size_t len );
+extern uint16_t calc_chksum ( void *b, int len );
extern struct tcpip_protocol * find_tcpip_protocol ( uint8_t trans_proto );
extern struct tcpip_net_protocol * find_tcpip_net_protocol ( sa_family_t sa_family );
diff --git a/src/include/gpxe/udp.h b/src/include/gpxe/udp.h
index e6511160..68034583 100644
--- a/src/include/gpxe/udp.h
+++ b/src/include/gpxe/udp.h
@@ -41,6 +41,23 @@ struct udp_connection;
*
*/
struct udp_operations {
+
+ /**
+ * Transmit data
+ *
+ * @v conn UDP connection
+ * @v buf Temporary data buffer
+ * @v len Length of temporary data buffer
+ *
+ * The application may use the temporary data buffer to
+ * construct the data to be sent. Note that merely filling
+ * the buffer will do nothing; the application must call
+ * udp_send() in order to actually transmit the data. Use of
+ * the buffer is not compulsory; the application may call
+ * udp_send() on any block of data.
+ */
+ void ( * senddata ) ( struct tcp_connection *conn, void *buf,
+ size_t len );
/**
* New data received
*
@@ -70,11 +87,6 @@ struct udp_connection {
};
/**
- * List of registered UDP connections
- */
-static LIST_HEAD ( udp_conns );
-
-/**
* UDP protocol
*/
extern struct tcpip_protocol udp_protocol;
diff --git a/src/net/tcpip_if.c b/src/net/tcpip_if.c
index 5c5e5962..80d69268 100644
--- a/src/net/tcpip_if.c
+++ b/src/net/tcpip_if.c
@@ -107,30 +107,19 @@ int trans_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip,
/**
* Calculate internet checksum
*
- * @v data Pointer to the data
- * @v len Length of data to be checksummed
- * @ret chksum 16 bit internet checksum
- *
- * This function calculates the internet checksum (refer RFC1071) for "len"
- * bytes beginning at the location "data"
+ * @v b Pointer to the data
+ * @v len Length of data to be checksummed
+ * @ret result 16 bit internet checksum
*/
-uint16_t calc_chksum ( void *data, size_t len ) {
- register long sum = 0;
- uint16_t checksum;
- unsigned short *temp;
- while ( len > 1 ) {
- temp = (unsigned short*) data++;
- sum += *temp;
- len -= 2;
- }
- if ( len > 0 ) {
- sum += *(unsigned char *)data;
- }
- while ( sum >> 16 ) {
- sum = ( sum & 0xffff ) + ( sum >> 16 );
- }
- checksum = ~sum;
- return checksum;
+uint16_t calc_chksum(void *b, int len) {
+ uint16_t *buf = b, result;
+ uint16_t sum=0;
+ for ( sum = 0; len > 1; len -= 2 ) /* Sum all 16b words */
+ sum += *buf++;
+ if ( len == 1 ) /* If any stray bytes, */
+ sum += *(unsigned char*)buf; /* add to sum */
+ sum = (sum >> 16) + (sum & 0xffff); /* Add the carry */
+ sum += (sum >> 16); /* (again) */
+ result = ~sum; /* Take the one's complement */
+ return result; /* Return 16b value */
}
-
-
diff --git a/src/net/udp.c b/src/net/udp.c
index b84d5161..0fca99a4 100644
--- a/src/net/udp.c
+++ b/src/net/udp.c
@@ -18,6 +18,14 @@
* UDP protocol
*/
+/**
+ * List of registered UDP connections
+ */
+static LIST_HEAD ( udp_conns );
+
+/**
+ * Some utility functions
+ */
static inline void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest ) {
memcpy ( dest, source, sizeof ( *dest ) );
}
@@ -98,7 +106,27 @@ int udp_buf_alloc ( struct udp_connection *conn, size_t len ) {
}
/**
- * Send data via a UDP connection
+ * User request to send data via a UDP connection
+ *
+ * @v conn UDP connection
+ *
+ * This function allocates buffer space and invokes the function's senddata()
+ * callback. The callback may use the buffer space
+ */
+int udp_senddata ( struct udp_connection *conn ) {
+ conn->tx_pkb = pkb_alloc ( UDP_MAX_TXPKB );
+ if ( conn->tx_pkb == NULL ) {
+ DBG ( "Error allocating packet buffer of length %d\n",
+ UDP_MAX_TXPKB );
+ return -ENOMEM;
+ }
+ conn->udp_op->senddata ( conn, conn->tx_pkb, pkb_len ( conn->tx_pkb ) );
+ return 0;
+}
+
+
+/**
+ * Transmit data via a UDP connection
*
* @v conn UDP connection
* @v data Data to send
@@ -124,7 +152,7 @@ int udp_send ( struct udp_connection *conn, const void *data, size_t len ) {
/* Reserve space for the headers and copy contents */
pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
- memcpy ( pkb_put ( conn->tx_pkb, len ), data, len );
+ memmove ( pkb_put ( conn->tx_pkb, len ), data, len );
}
/*