1/*
2 * dhcpcd - DHCP client daemon
3 * Copyright (c) 2006-2019 Roy Marples <roy@marples.name>
4 * All rights reserved
5
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
16 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
17 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
18 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
19 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
21 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
22 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
23 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
24 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
25 * SUCH DAMAGE.
26 */
27
28#ifndef IPV4_H
29#define IPV4_H
30
31#include "dhcpcd.h"
32
33/* Prefer our macro */
34#ifdef HTONL
35#undef HTONL
36#endif
37
38#ifndef BYTE_ORDER
39#define BIG_ENDIAN 1234
40#define LITTLE_ENDIAN 4321
41#if defined(_BIG_ENDIAN)
42#define BYTE_ORDER BIG_ENDIAN
43#elif defined(_LITTLE_ENDIAN)
44#define BYTE_ORDER LITTLE_ENDIAN
45#else
46#error Endian unknown
47#endif
48#endif
49
50#if BYTE_ORDER == BIG_ENDIAN
51#define HTONL(A) (A)
52#elif BYTE_ORDER == LITTLE_ENDIAN
53#define HTONL(A) \
54 ((((uint32_t)(A) & 0xff000000) >> 24) | \
55 (((uint32_t)(A) & 0x00ff0000) >> 8) | \
56 (((uint32_t)(A) & 0x0000ff00) << 8) | \
57 (((uint32_t)(A) & 0x000000ff) << 24))
58#endif /* BYTE_ORDER */
59
60#ifdef __sun
61 /* Solaris lacks these defines.
62 * While it supports DaD, to seems to only expose IFF_DUPLICATE
63 * so we have no way of knowing if it's tentative or not.
64 * I don't even know if Solaris has any special treatment for tentative. */
65# define IN_IFF_DUPLICATED 0x02
66# define IN_IFF_NOTUSEABLE IN_IFF_DUPLICATED
67#endif
68
69#ifdef IN_IFF_TENTATIVE
70#define IN_IFF_NOTUSEABLE \
71 (IN_IFF_TENTATIVE | IN_IFF_DUPLICATED | IN_IFF_DETACHED)
72#endif
73
74struct ipv4_addr {
75 TAILQ_ENTRY(ipv4_addr) next;
76 struct in_addr addr;
77 struct in_addr mask;
78 struct in_addr brd;
79 struct interface *iface;
80 int addr_flags;
81 unsigned int flags;
82 char saddr[INET_ADDRSTRLEN + 3];
83#ifdef ALIAS_ADDR
84 char alias[IF_NAMESIZE];
85#endif
86};
87TAILQ_HEAD(ipv4_addrhead, ipv4_addr);
88
89#define IPV4_AF_STALE (1U << 0)
90
91#define IPV4_ADDR_EQ(a1, a2) ((a1) && (a1)->addr.s_addr == (a2)->addr.s_addr)
92#define IPV4_MASK1_EQ(a1, a2) ((a1) && (a1)->mask.s_addr == (a2)->mask.s_addr)
93#define IPV4_MASK_EQ(a1, a2) (IPV4_ADDR_EQ(a1, a2) && IPV4_MASK1_EQ(a1, a2))
94#define IPV4_BRD1_EQ(a1, a2) ((a1) && (a1)->brd.s_addr == (a2)->brd.s_addr)
95#define IPV4_BRD_EQ(a1, a2) (IPV4_MASK_EQ(a1, a2) && IPV4_BRD1_EQ(a1, a2))
96
97struct ipv4_state {
98 struct ipv4_addrhead addrs;
99
100 /* Buffer for BPF */
101 size_t buffer_size, buffer_len, buffer_pos;
102 char *buffer;
103};
104
105#define IPV4_STATE(ifp) \
106 ((struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4])
107#define IPV4_CSTATE(ifp) \
108 ((const struct ipv4_state *)(ifp)->if_data[IF_DATA_IPV4])
109
110#ifdef INET
111struct ipv4_state *ipv4_getstate(struct interface *);
112int ipv4_ifcmp(const struct interface *, const struct interface *);
113uint8_t inet_ntocidr(struct in_addr);
114int inet_cidrtoaddr(int, struct in_addr *);
115uint32_t ipv4_getnetmask(uint32_t);
116int ipv4_hasaddr(const struct interface *);
117
118bool inet_getroutes(struct dhcpcd_ctx *, struct rt_head *);
119
120#define STATE_ADDED 0x01
121#define STATE_FAKE 0x02
122
123int ipv4_deladdr(struct ipv4_addr *, int);
124struct ipv4_addr *ipv4_addaddr(struct interface *,
125 const struct in_addr *, const struct in_addr *, const struct in_addr *);
126void ipv4_applyaddr(void *);
127
128struct ipv4_addr *ipv4_iffindaddr(struct interface *,
129 const struct in_addr *, const struct in_addr *);
130struct ipv4_addr *ipv4_iffindlladdr(struct interface *);
131struct ipv4_addr *ipv4_findaddr(struct dhcpcd_ctx *, const struct in_addr *);
132struct ipv4_addr *ipv4_findmaskaddr(struct dhcpcd_ctx *,
133 const struct in_addr *);
134void ipv4_markaddrsstale(struct interface *);
135void ipv4_deletestaleaddrs(struct interface *);
136void ipv4_handleifa(struct dhcpcd_ctx *, int, struct if_head *, const char *,
137 const struct in_addr *, const struct in_addr *, const struct in_addr *,
138 int, pid_t);
139
140void ipv4_free(struct interface *);
141#endif /* INET */
142
143#endif /* IPV4_H */
144