The following edits were made: \
1. Updated UDP send data code\ 2. Corrected internet checksum\ 3. Moved udp_buffer() and udp_buflen() to udp.c from udp.h
This commit is contained in:
parent
b8d619e822
commit
ab577e1a3a
@ -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,
|
extern int trans_tx ( struct pk_buff *pkb, struct tcpip_protocol *tcpip,
|
||||||
struct sockaddr *dest );
|
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_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_net_protocol * find_tcpip_net_protocol ( sa_family_t sa_family );
|
||||||
|
@ -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
|
||||||
*/
|
*/
|
||||||
|
@ -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 b Pointer to the data
|
||||||
* @v len Length of data to be checksummed
|
* @v len Length of data to be checksummed
|
||||||
* @ret chksum 16 bit internet checksum
|
* @ret result 16 bit internet checksum
|
||||||
*
|
|
||||||
* This function calculates the internet checksum (refer RFC1071) for "len"
|
|
||||||
* bytes beginning at the location "data"
|
|
||||||
*/
|
*/
|
||||||
uint16_t calc_chksum ( void *data, size_t len ) {
|
uint16_t calc_chksum(void *b, int len) {
|
||||||
register long sum = 0;
|
uint16_t *buf = b, result;
|
||||||
uint16_t checksum;
|
uint16_t sum=0;
|
||||||
unsigned short *temp;
|
for ( sum = 0; len > 1; len -= 2 ) /* Sum all 16b words */
|
||||||
while ( len > 1 ) {
|
sum += *buf++;
|
||||||
temp = (unsigned short*) data++;
|
if ( len == 1 ) /* If any stray bytes, */
|
||||||
sum += *temp;
|
sum += *(unsigned char*)buf; /* add to sum */
|
||||||
len -= 2;
|
sum = (sum >> 16) + (sum & 0xffff); /* Add the carry */
|
||||||
}
|
sum += (sum >> 16); /* (again) */
|
||||||
if ( len > 0 ) {
|
result = ~sum; /* Take the one's complement */
|
||||||
sum += *(unsigned char *)data;
|
return result; /* Return 16b value */
|
||||||
}
|
|
||||||
while ( sum >> 16 ) {
|
|
||||||
sum = ( sum & 0xffff ) + ( sum >> 16 );
|
|
||||||
}
|
|
||||||
checksum = ~sum;
|
|
||||||
return checksum;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -18,6 +18,14 @@
|
|||||||
* 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 ) {
|
static inline void copy_sockaddr ( struct sockaddr *source, struct sockaddr *dest ) {
|
||||||
memcpy ( dest, source, sizeof ( *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 conn UDP connection
|
||||||
* @v data Data to send
|
* @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 */
|
/* Reserve space for the headers and copy contents */
|
||||||
pkb_reserve ( conn->tx_pkb, UDP_MAX_HLEN );
|
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 );
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
Reference in New Issue
Block a user