AquilaOS documentation
How it works, and its code
Loading...
Searching...
No Matches
inet.h File Reference
#include <core/system.h>
#include <net/netbuf.h>
#include <net/netif.h>
#include <aquila/socket.h>

Go to the source code of this file.

Data Structures

struct  ether_hdr
 An Ethernet frame's header. More...
struct  arp_hdr
 An ARP packet, for IPv4 over Ethernet. More...
struct  ipv4_hdr
 An IPv4 packet's header. More...
struct  icmp_hdr
 An ICMP message's header. More...
struct  udp_hdr
 A UDP datagram's header. More...

Macros

#define ETHER_TYPE_IPV4   0x0800
#define ETHER_TYPE_ARP   0x0806
#define IP_PROTO_ICMP   1
#define IP_PROTO_TCP   6
#define IP_PROTO_UDP   17
#define ICMP_ECHO_REPLY   0
#define ICMP_UNREACH   3
#define ICMP_ECHO_REQUEST   8
#define ICMP_UNREACH_HOST   1
#define ICMP_UNREACH_PORT   3

Functions

uint16_t inet_checksum (const void *data, size_t len)
 Computes the Internet checksum (RFC 1071): the ones' complement of the ones' complement sum of the data's 16-bit words.
uint16_t inet_checksum_pseudo (uint32_t src, uint32_t dst, uint8_t proto, const void *data, size_t len)
 Computes the Internet checksum of data with the IPv4 pseudo-header before it (the addresses, the protocol and the length), as UDP and TCP do.
void ether_input (struct netif *netif, struct netbuf *nb)
 Takes in a frame that an interface received, and passes it to ARP or IPv4.
int ether_output (struct netif *netif, const uint8_t dst[6], uint16_t type, struct netbuf *nb)
 Sends a frame: adds its Ethernet header and gives it to the interface.
void arp_input (struct netif *netif, struct netbuf *nb)
 Takes in an ARP packet: the sender's address is recorded, and a request for our address is answered.
void arp_update (struct netif *netif, uint32_t ip, const uint8_t mac[6])
 Records an address's hardware address, replacing the oldest entry if the table is full, and sends the packets that waited for it.
int arp_lookup (struct netif *netif, uint32_t ip, uint8_t mac[6])
 Looks up an address's hardware address.
int arp_resolve (struct netif *netif, uint32_t ip, struct netbuf *nb)
 Holds a packet until the hardware address of its next hop is known, and asks for it.
void ipv4_input (struct netif *netif, struct netbuf *nb, const uint8_t src_mac[6])
 Takes in an IPv4 packet that an interface received, and passes it to its protocol.
int ipv4_output (struct netif *netif, uint32_t src, uint32_t dst, uint8_t proto, struct netbuf *nb)
 Sends a packet through an interface: adds its IPv4 header and sends it to dst, or to the gateway if dst isn't on the link, once ARP knows the hardware address.
uint32_t ipv4_source (struct netif *netif, uint32_t dst)
 Chooses the source address of a packet to dst sent through netif.
int ipv4_send (uint32_t dst, uint8_t proto, struct netbuf *nb)
 Sends a packet to dst, through the interface its route says.
struct netif * ipv4_route (uint32_t dst)
 Chooses the interface to send a packet to dst through: the one whose link it is on, or else the first one with a gateway.
int ipv4_is_local (uint32_t ip)
 Says whether an address is one of ours: a loopback address, or an interface's.
void icmp_input (struct netif *netif, struct netbuf *nb, uint32_t src, uint32_t dst)
 Takes in an ICMP message that IPv4 received.
void icmp_unreachable (struct netif *netif, const struct ipv4_hdr *ih, int code)
 Tells the sender of a datagram that it couldn't get where it was sent.
void udp_input (struct netif *netif, struct netbuf *nb, const struct ipv4_hdr *ih)
 Takes in a UDP datagram that IPv4 received, and delivers it to its socket.
struct inet_sock * inet_sock_find (struct netif *netif, uint8_t proto, uint32_t local, uint16_t port, uint32_t remote, uint16_t remote_port)
 Finds the socket that a received datagram is for: a socket connected to its sender first, or else one that isn't connected.
