PERFORCE change 121227 for review
Alexey Tarasov
taleks at FreeBSD.org
Fri Jun 8 16:34:15 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=121227
Change 121227 by taleks at taleks_th on 2007/06/08 16:33:48
Added pxe_buffer and pxe_dhcp modules. pxe_buffer contains functions to work with cyclic buffers (PXE_BUFFER definition also moved in this module). pxe_dhcp - firest few linres to perform getting of information. that is not available from bootplayer for unknown reasons. pxe_core: moved out print_dhcp_options() to pxe_dhcp. pxe_ip: added simple broadcast ip address sending (need to check working on dhcp client). pxe_sock: made it a little bit more similar to stansart sockets interface, (added pxe_bind() function and pxe_recvfrom()) and socket states now are used not just to differ free/used states. pxe_udp: finally checksum works correctly after adding of two checksumes, pxe_udp_callback() now places data in sockets using pxe_buffer routines and stores pxe_udp_dgram structs in buffer.
Affected files ...
.. //depot/projects/soc2007/taleks-pxe_http/Makefile#5 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_buffer.c#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_buffer.h#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#13 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#11 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_dhcp.c#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_dhcp.h#1 add
.. //depot/projects/soc2007/taleks-pxe_http/pxe_ip.c#6 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_ip.h#5 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#6 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#6 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_udp.c#3 edit
.. //depot/projects/soc2007/taleks-pxe_http/pxe_udp.h#2 edit
Differences ...
==== //depot/projects/soc2007/taleks-pxe_http/Makefile#5 (text+ko) ====
@@ -3,8 +3,8 @@
LIB= pxe_http
INTERNALLIB=
-SRCS= pxe_conv.c pxe_core.h pxe_isr.S pxe_sock.c pxe_arp.c pxe_ip.c pxe_mutex.c \
- pxe_core.c pxe_icmp.c pxe_mem.c pxe_udp.c pxe_filter.c pxe_dns.c
+SRCS= pxe_conv.c pxe_isr.S pxe_mem.c pxe_buffer.c pxe_sock.c pxe_arp.c pxe_ip.c pxe_mutex.c \
+ pxe_core.c pxe_icmp.c pxe_udp.c pxe_filter.c pxe_dns.c pxe_dhcp.c
CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \
-I${.CURDIR}/../../../contrib/dev/acpica \
==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#13 (text+ko) ====
@@ -19,7 +19,6 @@
/* NOTE: to think about using of this buffers */
#define PXE_BUFFER_SIZE 0x1000
-#define PXE_TFTP_BUFFER_SIZE 512
static uint8_t scratch_buffer[PXE_BUFFER_SIZE];
static uint8_t data_buffer[PXE_BUFFER_SIZE];
static pxenv_t *pxenv = NULL; /* PXENV+ */
@@ -72,54 +71,6 @@
return (status);
}
-
-void
-print_dhcp_options(uint8_t *opts)
-{
- uint8_t *p=opts;
- uint8_t code = opts[0];
- uint8_t len = 0;
-
- printf("DHCP options:\n");
-
- while (code != 255) {
-
- ++p;
- len = 1 + (*p);
- printf("code %d, len %d: ", code, len);
-
- switch (code) {
- case 0: /* pad */
- len = 0;
- break;
-
- case 1: /* netmask */
- printf("netmask: %d.%d.%d.%d\n", *(p+1), *(p+2), *(p+3), *(p+4));
- break;
-
- case 3: /* routers */
- printf("first router: %d.%d.%d.%d\n", *(p+1), *(p+2), *(p+3), *(p+4));
- break;
-
- case 5: /* nameserver */
- printf("first nameserver: %d.%d.%d.%d\n", *(p+1), *(p+2), *(p+3), *(p+4));
- break;
-
- default:
- break;
- };
-
- printf("\n");
- p += len;
- code = *p;
- len = 0;
-
- if (p - opts > BOOTP_DHCPVEND)
- break;
- }
-}
-
-
/*
* performs UNDI initialization call during pxe_core_init()
* out:
@@ -170,14 +121,7 @@
pxe = pxe_p;
- /* creating 2-linked list of packets */
-/* for (; i < PXE_MAX_PACKETS; ++i) {
- core_packets[i].prev = &core_packets[i-1];
- core_packets[i-1].next = &core_packets[i];
- }
-*/
/* 1. determine PXE API entry point */
-
if(pxenv_p == NULL)
return (0);
@@ -246,14 +190,20 @@
__pxe_entry_seg = pxe->EntryPointSP.segment;
__pxe_entry_off = pxe->EntryPointSP.offset;
+ /* 2. getting cached info */
gci_p = (t_PXENV_GET_CACHED_INFO *) scratch_buffer;
- pxe_memset(gci_p, 0, sizeof(*gci_p));
- gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;
+ pxe_memset(gci_p, 0, sizeof(*gci_p));
- if (!pxe_core_call(PXENV_GET_CACHED_INFO)) {
- }
+/* gci_p->PacketType = PXENV_PACKET_TYPE_BINL_REPLY;*/
+/**/
+ gci_p->PacketType = PXENV_PACKET_TYPE_DHCP_ACK;
+ gci_p->BufferSize = sizeof(BOOTPLAYER);
+ gci_p->Buffer.segment = VTOPSEG(&bootplayer);
+ gci_p->Buffer.offset = VTOPOFF(&bootplayer);
- if (gci_p->Status != 0) {
+ if ( (!pxe_core_call(PXENV_GET_CACHED_INFO)) ||
+ (gci_p->Status != 0) )
+ {
#ifdef PXE_DEBUG
printf("pxe_core_init(): error status = 0x%x\n", gci_p->Status);
#endif
@@ -261,37 +211,13 @@
return (0);
}
- pxe_memcpy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
+/* pxe_memcpy(PTOV((gci_p->Buffer.segment << 4) + gci_p->Buffer.offset),
&bootplayer, gci_p->BufferSize);
-
-
- /* 2. additional start UNDI */
-
- /* 2.1 close connection to network */
-/*
- t_PXENV_UNDI_CLOSE *undi_close =
- (t_PXENV_UNDI_CLOSE *)scratch_buffer;
-
- undi_close->Status = 0;
-
- pxe_core_call(PXENV_UNDI_CLOSE);
- delay(10000000);
- }
*/
- /* 2.1. shutdown UNDI */
-
-/* t_PXENV_UNDI_SHUTDOWN *undi_shutdown =
- (t_PXENV_UNDI_SHUTDOWN *)scratch_buffer;
-
- undi_shutdown->Status = 0;
+#ifdef PXE_DEBUG
+ printf("pxe_core_init(): copied %d bytes of cached packet. Limit = %d.\n", gci_p->BufferSize, gci_p->BufferLimit);
+#endif
- pxe_core_call(PXENV_UNDI_SHUTDOWN);
-*/
- /* 2.2 init UNDI */
-/* if (!pxe_core_undi_init()) {
- return (0);
- }
-*/
/* 3. install isr */
pxe_core_install_isr();
@@ -313,6 +239,8 @@
printf("my MAC: %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x\n",
nic_mac[0], nic_mac[1], nic_mac[2], nic_mac[3], nic_mac[4], nic_mac[5]);
+ printf("gip ip: 0x%8x\n", bootplayer.gip);
+
ns_ip.ip = 0x0100a8c0; /* TODO: to determiny nameserver ip*/
pxe_arp_init();
==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#11 (text+ko) ====
@@ -118,6 +118,7 @@
/* returns nameserver ip */
uint32_t pxe_get_nsip32();
+/* sets nameserver ip */
void pxe_set_nsip32(uint32_t new_ns);
#endif // PXE_CORE_H_INCLUDED
==== //depot/projects/soc2007/taleks-pxe_http/pxe_ip.c#6 (text+ko) ====
@@ -307,15 +307,19 @@
pxe_create_ip_hdr(pack_out->data, dst_ip, protocol, pack_size, 0);
/* setting pxe_core packet parameters*/
- pack_out->flags = PXE_SINGLE;
+ pack_out->flags = (dst_ip != PXE_IP_BCAST) ? PXE_SINGLE : PXE_BCAST;
pack_out->protocol = PXE_PROTOCOL_IP;
/* find gateway or direct MAC*/
- uint32_t ip_to_send = pxe_ip_route_find(dst_ip);
+ uint32_t ip_to_send = dst_ip;
- pack_out->dest_mac = pxe_arp_ip4mac(ip_to_send);
+ if (pack_out->flags != PXE_BCAST) {
+ ip_to_send = pxe_ip_route_find(dst_ip);
+ pack_out->dest_mac = pxe_arp_ip4mac(ip_to_send);
+ }
- if ( pack_out->dest_mac == NULL) { /* MAC is not found fo destination ip or gateway */
+ if ( (pack_out->flags != PXE_BCAST) && (pack_out->dest_mac == NULL) ) {
+ /* MAC is not found for destination ip or gateway */
#ifdef PXE_DEBUG
PXE_IPADDR dst;
PXE_IPADDR to;
@@ -333,7 +337,7 @@
printf("pxe_ip_send(): failed to send packet.\n");
#endif
} else {
- status = 1;
+ status = 1;
}
}
==== //depot/projects/soc2007/taleks-pxe_http/pxe_ip.h#5 (text+ko) ====
@@ -34,6 +34,9 @@
};
} __packed PXE_IPADDR;
+/* often used here broadcast ip */
+#define PXE_IP_BCAST 0xffffffff
+/* maximum route table size */
#define PXE_MAX_ROUTES 4
/* routing related structure */
==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#6 (text+ko) ====
@@ -1,5 +1,6 @@
+#include "pxe_buffer.h"
+#include "pxe_filter.h"
#include "pxe_mem.h"
-#include "pxe_filter.h"
#include "pxe_sock.h"
#include "pxe_udp.h"
@@ -40,12 +41,6 @@
sock->state = PXE_SOCKET_FREE;
-/* NOTE: may be it's not good place for it
- if (sock->filter) {
- pxe_filter_remove(sock->filter);
- sock->filter = NULL;
- }
-*/
return (1);
}
@@ -66,32 +61,29 @@
PXE_BUFFER *rbuf = &pxe_sockets[socket].recv_buffer;
PXE_BUFFER *sbuf = &pxe_sockets[socket].send_buffer;
- sbuf->data = pxe_alloc(PXE_DEFAULT_SEND_BUFSIZE);
+ if (!pxe_buffer_memalloc(sbuf, PXE_DEFAULT_SEND_BUFSIZE)) {
- if (sbuf->data == NULL) {
-
pxe_socket_free(socket);
return (-1);
}
sbuf->bufsize = PXE_DEFAULT_SEND_BUFSIZE;
sbuf->bufleft = PXE_DEFAULT_SEND_BUFSIZE;
- sbuf->free_start = sbuf->data;
- sbuf->free_end = sbuf->data + sbuf->bufsize;
+ sbuf->fstart = 0;
+ sbuf->fend = sbuf->bufsize;
- rbuf->data = pxe_alloc(PXE_DEFAULT_RECV_BUFSIZE);
- if (rbuf->data == NULL) {
+ if (!pxe_buffer_memalloc(rbuf, PXE_DEFAULT_RECV_BUFSIZE)) {
- pxe_free(rbuf->data);
+ pxe_buffer_memfree(sbuf);
pxe_socket_free(socket);
return (-1);
}
rbuf->bufsize = PXE_DEFAULT_RECV_BUFSIZE;
rbuf->bufleft = PXE_DEFAULT_RECV_BUFSIZE;
- rbuf->free_start = rbuf->data;
- rbuf->free_end = rbuf->data + rbuf->bufsize;
+ rbuf->fstart = 0;
+ rbuf->fend = rbuf->bufsize;
return (socket);
}
@@ -124,8 +116,8 @@
#endif
}
- pxe_free(sock->send_buffer.data);
- pxe_free(sock->recv_buffer.data);
+ pxe_buffer_memfree(&sock->send_buffer);
+ pxe_buffer_memfree(&sock->recv_buffer);
return pxe_socket_free(socket);
}
@@ -229,84 +221,6 @@
}
}
-int
-pxe_sock_bufspace(int socket)
-{
- if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
- return (-1);
- }
-
- return pxe_sockets[socket].recv_buffer.bufleft;
-}
-
-int
-pxe_sock_place(int socket, void* data, uint16_t size)
-{
-#ifdef PXE_DEBUG
- printf("pxe_sock_place(): socket: %d, data: 0x%x, size: %d\n", socket, data, size);
-#endif
- if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
- return (-1);
- }
-
- PXE_BUFFER *rbuf = &pxe_sockets[socket].recv_buffer;
- uint16_t copy_size = size;
-
- /* there is no enogh space available in recv buffer
- * try as much as possible.
- */
- if (rbuf->bufleft < size) {
-
- copy_size = rbuf->bufleft;
-
- if (copy_size == 0)
- return (0);
- }
-
- pxe_memcpy(data, rbuf->free_start, copy_size);
-
- rbuf->free_start += copy_size;
- rbuf->bufleft -= copy_size;
-
-#ifdef PXE_DEBUG
- printf("pxe_sock_place(): left: %d\n", rbuf->bufleft);
-#endif
- return (copy_size);
-}
-
-int
-pxe_sock_get(PXE_SOCKET *sock)
-{
- int res = sock - pxe_sockets;
-
- if (res > PXE_DEFAULT_SOCKETS)
- return (-1);
-
- return (res);
-}
-
-int
-pxe_sock_rewind(int socket, uint16_t size)
-{
-
- if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
- return (-1);
- }
-
- PXE_SOCKET *sock = &pxe_sockets[socket];
-
- uint16_t rew_bytes = sock->recv_buffer.free_start - sock->recv_buffer.data;
-
- /* if data to rewind enough, than rewing size, else only available rew_bytes */
- if (rew_bytes > size)
- rew_bytes = size;
-
- sock->recv_buffer.free_start -= rew_bytes;
- sock->recv_buffer.bufleft += rew_bytes;
-
- return (rew_bytes);
-}
-
/* out:
* 0 - no free port
* >0 - port number
@@ -330,13 +244,35 @@
printf("pxe_sendto(): send buffer too small for %d bytes.\n", size);
return (-1);
}
+
+ PXE_SOCKET *sock = &pxe_sockets[socket];
+
+
+ if ( sock->state == PXE_SOCKET_BINDED) {
+ /* if socket binded filter must not be NULL, cause pxe_bind() installs filter */
+ if (sock->filter == NULL) {
+ printf("pxe_sendto(): filter is NULL for binded socket %d.\n", socket);
+ return (-1);
+ }
+
+ /* NOTE: is really difference? */
+ /* if (filter->protocol == PXE_UDP_PROTOCOL) {
+
+ } else {
+
+ }
+ */
+
+ } else { /* not binded, connect */
- if (!pxe_connect(socket, ip, port, PXE_UDP_PROTOCOL)) {
- printf("pxe_sendto(): failed to connect.\n");
- return (-1);
+ /* NOTE: if it's already connected, return error */
+ if (!pxe_connect(socket, ip, port, PXE_UDP_PROTOCOL)) {
+ printf("pxe_sendto(): failed to connect.\n");
+ return (-1);
+ }
}
- PXE_SOCKET *sock = &pxe_sockets[socket];
+ PXE_FILTER_ENTRY *filter = sock->filter;
/* for UDP socket, send buffer used only for one dgram */
PXE_UDP_PACKET *udp_pack = (PXE_UDP_PACKET *)sock->send_buffer.data;
@@ -344,12 +280,12 @@
/* copy user data */
pxe_memcpy(data, udp_pack + 1, size);
- PXE_FILTER_ENTRY *filter = sock->filter;
-
/* filters are useful for incoming packet, so dst_port
- * is local port.
+ * is local port. It's always set on this step (both for binded and connected sockets).
+ * for binded sockets pxe_connect() skipped, so we need manually call pxe_next_port()
+ * to get local port (so, we don't use binded local port, it seems correct behaviour)
*/
- uint16_t lport = filter->dst_port;
+ uint16_t lport = (sock->state == PXE_SOCKET_BINDED) ? pxe_next_port() : filter->dst_port;
#ifdef PXE_DEBUG
printf("pxe_sendto(): %8x:%d -> %8x:%d, size = %d bytes.\n", pxe_get_myip32(), lport, ip, port, size);
@@ -359,22 +295,29 @@
printf("pxe_sendto(): failed to send data.\n");
return (-1);
}
-
+
+ /* NOTE: normally for UDP here must be disconnecting of socket
+ * pxe_disconnect(socket);
+ */
return (size);
}
-
-
int
pxe_connect(int socket, uint32_t ip, uint16_t port, uint8_t proto)
{
+
if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
return (0);
}
PXE_SOCKET *sock = &pxe_sockets[socket];
+ if (sock->state >= PXE_SOCKET_CONNECTED) {
+ printf("pxe_connect(): socket %d already connected.\n", socket);
+ return (-1);
+ }
+
/* socket was already initalized */
if (sock->filter != NULL) {
@@ -399,6 +342,8 @@
}
sock->filter = entry;
+ sock->state = PXE_SOCKET_CONNECTED;
+ printf("pxe_connect(): socket %d,0x%x:%d -> 0x%x:%d\n", socket, pxe_get_myip32(), lport, ip, port);
/* all is ok */
return (1);
@@ -408,7 +353,6 @@
* also, need to understand how to update buffer for multiple received dgrams
* buffer free space is specified by two pointers (may be better to change to
* indexes) free_start and free_end. Cycled buffer.
- * That's how i see it (cyclic buffer)
*/
int
pxe_send(int socket, void *buf, size_t buflen)
@@ -449,7 +393,60 @@
int
pxe_recv(int socket, void *tobuf, size_t buflen)
{
+ /* common part */
+ if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
+ printf("pxe_recv(): invalid socket %d.\n", socket);
+ return (-1);
+ }
+
+ PXE_BUFFER *buffer = &pxe_sockets[socket].recv_buffer;
+
+ size_t usage = buffer->bufsize - buffer->bufleft;
+
+ if ( usage == 0 ) { /* nothing received */
+#ifdef PXE_DEBUG
+ printf("pxe_recv(): nothing to recv for socket %d.\n", socket);
+#endif
+ return (0);
+ }
+
+#ifdef PXE_DEBUG
+ printf("pxe_recv(): usage = %d, buflen = %d.\n", usage, buflen);
+#endif
+
+ /* udp related part, need to move it to separate function */
+ PXE_UDP_DGRAM udp_dgram;
+
+ if (sizeof(PXE_UDP_DGRAM) != pxe_buffer_read(buffer, &udp_dgram, sizeof(PXE_UDP_DGRAM))) {
+#ifdef PXE_DEBUG
+ printf("pxe_udp_sock_recv(): failed to read datagram data.\n");
+#endif
+ return (0);
+ }
+
+ if (udp_dgram.magic != PXE_MAGIC_DGRAM) { /* sanity check failed */
+#ifdef PXE_DEBUG
+ printf("pxe_udp_sock_recv(): dgram magic failed.\n");
+#endif
+ return (0);
+ }
+
+ uint16_t tocopy = ((uint16_t)buflen < udp_dgram.size) ? (uint16_t)buflen : udp_dgram.size;
+
+ uint16_t result = pxe_buffer_read(buffer, tobuf, tocopy);
+
+ if (result < udp_dgram.size) { /* free truncated dgram part */
+ pxe_buffer_read(buffer, NULL, udp_dgram.size - result);
+ }
+
+ return ((int)result);
+}
+
+int
+pxe_recvfrom(int socket, void *tobuf, size_t buflen, uint32_t *src_ip)
+{
+ /* common part */
if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
printf("pxe_recv(): invalid socket %d.\n", socket);
return (-1);
@@ -469,10 +466,77 @@
#ifdef PXE_DEBUG
printf("pxe_recv(): usage = %d, buflen = %d.\n", usage, buflen);
#endif
+
+ /* udp related part, need to move it to separate function */
+ PXE_UDP_DGRAM udp_dgram;
+
+ if (sizeof(PXE_UDP_DGRAM) != pxe_buffer_read(buffer, &udp_dgram, sizeof(PXE_UDP_DGRAM))) {
+#ifdef PXE_DEBUG
+ printf("pxe_udp_sock_recv(): failed to read datagram data.\n");
+#endif
+ return (0);
+ }
+
+ if (udp_dgram.magic != PXE_MAGIC_DGRAM) {/* sanity check failed */
+#ifdef PXE_DEBUG
+ printf("pxe_udp_sock_recv(): dgram magic failed.\n");
+#endif
+ return (0);
+ }
+
+ uint16_t tocopy = ((uint16_t)buflen < udp_dgram.size) ? (uint16_t)buflen : udp_dgram.size;
+
+ uint16_t result = pxe_buffer_read(buffer, tobuf, tocopy);
+
+ if (result < udp_dgram.size) { /* free truncated dgram part */
+ pxe_buffer_read(buffer, NULL, udp_dgram.size - result);
+ }
+
+ if (src_ip) {
+ *src_ip = udp_dgram.src_ip;
+ }
+
+ return ((int)result);
+}
+
+int
+pxe_bind(int socket, uint32_t ip, uint16_t lport, uint8_t proto)
+{
+ if ( (socket >= PXE_DEFAULT_SOCKETS) || (socket == -1)) {
+ printf("pxe_bind(): invalid socket %d.\n", socket);
+ return (-1);
+ }
+
+ PXE_SOCKET *sock = &pxe_sockets[socket];
+
+ if (sock->state == PXE_SOCKET_CONNECTED) {
+ printf("pxe_bind(): cannot bind connected socket %d.\n", socket);
+ return (-1);
+ }
+
+ /* socket was already initalized */
+ if (sock->filter != NULL) {
+
+ pxe_filter_remove(sock->filter);
+ sock->filter = NULL;
+ }
+
+ PXE_FILTER_ENTRY *entry =
+ pxe_filter_add( 0, 0, ip, lport, sock, proto);
+
- size_t tocopy = (buflen < usage) ? buflen : usage;
+ if ( entry == NULL ) {
+ printf("pxe_bind(): failed to add filter.\n");
+ return (0);
+ }
- pxe_memcpy(buffer->data, tobuf, tocopy);
+ /* allow any src_ip:port to our ip:lport */
+ pxe_filter_mask(entry, 0, 0, 0xffffffff, 0xffff);
+ sock->filter = entry;
+
+ /* all is ok */
+
+ sock->state = PXE_SOCKET_BINDED;
- return (tocopy);
+ return (0);
}
==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#6 (text+ko) ====
@@ -4,6 +4,7 @@
#include <stdint.h>
#include <stddef.h>
+#include "pxe_buffer.h"
#include "pxe_filter.h"
#include "pxe_ip.h"
/* buffer size choosed by default for sending/recieving*/
@@ -17,21 +18,12 @@
/* default count of waiting queue */
#define PXE_DEFAULT_WAITCOUNT 3
/* socket states */
-#define PXE_SOCKET_FREE 0x0
-#define PXE_SOCKET_USED 0x1
+#define PXE_SOCKET_FREE 0x0 /* socket unused and free for allocating */
+#define PXE_SOCKET_USED 0x1 /* socket structure used */
+#define PXE_SOCKET_BINDED 0x2 /* socket binded (set local ip/local port) */
+#define PXE_SOCKET_CONNECTED 0x3 /* socket connected (set remote ip/remote port) */
+#define PXE_SOCKET_ESTABLISHED 0x4 /* connection established, may be bad place for this flag */
-/* pxe_buffer - buffer related information */
-typedef struct pxe_buffer {
-
- void *data; /* pointer to memory block, used for buffer*/
- void *free_start;
- void *free_end; /* pointer to next free byte in memory block*/
-
- uint16_t bufsize; /* size of memory block */
- uint16_t bufleft; /* left buffer space */
-
-} PXE_BUFFER;
-
/* socket*/
typedef struct pxe_socket {
PXE_BUFFER send_buffer;
@@ -58,11 +50,11 @@
/* shows socket usage statistics */
void pxe_sock_stats();
/* returns available space in recv buffer of socket */
-int pxe_sock_bufspace(int socket);
+/* int pxe_sock_bufspace(int socket); */
/* places data to buffer */
-int pxe_sock_place(int socket, void* data, uint16_t size);
+/* int pxe_sock_place(int socket, void* data, uint16_t size); */
/* removes data from buffer */
-int pxe_sock_rewind(int socket, uint16_t size);
+/* int pxe_sock_rewind(int socket, uint16_t size); */
/* removes int socket by pointer to PXE_SOCKET
* TODO: think about interfaces between pxe_filter and pxe_sock
*/
@@ -92,9 +84,16 @@
int pxe_recv(int socket, void *buf, size_t buflen);
/* create new socket */
int pxe_socket();
+/* binding */
+int pxe_bind(int socket, uint32_t ip, uint16_t port, uint8_t proto);
/* close socket */
int pxe_close(int socket);
/* returns next available local port */
uint16_t pxe_next_port();
+/*uint16_t pxe_buffer_write(PXE_BUFFER *buffer, const void* data, uint16_t size);
+uint16_t pxe_buffer_free(PXE_BUFFER *buffer, void* to, uint16_t size);
+uint16_t pxe_buffer_space(PXE_BUFFER *buffer);
+*/
+
#endif // PXE_SOCK_H_INCLUDED
==== //depot/projects/soc2007/taleks-pxe_http/pxe_udp.c#3 (text+ko) ====
@@ -50,20 +50,24 @@
if (buf_free < data_size)
return (0);
- int socket = pxe_sock_get(sock);
-
- if (socket == -1) { /* it must not ever be, but... */
-
- printf("pxe_udp_callback(): internal error, sokcet = -1.\n");
- return (0);
- }
-
- if (0 > pxe_sock_place(socket, pack->data + sizeof(PXE_UDP_PACKET), data_size )) {
+ PXE_BUFFER* recv_buffer = &sock->recv_buffer;
+ PXE_UDP_DGRAM udp_dgram;
+
+ if (pxe_buffer_space(recv_buffer) < data_size + sizeof(PXE_UDP_DGRAM)) {
+ printf("pxe_udp_callback(): not enough space in recv buffer for socket %d\n", sock);
+ } else {
+ udp_dgram.magic = PXE_MAGIC_DGRAM;
+ udp_dgram.src_ip = from.ip;
+ udp_dgram.src_port = src_port;
+ udp_dgram.size = data_size;
- printf("pxe_udp_callback(): failed to received data for socket %d\n", sock);
+ /* NOTE: here is assuming that there is no other writings to buffer,
+ * so, to writes, place data sequentially in bufer.
+ */
+ pxe_buffer_write(recv_buffer, &udp_dgram, sizeof(PXE_UDP_DGRAM));
+ pxe_buffer_write(recv_buffer, pack->data + sizeof(PXE_UDP_PACKET), data_size );
}
-/* pxe_sock_stats(); */
return (0);
}
@@ -112,19 +116,28 @@
pseudo_hdr.length = udp_packet->udphdr.length;
/* adding pseudo header checksum to checksum of udp header with data
- * and made it complimentary
+ * and make it complimentary
*/
- udp_packet->udphdr.checksum =
- ~(
- ( (uint32_t)pxe_ip_checksum(&pseudo_hdr, sizeof(PXE_IP4_PSEUDO_HDR)) +
- pxe_ip_checksum(&udp_packet->udphdr, length)
- ) & 0x0000ffff
- );
+
+ uint16_t part1 = pxe_ip_checksum(&pseudo_hdr, sizeof(PXE_IP4_PSEUDO_HDR));
+ uint16_t part2 = pxe_ip_checksum(&udp_packet->udphdr, length);
+
+ uint32_t tmp_sum = ((uint32_t)part1) + ((uint32_t)part2);
+ if (tmp_sum & 0xf0000) { /*need carry out */
+ tmp_sum -= 0xffff;
+ }
+
+ udp_packet->udphdr.checksum = ~((uint16_t)(tmp_sum & 0xffff));
+
+ /* special case */
+ if (udp_packet->udphdr.checksum == 0)
+ udp_packet->udphdr.checksum = 0xffff;
+
#ifdef PXE_DEBUG_HELL
printf("pxe_udp_send(): checksum 0x%4x for %d bytes\n", udp_packet->udphdr.checksum, length);
#endif
-/* if (!pxe_ip_send(udp_packet, dst_ip, PXE_UDP_PROTOCOL, size + sizeof(PXE_UDP_PACKET), 1)) {*/
+
if (!pxe_ip_send(udp_packet, dst_ip, PXE_UDP_PROTOCOL, length + sizeof(PXE_IP_HDR), 1)) {
printf("pxe_udp_send(): failed to send udp packet to 0x%x\n", dst_ip);
==== //depot/projects/soc2007/taleks-pxe_http/pxe_udp.h#2 (text+ko) ====
@@ -44,11 +44,7 @@
uint32_t magic; /* magic for debug purposes */
uint32_t src_ip; /* ip of dgram sender */
- uint32_t dst_ip; /* destination ip */
uint16_t src_port; /* source port */
- uint16_t dst_port; /* destination port */
-
- uint16_t prev_off; /* offset to previous pxe_udp_dgram */
uint16_t size; /* size of datagram */
} PXE_UDP_DGRAM;
More information about the p4-projects
mailing list