PERFORCE change 120673 for review
Alexey Tarasov
taleks at FreeBSD.org
Thu May 31 16:09:02 UTC 2007
http://perforce.freebsd.org/chv.cgi?CH=120673
Change 120673 by taleks at 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 <bsd.lib.mk>
==== //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 <stdint.h>
#include <stddef.h>
+#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
More information about the p4-projects
mailing list