xref: /dragonfly/usr.sbin/rtsold/rtsock.c (revision c37c9ab3)
1 /*	$KAME: rtsock.c,v 1.3 2000/10/10 08:46:45 itojun Exp $	*/
2 /*	$FreeBSD: src/usr.sbin/rtsold/rtsock.c,v 1.1.2.1 2001/07/03 11:02:16 ume Exp $	*/
3 /*	$DragonFly: src/usr.sbin/rtsold/rtsock.c,v 1.6 2005/12/05 00:56:37 swildner Exp $	*/
4 
5 /*
6  * Copyright (C) 2000 WIDE Project.
7  * All rights reserved.
8  *
9  * Redistribution and use in source and binary forms, with or without
10  * modification, are permitted provided that the following conditions
11  * are met:
12  * 1. Redistributions of source code must retain the above copyright
13  *    notice, this list of conditions and the following disclaimer.
14  * 2. Redistributions in binary form must reproduce the above copyright
15  *    notice, this list of conditions and the following disclaimer in the
16  *    documentation and/or other materials provided with the distribution.
17  * 3. Neither the name of the project nor the names of its contributors
18  *    may be used to endorse or promote products derived from this software
19  *    without specific prior written permission.
20  *
21  * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
22  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
23  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
24  * ARE DISCLAIMED.  IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
25  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31  * SUCH DAMAGE.
32  */
33 
34 #include <sys/param.h>
35 #include <sys/socket.h>
36 #include <sys/uio.h>
37 #include <sys/time.h>
38 #include <sys/queue.h>
39 
40 #include <net/if.h>
41 #include <net/route.h>
42 #include <net/if_dl.h>
43 
44 #include <netinet/in.h>
45 #include <netinet/ip6.h>
46 #include <netinet/icmp6.h>
47 
48 #include <time.h>
49 #include <unistd.h>
50 #include <stdio.h>
51 #include <stddef.h>
52 #include <err.h>
53 #include <errno.h>
54 #include <string.h>
55 #include <stdlib.h>
56 #include <syslog.h>
57 #include "rtsold.h"
58 
59 #ifdef RTM_IFANNOUNCE	/*NetBSD 1.5 or later*/
60 static int rtsock_input_ifannounce(int, struct rt_msghdr *, char *);
61 #endif
62 
63 static struct {
64 	u_char type;
65 	size_t minlen;
66 	int (*func)(int, struct rt_msghdr *, char *);
67 } rtsock_dispatch[] = {
68 #ifdef RTM_IFANNOUNCE	/*NetBSD 1.5 or later*/
69 	{ RTM_IFANNOUNCE, sizeof(struct if_announcemsghdr),
70 	  rtsock_input_ifannounce },
71 #endif
72 	{ 0, 0, NULL },
73 };
74 
75 int
76 rtsock_open(void)
77 {
78 
79 	return socket(PF_ROUTE, SOCK_RAW, 0);
80 }
81 
82 int
83 rtsock_input(int s)
84 {
85 	ssize_t n;
86 	char msg[2048];
87 	char *lim, *next;
88 	struct rt_msghdr *rtm;
89 	int idx;
90 	ssize_t len;
91 	int ret = 0;
92 	const ssize_t lenlim =
93 	    offsetof(struct rt_msghdr, rtm_msglen) + sizeof(rtm->rtm_msglen);
94 
95 	n = read(s, msg, sizeof(msg));
96 
97 	lim = msg + n;
98 	for (next = msg; next < lim; next += len) {
99 		rtm = (struct rt_msghdr *)next;
100 		if (lim - next < lenlim)
101 			break;
102 		len = rtm->rtm_msglen;
103 		if (len < lenlim)
104 			break;
105 
106 		if (dflag > 1) {
107 			warnmsg(LOG_INFO, __func__,
108 			    "rtmsg type %d, len=%lu", rtm->rtm_type,
109 			    (u_long)len);
110 		}
111 
112 		for (idx = 0; rtsock_dispatch[idx].func; idx++) {
113 			if (rtm->rtm_type != rtsock_dispatch[idx].type)
114 				continue;
115 			if (rtm->rtm_msglen < rtsock_dispatch[idx].minlen) {
116 				warnmsg(LOG_INFO, __func__,
117 				    "rtmsg type %d too short!", rtm->rtm_type);
118 				continue;
119 			}
120 
121 			ret = (*rtsock_dispatch[idx].func)(s, rtm, lim);
122 			break;
123 		}
124 	}
125 
126 	return ret;
127 }
128 
129 #ifdef RTM_IFANNOUNCE	/*NetBSD 1.5 or later*/
130 static int
131 rtsock_input_ifannounce(int s __unused, struct rt_msghdr *rtm, char *lim)
132 {
133 	struct if_announcemsghdr *ifan;
134 	struct ifinfo *ifinfo;
135 
136 	ifan = (struct if_announcemsghdr *)rtm;
137 	if ((char *)(ifan + 1) > lim)
138 		return -1;
139 
140 	switch (ifan->ifan_what) {
141 	case IFAN_ARRIVAL:
142 		/*
143 		 * XXX for NetBSD 1.5, interface index will monotonically be
144 		 * increased as new pcmcia card gets inserted.
145 		 * we may be able to do a name-based interface match,
146 		 * and call ifreconfig() to enable the interface again.
147 		 */
148 		warnmsg(LOG_INFO, __func__,
149 		    "interface %s inserted", ifan->ifan_name);
150 		break;
151 	case IFAN_DEPARTURE:
152 		warnmsg(LOG_WARNING, __func__,
153 		    "interface %s removed", ifan->ifan_name);
154 		ifinfo = find_ifinfo(ifan->ifan_index);
155 		if (ifinfo) {
156 			if (dflag > 1) {
157 				warnmsg(LOG_INFO, __func__,
158 				    "bring interface %s to DOWN state",
159 				    ifan->ifan_name);
160 			}
161 			ifinfo->state = IFS_DOWN;
162 		}
163 		break;
164 	}
165 
166 	return 0;
167 }
168 #endif
169