Skip site navigation (1)Skip section navigation (2)
Date:      Fri, 8 Jun 2007 16:34:14 GMT
From:      Alexey Tarasov <taleks@FreeBSD.org>
To:        Perforce Change Reviews <perforce@FreeBSD.org>
Subject:   PERFORCE change 121227 for review
Message-ID:  <200706081634.l58GYEUe084667@repoman.freebsd.org>

next in thread | raw e-mail | index | archive | help
http://perforce.freebsd.org/chv.cgi?CH=121227

Change 121227 by taleks@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;



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200706081634.l58GYEUe084667>