in_var.h revision 170613
1228753Smm/*-
2228753Smm * Copyright (c) 1985, 1986, 1993
3228753Smm *	The Regents of the University of California.  All rights reserved.
4228753Smm *
5228753Smm * Redistribution and use in source and binary forms, with or without
6228753Smm * modification, are permitted provided that the following conditions
7228753Smm * are met:
8228753Smm * 1. Redistributions of source code must retain the above copyright
9228753Smm *    notice, this list of conditions and the following disclaimer.
10228753Smm * 2. Redistributions in binary form must reproduce the above copyright
11228753Smm *    notice, this list of conditions and the following disclaimer in the
12228753Smm *    documentation and/or other materials provided with the distribution.
13228753Smm * 4. Neither the name of the University nor the names of its contributors
14228753Smm *    may be used to endorse or promote products derived from this software
15228753Smm *    without specific prior written permission.
16228753Smm *
17228753Smm * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
18228753Smm * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
19228753Smm * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
20228753Smm * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
21228753Smm * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
22228753Smm * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
23228753Smm * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
24228753Smm * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
25228753Smm * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
26228753Smm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
27228753Smm * SUCH DAMAGE.
28228753Smm *
29228753Smm *	@(#)in_var.h	8.2 (Berkeley) 1/9/95
30228753Smm * $FreeBSD: head/sys/netinet/in_var.h 170613 2007-06-12 16:24:56Z bms $
31228753Smm */
32228753Smm
33228753Smm#ifndef _NETINET_IN_VAR_H_
34228753Smm#define _NETINET_IN_VAR_H_
35228753Smm
36228753Smm#include <sys/queue.h>
37228753Smm#include <sys/fnv_hash.h>
38228753Smm
39228753Smm/*
40228753Smm * Interface address, Internet version.  One of these structures
41228753Smm * is allocated for each Internet address on an interface.
42228753Smm * The ifaddr structure contains the protocol-independent part
43228753Smm * of the structure and is assumed to be first.
44228753Smm */
45228753Smmstruct in_ifaddr {
46228753Smm	struct	ifaddr ia_ifa;		/* protocol-independent info */
47228753Smm#define	ia_ifp		ia_ifa.ifa_ifp
48228753Smm#define ia_flags	ia_ifa.ifa_flags
49228753Smm					/* ia_{,sub}net{,mask} in host order */
50228753Smm	u_long	ia_net;			/* network number of interface */
51228753Smm	u_long	ia_netmask;		/* mask of net part */
52228753Smm	u_long	ia_subnet;		/* subnet number, including net */
53228753Smm	u_long	ia_subnetmask;		/* mask of subnet part */
54228753Smm	struct	in_addr ia_netbroadcast; /* to recognize net broadcasts */
55228753Smm	LIST_ENTRY(in_ifaddr) ia_hash;	/* entry in bucket of inet addresses */
56228753Smm	TAILQ_ENTRY(in_ifaddr) ia_link;	/* list of internet addresses */
57228753Smm	struct	sockaddr_in ia_addr;	/* reserve space for interface name */
58228753Smm	struct	sockaddr_in ia_dstaddr; /* reserve space for broadcast addr */
59228753Smm#define	ia_broadaddr	ia_dstaddr
60228753Smm	struct	sockaddr_in ia_sockmask; /* reserve space for general netmask */
61228753Smm};
62228753Smm
63228753Smmstruct	in_aliasreq {
64228753Smm	char	ifra_name[IFNAMSIZ];		/* if name, e.g. "en0" */
65228753Smm	struct	sockaddr_in ifra_addr;
66228753Smm	struct	sockaddr_in ifra_broadaddr;
67228753Smm#define ifra_dstaddr ifra_broadaddr
68228753Smm	struct	sockaddr_in ifra_mask;
69228753Smm};
70228753Smm/*
71228753Smm * Given a pointer to an in_ifaddr (ifaddr),
72228753Smm * return a pointer to the addr as a sockaddr_in.
73228753Smm */
74228753Smm#define IA_SIN(ia)    (&(((struct in_ifaddr *)(ia))->ia_addr))
75228753Smm#define IA_DSTSIN(ia) (&(((struct in_ifaddr *)(ia))->ia_dstaddr))
76228753Smm
77228753Smm#define IN_LNAOF(in, ifa) \
78228753Smm	((ntohl((in).s_addr) & ~((struct in_ifaddr *)(ifa)->ia_subnetmask))
79228753Smm
80228753Smm
81228753Smm#ifdef	_KERNEL
82228753Smmextern	u_char	inetctlerrmap[];
83228753Smm
84228753Smm/*
85228753Smm * Hash table for IP addresses.
86228753Smm */
87228753Smmextern	LIST_HEAD(in_ifaddrhashhead, in_ifaddr) *in_ifaddrhashtbl;
88228753Smmextern	TAILQ_HEAD(in_ifaddrhead, in_ifaddr) in_ifaddrhead;
89228753Smmextern	u_long in_ifaddrhmask;			/* mask for hash table */
90228753Smm
91228753Smm#define INADDR_NHASH_LOG2       9
92228753Smm#define INADDR_NHASH		(1 << INADDR_NHASH_LOG2)
93228753Smm#define INADDR_HASHVAL(x)	fnv_32_buf((&(x)), sizeof(x), FNV1_32_INIT)
94228753Smm#define INADDR_HASH(x) \
95228753Smm	(&in_ifaddrhashtbl[INADDR_HASHVAL(x) & in_ifaddrhmask])
96228753Smm
97228753Smm/*
98228753Smm * Macro for finding the internet address structure (in_ifaddr)
99228753Smm * corresponding to one of our IP addresses (in_addr).
100228753Smm */
101228753Smm#define INADDR_TO_IFADDR(addr, ia) \
102	/* struct in_addr addr; */ \
103	/* struct in_ifaddr *ia; */ \
104do { \
105\
106	LIST_FOREACH(ia, INADDR_HASH((addr).s_addr), ia_hash) \
107		if (IA_SIN(ia)->sin_addr.s_addr == (addr).s_addr) \
108			break; \
109} while (0)
110
111/*
112 * Macro for finding the interface (ifnet structure) corresponding to one
113 * of our IP addresses.
114 */
115#define INADDR_TO_IFP(addr, ifp) \
116	/* struct in_addr addr; */ \
117	/* struct ifnet *ifp; */ \
118{ \
119	struct in_ifaddr *ia; \
120\
121	INADDR_TO_IFADDR(addr, ia); \
122	(ifp) = (ia == NULL) ? NULL : ia->ia_ifp; \
123}
124
125/*
126 * Macro for finding the internet address structure (in_ifaddr) corresponding
127 * to a given interface (ifnet structure).
128 */
129#define IFP_TO_IA(ifp, ia) \
130	/* struct ifnet *ifp; */ \
131	/* struct in_ifaddr *ia; */ \
132{ \
133	for ((ia) = TAILQ_FIRST(&in_ifaddrhead); \
134	    (ia) != NULL && (ia)->ia_ifp != (ifp); \
135	    (ia) = TAILQ_NEXT((ia), ia_link)) \
136		continue; \
137}
138#endif
139
140/*
141 * This information should be part of the ifnet structure but we don't wish
142 * to change that - as it might break a number of things
143 */
144
145struct router_info {
146	struct ifnet *rti_ifp;
147	int    rti_type; /* type of router which is querier on this interface */
148	int    rti_time; /* # of slow timeouts since last old query */
149	SLIST_ENTRY(router_info) rti_list;
150#ifdef notyet
151	int	rti_timev1;	/* IGMPv1 querier present */
152	int	rti_timev2;	/* IGMPv2 querier present */
153	int	rti_timer;	/* report to general query */
154	int	rti_qrv;	/* querier robustness */
155#endif
156};
157
158/*
159 * Internet multicast address structure.  There is one of these for each IP
160 * multicast group to which this host belongs on a given network interface.
161 * For every entry on the interface's if_multiaddrs list which represents
162 * an IP multicast group, there is one of these structures.  They are also
163 * kept on a system-wide list to make it easier to keep our legacy IGMP code
164 * compatible with the rest of the world (see IN_FIRST_MULTI et al, below).
165 */
166struct in_multi {
167	LIST_ENTRY(in_multi) inm_link;	/* queue macro glue */
168	struct	in_addr inm_addr;	/* IP multicast address, convenience */
169	struct	ifnet *inm_ifp;		/* back pointer to ifnet */
170	struct	ifmultiaddr *inm_ifma;	/* back pointer to ifmultiaddr */
171	u_int	inm_timer;		/* IGMP membership report timer */
172	u_int	inm_state;		/*  state of the membership */
173	struct	router_info *inm_rti;	/* router info*/
174	u_int	inm_refcount;		/* reference count */
175#ifdef notyet		/* IGMPv3 source-specific multicast fields */
176	TAILQ_HEAD(, in_msfentry) inm_msf;	/* all active source filters */
177	TAILQ_HEAD(, in_msfentry) inm_msf_record;	/* recorded sources */
178	TAILQ_HEAD(, in_msfentry) inm_msf_exclude;	/* exclude sources */
179	TAILQ_HEAD(, in_msfentry) inm_msf_include;	/* include sources */
180	/* XXX: should this lot go to the router_info structure? */
181	/* XXX: can/should these be callouts? */
182	/* IGMP protocol timers */
183	int32_t		inm_ti_curstate;	/* current state timer */
184	int32_t		inm_ti_statechg;	/* state change timer */
185	/* IGMP report timers */
186	uint16_t	inm_rpt_statechg;	/* state change report timer */
187	uint16_t	inm_rpt_toxx;		/* fmode change report timer */
188	/* IGMP protocol state */
189	uint16_t	inm_fmode;		/* filter mode */
190	uint32_t	inm_recsrc_count;	/* # of recorded sources */
191	uint16_t	inm_exclude_sock_count;	/* # of exclude-mode sockets */
192	uint16_t	inm_gass_count;		/* # of g-a-s queries */
193#endif
194};
195
196#ifdef notyet
197/*
198 * Internet multicast source filter list. This list is used to store
199 * IP multicast source addresses for each membership on an interface.
200 * TODO: Allocate these structures using UMA.
201 * TODO: Find an easier way of linking the struct into two lists at once.
202 */
203struct in_msfentry {
204	TAILQ_ENTRY(in_msfentry) isf_link;	/* next filter in all-list */
205	TAILQ_ENTRY(in_msfentry) isf_next;	/* next filter in queue */
206	struct in_addr	isf_addr;	/* the address of this source */
207	uint16_t	isf_refcount;	/* reference count */
208	uint16_t	isf_reporttag;	/* what to report to the IGMP router */
209	uint16_t	isf_rexmit;	/* retransmission state/count */
210};
211#endif
212
213#ifdef _KERNEL
214
215#ifdef SYSCTL_DECL
216SYSCTL_DECL(_net_inet);
217SYSCTL_DECL(_net_inet_ip);
218SYSCTL_DECL(_net_inet_raw);
219#endif
220
221extern LIST_HEAD(in_multihead, in_multi) in_multihead;
222
223/*
224 * Lock macros for IPv4 layer multicast address lists.  IPv4 lock goes
225 * before link layer multicast locks in the lock order.  In most cases,
226 * consumers of IN_*_MULTI() macros should acquire the locks before
227 * calling them; users of the in_{add,del}multi() functions should not.
228 */
229extern struct mtx in_multi_mtx;
230#define	IN_MULTI_LOCK()		mtx_lock(&in_multi_mtx)
231#define	IN_MULTI_UNLOCK()	mtx_unlock(&in_multi_mtx)
232#define	IN_MULTI_LOCK_ASSERT()	mtx_assert(&in_multi_mtx, MA_OWNED)
233
234/*
235 * Structure used by macros below to remember position when stepping through
236 * all of the in_multi records.
237 */
238struct in_multistep {
239	struct in_multi *i_inm;
240};
241
242/*
243 * Macro for looking up the in_multi record for a given IP multicast address
244 * on a given interface.  If no matching record is found, "inm" is set null.
245 */
246#define IN_LOOKUP_MULTI(addr, ifp, inm) \
247	/* struct in_addr addr; */ \
248	/* struct ifnet *ifp; */ \
249	/* struct in_multi *inm; */ \
250do { \
251	struct ifmultiaddr *ifma; \
252\
253	IN_MULTI_LOCK_ASSERT(); \
254	IF_ADDR_LOCK(ifp); \
255	TAILQ_FOREACH(ifma, &((ifp)->if_multiaddrs), ifma_link) { \
256		if (ifma->ifma_addr->sa_family == AF_INET \
257		    && ((struct sockaddr_in *)ifma->ifma_addr)->sin_addr.s_addr == \
258		    (addr).s_addr) \
259			break; \
260	} \
261	(inm) = ifma ? ifma->ifma_protospec : 0; \
262	IF_ADDR_UNLOCK(ifp); \
263} while(0)
264
265/*
266 * Macro to step through all of the in_multi records, one at a time.
267 * The current position is remembered in "step", which the caller must
268 * provide.  IN_FIRST_MULTI(), below, must be called to initialize "step"
269 * and get the first record.  Both macros return a NULL "inm" when there
270 * are no remaining records.
271 */
272#define IN_NEXT_MULTI(step, inm) \
273	/* struct in_multistep  step; */ \
274	/* struct in_multi *inm; */ \
275do { \
276	IN_MULTI_LOCK_ASSERT(); \
277	if (((inm) = (step).i_inm) != NULL) \
278		(step).i_inm = LIST_NEXT((step).i_inm, inm_link); \
279} while(0)
280
281#define IN_FIRST_MULTI(step, inm) \
282	/* struct in_multistep step; */ \
283	/* struct in_multi *inm; */ \
284do { \
285	IN_MULTI_LOCK_ASSERT(); \
286	(step).i_inm = LIST_FIRST(&in_multihead); \
287	IN_NEXT_MULTI((step), (inm)); \
288} while(0)
289
290struct	route;
291struct	ip_moptions;
292
293size_t	imo_match_group(struct ip_moptions *, struct ifnet *,
294	    struct sockaddr *);
295struct	in_msource *imo_match_source(struct ip_moptions *, size_t,
296	    struct sockaddr *);
297struct	in_multi *in_addmulti(struct in_addr *, struct ifnet *);
298void	in_delmulti(struct in_multi *);
299void	in_delmulti_locked(struct in_multi *);
300int	in_control(struct socket *, u_long, caddr_t, struct ifnet *,
301	    struct thread *);
302void	in_rtqdrain(void);
303void	ip_input(struct mbuf *);
304int	in_ifadown(struct ifaddr *ifa, int);
305void	in_ifscrub(struct ifnet *, struct in_ifaddr *);
306struct	mbuf	*ip_fastforward(struct mbuf *);
307
308#endif /* _KERNEL */
309
310/* INET6 stuff */
311#include <netinet6/in6_var.h>
312
313#endif /* _NETINET_IN_VAR_H_ */
314