void inet_sock_deliver (struct inet_sock *sock, struct netbuf *nb)
 Queues a received datagram on its socket, and wakes up its readers.
void inet_sock_error (struct inet_sock *sock, int err)
 Gives a socket an error (from ICMP), which its next call reports.
int inet_sockaddr_get (const struct sockaddr *addr, socklen_t len, uint32_t *ip, uint16_t *port)
 Reads an AF_INET address.
void inet_sockaddr_put (struct sockaddr *addr, socklen_t *len, uint32_t ip, uint16_t port)
 Writes an AF_INET address, cut to *len bytes if it doesn't fit.
int inet_ifioctl (int request, void *argp)
 Handles an interface ioctl() request on an AF_INET socket.

Macro Definition Documentation

◆ ETHER_TYPE_ARP

#define ETHER_TYPE_ARP   0x0806

Definition at line 18 of file inet.h.

Referenced by arp_input(), arp_request(), and ether_input().

◆ ETHER_TYPE_IPV4

#define ETHER_TYPE_IPV4   0x0800

Definition at line 17 of file inet.h.

Referenced by arp_input(), arp_request(), ether_input(), ipv4_output(), and pending_flush().

◆ ICMP_ECHO_REPLY

#define ICMP_ECHO_REPLY   0

Definition at line 60 of file inet.h.

Referenced by icmp_input().

◆ ICMP_ECHO_REQUEST

#define ICMP_ECHO_REQUEST   8

Definition at line 62 of file inet.h.

Referenced by icmp_input(), and socket_inet_send().

◆ ICMP_UNREACH

#define ICMP_UNREACH   3

Definition at line 61 of file inet.h.

Referenced by icmp_input(), and icmp_unreachable().

◆ ICMP_UNREACH_HOST

#define ICMP_UNREACH_HOST   1

Definition at line 64 of file inet.h.

◆ ICMP_UNREACH_PORT

#define ICMP_UNREACH_PORT   3

Definition at line 65 of file inet.h.

Referenced by icmp_unreachable_input(), and udp_input().

◆ IP_PROTO_ICMP

#define IP_PROTO_ICMP   1

Definition at line 41 of file inet.h.

Referenced by icmp_input(), icmp_unreachable(), inet_sock_find(), ipv4_input(), and socket_inet_create().

◆ IP_PROTO_TCP

#define IP_PROTO_TCP   6

Definition at line 42 of file inet.h.

Referenced by ipv4_input(), segment(), tcp_input(), and tcp_reply_rst().

◆ IP_PROTO_UDP

#define IP_PROTO_UDP   17

Function Documentation

◆ arp_input()

void arp_input ( struct netif * netif,
struct netbuf * nb )

Takes in an ARP packet: the sender's address is recorded, and a request for our address is answered.

Parameters
netifthe interface it came in on
nbthe packet; it is freed or turned into the reply

Definition at line 244 of file arp.c.

References arp_input(), arp_update(), netbuf::data, ether_output(), ETHER_TYPE_ARP, ETHER_TYPE_IPV4, arp_hdr::hlen, htons, arp_hdr::htype, netif::ip, netbuf::len, netif::mac, memcpy(), netbuf_free(), ntohs, arp_hdr::op, arp_hdr::plen, arp_hdr::ptype, arp_hdr::sha, arp_hdr::spa, netif::stats, arp_hdr::tha, and arp_hdr::tpa.

Referenced by arp_input(), and ether_input().

◆ arp_lookup()

int arp_lookup ( struct netif * netif,
uint32_t ip,
uint8_t mac[6] )

Looks up an address's hardware address.

An entry that has expired is dropped, so that the address is asked for again.

Parameters
netifthe interface
ipthe IPv4 address
macset to the hardware address, if it is known
Returns
0 if it is known, or -1

Definition at line 218 of file arp.c.

References arch_rtime_ms(), ARP_ENTRIES, ARP_EXPIRE, arp_lookup(), arp_entry::heard, arp_entry::ip, arp_entry::mac, memcpy(), arp_entry::netif, NULL, and table().

