|
AquilaOS documentation
How it works, and its code
|
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. | |
| #define ETHER_TYPE_ARP 0x0806 |
Definition at line 18 of file inet.h.
Referenced by arp_input(), arp_request(), and ether_input().
| #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().
| #define ICMP_ECHO_REPLY 0 |
Definition at line 60 of file inet.h.
Referenced by icmp_input().
| #define ICMP_ECHO_REQUEST 8 |
Definition at line 62 of file inet.h.
Referenced by icmp_input(), and socket_inet_send().
| #define ICMP_UNREACH 3 |
Definition at line 61 of file inet.h.
Referenced by icmp_input(), and icmp_unreachable().
| #define ICMP_UNREACH_PORT 3 |
Definition at line 65 of file inet.h.
Referenced by icmp_unreachable_input(), and udp_input().
| #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().
| #define IP_PROTO_TCP 6 |
Definition at line 42 of file inet.h.
Referenced by ipv4_input(), segment(), tcp_input(), and tcp_reply_rst().
| #define IP_PROTO_UDP 17 |
Definition at line 43 of file inet.h.
Referenced by icmp_unreachable_input(), ipv4_input(), socket_inet_bind(), socket_inet_connect(), socket_inet_create(), socket_inet_send(), and udp_input().
Takes in an ARP packet: the sender's address is recorded, and a request for our address is answered.
| netif | the interface it came in on |
| nb | the 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().
Looks up an address's hardware address.
An entry that has expired is dropped, so that the address is asked for again.
| netif | the interface |
| ip | the IPv4 address |
| mac | set to the hardware address, if it is known |
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().
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.
| netif | the interface to send it on |
| ip | the next hop's address |
| nb | the IPv4 packet |
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().
Records an address's hardware address, replacing the oldest entry if the table is full, and sends the packets that waited for it.
| netif | the interface it was heard on |
| ip | the IPv4 address |
| mac | its 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().
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.
| netif | the interface it came in on |
| nb | the 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().
Sends a frame: adds its Ethernet header and gives it to the interface.
The netbuf is freed in every case.
| netif | the interface to send it on |
| dst | the destination MAC address |
| type | the frame's type (ETHER_TYPE_*) |
| nb | the frame's data, with room for the header before it |
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().
Takes in an ICMP message that IPv4 received.
| netif | the interface it came in on |
| nb | the message, from its ICMP header; it is freed, sent back or delivered |
| src | the sender's address |
| dst | the 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().
Tells the sender of a datagram that it couldn't get where it was sent.
| netif | the interface the datagram came in on |
| ih | the datagram's IPv4 header, with its payload after it |
| code | why (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().
Computes the Internet checksum (RFC 1071): the ones' complement of the ones' complement sum of the data's 16-bit words.
| data | the data |
| len | its length, in bytes |
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().
| 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.
| src | the source address |
| dst | the destination address |
| proto | the protocol (IP_PROTO_*) |
| data | the UDP or TCP header and data |
| len | their length, in bytes |
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().
| int inet_ifioctl | ( | int | request, |
| void * | argp ) |
Handles an interface ioctl() request on an AF_INET socket.
| request | the request (SIOC*) |
| argp | its argument, in user memory |
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().
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.
| sock | the socket |
| nb | the 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().
| void inet_sock_error | ( | struct inet_sock * | sock, |
| int | err ) |
Gives a socket an error (from ICMP), which its next call reports.
| sock | the socket |
| err | the 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().
| 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.
| netif | the interface it came in on |
| proto | IP_PROTO_UDP or IP_PROTO_ICMP |
| local | the address it was sent to |
| port | the port it was sent to (a ping's identifier) |
| remote | the sender's address |
| remote_port | the sender's port |
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().
| int inet_sockaddr_get | ( | const struct sockaddr * | addr, |
| socklen_t | len, | ||
| uint32_t * | ip, | ||
| uint16_t * | port ) |
Reads an AF_INET address.
| addr | the address, in the kernel's memory |
| len | its size |
| ip | set to its IPv4 address |
| port | set to its port |
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().
Writes an AF_INET address, cut to *len bytes if it doesn't fit.
| addr | where to write it |
| len | its room, set to the address's full size |
| ip | the IPv4 address |
| port | the 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().
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".
| netif | the interface it came in on |
| nb | the packet, from its IPv4 header; it is freed or passed on |
| src_mac | the 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().
| int ipv4_is_local | ( | uint32_t | ip | ) |
Says whether an address is one of ours: a loopback address, or an interface's.
| ip | the address, in network byte order |
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().
| 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).
| netif | the interface |
| src | the source address, or 0 for ipv4_source()'s |
| dst | the destination |
| proto | the protocol (IP_PROTO_*) |
| nb | the payload, with room for the headers before it |
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().
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.
| dst | the destination |
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().
Sends a packet to dst, through the interface its route says.
The netbuf is freed.
| dst | the destination |
| proto | the protocol (IP_PROTO_*) |
| nb | the payload, with room for the headers before it |
Definition at line 244 of file ipv4.c.
References ipv4_output(), ipv4_route(), ipv4_send(), and netbuf_free().
Referenced by ipv4_send().
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.
| netif | the interface it is sent through |
| dst | its destination |
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().
Takes in a UDP datagram that IPv4 received, and delivers it to its socket.
A datagram with a bad length or checksum is dropped.
| netif | the interface it came in on |
| nb | the datagram, from its UDP header; it is freed or given to the socket |
| ih | the 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().