The following edits were made: \
authorNikhil Chandru Rao <nikhilcrao@users.sourceforge.net>
Wed, 19 Jul 2006 16:25:23 +0000 (16:25 +0000)
committerNikhil Chandru Rao <nikhilcrao@users.sourceforge.net>
Wed, 19 Jul 2006 16:25:23 +0000 (16:25 +0000)
1. Updated UDP send data code\
2. Corrected internet checksum\
3. Moved udp_buffer() and udp_buflen() to udp.c from udp.h

src/include/gpxe/tcpip_if.h
src/include/gpxe/udp.h
src/net/tcpip_if.c
src/net/udp.c

index bac3969..ce095ef 100644 (file)
@@ -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 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 );
 
 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 );
index e651116..6803458 100644 (file)
@@ -41,6 +41,23 @@ struct udp_connection;
  *
  */
 struct udp_operations {
  *
  */
 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
         *
        /**
         * New data received
         *
@@ -69,11 +86,6 @@ struct udp_connection {
        struct udp_operations *udp_op;
 };
 
        struct udp_operations *udp_op;
 };
 
-/**
- * List of registered UDP connections
- */
-static LIST_HEAD ( udp_conns );
-
 /**
  * UDP protocol
  */
 /**
  * UDP protocol
  */
index 5c5e596..80d6926 100644 (file)
@@ -107,30 +107,19 @@ int trans_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip,
 /**
  * Calculate internet checksum
  *
 /**
  * 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 */
 }
 }
-
-
index b84d516..0fca99a 100644 (file)
  * UDP protocol
  */
 
  * 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 ) );
 }
 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
  *
  * @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 );
 
                /* 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 );
        }
 
        /*
        }
 
        /*