Referenced by arp_lookup(), and ipv4_output().

◆ arp_resolve()

int arp_resolve ( struct netif * netif,
uint32_t ip,
struct netbuf * nb )

Holds a packet until the hardware address of its next hop is known, and asks for it.

If too many packets wait for that address, the oldest is dropped. The netbuf is ARP's from now on.

Parameters
netifthe interface to send it on
ipthe next hop's address
nbthe IPv4 packet
Returns
0, or -ENOBUFS if too many addresses are being asked for already (the packet is dropped)

Definition at line 118 of file arp.c.

References ARP_HOLD, ARP_PENDING, arp_request(), arp_resolve(), arp_retry(), arp_pending::held, arp_pending::ip, memmove(), net_callout_set(), netbuf_free(), arp_pending::netif, arp_pending::nheld, NULL, pending, arp_pending::retry, netif::stats, and arp_pending::tries.

Referenced by arp_resolve(), and ipv4_output().

◆ arp_update()

void arp_update ( struct netif * netif,
uint32_t ip,
const uint8_t mac[6] )

Records an address's hardware address, replacing the oldest entry if the table is full, and sends the packets that waited for it.

Parameters
netifthe interface it was heard on
ipthe IPv4 address
macits hardware address

Definition at line 185 of file arp.c.

References arch_rtime_ms(), ARP_ENTRIES, arp_update(), clock, arp_entry::heard, arp_entry::ip, arp_entry::mac, memcpy(), arp_entry::netif, pending_flush(), table(), arp_entry::used, and used.

Referenced by arp_input(), arp_update(), and ipv4_input().

◆ ether_input()

void ether_input ( struct netif * netif,
struct netbuf * nb )

Takes in a frame that an interface received, and passes it to ARP or IPv4.

A frame of another type, or too short, is dropped.

Parameters
netifthe interface it came in on
nbthe frame; it is freed or passed on

Definition at line 21 of file ether.c.

References arp_input(), ether_input(), ETHER_TYPE_ARP, ETHER_TYPE_IPV4, ipv4_input(), netbuf_free(), netbuf_pull(), ntohs, ether_hdr::src, netif::stats, and ether_hdr::type.

Referenced by ether_input(), and net_main().

◆ ether_output()

int ether_output ( struct netif * netif,
const uint8_t dst[6],
uint16_t type,
struct netbuf * nb )

Sends a frame: adds its Ethernet header and gives it to the interface.

The netbuf is freed in every case.

Parameters
netifthe interface to send it on
dstthe destination MAC address
typethe frame's type (ETHER_TYPE_*)
nbthe frame's data, with room for the header before it
Returns
0, or a negative errno from the interface

Definition at line 54 of file ether.c.

References ether_hdr::dst, ether_output(), htons, netif::mac, memcpy(), netbuf_free(), netbuf_push(), netif_output(), ether_hdr::src, and ether_hdr::type.

Referenced by arp_input(), arp_request(), ether_output(), ipv4_output(), and pending_flush().

◆ icmp_input()

void icmp_input ( struct netif * netif,
struct netbuf * nb,
uint32_t src,
uint32_t dst )

Takes in an ICMP message that IPv4 received.

Parameters
netifthe interface it came in on
nbthe message, from its ICMP header; it is freed, sent back or delivered
srcthe sender's address
dstthe address it was sent to

Definition at line 50 of file icmp.c.

References icmp_hdr::checksum, icmp_hdr::code, netbuf::data, ICMP_ECHO_REPLY, ICMP_ECHO_REQUEST, icmp_input(), ICMP_UNREACH, icmp_unreachable_input(), icmp_hdr::id, inet_checksum(), inet_sock_deliver(), inet_sock_find(), IP_PROTO_ICMP, ipv4_is_local(), ipv4_output(), netbuf::len, netbuf_free(), netbuf::src_ip, netbuf::src_port, netif::stats, and icmp_hdr::type.

Referenced by icmp_input(), and ipv4_input().

◆ icmp_unreachable()

void icmp_unreachable ( struct netif * netif,
const struct ipv4_hdr * ih,
int code )

