phunix/minix/net/lwip/ipsock.h
David van Moolenbroek ef8d499e2d Add lwip: a new lwIP-based TCP/IP service
This commit adds a new TCP/IP service to MINIX 3.  As its core, the
service uses the lwIP TCP/IP stack for maintenance reasons.  The
service aims to be compatible with NetBSD userland, including its
low-level network management utilities.  It also aims to support
modern features such as IPv6.  In summary, the new LWIP service has
support for the following main features:

- TCP, UDP, RAW sockets with mostly standard BSD API semantics;
- IPv6 support: host mode (complete) and router mode (partial);
- most of the standard BSD API socket options (SO_);
- all of the standard BSD API message flags (MSG_);
- the most used protocol-specific socket and control options;
- a default loopback interface and the ability to create one more;
- configuration-free ethernet interfaces and driver tracking;
- queuing and multiple concurrent requests to each ethernet driver;
- standard ioctl(2)-based BSD interface management;
- radix tree backed, destination-based routing;
- routing sockets for standard BSD route reporting and management;
- multicast traffic and multicast group membership tracking;
- Berkeley Packet Filter (BPF) devices;
- standard and custom sysctl(7) nodes for many internals;
- a slab allocation based, hybrid static/dynamic memory pool model.

Many of its modules come with fairly elaborate comments that cover
many aspects of what is going on.  The service is primarily a socket
driver built on top of the libsockdriver library, but for BPF devices
it is at the same time also a character driver.

Change-Id: Ib0c02736234b21143915e5fcc0fda8fe408f046f
2017-04-30 13:16:03 +00:00

96 lines
4.1 KiB
C

#ifndef MINIX_NET_LWIP_IPSOCK_H
#define MINIX_NET_LWIP_IPSOCK_H
/* IP-level socket, shared by TCP, UDP, and RAW. */
struct ipsock {
struct sock ip_sock; /* socket object, MUST be first */
unsigned int ip_flags; /* all socket flags */
size_t ip_sndbuf; /* send buffer size */
size_t ip_rcvbuf; /* receive buffer size */
};
/*
* Socket flags. In order to reduce memory consumption, all these flags are
* stored in the same field (ipsock.ip_flags) and thus must not overlap between
* the same users of the field, and that is why they are all here. For
* example, UDPF/PKTF/IPF should all be unique, and TCPF/IPF should be unique,
* but UDPF/PKTF may overlap with TCPF and UDPF may overlap with RAWF. In
* practice, we have no UDPF or RAWF flags and plenty of space to make all
* flags unique anyway.
*/
#define IPF_IPV6 0x0000001 /* socket is IPv6 */
#define IPF_V6ONLY 0x0000002 /* socket is IPv6 only */
#define PKTF_RECVINFO 0x0000010 /* receive ancillary PKTINFO */
#define PKTF_RECVTTL 0x0000020 /* receive ancillary TTL */
#define PKTF_RECVTOS 0x0000040 /* receive ancillary TOS */
#define PKTF_MCAWARE 0x0000080 /* owner is multicast aware */
#define TCPF_CONNECTING 0x0001000 /* attempting to connect */
#define TCPF_SENT_FIN 0x0002000 /* send FIN when possible */
#define TCPF_RCVD_FIN 0x0004000 /* received FIN from peer */
#define TCPF_FULL 0x0008000 /* PCB send buffer is full */
#define TCPF_OOM 0x0010000 /* memory allocation failed */
#define ipsock_get_sock(ip) (&(ip)->ip_sock)
#define ipsock_is_ipv6(ip) ((ip)->ip_flags & IPF_IPV6)
#define ipsock_is_v6only(ip) ((ip)->ip_flags & IPF_V6ONLY)
#define ipsock_get_flags(ip) ((ip)->ip_flags)
#define ipsock_get_flag(ip,fl) ((ip)->ip_flags & (fl))
#define ipsock_set_flag(ip,fl) ((ip)->ip_flags |= (fl))
#define ipsock_clear_flag(ip,fl) ((ip)->ip_flags &= ~(fl))
#define ipsock_get_sndbuf(ip) ((ip)->ip_sndbuf)
#define ipsock_get_rcvbuf(ip) ((ip)->ip_rcvbuf)
/*
* IP-level option pointers. This is necessary because even though lwIP's
* TCP, UDP, and RAW PCBs share the same initial fields, the C standard does
* not permit generic access to such initial fields (due to both possible
* padding differences and strict-aliasing rules). The fields in this
* structure are therefore pointers to the initial fields of each of the PCB
* structures. If lwIP ever groups its IP PCB fields into a single structure
* and uses that structure as first field of each of the other PCBs, then we
* will be able to replace this structure with a pointer to the IP PCB instead.
* For convenience we also carry the send and receive buffer limits here.
*/
struct ipopts {
ip_addr_t *local_ip;
ip_addr_t *remote_ip;
uint8_t *tos;
uint8_t *ttl;
size_t sndmin;
size_t sndmax;
size_t rcvmin;
size_t rcvmax;
};
struct ifdev;
void ipsock_init(void);
int ipsock_socket(struct ipsock * ip, int domain, size_t sndbuf, size_t rcvbuf,
struct sock ** sockp);
void ipsock_clone(struct ipsock * ip, struct ipsock * newip, sockid_t newid);
void ipsock_get_any_addr(struct ipsock * ip, ip_addr_t * ipaddr);
int ipsock_check_src_addr(struct ipsock * ip, ip_addr_t * ipaddr,
int allow_mcast, struct ifdev ** ifdevp);
int ipsock_get_src_addr(struct ipsock * ip, const struct sockaddr * addr,
socklen_t addr_len, endpoint_t user_endpt, ip_addr_t * local_ip,
uint16_t local_port, int allow_mcast, ip_addr_t * ipaddr,
uint16_t * portp);
int ipsock_get_dst_addr(struct ipsock * ip, const struct sockaddr * addr,
socklen_t addr_len, const ip_addr_t * local_addr, ip_addr_t * dst_addr,
uint16_t * dst_port);
void ipsock_put_addr(struct ipsock * ip, struct sockaddr * addr,
socklen_t * addr_len, ip_addr_t * ipaddr, uint16_t port);
int ipsock_setsockopt(struct ipsock * ip, int level, int name,
const struct sockdriver_data * data, socklen_t len,
struct ipopts * ipopts);
int ipsock_getsockopt(struct ipsock * ip, int level, int name,
const struct sockdriver_data * data, socklen_t * len,
struct ipopts * ipopts);
void ipsock_get_info(struct kinfo_pcb * ki, const ip_addr_t * local_ip,
uint16_t local_port, const ip_addr_t * remote_ip,
uint16_t remote_port);
#endif /* !MINIX_NET_LWIP_IPSOCK_H */