From owner-p4-projects@FreeBSD.ORG Thu May 31 16:09:02 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 E615C16A469; Thu, 31 May 2007 16:09:01 +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 AA65416A41F for ; Thu, 31 May 2007 16:09:01 +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 9CC6913C458 for ; Thu, 31 May 2007 16:09:01 +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 l4VG91BQ012758 for ; Thu, 31 May 2007 16:09:01 GMT (envelope-from taleks@FreeBSD.org) Received: (from perforce@localhost) by repoman.freebsd.org (8.13.8/8.13.8/Submit) id l4VG91VX012741 for perforce@freebsd.org; Thu, 31 May 2007 16:09:01 GMT (envelope-from taleks@FreeBSD.org) Date: Thu, 31 May 2007 16:09:01 GMT Message-Id: <200705311609.l4VG91VX012741@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 120673 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: Thu, 31 May 2007 16:09:02 -0000 http://perforce.freebsd.org/chv.cgi?CH=120673 Change 120673 by taleks@taleks_th on 2007/05/31 16:08:23 Started adding of UDP, sockets and DNS resolving. Most of functions are stubs. Added pxe_filter module to make filtration of incoming packets and serves as ip/port data storage for sockets. pxe_udp module - handles UDP protocol. pxe_dns - DNS resolving module. Updated pxe_arp with stats getting function. pxe_sock module now has only send/recv buffer related information, all ip/port data went to pxe_filter. Affected files ... .. //depot/projects/soc2007/taleks-pxe_http/Makefile#4 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#5 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#5 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#11 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#9 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_dns.c#1 add .. //depot/projects/soc2007/taleks-pxe_http/pxe_dns.h#1 add .. //depot/projects/soc2007/taleks-pxe_http/pxe_filter.c#1 add .. //depot/projects/soc2007/taleks-pxe_http/pxe_filter.h#1 add .. //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.c#7 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.h#6 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#4 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#4 edit .. //depot/projects/soc2007/taleks-pxe_http/pxe_udp.c#1 add .. //depot/projects/soc2007/taleks-pxe_http/pxe_udp.h#1 add Differences ... ==== //depot/projects/soc2007/taleks-pxe_http/Makefile#4 (text+ko) ==== @@ -4,7 +4,7 @@ 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_core.c pxe_icmp.c pxe_mem.c pxe_udp.c pxe_filter.c pxe_dns.c CFLAGS+= -I${.CURDIR}/../../common -I${.CURDIR}/../btx/lib \ -I${.CURDIR}/../../../contrib/dev/acpica \ @@ -13,7 +13,7 @@ CFLAGS+= -I${.CURDIR}/../../../../lib/libstand/ #debug flag -#CFLAGS+= -DPXE_DEBUG +CFLAGS+= -DPXE_DEBUG #CFLAGS+= -DPXE_DEBUG_HELL .include ==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.c#5 (text+ko) ==== @@ -73,6 +73,31 @@ return (NULL); } +void +pxe_arp_stats() +{ + int entry = 0; + int limit = (arp_usage > MAX_ARP_ENTRIES) ? MAX_ARP_ENTRIES : arp_usage; + + printf("ARP updates: %d\n", arp_usage); + + for (; entry < limit; ++entry) { + + PXE_IPADDR ip; + uint8_t *mac = arp_table[entry].mac; + ip.ip = arp_table[entry].ip4.ip; + + if ( (ip.ip == 0) || (mac == NULL) ) + continue; + + printf("%d.%d.%d.%d\t%2x:%2x:%2x:%2x:%2x:%2x\n", + ip.octet[0], ip.octet[1], ip.octet[2], ip.octet[3], + mac[0], mac[1], mac[2], mac[3], mac[4], mac[5] + ); + } + +} + /* * pxe_arp_protocol() - process received arp packet, this function is called in style * of pxe_protocol_call function type, but last two parameters are unused ==== //depot/projects/soc2007/taleks-pxe_http/pxe_arp.h#5 (text+ko) ==== @@ -33,9 +33,11 @@ /* initialisation routine */ void pxe_arp_init(); /* find MAC by provided ip */ -const MAC_ADDR* pxe_arp_ip4mac(uint32_t ip); +const MAC_ADDR *pxe_arp_ip4mac(uint32_t ip); /* protocol handler for received packets */ int pxe_arp_protocol(PXE_PACKET *pack, uint8_t function, void *data); +/* ARP table statistics */ +void pxe_arp_stats(); /* ARP packet types */ #define PXE_ARPOP_REQUEST 1 ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.c#11 (text+ko) ==== @@ -11,6 +11,7 @@ #include "pxe_isr.h" #include "pxe_mem.h" #include "pxe_mutex.h" +#include "pxe_udp.h" /* PXE API calls here will be made in same way as in pxeboot. * the only difference - installation of isr, that was not needed in pxe.c. @@ -25,7 +26,10 @@ static pxe_t *pxe = NULL; /* !PXE */ static BOOTPLAYER bootplayer; /* PXE Cached information. */ - +/* TODO: to think if packets queue must be in pxe_core. + * It seems, it'll be used only by TCP + */ + /* pxe core structures*/ PXE_PACKET core_packets[PXE_MAX_PACKETS]; /* buffered packets */ pxe_protocol_call core_protocol[256]; /* protocol's callback fuctions */ @@ -34,6 +38,7 @@ /* NIC info */ PXE_IPADDR nic_ip = {0}; MAC_ADDR nic_mac; /* may be init it also by zero? */ +PXE_IPADDR ns_ip = {0};/* nameserver addr */ /* core packet statistics */ uint32_t packets_dropped = 0; @@ -305,11 +310,18 @@ printf("my ip: %d.%d.%d.%d\n", nic_ip.octet[0], nic_ip.octet[1], nic_ip.octet[2], nic_ip.octet[3]); /* my MAC */ pxe_memcpy(&bootplayer.CAddr, &nic_mac, MAC_ADDR_LEN); - 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("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]); + ns_ip.ip = 0x0100a8c0; /* TODO: to determiny nameserver ip*/ + pxe_arp_init(); + pxe_filter_init(); + pxe_socket_init(); pxe_icmp_init(); + pxe_udp_init(); + pxe_ip_route_init(0x0100a8c0); /* NOTE: setting default route 192.168.0.1 * need to determiny gateway by getting info drom DHCP packets, * but cached packets for some resons have no gip set. So, @@ -349,11 +361,9 @@ #ifdef PXE_DEBUG printf("pxe_core_install_isr() info:\n"); - printf("IRQ (int): %d (%d)\n", undi_info->IntNumber, int_num); - printf("Base io: %d\n", undi_info->BaseIo); - printf("MTU: %d\n", undi_info->MaxTranUnit); - printf("RX buffer queue: %d\n", undi_info->RxBufCt); - printf("TX buffer queue: %d\n", undi_info->TxBufCt); + printf("\tIRQ (int): %d (%d)\n", undi_info->IntNumber, int_num); + printf("\tMTU: %d\n", undi_info->MaxTranUnit); + printf("\tRX/TX buffer queue: %d/%d\n", undi_info->RxBufCt, undi_info->TxBufCt); #endif __pxe_entry_seg2 = pxe->EntryPointSP.segment; __pxe_entry_off2 = pxe->EntryPointSP.offset; @@ -368,7 +378,7 @@ v86int(); v86.ctl = V86_FLAGS; - printf("chained handler @ 0x%x:0x%x (0x%x/0x%x:0x%x)\n", v86.ebx, v86.edx, v86.ecx, VTOPSEG(__chained_irq_off), VTOPOFF(__chained_irq_off)); + printf("\tchained handler @ 0x%x:0x%x\n", v86.ebx, v86.edx); /* v86.ctl = V86_ADDR | V86_CALLF | V86_FLAGS; v86.addr = (VTOPSEG(__mask_irq) << 16) | VTOPOFF(__mask_irq); @@ -788,7 +798,7 @@ if (protocol == PXE_PROTOCOL_ARP) { - pxe_arp_protocol(&dummy_pack, PXE_CORE_FRAG, NULL); + pxe_arp_protocol(&dummy_pack, PXE_CORE_HANDLE, NULL); ++processed_packets; /* aasume ARP packet always in one fragment */ @@ -802,7 +812,7 @@ if ( (!core_protocol[iphdr->protocol]) || (!core_protocol[iphdr->protocol](&dummy_pack, - PXE_CORE_FRAG, NULL)) ) { + (buffer_size == frame_size) ? PXE_CORE_HANDLE : PXE_CORE_FRAG, NULL)) ) { drop_flag = 1; } else { @@ -1012,6 +1022,13 @@ return nic_ip.ip; } +uint32_t +pxe_get_nsip32() +{ + + return ns_ip.ip; +} + const MAC_ADDR* pxe_get_mymac() { ==== //depot/projects/soc2007/taleks-pxe_http/pxe_core.h#9 (text+ko) ==== @@ -116,4 +116,7 @@ /* returns NIC MAC */ const MAC_ADDR *pxe_get_mymac(); +/* returns nameserver ip */ +uint32_t pxe_get_nsip32(); + #endif // PXE_CORE_H_INCLUDED ==== //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.c#7 (text+ko) ==== @@ -112,7 +112,7 @@ reply_icmphdr->checksum = ~pxe_ip_checksum(reply_icmphdr, sizeof(PXE_ICMP_HDR) + data_size); - if (!pxe_ip_send(pack->data, iphdr->src_ip, 0x01, pack->data_size, 1) && echo_flags) { + if (!pxe_ip_send(pack->data, iphdr->src_ip, PXE_ICMP_PROTOCOL, pack->data_size, 1) && echo_flags) { printf("pxe_ping(): failed to send echo reply.\n"); } @@ -127,8 +127,7 @@ { /* register protocol in pxe_core protocols table. */ - /* 0x01 - ICMP protocol */ - pxe_core_register(0x01, pxe_icmp_callback); + pxe_core_register(PXE_ICMP_PROTOCOL, pxe_icmp_callback); return (1); } @@ -174,7 +173,7 @@ icmphdr->checksum = ~(pxe_ip_checksum(icmphdr, sizeof(PXE_ICMP_HDR) + 32)); - if (!pxe_ip_send(data, ip->ip, 0x01, pack_size, 1) && echo_flags) { + if (!pxe_ip_send(data, ip->ip, PXE_ICMP_PROTOCOL, pack_size, 1) && echo_flags) { printf("pxe_ping(): failed to send echo reply.\n"); } ==== //depot/projects/soc2007/taleks-pxe_http/pxe_icmp.h#6 (text+ko) ==== @@ -9,6 +9,7 @@ * reference: RFC792 */ +#define PXE_ICMP_PROTOCOL 0x01 /* ICMP header */ typedef struct pxe_icmp_hdr { uint8_t type; /* type of ICMP packet */ @@ -20,14 +21,16 @@ /* timeout in milliseconds */ #define PXE_ICMP_TIMEOUT 5000 + /* pxe_ping - send icmp echo request packets to host * in: * ip - host ip address * count - packets to send, 0 - to send infinte count + * flags - 1 echo ping information to screen * out: * successfull recieved echo's count */ -int pxe_ping(PXE_IPADDR *ip, int count); +int pxe_ping(PXE_IPADDR *ip, int count, int flags); /* pxe_icmp_init - inits icmp protocol * in: ==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.c#4 (text+ko) ==== @@ -1,81 +1,377 @@ #include "pxe_mem.h" +#include "pxe_filter.h" #include "pxe_sock.h" -#include "pxe_tcp.h" +#include "pxe_udp.h" +static PXE_SOCKET pxe_sockets[PXE_DEFAULT_SOCKETS]; +static uint16_t avail_port = 1025; -PXE_SOCKET pxe_sockets[PXE_DEFAULT_SOCKETS]; - -int -pxe_sockets_init() +void +pxe_socket_init() { pxe_memset(pxe_sockets, 0, sizeof(pxe_sockets)); - - return (1); } int -pxe_tcp_socket() +pxe_socket_alloc() { int sock_index = 0; /* searching free sockets */ for (; sock_index < PXE_DEFAULT_SOCKETS; ++sock_index) { - if (pxe_sockets[sock_index].state == PXE_TCP_CLOSED) { + if (pxe_sockets[sock_index].state == PXE_SOCKET_FREE) { /* found free socket */ - pxe_sockets[sock_index].state = PXE_TCP_MARK; + pxe_memset(&pxe_sockets[sock_index], 0, sizeof(PXE_SOCKET)); + pxe_sockets[sock_index].state = PXE_SOCKET_USED; return sock_index; } } return (-1); /* no socket found :( */ } -/* + +int +pxe_socket_free(int socket) +{ + PXE_SOCKET *sock = &pxe_sockets[socket]; + + sock->state = PXE_SOCKET_FREE; + + if (sock->filter) { + pxe_filter_remove(sock->filter); + sock->filter = NULL; + } + + return (1); +} + + +int +pxe_socket() +{ + int socket = pxe_socket_alloc(); + + /* allocating structure */ + if (socket == -1) + return (-1); + + /* creating buffers */ + PXE_SOCKET *sock = &pxe_sockets[socket]; + + sock->send_buffer.data = pxe_alloc(PXE_DEFAULT_SEND_BUFSIZE); + + if (sock->send_buffer.data == NULL) { + + pxe_socket_free(socket); + return (-1); + } + + sock->send_buffer.bufsize = PXE_DEFAULT_SEND_BUFSIZE; + sock->send_buffer.bufleft = PXE_DEFAULT_SEND_BUFSIZE; + sock->send_buffer.next_data = sock->send_buffer.data; + + sock->recv_buffer.data = pxe_alloc(PXE_DEFAULT_RECV_BUFSIZE); + + if (sock->recv_buffer.data == NULL) { + + pxe_free(sock->send_buffer.data); + pxe_socket_free(socket); + return (-1); + } + + sock->recv_buffer.bufsize = PXE_DEFAULT_RECV_BUFSIZE; + sock->recv_buffer.bufleft = PXE_DEFAULT_RECV_BUFSIZE; + sock->recv_buffer.next_data = sock->recv_buffer.data; + + return (socket); +} + int -pxe_connect(int socket, uint32_t ip, uint16_t port) +pxe_close(int socket) { - int result = pxe_tcp_send_packet(pxe_sockets[socket], NULL, 0, - PXE_TCP_SYN); - if (result == 0) { + if (socket > PXE_DEFAULT_SOCKETS) { return (0); } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + + pxe_free(sock->send_buffer.data); + pxe_free(sock->recv_buffer.data); + + return pxe_socket_free(socket); +} - pxe_sockets[socket].state = PXE_TCP_SYN_SENT; - return (1); +int +pxe_listen(int socket, uint8_t proto, uint16_t port) +{ +#ifdef PXE_DEBUG + printf("pxe_listen(): proto 0x%x, port: %d.\n", proto, port); +#endif - pxe_tcp_recv_packet(pxe_sockets[socket], NULL, 0, - PXE_TCP_SYN | PXE_TCP_ACK); - pxe_tcp_send_packet(pxe_sockets[socket], NULL, 0, PXE_TCP_ACK); + PXE_FILTER_ENTRY *filter = pxe_filter_add(0, 0, pxe_get_myip32(), port, &pxe_sockets[socket], proto); + + if (filter == NULL) { + printf("pxe_listen(): failed to add filter.\n"); + return (-1); + } + + pxe_filter_mask(filter, 0, 0, 0xffffffff, 0xffff); + + pxe_sockets[socket].filter = filter; + + if (proto == PXE_UDP_PROTOCOL) { /* for UDP it's fake listen */ + return (socket); + } + + while (pxe_sockets[socket].waiting == 0) { +#ifdef PXE_DEBUG + twiddle(); +#endif + if (!pxe_core_recv_packets()) { + delay(100000); + } + } + + return (0); } int -pxe_send(int socket, void *buf, size_t buflen) +pxe_accept(int socket) +{ + + if (socket > PXE_DEFAULT_SOCKETS) { + return (-1); + } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + + if (sock->waiting == 0) + return (-1); + + int back = sock->waiting; + + PXE_FILTER_ENTRY *entry = sock->filter; + + for ( ; back != 0; --back) { + + /* filter childs are earlier */ + entry = entry->prev; + + if (entry == NULL) { +#ifdef PXE_DEBUG + printf("pxe_accept(): corrupted waiting count.\n"); +#endif + return (-1); + } + } + + int accepted_socket = pxe_socket(); + + if (accepted_socket == -1) + return (-1); + + /* decreasing waiting queue */ + --sock->waiting; + + sock = &pxe_sockets[accepted_socket]; + + sock->filter = entry; + entry->socket = sock; + + return (accepted_socket); +} + +void +pxe_sock_stats() { + int socket = 0; + PXE_SOCKET* sock = pxe_sockets; + + for ( ; socket < PXE_DEFAULT_SOCKETS; ++socket, ++sock) { + + if (sock->state == PXE_SOCKET_FREE) + continue; + + printf("%d: filter 0x%x, recv/send: %d/%d, waiting: %d.\n ", + socket, sock->filter, sock->recv, sock->sent, sock->waiting + ); + } +} - if (!pxe_tcp_pack(socket, buf, buflen)) { - pxe_flush(socket); - pxe_tcp_pack(socket, buf, buflen); +int +pxe_sock_bufspace(int socket) +{ + if (socket > PXE_DEFAULT_SOCKETS) { + return (-1); } + + return pxe_sockets[socket].recv_buffer.bufleft; } int -pxe_recv(int socket, void *buf, size_t buflen) +pxe_sock_place(int socket, void* data, uint16_t size) { - PXE_SOCKET *sock = &pxe_sockets[socket]; +#ifdef PXE_DEBUG_HELL + printf("pxe_sock_place(): sock: %d, data: 0x%x, size: %d\n", socket, data, size); +#endif + if (socket > PXE_DEFAULT_SOCKETS) { + return (-1); + } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + uint16_t copy_size = size; + + /* there is no enogh space available in recv buffer + * try as much as possible. + */ + if (sock->recv_buffer.bufleft < size) { + + copy_size = sock->recv_buffer.bufleft; + + if (copy_size == 0) + return (0); + } + + pxe_memcpy(data, sock->recv_buffer.next_data, copy_size); + + sock->recv_buffer.next_data += copy_size; + sock->recv_buffer.bufleft -= copy_size; + + return (copy_size); +} - if (sock->sendbuffer.leftbuf < buflen) { +int +pxe_sock_rewind(int socket, uint16_t size) +{ + if (socket > PXE_DEFAULT_SOCKETS) { + return (-1); } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + + uint16_t rew_bytes = sock->recv_buffer.next_data - 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.next_data -= rew_bytes; + sock->recv_buffer.bufleft += rew_bytes; + + return (rew_bytes); +} + +/* out: + * 0 - no free port + * >0 - port number + */ +uint16_t +pxe_next_port() +{ /* dummy, TODO: check filters, if port used */ + + if (avail_port == 40000) + avail_port = 1025; + + return (avail_port++); } -*/ +/* NOTE: now assuming that only UDP is implemented */ int -pxe_close(int socket) +pxe_sendto(int socket, uint32_t ip, uint16_t port, void *data, uint16_t size) { - pxe_sockets[socket].state = PXE_TCP_CLOSED; +#ifdef PXE_DEBUG + printf("pxe_sendto(): ip:port = %8x:%d, size = %d bytes.\n", ip, port, size); +#endif + if (size + sizeof(PXE_UDP_PACKET) > PXE_DEFAULT_SEND_BUFSIZE) { + printf("pxe_sendto(): send buffer too small for %d bytes.\n", size); + return (-1); + } + + if (!pxe_connect(socket, ip, port, PXE_UDP_PROTOCOL)) { + printf("pxe_sendto(): failed to connect.\n"); + return (-1); + } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + + /* for UDP socket, send buffer used only for one dgram */ + PXE_UDP_PACKET *udp_pack = (PXE_UDP_PACKET *)sock->send_buffer.data; + + /* 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. + */ + uint16_t lport = filter->dst_port; + + if (!pxe_udp_send(udp_pack, ip, port, lport, size + sizeof(PXE_UDP_PACKET), 1)) { + printf("pxe_sendto(): failed to send data.\n"); + return (-1); + } + + return (size); +} + + + +int +pxe_connect(int socket, uint32_t ip, uint16_t port, uint8_t proto) +{ + if (socket > PXE_DEFAULT_SOCKETS) { + return (0); + } + + PXE_SOCKET *sock = &pxe_sockets[socket]; + + /* socket was already initalized */ + if (sock->filter != NULL) { + + pxe_filter_remove(sock->filter); + sock->filter = NULL; /* just to be sure... */ + } + + uint16_t lport = pxe_next_port(); /* getting free local port */ + + if (port == 0) { + printf("pxe_connect(): failed to allocate local port.\n"); + return (0); + } + + PXE_FILTER_ENTRY *entry = + pxe_filter_add( ip, port, pxe_get_myip32(), lport, sock, proto); + + + if ( entry == NULL ) { + printf("pxe_connect(): failed to add filter.\n"); + return (0); + } + + /* all is ok */ return (1); } + + +int +pxe_send(int socket, void *buf, size_t buflen) +{ + + return (0); +} + +int +pxe_recv(int socket, void *buf, size_t buflen) +{ + + return (0); +} + + ==== //depot/projects/soc2007/taleks-pxe_http/pxe_sock.h#4 (text+ko) ==== @@ -4,50 +4,90 @@ #include #include +#include "pxe_filter.h" #include "pxe_ip.h" - /* buffer size choosed by default for sending/recieving*/ -#define PXE_DEFAULT_RECV_BUFSIZE 16384 -#define PXE_DEFAULT_SEND_BUFSIZE 2048 +#define PXE_DEFAULT_RECV_BUFSIZE 8192 +#define PXE_DEFAULT_SEND_BUFSIZE 2048 /* minimal and max packet sizes to optimize tcp usage*/ -#define PXE_MIN_SEND_PACKET_SIZE 512 -#define PXE_MTU 1500 -/* dwfault count of sockets used at the same time */ -#define PXE_DEFAULT_SOCKETS 2 +#define PXE_MIN_SEND_PACKET_SIZE 512 +#define PXE_MTU 1500 +/* default count of sockets used at the same time */ +#define PXE_DEFAULT_SOCKETS 8 +/* default count of waiting queue */ +#define PXE_DEFAULT_WAITCOUNT 3 +/* socket states */ +#define PXE_SOCKET_FREE 0x0 +#define PXE_SOCKET_USED 0x1 /* pxe_buffer - buffer related information */ typedef struct pxe_buffer { - void *data; /* pointer to memory block, used for buffer*/ - uint32_t bufsize; /* size of memory block */ + void *data; /* pointer to memory block, used for buffer*/ + uint32_t bufsize; /* size of memory block */ - void *next_data; /* pointer to next free byte in memory block*/ - uint32_t bufleft; /* left buffer space */ + void *next_data; /* pointer to next free byte in memory block*/ + uint32_t bufleft; /* left buffer space */ } PXE_BUFFER; +/* socket*/ typedef struct pxe_socket { - PXE_BUFFER send_buffer; - PXE_BUFFER recv_buffer; + PXE_BUFFER send_buffer; + PXE_BUFFER recv_buffer; - uint32_t sent; - uint32_t recv; - uint8_t state; + /* transmit and status counters*/ + uint32_t sent; + uint32_t recv; + uint8_t state; + uint8_t waiting; /* number of connections waiting to accept */ - PXE_IPADDR local_ip; - uint16_t local_port; + /* for resending usage */ + uint32_t last_time_sent; + uint32_t last_time_recv; + PXE_FILTER_ENTRY *filter; /* filter, that feeds data to this socket */ +} PXE_SOCKET; - PXE_IPADDR remote_ip; - uint16_t remote_port; +/* inits this module */ +void pxe_sock_init(); +/* allocates pxe_socket structure */ +int pxe_socket_alloc(); +/* frees socket structure */ +int pxe_socket_free(int socket); +/* shows socket usage statistics */ +void pxe_sock_stats(); +/* returns available space in recv buffer of socket */ +int pxe_sock_bufspace(int socket); +/* places data to buffer */ +int pxe_sock_place(int socket, void* data, uint16_t size); +/* removes data from buffer */ +int pxe_sock_rewind(int socket, uint16_t size); - uint32_t last_time_sent; - uint32_t last_time_recv; +/* pxe_listen() - creates "listening" socket + * it's not the same as normal listen() system call. + * Every pxe_listen() call creates pxe_socket structure + * and adds filter to filter table. + * WARN: + * -1 - means failed + * >= 0 - socket for UDP + * == 0 - success for TCP + */ +int pxe_listen(int socket, uint8_t proto, uint16_t port); +/* accept awaiting connections */ +int pxe_accept(int socket); +/* send to provided ip/port, updating filter for socket */ +int pxe_sendto(int socket, uint32_t ip, uint16_t port, void *data, uint16_t size); +int pxe_connect(int socket, uint32_t ip, uint16_t port, uint8_t proto); -} PXE_SOCKET; +/* int pxe_listen_from(int socket, uint8_t proto, uint16_t port, uint32_t src_ip, uint16_t port, int block); */ -int pxe_sockets_init(); -int pxe_tcp_socket(); -int pxe_connect(int socket, uint32_t ip, uint16_t port); +/* send data to socket, blocking */ int pxe_send(int socket, void *buf, size_t buflen); +/* receive data from socket, blocking */ int pxe_recv(int socket, void *buf, size_t buflen); +/* create new socket */ +int pxe_socket(); +/* close socket */ int pxe_close(int socket); +/* returns next available local port */ +uint16_t pxe_next_port(); #endif // PXE_SOCK_H_INCLUDED