Tells the sender of a datagram that it couldn't get where it was sent.

Parameters
netifthe interface the datagram came in on
ihthe datagram's IPv4 header, with its payload after it
codewhy (ICMP_UNREACH_*)

Definition at line 105 of file icmp.c.

References icmp_hdr::checksum, icmp_hdr::code, ICMP_UNREACH, icmp_unreachable(), icmp_hdr::id, inet_checksum(), IP_PROTO_ICMP, ipv4_output(), ipv4_hdr::len, memcpy(), netbuf_alloc(), ntohs, icmp_hdr::seq, ipv4_hdr::src, icmp_hdr::type, and ipv4_hdr::ver_ihl.

Referenced by icmp_unreachable(), ipv4_input(), and udp_input().

◆ inet_checksum()

uint16_t inet_checksum ( const void * data,
size_t len )

Computes the Internet checksum (RFC 1071): the ones' complement of the ones' complement sum of the data's 16-bit words.

Parameters
datathe data
lenits length, in bytes
Returns
the checksum, in network byte order (0 if the data includes a correct checksum)

Definition at line 76 of file ether.c.

References htons, and inet_checksum().

Referenced by icmp_input(), icmp_unreachable(), inet_checksum(), ipv4_input(), ipv4_output(), and socket_inet_send().

◆ inet_checksum_pseudo()

uint16_t inet_checksum_pseudo ( uint32_t src,
uint32_t dst,
uint8_t proto,
const void * data,
size_t len )

Computes the Internet checksum of data with the IPv4 pseudo-header before it (the addresses, the protocol and the length), as UDP and TCP do.

Parameters
srcthe source address
dstthe destination address
protothe protocol (IP_PROTO_*)
datathe UDP or TCP header and data
lentheir length, in bytes
Returns
the checksum, in network byte order (0 if the data includes a correct checksum)

Definition at line 106 of file ether.c.

References __packed, ether_hdr::dst, htons, inet_checksum_pseudo(), and ether_hdr::src.

Referenced by inet_checksum_pseudo(), segment(), socket_inet_send(), tcp_input(), tcp_reply_rst(), and udp_input().

◆ inet_ifioctl()

int inet_ifioctl ( int request,
void * argp )

Handles an interface ioctl() request on an AF_INET socket.

Parameters
requestthe request (SIOC*)
argpits argument, in user memory
Returns
0, or a negative errno: -ENOTTY for another request, -EPERM to set something without being root, -ENODEV for no such interface, or -EFAULT

Definition at line 153 of file ifioctl.c.

References curproc, ifconf(), ifreq_request(), inet_ifioctl(), and route().

Referenced by inet_ifioctl(), socket_inet_ioctl(), and socket_tcp_ioctl().

◆ inet_sock_deliver()

void inet_sock_deliver ( struct inet_sock * sock,
struct netbuf * nb )

Queues a received datagram on its socket, and wakes up its readers.

The datagram is dropped if the socket's queue is full or reading is shut down. The netbuf is the socket's from now on.

Parameters
sockthe socket
nbthe datagram's data, with src_ip and src_port set

Definition at line 185 of file socket.c.

References inet_sock_deliver(), netbuf_free(), NETBUF_SIZE, netbuf::next, NULL, inet_sock::recv_bytes, inet_sock::recv_head, RECV_MAX, inet_sock::recv_tail, inet_sock::recv_wait, inet_sock::shut_rd, and waitq_wakeup().

Referenced by icmp_input(), inet_sock_deliver(), and udp_input().

◆ inet_sock_error()

void inet_sock_error ( struct inet_sock * sock,
int err )

Gives a socket an error (from ICMP), which its next call reports.

Parameters
sockthe socket
errthe error (a positive errno)

Definition at line 211 of file socket.c.

References inet_sock::error, inet_sock_error(), inet_sock::recv_wait, and waitq_wakeup().

Referenced by icmp_unreachable_input(), and inet_sock_error().

◆ inet_sock_find()

struct inet_sock * inet_sock_find ( struct netif * netif,
uint8_t proto,
uint32_t local,
uint16_t port,
uint32_t remote,
uint16_t remote_port )

