From owner-p4-projects@FreeBSD.ORG Fri Jun 8 16:34:15 2007 Return-Path: X-Original-To: p4-projects@freebsd.org Delivered-To: p4-projects@freebsd.org Received: by hub.freebsd.org (Postfix, from userid 32767) id 99B0516A421; Fri, 8 Jun 2007 16:34:15 +0000 (UTC) X-Original-To: perforce@FreeBSD.org Delivered-To: perforce@FreeBSD.org Received: from mx1.freebsd.org (mx1.freebsd.org [69.147.83.52]) by hub.freebsd.org (Postfix) with ESMTP id 2A7D316A46D for ; Fri, 8 Jun 2007 16:34:15 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (repoman.freebsd.org [69.147.83.41]) by mx1.freebsd.org (Postfix) with ESMTP id 1B31E13C44B for ; Fri, 8 Jun 2007 16:34:15 +0000 (UTC) (envelope-from taleks@FreeBSD.org) Received: from repoman.freebsd.org (localhost [127.0.0.1]) by repoman.freebsd.org (8.13.8/8.13.8) with ESMTP id l58GYFfg084679 for ; Fri, 8 Jun 2007 16:34:15 GMT (envelope-from taleks@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l58GYEUe084667 for perforce@freebsd.org; Fri, 8 Jun 2007 16:34:14 GMT (envelope-from taleks@FreeBSD.org) Date: Fri, 8 Jun 2007 16:34:14 GMT Message-Id: <200706081634.l58GYEUe084667@repoman.freebsd.org> X-Authentication-Warning: repoman.freebsd.org: perforce set sender to taleks@FreeBSD.org using -f From: Alexey Tarasov To: Perforce Change Reviews Cc: Subject: PERFORCE change 121227 for review X-BeenThere: p4-projects@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: p4 projects tree changes List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Fri, 08 Jun 2007 16:34:15 -0000 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 #include +#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;