Finds the socket that a received datagram is for: a socket connected to its sender first, or else one that isn't connected.

A socket bound to another interface doesn't count. For ping sockets, the remote port doesn't count.

Parameters
netifthe interface it came in on
protoIP_PROTO_UDP or IP_PROTO_ICMP
localthe address it was sent to
portthe port it was sent to (a ping's identifier)
remotethe sender's address
remote_portthe sender's port
Returns
the socket, or NULL

Definition at line 154 of file socket.c.

References bound, inet_sock_find(), IP_PROTO_ICMP, inet_sock::next, NULL, and inet_sock::proto.

Referenced by icmp_input(), icmp_unreachable_input(), inet_sock_find(), and udp_input().

◆ inet_sockaddr_get()

int inet_sockaddr_get ( const struct sockaddr * addr,
socklen_t len,
uint32_t * ip,
uint16_t * port )

Reads an AF_INET address.

Parameters
addrthe address, in the kernel's memory
lenits size
ipset to its IPv4 address
portset to its port
Returns
0, -EINVAL if it's too short, or -EAFNOSUPPORT

Definition at line 283 of file socket.c.

References inet_sockaddr_get().

Referenced by inet_sockaddr_get(), socket_inet_bind(), socket_inet_connect(), socket_inet_send(), socket_tcp_bind(), and socket_tcp_connect().

◆ inet_sockaddr_put()

void inet_sockaddr_put ( struct sockaddr * addr,
socklen_t * len,
uint32_t ip,
uint16_t port )

Writes an AF_INET address, cut to *len bytes if it doesn't fit.

Parameters
addrwhere to write it
lenits room, set to the address's full size
ipthe IPv4 address
portthe port

Definition at line 306 of file socket.c.

References inet_sockaddr_put(), memcpy(), and MIN.

Referenced by inet_sockaddr_put(), socket_inet_getname(), socket_inet_recv(), socket_tcp_accept(), socket_tcp_getname(), and socket_tcp_recv().

◆ ipv4_input()

void ipv4_input ( struct netif * netif,
struct netbuf * nb,
const uint8_t src_mac[6] )

Takes in an IPv4 packet that an interface received, and passes it to its protocol.

A packet that is malformed, not for us, or a fragment is dropped; one for a protocol we don't have gets a "protocol unreachable".

Parameters
netifthe interface it came in on
nbthe packet, from its IPv4 header; it is freed or passed on
src_macthe sender's MAC address, to update ARP's cache

Definition at line 84 of file ipv4.c.

References arp_update(), netbuf::data, ipv4_hdr::dst, netif::flags, ipv4_hdr::frag, icmp_input(), icmp_unreachable(), inet_checksum(), netif::ip, IP_PROTO_ICMP, IP_PROTO_TCP, IP_PROTO_UDP, ipv4_input(), ipv4_is_local(), is_broadcast(), ipv4_hdr::len, netbuf::len, netbuf_free(), netbuf_pull(), NETIF_LOOPBACK, ntohs, on_link(), ipv4_hdr::proto, ipv4_hdr::src, netif::stats, tcp_input(), udp_input(), and ipv4_hdr::ver_ihl.

Referenced by ether_input(), ipv4_input(), and net_main().

◆ ipv4_is_local()

int ipv4_is_local ( uint32_t ip)

Says whether an address is one of ours: a loopback address, or an interface's.

Parameters
ipthe address, in network byte order
Returns
1 if it is ours, 0 if not

Definition at line 48 of file ipv4.c.

References netif::ip, ipv4_is_local(), is_loopback(), netifs, and netif::next.

Referenced by icmp_input(), ipv4_input(), ipv4_is_local(), ipv4_output(), ipv4_source(), socket_inet_bind(), socket_tcp_bind(), tcp_input(), and udp_input().

◆ ipv4_output()

int ipv4_output ( struct netif * netif,
uint32_t src,
uint32_t dst,
uint8_t proto,
struct netbuf * nb )

Sends a packet through an interface: adds its IPv4 header and sends it to dst, or to the gateway if dst isn't on the link, once ARP knows the hardware address.

A packet to one of our own addresses loops back. The netbuf is freed (or kept by ARP until it can be sent).

Parameters
netifthe interface
srcthe source address, or 0 for ipv4_source()'s
dstthe destination
protothe protocol (IP_PROTO_*)
nbthe payload, with room for the headers before it
Returns
0, -ENETUNREACH if there is no gateway to send it through, or a negative errno from the interface

Definition at line 190 of file ipv4.c.

References arp_lookup(), arp_resolve(), ipv4_hdr::checksum, ipv4_hdr::dst, ether_broadcast, ether_output(), ETHER_TYPE_IPV4, ipv4_hdr::frag, netif::gateway, htons, ipv4_hdr::id, inet_checksum(), ip_id, ipv4_is_local(), ipv4_output(), ipv4_source(), is_broadcast(), ipv4_hdr::len, netbuf::len, netbuf_free(), netbuf_push(), netif_loopback(), on_link(), ipv4_hdr::proto, ipv4_hdr::src, netif::stats, ipv4_hdr::tos, ipv4_hdr::ttl, and ipv4_hdr::ver_ihl.

Referenced by icmp_input(), icmp_unreachable(), ipv4_output(), ipv4_send(), segment(), socket_inet_send(), and tcp_reply_rst().

◆ ipv4_route()

struct netif * ipv4_route ( uint32_t dst)

Chooses the interface to send a packet to dst through: the one whose link it is on, or else the first one with a gateway.

Parameters
dstthe destination
Returns
the interface, or NULL if there is no route

Definition at line 142 of file ipv4.c.

References netif::flags, netif::gateway, netif::ip, ipv4_route(), is_loopback(), NETIF_LOOPBACK, NETIF_UP, netifs, netif::next, NULL, and on_link().

Referenced by ipv4_route(), ipv4_send(), our_mss(), segment(), set_mss(), socket_inet_send(), and socket_tcp_connect().

◆ ipv4_send()

int ipv4_send ( uint32_t dst,
uint8_t proto,
struct netbuf * nb )

Sends a packet to dst, through the interface its route says.

The netbuf is freed.

Parameters
dstthe destination
protothe protocol (IP_PROTO_*)
nbthe payload, with room for the headers before it
Returns
0, -ENETUNREACH if there is no route, or a negative errno

Definition at line 244 of file ipv4.c.

References ipv4_output(), ipv4_route(), ipv4_send(), and netbuf_free().

Referenced by ipv4_send().

◆ ipv4_source()

uint32_t ipv4_source ( struct netif * netif,
uint32_t dst )

Chooses the source address of a packet to dst sent through netif.

A packet to one of our own addresses (127.0.0.0/8 too) is sent from that address; any other is sent from the interface's.

Parameters
netifthe interface it is sent through
dstits destination
Returns
the source address

Definition at line 69 of file ipv4.c.

References netif::ip, ipv4_is_local(), and ipv4_source().

Referenced by ipv4_output(), ipv4_source(), socket_inet_send(), and socket_tcp_connect().

◆ udp_input()

void udp_input ( struct netif * netif,
struct netbuf * nb,
const struct ipv4_hdr * ih )

Takes in a UDP datagram that IPv4 received, and delivers it to its socket.

A datagram with a bad length or checksum is dropped.

Parameters
netifthe interface it came in on
nbthe datagram, from its UDP header; it is freed or given to the socket
ihthe IPv4 header it came with

Definition at line 24 of file udp.c.

References udp_hdr::checksum, netbuf::data, ipv4_hdr::dst, udp_hdr::dst, ICMP_UNREACH_PORT, icmp_unreachable(), inet_checksum_pseudo(), inet_sock_deliver(), inet_sock_find(), IP_PROTO_UDP, ipv4_is_local(), netbuf::len, udp_hdr::len, netbuf_free(), netbuf_pull(), ntohs, ipv4_hdr::src, udp_hdr::src, netbuf::src_ip, netbuf::src_port, netif::stats, and udp_input().

Referenced by ipv4_input(), and udp_input().