1*bd1f8aebSAndroid Build Coastguard Worker /* $USAGI: ninfod.c,v 1.34 2003-01-15 06:41:23 mk Exp $ */
2*bd1f8aebSAndroid Build Coastguard Worker /*
3*bd1f8aebSAndroid Build Coastguard Worker * Copyright (C) 2002 USAGI/WIDE Project.
4*bd1f8aebSAndroid Build Coastguard Worker * All rights reserved.
5*bd1f8aebSAndroid Build Coastguard Worker *
6*bd1f8aebSAndroid Build Coastguard Worker * Redistribution and use in source and binary forms, with or without
7*bd1f8aebSAndroid Build Coastguard Worker * modification, are permitted provided that the following conditions
8*bd1f8aebSAndroid Build Coastguard Worker * are met:
9*bd1f8aebSAndroid Build Coastguard Worker * 1. Redistributions of source code must retain the above copyright
10*bd1f8aebSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer.
11*bd1f8aebSAndroid Build Coastguard Worker * 2. Redistributions in binary form must reproduce the above copyright
12*bd1f8aebSAndroid Build Coastguard Worker * notice, this list of conditions and the following disclaimer in the
13*bd1f8aebSAndroid Build Coastguard Worker * documentation and/or other materials provided with the distribution.
14*bd1f8aebSAndroid Build Coastguard Worker * 3. Neither the name of the project nor the names of its contributors
15*bd1f8aebSAndroid Build Coastguard Worker * may be used to endorse or promote products derived from this software
16*bd1f8aebSAndroid Build Coastguard Worker * without specific prior written permission.
17*bd1f8aebSAndroid Build Coastguard Worker *
18*bd1f8aebSAndroid Build Coastguard Worker * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
19*bd1f8aebSAndroid Build Coastguard Worker * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20*bd1f8aebSAndroid Build Coastguard Worker * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21*bd1f8aebSAndroid Build Coastguard Worker * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
22*bd1f8aebSAndroid Build Coastguard Worker * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
23*bd1f8aebSAndroid Build Coastguard Worker * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
24*bd1f8aebSAndroid Build Coastguard Worker * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
25*bd1f8aebSAndroid Build Coastguard Worker * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
26*bd1f8aebSAndroid Build Coastguard Worker * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
27*bd1f8aebSAndroid Build Coastguard Worker * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
28*bd1f8aebSAndroid Build Coastguard Worker * SUCH DAMAGE.
29*bd1f8aebSAndroid Build Coastguard Worker */
30*bd1f8aebSAndroid Build Coastguard Worker /*
31*bd1f8aebSAndroid Build Coastguard Worker * Author:
32*bd1f8aebSAndroid Build Coastguard Worker * YOSHIFUJI Hideaki <[email protected]>
33*bd1f8aebSAndroid Build Coastguard Worker */
34*bd1f8aebSAndroid Build Coastguard Worker
35*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_CONFIG_H
36*bd1f8aebSAndroid Build Coastguard Worker #include "config.h"
37*bd1f8aebSAndroid Build Coastguard Worker #endif
38*bd1f8aebSAndroid Build Coastguard Worker
39*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_TYPES_H
40*bd1f8aebSAndroid Build Coastguard Worker # include <sys/types.h>
41*bd1f8aebSAndroid Build Coastguard Worker #endif
42*bd1f8aebSAndroid Build Coastguard Worker #if STDC_HEADERS
43*bd1f8aebSAndroid Build Coastguard Worker # include <stdio.h>
44*bd1f8aebSAndroid Build Coastguard Worker # include <stdlib.h>
45*bd1f8aebSAndroid Build Coastguard Worker # include <stddef.h>
46*bd1f8aebSAndroid Build Coastguard Worker # include <stdarg.h>
47*bd1f8aebSAndroid Build Coastguard Worker #else
48*bd1f8aebSAndroid Build Coastguard Worker # if HAVE_STDLIB_H
49*bd1f8aebSAndroid Build Coastguard Worker # include <stdlib.h>
50*bd1f8aebSAndroid Build Coastguard Worker # endif
51*bd1f8aebSAndroid Build Coastguard Worker #endif
52*bd1f8aebSAndroid Build Coastguard Worker
53*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_STRING_H
54*bd1f8aebSAndroid Build Coastguard Worker # if !STDC_HEADERS && HAVE_MEMORY_H
55*bd1f8aebSAndroid Build Coastguard Worker # include <memory.h>
56*bd1f8aebSAndroid Build Coastguard Worker # endif
57*bd1f8aebSAndroid Build Coastguard Worker # include <string.h>
58*bd1f8aebSAndroid Build Coastguard Worker #endif
59*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_STRINGS_H
60*bd1f8aebSAndroid Build Coastguard Worker # include <strings.h>
61*bd1f8aebSAndroid Build Coastguard Worker #endif
62*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_INTTYPES_H
63*bd1f8aebSAndroid Build Coastguard Worker # include <inttypes.h>
64*bd1f8aebSAndroid Build Coastguard Worker #else
65*bd1f8aebSAndroid Build Coastguard Worker # if HAVE_STDINT_H
66*bd1f8aebSAndroid Build Coastguard Worker # include <stdint.h>
67*bd1f8aebSAndroid Build Coastguard Worker # endif
68*bd1f8aebSAndroid Build Coastguard Worker #endif
69*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_LIMITS_H
70*bd1f8aebSAndroid Build Coastguard Worker # include <limits.h>
71*bd1f8aebSAndroid Build Coastguard Worker #endif
72*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_UNISTD_H
73*bd1f8aebSAndroid Build Coastguard Worker # include <unistd.h>
74*bd1f8aebSAndroid Build Coastguard Worker #endif
75*bd1f8aebSAndroid Build Coastguard Worker
76*bd1f8aebSAndroid Build Coastguard Worker #ifdef TIME_WITH_SYS_TIME
77*bd1f8aebSAndroid Build Coastguard Worker # include <sys/time.h>
78*bd1f8aebSAndroid Build Coastguard Worker # include <time.h>
79*bd1f8aebSAndroid Build Coastguard Worker #else
80*bd1f8aebSAndroid Build Coastguard Worker # ifdef HAVE_SYS_TIME_H
81*bd1f8aebSAndroid Build Coastguard Worker # include <sys/time.h>
82*bd1f8aebSAndroid Build Coastguard Worker # else
83*bd1f8aebSAndroid Build Coastguard Worker # include <time.h>
84*bd1f8aebSAndroid Build Coastguard Worker # endif
85*bd1f8aebSAndroid Build Coastguard Worker #endif
86*bd1f8aebSAndroid Build Coastguard Worker
87*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_UIO_H
88*bd1f8aebSAndroid Build Coastguard Worker #include <sys/uio.h>
89*bd1f8aebSAndroid Build Coastguard Worker #endif
90*bd1f8aebSAndroid Build Coastguard Worker
91*bd1f8aebSAndroid Build Coastguard Worker #include <sys/socket.h>
92*bd1f8aebSAndroid Build Coastguard Worker
93*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETINET_IN_H
94*bd1f8aebSAndroid Build Coastguard Worker # include <netinet/in.h>
95*bd1f8aebSAndroid Build Coastguard Worker #endif
96*bd1f8aebSAndroid Build Coastguard Worker
97*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETINET_ICMP6_H
98*bd1f8aebSAndroid Build Coastguard Worker # include <netinet/icmp6.h>
99*bd1f8aebSAndroid Build Coastguard Worker #endif
100*bd1f8aebSAndroid Build Coastguard Worker #ifndef HAVE_STRUCT_ICMP6_NODEINFO
101*bd1f8aebSAndroid Build Coastguard Worker # include "icmp6_nodeinfo.h"
102*bd1f8aebSAndroid Build Coastguard Worker #endif
103*bd1f8aebSAndroid Build Coastguard Worker
104*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NETDB_H
105*bd1f8aebSAndroid Build Coastguard Worker # include <netdb.h>
106*bd1f8aebSAndroid Build Coastguard Worker #endif
107*bd1f8aebSAndroid Build Coastguard Worker #include <errno.h>
108*bd1f8aebSAndroid Build Coastguard Worker
109*bd1f8aebSAndroid Build Coastguard Worker #include <signal.h>
110*bd1f8aebSAndroid Build Coastguard Worker
111*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYSLOG_H
112*bd1f8aebSAndroid Build Coastguard Worker # include <syslog.h>
113*bd1f8aebSAndroid Build Coastguard Worker #endif
114*bd1f8aebSAndroid Build Coastguard Worker
115*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_PWD_H
116*bd1f8aebSAndroid Build Coastguard Worker # include <pwd.h>
117*bd1f8aebSAndroid Build Coastguard Worker #endif
118*bd1f8aebSAndroid Build Coastguard Worker
119*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_SYS_CAPABILITY_H
120*bd1f8aebSAndroid Build Coastguard Worker # include <sys/prctl.h>
121*bd1f8aebSAndroid Build Coastguard Worker # include <sys/capability.h>
122*bd1f8aebSAndroid Build Coastguard Worker #endif
123*bd1f8aebSAndroid Build Coastguard Worker
124*bd1f8aebSAndroid Build Coastguard Worker #include "ninfod.h"
125*bd1f8aebSAndroid Build Coastguard Worker
126*bd1f8aebSAndroid Build Coastguard Worker #ifndef offsetof
127*bd1f8aebSAndroid Build Coastguard Worker # define offsetof(aggregate,member) ((size_t)&((aggregate *)0)->member)
128*bd1f8aebSAndroid Build Coastguard Worker #endif
129*bd1f8aebSAndroid Build Coastguard Worker
130*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
131*bd1f8aebSAndroid Build Coastguard Worker /* ID */
132*bd1f8aebSAndroid Build Coastguard Worker static char *RCSID __attribute__ ((unused)) = "$USAGI: ninfod.c,v 1.34 2003-01-15 06:41:23 mk Exp $";
133*bd1f8aebSAndroid Build Coastguard Worker
134*bd1f8aebSAndroid Build Coastguard Worker /* Variables */
135*bd1f8aebSAndroid Build Coastguard Worker int sock;
136*bd1f8aebSAndroid Build Coastguard Worker int daemonized;
137*bd1f8aebSAndroid Build Coastguard Worker
138*bd1f8aebSAndroid Build Coastguard Worker char *appname;
139*bd1f8aebSAndroid Build Coastguard Worker static int opt_d = 0; /* debug */
140*bd1f8aebSAndroid Build Coastguard Worker static int opt_h = 0; /* help */
141*bd1f8aebSAndroid Build Coastguard Worker static char *opt_p = NINFOD_PIDFILE; /* pidfile */
142*bd1f8aebSAndroid Build Coastguard Worker static int got_signal = 0; /* loop unless true */
143*bd1f8aebSAndroid Build Coastguard Worker int opt_v = 0; /* verbose */
144*bd1f8aebSAndroid Build Coastguard Worker static uid_t opt_u;
145*bd1f8aebSAndroid Build Coastguard Worker
146*bd1f8aebSAndroid Build Coastguard Worker static int ipv6_pktinfo = IPV6_PKTINFO;
147*bd1f8aebSAndroid Build Coastguard Worker
148*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
149*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
log_level(int priority)150*bd1f8aebSAndroid Build Coastguard Worker static const __inline__ char * log_level(int priority) {
151*bd1f8aebSAndroid Build Coastguard Worker switch(priority) {
152*bd1f8aebSAndroid Build Coastguard Worker case LOG_EMERG: return "EMERG";
153*bd1f8aebSAndroid Build Coastguard Worker case LOG_ALERT: return "ALERT";
154*bd1f8aebSAndroid Build Coastguard Worker case LOG_CRIT: return "CRIT";
155*bd1f8aebSAndroid Build Coastguard Worker case LOG_ERR: return "ERR";
156*bd1f8aebSAndroid Build Coastguard Worker case LOG_WARNING: return "WARNING";
157*bd1f8aebSAndroid Build Coastguard Worker case LOG_NOTICE: return "NOTICE";
158*bd1f8aebSAndroid Build Coastguard Worker case LOG_INFO: return "INFO";
159*bd1f8aebSAndroid Build Coastguard Worker case LOG_DEBUG: return "DEBUG";
160*bd1f8aebSAndroid Build Coastguard Worker default: return "???";
161*bd1f8aebSAndroid Build Coastguard Worker }
162*bd1f8aebSAndroid Build Coastguard Worker }
163*bd1f8aebSAndroid Build Coastguard Worker
stderrlog(int pri,char * fmt,...)164*bd1f8aebSAndroid Build Coastguard Worker void stderrlog(int pri, char *fmt, ...)
165*bd1f8aebSAndroid Build Coastguard Worker {
166*bd1f8aebSAndroid Build Coastguard Worker va_list ap;
167*bd1f8aebSAndroid Build Coastguard Worker char ebuf[512];
168*bd1f8aebSAndroid Build Coastguard Worker char *buf;
169*bd1f8aebSAndroid Build Coastguard Worker size_t buflen;
170*bd1f8aebSAndroid Build Coastguard Worker
171*bd1f8aebSAndroid Build Coastguard Worker va_start(ap, fmt);
172*bd1f8aebSAndroid Build Coastguard Worker
173*bd1f8aebSAndroid Build Coastguard Worker for (buf = ebuf, buflen = sizeof(ebuf);
174*bd1f8aebSAndroid Build Coastguard Worker buflen < SIZE_MAX / 2;
175*bd1f8aebSAndroid Build Coastguard Worker free(buf != ebuf ? buf : NULL), buf = NULL, buflen *= 2) {
176*bd1f8aebSAndroid Build Coastguard Worker size_t rem;
177*bd1f8aebSAndroid Build Coastguard Worker size_t res;
178*bd1f8aebSAndroid Build Coastguard Worker
179*bd1f8aebSAndroid Build Coastguard Worker buf = malloc(buflen);
180*bd1f8aebSAndroid Build Coastguard Worker if (!buf)
181*bd1f8aebSAndroid Build Coastguard Worker break; /*XXX*/
182*bd1f8aebSAndroid Build Coastguard Worker
183*bd1f8aebSAndroid Build Coastguard Worker rem = buflen;
184*bd1f8aebSAndroid Build Coastguard Worker
185*bd1f8aebSAndroid Build Coastguard Worker res = snprintf(buf, rem, "[%s] ", log_level(pri));
186*bd1f8aebSAndroid Build Coastguard Worker if (res >= rem)
187*bd1f8aebSAndroid Build Coastguard Worker continue;
188*bd1f8aebSAndroid Build Coastguard Worker rem -= res;
189*bd1f8aebSAndroid Build Coastguard Worker
190*bd1f8aebSAndroid Build Coastguard Worker res = vsnprintf(buf + res, rem, fmt, ap);
191*bd1f8aebSAndroid Build Coastguard Worker
192*bd1f8aebSAndroid Build Coastguard Worker if (res >= rem)
193*bd1f8aebSAndroid Build Coastguard Worker continue;
194*bd1f8aebSAndroid Build Coastguard Worker break;
195*bd1f8aebSAndroid Build Coastguard Worker }
196*bd1f8aebSAndroid Build Coastguard Worker
197*bd1f8aebSAndroid Build Coastguard Worker if (buf) {
198*bd1f8aebSAndroid Build Coastguard Worker fputs(buf, stderr);
199*bd1f8aebSAndroid Build Coastguard Worker free(buf != ebuf ? buf : NULL);
200*bd1f8aebSAndroid Build Coastguard Worker }
201*bd1f8aebSAndroid Build Coastguard Worker
202*bd1f8aebSAndroid Build Coastguard Worker va_end(ap);
203*bd1f8aebSAndroid Build Coastguard Worker }
204*bd1f8aebSAndroid Build Coastguard Worker #endif
205*bd1f8aebSAndroid Build Coastguard Worker
206*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
open_sock(void)207*bd1f8aebSAndroid Build Coastguard Worker static int __inline__ open_sock(void)
208*bd1f8aebSAndroid Build Coastguard Worker {
209*bd1f8aebSAndroid Build Coastguard Worker return socket(PF_INET6, SOCK_RAW, IPPROTO_ICMPV6);
210*bd1f8aebSAndroid Build Coastguard Worker }
211*bd1f8aebSAndroid Build Coastguard Worker
set_recvpktinfo(int sock)212*bd1f8aebSAndroid Build Coastguard Worker static int set_recvpktinfo(int sock)
213*bd1f8aebSAndroid Build Coastguard Worker {
214*bd1f8aebSAndroid Build Coastguard Worker int on, ret;
215*bd1f8aebSAndroid Build Coastguard Worker
216*bd1f8aebSAndroid Build Coastguard Worker on = 1;
217*bd1f8aebSAndroid Build Coastguard Worker
218*bd1f8aebSAndroid Build Coastguard Worker #if defined(IPV6_RECVPKTINFO)
219*bd1f8aebSAndroid Build Coastguard Worker ret = setsockopt(sock,
220*bd1f8aebSAndroid Build Coastguard Worker IPPROTO_IPV6, IPV6_RECVPKTINFO,
221*bd1f8aebSAndroid Build Coastguard Worker &on, sizeof(on));
222*bd1f8aebSAndroid Build Coastguard Worker if (!ret)
223*bd1f8aebSAndroid Build Coastguard Worker return 0;
224*bd1f8aebSAndroid Build Coastguard Worker # if defined(IPV6_2292PKTINFO)
225*bd1f8aebSAndroid Build Coastguard Worker ret = setsockopt(sock,
226*bd1f8aebSAndroid Build Coastguard Worker IPPROTO_IPV6, IPV6_2292PKTINFO,
227*bd1f8aebSAndroid Build Coastguard Worker &on, sizeof(on));
228*bd1f8aebSAndroid Build Coastguard Worker if (!ret) {
229*bd1f8aebSAndroid Build Coastguard Worker ipv6_pktinfo = IPV6_2292PKTINFO;
230*bd1f8aebSAndroid Build Coastguard Worker return 0;
231*bd1f8aebSAndroid Build Coastguard Worker }
232*bd1f8aebSAndroid Build Coastguard Worker
233*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setsockopt(IPV6_RECVPKTINFO/IPV6_2292PKTINFO): %s\n",
234*bd1f8aebSAndroid Build Coastguard Worker strerror(errno));
235*bd1f8aebSAndroid Build Coastguard Worker # else
236*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setsockopt(IPV6_RECVPKTINFO): %s\n",
237*bd1f8aebSAndroid Build Coastguard Worker strerror(errno));
238*bd1f8aebSAndroid Build Coastguard Worker # endif
239*bd1f8aebSAndroid Build Coastguard Worker #else
240*bd1f8aebSAndroid Build Coastguard Worker ret = setsockopt(sock,
241*bd1f8aebSAndroid Build Coastguard Worker IPPROTO_IPV6, IPV6_PKTINFO,
242*bd1f8aebSAndroid Build Coastguard Worker &on, sizeof(on));
243*bd1f8aebSAndroid Build Coastguard Worker if (!ret)
244*bd1f8aebSAndroid Build Coastguard Worker return 0;
245*bd1f8aebSAndroid Build Coastguard Worker
246*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setsockopt(IPV6_PKTINFO): %s\n",
247*bd1f8aebSAndroid Build Coastguard Worker strerror(errno));
248*bd1f8aebSAndroid Build Coastguard Worker #endif
249*bd1f8aebSAndroid Build Coastguard Worker
250*bd1f8aebSAndroid Build Coastguard Worker return -1;
251*bd1f8aebSAndroid Build Coastguard Worker }
252*bd1f8aebSAndroid Build Coastguard Worker
init_sock(int sock)253*bd1f8aebSAndroid Build Coastguard Worker static int __inline__ init_sock(int sock)
254*bd1f8aebSAndroid Build Coastguard Worker {
255*bd1f8aebSAndroid Build Coastguard Worker struct icmp6_filter filter;
256*bd1f8aebSAndroid Build Coastguard Worker #if NEED_IPV6CHECKSUM
257*bd1f8aebSAndroid Build Coastguard Worker int i;
258*bd1f8aebSAndroid Build Coastguard Worker
259*bd1f8aebSAndroid Build Coastguard Worker i = offsetof(struct icmp6_nodeinfo, ni_cksum);
260*bd1f8aebSAndroid Build Coastguard Worker if (setsockopt(sock,
261*bd1f8aebSAndroid Build Coastguard Worker IPPROTO_IPV6, IPV6_CHECKSUM,
262*bd1f8aebSAndroid Build Coastguard Worker &i, sizeof(i)) < 0) {
263*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setsockopt(IPV6_CHECKSUM): %s\n",
264*bd1f8aebSAndroid Build Coastguard Worker strerror(errno));
265*bd1f8aebSAndroid Build Coastguard Worker return -1;
266*bd1f8aebSAndroid Build Coastguard Worker }
267*bd1f8aebSAndroid Build Coastguard Worker #endif
268*bd1f8aebSAndroid Build Coastguard Worker
269*bd1f8aebSAndroid Build Coastguard Worker ICMP6_FILTER_SETBLOCKALL(&filter);
270*bd1f8aebSAndroid Build Coastguard Worker ICMP6_FILTER_SETPASS(ICMP6_NI_QUERY, &filter);
271*bd1f8aebSAndroid Build Coastguard Worker if (setsockopt(sock,
272*bd1f8aebSAndroid Build Coastguard Worker IPPROTO_ICMPV6, ICMP6_FILTER,
273*bd1f8aebSAndroid Build Coastguard Worker &filter, sizeof(filter)) < 0) {
274*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setsockopt(ICMP6_FILTER): %s\n",
275*bd1f8aebSAndroid Build Coastguard Worker strerror(errno));
276*bd1f8aebSAndroid Build Coastguard Worker return -1;
277*bd1f8aebSAndroid Build Coastguard Worker }
278*bd1f8aebSAndroid Build Coastguard Worker
279*bd1f8aebSAndroid Build Coastguard Worker if (set_recvpktinfo(sock) < 0)
280*bd1f8aebSAndroid Build Coastguard Worker return -1;
281*bd1f8aebSAndroid Build Coastguard Worker
282*bd1f8aebSAndroid Build Coastguard Worker return 0;
283*bd1f8aebSAndroid Build Coastguard Worker }
284*bd1f8aebSAndroid Build Coastguard Worker
285*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
ni_recv(struct packetcontext * p)286*bd1f8aebSAndroid Build Coastguard Worker int ni_recv(struct packetcontext *p)
287*bd1f8aebSAndroid Build Coastguard Worker {
288*bd1f8aebSAndroid Build Coastguard Worker int sock = p->sock;
289*bd1f8aebSAndroid Build Coastguard Worker struct iovec iov[1];
290*bd1f8aebSAndroid Build Coastguard Worker struct msghdr msgh;
291*bd1f8aebSAndroid Build Coastguard Worker char recvcbuf[CMSG_SPACE(sizeof(p->pktinfo))];
292*bd1f8aebSAndroid Build Coastguard Worker struct cmsghdr *cmsg;
293*bd1f8aebSAndroid Build Coastguard Worker int cc;
294*bd1f8aebSAndroid Build Coastguard Worker
295*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_DEBUG, "%s()\n", __func__);
296*bd1f8aebSAndroid Build Coastguard Worker
297*bd1f8aebSAndroid Build Coastguard Worker memset(&iov, 0, sizeof(iov));
298*bd1f8aebSAndroid Build Coastguard Worker iov[0].iov_base = p->query;
299*bd1f8aebSAndroid Build Coastguard Worker iov[0].iov_len = sizeof(p->query);
300*bd1f8aebSAndroid Build Coastguard Worker
301*bd1f8aebSAndroid Build Coastguard Worker memset(&msgh, 0, sizeof(msgh));
302*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_name = (struct sockaddr *)&p->addr;
303*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_namelen = sizeof(p->addr);
304*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_iov = iov;
305*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_iovlen = 1;
306*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_control = recvcbuf;
307*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_controllen = sizeof(recvcbuf);
308*bd1f8aebSAndroid Build Coastguard Worker
309*bd1f8aebSAndroid Build Coastguard Worker if ((cc = recvmsg(sock, &msgh, 0)) < 0)
310*bd1f8aebSAndroid Build Coastguard Worker return -1;
311*bd1f8aebSAndroid Build Coastguard Worker
312*bd1f8aebSAndroid Build Coastguard Worker p->querylen = cc;
313*bd1f8aebSAndroid Build Coastguard Worker p->addrlen = msgh.msg_namelen;
314*bd1f8aebSAndroid Build Coastguard Worker
315*bd1f8aebSAndroid Build Coastguard Worker for (cmsg = CMSG_FIRSTHDR(&msgh); cmsg;
316*bd1f8aebSAndroid Build Coastguard Worker cmsg = CMSG_NXTHDR(&msgh, cmsg)) {
317*bd1f8aebSAndroid Build Coastguard Worker if (cmsg->cmsg_level == IPPROTO_IPV6 &&
318*bd1f8aebSAndroid Build Coastguard Worker (cmsg->cmsg_type == IPV6_PKTINFO
319*bd1f8aebSAndroid Build Coastguard Worker #if defined(IPV6_2292PKTINFO)
320*bd1f8aebSAndroid Build Coastguard Worker || cmsg->cmsg_type == IPV6_2292PKTINFO
321*bd1f8aebSAndroid Build Coastguard Worker #endif
322*bd1f8aebSAndroid Build Coastguard Worker )) {
323*bd1f8aebSAndroid Build Coastguard Worker memcpy(&p->pktinfo, CMSG_DATA(cmsg), sizeof(p->pktinfo));
324*bd1f8aebSAndroid Build Coastguard Worker break;
325*bd1f8aebSAndroid Build Coastguard Worker }
326*bd1f8aebSAndroid Build Coastguard Worker }
327*bd1f8aebSAndroid Build Coastguard Worker
328*bd1f8aebSAndroid Build Coastguard Worker return 0;
329*bd1f8aebSAndroid Build Coastguard Worker }
330*bd1f8aebSAndroid Build Coastguard Worker
ni_send(struct packetcontext * p)331*bd1f8aebSAndroid Build Coastguard Worker int ni_send(struct packetcontext *p)
332*bd1f8aebSAndroid Build Coastguard Worker {
333*bd1f8aebSAndroid Build Coastguard Worker int sock = p->sock;
334*bd1f8aebSAndroid Build Coastguard Worker struct iovec iov[2];
335*bd1f8aebSAndroid Build Coastguard Worker char cbuf[CMSG_SPACE(sizeof(p->pktinfo))];
336*bd1f8aebSAndroid Build Coastguard Worker struct msghdr msgh;
337*bd1f8aebSAndroid Build Coastguard Worker struct cmsghdr *cmsg;
338*bd1f8aebSAndroid Build Coastguard Worker int cc;
339*bd1f8aebSAndroid Build Coastguard Worker
340*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_DEBUG, "%s()\n", __func__);
341*bd1f8aebSAndroid Build Coastguard Worker
342*bd1f8aebSAndroid Build Coastguard Worker memset(&iov, 0, sizeof(iov));
343*bd1f8aebSAndroid Build Coastguard Worker iov[0].iov_base = &p->reply;
344*bd1f8aebSAndroid Build Coastguard Worker iov[0].iov_len = sizeof(p->reply);
345*bd1f8aebSAndroid Build Coastguard Worker iov[1].iov_base = p->replydata;
346*bd1f8aebSAndroid Build Coastguard Worker iov[1].iov_len = p->replydatalen;
347*bd1f8aebSAndroid Build Coastguard Worker
348*bd1f8aebSAndroid Build Coastguard Worker memset(&msgh, 0, sizeof(msgh));
349*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_name = (struct sockaddr *)&p->addr;
350*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_namelen = p->addrlen;
351*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_iov = iov;
352*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_iovlen = p->replydata ? 2 : 1;
353*bd1f8aebSAndroid Build Coastguard Worker
354*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_control = cbuf;
355*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_controllen = sizeof(cbuf);
356*bd1f8aebSAndroid Build Coastguard Worker
357*bd1f8aebSAndroid Build Coastguard Worker cmsg = CMSG_FIRSTHDR(&msgh);
358*bd1f8aebSAndroid Build Coastguard Worker cmsg->cmsg_level = IPPROTO_IPV6;
359*bd1f8aebSAndroid Build Coastguard Worker cmsg->cmsg_type = ipv6_pktinfo;
360*bd1f8aebSAndroid Build Coastguard Worker cmsg->cmsg_len = CMSG_LEN(sizeof(p->pktinfo));
361*bd1f8aebSAndroid Build Coastguard Worker memcpy(CMSG_DATA(cmsg), &p->pktinfo, sizeof(p->pktinfo));
362*bd1f8aebSAndroid Build Coastguard Worker
363*bd1f8aebSAndroid Build Coastguard Worker msgh.msg_controllen = cmsg->cmsg_len;
364*bd1f8aebSAndroid Build Coastguard Worker
365*bd1f8aebSAndroid Build Coastguard Worker if (p->delay) {
366*bd1f8aebSAndroid Build Coastguard Worker #if HAVE_NANOSLEEP
367*bd1f8aebSAndroid Build Coastguard Worker struct timespec ts, rts;
368*bd1f8aebSAndroid Build Coastguard Worker int err = 0;
369*bd1f8aebSAndroid Build Coastguard Worker
370*bd1f8aebSAndroid Build Coastguard Worker rts.tv_sec = p->delay / 1000000;
371*bd1f8aebSAndroid Build Coastguard Worker rts.tv_nsec = (long)(p->delay % 1000000) * 1000;
372*bd1f8aebSAndroid Build Coastguard Worker
373*bd1f8aebSAndroid Build Coastguard Worker do {
374*bd1f8aebSAndroid Build Coastguard Worker ts = rts;
375*bd1f8aebSAndroid Build Coastguard Worker err = nanosleep(&ts, &rts);
376*bd1f8aebSAndroid Build Coastguard Worker } while(err < 0);
377*bd1f8aebSAndroid Build Coastguard Worker #else
378*bd1f8aebSAndroid Build Coastguard Worker usleep(p->delay); /*XXX: signal*/
379*bd1f8aebSAndroid Build Coastguard Worker #endif
380*bd1f8aebSAndroid Build Coastguard Worker }
381*bd1f8aebSAndroid Build Coastguard Worker
382*bd1f8aebSAndroid Build Coastguard Worker cc = sendmsg(sock, &msgh, 0);
383*bd1f8aebSAndroid Build Coastguard Worker if (cc < 0)
384*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_DEBUG, "sendmsg(): %s\n", strerror(errno));
385*bd1f8aebSAndroid Build Coastguard Worker
386*bd1f8aebSAndroid Build Coastguard Worker ni_free(p->replydata);
387*bd1f8aebSAndroid Build Coastguard Worker ni_free(p);
388*bd1f8aebSAndroid Build Coastguard Worker
389*bd1f8aebSAndroid Build Coastguard Worker return cc;
390*bd1f8aebSAndroid Build Coastguard Worker }
391*bd1f8aebSAndroid Build Coastguard Worker
392*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
sig_handler(int sig)393*bd1f8aebSAndroid Build Coastguard Worker static void sig_handler(int sig)
394*bd1f8aebSAndroid Build Coastguard Worker {
395*bd1f8aebSAndroid Build Coastguard Worker if (!got_signal)
396*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_INFO, "singnal(%d) received, quitting.\n", sig);
397*bd1f8aebSAndroid Build Coastguard Worker got_signal = 1;
398*bd1f8aebSAndroid Build Coastguard Worker }
399*bd1f8aebSAndroid Build Coastguard Worker
setup_sighandlers(void)400*bd1f8aebSAndroid Build Coastguard Worker static void setup_sighandlers(void)
401*bd1f8aebSAndroid Build Coastguard Worker {
402*bd1f8aebSAndroid Build Coastguard Worker struct sigaction act;
403*bd1f8aebSAndroid Build Coastguard Worker sigset_t smask;
404*bd1f8aebSAndroid Build Coastguard Worker sigemptyset(&smask);
405*bd1f8aebSAndroid Build Coastguard Worker sigaddset(&smask, SIGHUP);
406*bd1f8aebSAndroid Build Coastguard Worker sigaddset(&smask, SIGINT);
407*bd1f8aebSAndroid Build Coastguard Worker sigaddset(&smask, SIGQUIT);
408*bd1f8aebSAndroid Build Coastguard Worker sigaddset(&smask, SIGTERM);
409*bd1f8aebSAndroid Build Coastguard Worker
410*bd1f8aebSAndroid Build Coastguard Worker memset(&act, 0, sizeof(act));
411*bd1f8aebSAndroid Build Coastguard Worker act.sa_handler = sig_handler;
412*bd1f8aebSAndroid Build Coastguard Worker act.sa_mask = smask;
413*bd1f8aebSAndroid Build Coastguard Worker
414*bd1f8aebSAndroid Build Coastguard Worker sigaction(SIGHUP, &act, NULL);
415*bd1f8aebSAndroid Build Coastguard Worker sigaction(SIGINT, &act, NULL);
416*bd1f8aebSAndroid Build Coastguard Worker sigaction(SIGQUIT, &act, NULL);
417*bd1f8aebSAndroid Build Coastguard Worker sigaction(SIGTERM, &act, NULL);
418*bd1f8aebSAndroid Build Coastguard Worker }
419*bd1f8aebSAndroid Build Coastguard Worker
set_logfile(void)420*bd1f8aebSAndroid Build Coastguard Worker static void set_logfile(void)
421*bd1f8aebSAndroid Build Coastguard Worker {
422*bd1f8aebSAndroid Build Coastguard Worker setbuf(stderr, NULL);
423*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
424*bd1f8aebSAndroid Build Coastguard Worker openlog(NINFOD, 0, LOG_USER);
425*bd1f8aebSAndroid Build Coastguard Worker #endif
426*bd1f8aebSAndroid Build Coastguard Worker }
427*bd1f8aebSAndroid Build Coastguard Worker
cleanup_pidfile(void)428*bd1f8aebSAndroid Build Coastguard Worker static void cleanup_pidfile(void)
429*bd1f8aebSAndroid Build Coastguard Worker {
430*bd1f8aebSAndroid Build Coastguard Worker int err;
431*bd1f8aebSAndroid Build Coastguard Worker
432*bd1f8aebSAndroid Build Coastguard Worker if (daemonized && opt_p) {
433*bd1f8aebSAndroid Build Coastguard Worker err = unlink(opt_p);
434*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "failed to unlink file '%s' : %s\n",
435*bd1f8aebSAndroid Build Coastguard Worker opt_p, strerror(errno));
436*bd1f8aebSAndroid Build Coastguard Worker }
437*bd1f8aebSAndroid Build Coastguard Worker }
438*bd1f8aebSAndroid Build Coastguard Worker
fopen_excl(const char * file)439*bd1f8aebSAndroid Build Coastguard Worker static FILE *fopen_excl(const char *file)
440*bd1f8aebSAndroid Build Coastguard Worker {
441*bd1f8aebSAndroid Build Coastguard Worker #ifndef __linux__
442*bd1f8aebSAndroid Build Coastguard Worker int fd;
443*bd1f8aebSAndroid Build Coastguard Worker FILE *fp;
444*bd1f8aebSAndroid Build Coastguard Worker
445*bd1f8aebSAndroid Build Coastguard Worker fd = open(file, O_CREAT | O_RDWR | O_EXCL,
446*bd1f8aebSAndroid Build Coastguard Worker S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);
447*bd1f8aebSAndroid Build Coastguard Worker if (fd < 0)
448*bd1f8aebSAndroid Build Coastguard Worker return NULL;
449*bd1f8aebSAndroid Build Coastguard Worker
450*bd1f8aebSAndroid Build Coastguard Worker return fdopen(file, "w+");
451*bd1f8aebSAndroid Build Coastguard Worker #else
452*bd1f8aebSAndroid Build Coastguard Worker return fopen(file, "w+x");
453*bd1f8aebSAndroid Build Coastguard Worker #endif
454*bd1f8aebSAndroid Build Coastguard Worker }
455*bd1f8aebSAndroid Build Coastguard Worker
do_daemonize(void)456*bd1f8aebSAndroid Build Coastguard Worker static void do_daemonize(void)
457*bd1f8aebSAndroid Build Coastguard Worker {
458*bd1f8aebSAndroid Build Coastguard Worker FILE *fp = NULL;
459*bd1f8aebSAndroid Build Coastguard Worker pid_t pid;
460*bd1f8aebSAndroid Build Coastguard Worker
461*bd1f8aebSAndroid Build Coastguard Worker if (opt_p) {
462*bd1f8aebSAndroid Build Coastguard Worker if (!access(opt_p, R_OK)) {
463*bd1f8aebSAndroid Build Coastguard Worker if ((fp = fopen(opt_p, "r"))) {
464*bd1f8aebSAndroid Build Coastguard Worker if (fscanf(fp, "%d", &pid) != 1) {
465*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "pid file '%s' exists, but read failed.\n",
466*bd1f8aebSAndroid Build Coastguard Worker opt_p);
467*bd1f8aebSAndroid Build Coastguard Worker } else {
468*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "pid file '%s' exists : %d\n",
469*bd1f8aebSAndroid Build Coastguard Worker opt_p, pid);
470*bd1f8aebSAndroid Build Coastguard Worker }
471*bd1f8aebSAndroid Build Coastguard Worker fclose(fp);
472*bd1f8aebSAndroid Build Coastguard Worker exit(1);
473*bd1f8aebSAndroid Build Coastguard Worker }
474*bd1f8aebSAndroid Build Coastguard Worker }
475*bd1f8aebSAndroid Build Coastguard Worker
476*bd1f8aebSAndroid Build Coastguard Worker fp = fopen_excl(opt_p);
477*bd1f8aebSAndroid Build Coastguard Worker if (!fp) {
478*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "failed to open file '%s': %s\n",
479*bd1f8aebSAndroid Build Coastguard Worker opt_p, strerror(errno));
480*bd1f8aebSAndroid Build Coastguard Worker exit(1);
481*bd1f8aebSAndroid Build Coastguard Worker }
482*bd1f8aebSAndroid Build Coastguard Worker }
483*bd1f8aebSAndroid Build Coastguard Worker
484*bd1f8aebSAndroid Build Coastguard Worker if (daemon(0, 0) < 0) {
485*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "failed to daemon(): %s\n", strerror(errno));
486*bd1f8aebSAndroid Build Coastguard Worker unlink(opt_p);
487*bd1f8aebSAndroid Build Coastguard Worker exit(1);
488*bd1f8aebSAndroid Build Coastguard Worker }
489*bd1f8aebSAndroid Build Coastguard Worker daemonized = 1;
490*bd1f8aebSAndroid Build Coastguard Worker
491*bd1f8aebSAndroid Build Coastguard Worker if (fp) {
492*bd1f8aebSAndroid Build Coastguard Worker fprintf(fp, "%d\n", getpid());
493*bd1f8aebSAndroid Build Coastguard Worker fclose(fp);
494*bd1f8aebSAndroid Build Coastguard Worker }
495*bd1f8aebSAndroid Build Coastguard Worker }
496*bd1f8aebSAndroid Build Coastguard Worker
497*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
498*bd1f8aebSAndroid Build Coastguard Worker #ifdef HAVE_LIBCAP
499*bd1f8aebSAndroid Build Coastguard Worker static const cap_value_t cap_net_raw = CAP_NET_RAW;
500*bd1f8aebSAndroid Build Coastguard Worker static const cap_value_t cap_setuid = CAP_SETUID;
501*bd1f8aebSAndroid Build Coastguard Worker static cap_flag_value_t cap_ok;
502*bd1f8aebSAndroid Build Coastguard Worker #else
503*bd1f8aebSAndroid Build Coastguard Worker static uid_t euid;
504*bd1f8aebSAndroid Build Coastguard Worker #endif
505*bd1f8aebSAndroid Build Coastguard Worker
limit_capabilities(void)506*bd1f8aebSAndroid Build Coastguard Worker static void limit_capabilities(void)
507*bd1f8aebSAndroid Build Coastguard Worker {
508*bd1f8aebSAndroid Build Coastguard Worker #ifdef HAVE_LIBCAP
509*bd1f8aebSAndroid Build Coastguard Worker cap_t cap_p, cap_cur_p;
510*bd1f8aebSAndroid Build Coastguard Worker
511*bd1f8aebSAndroid Build Coastguard Worker cap_p = cap_init();
512*bd1f8aebSAndroid Build Coastguard Worker if (!cap_p) {
513*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_init: %s\n", strerror(errno));
514*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
515*bd1f8aebSAndroid Build Coastguard Worker }
516*bd1f8aebSAndroid Build Coastguard Worker
517*bd1f8aebSAndroid Build Coastguard Worker cap_cur_p = cap_get_proc();
518*bd1f8aebSAndroid Build Coastguard Worker if (!cap_cur_p) {
519*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_get_proc: %s\n", strerror(errno));
520*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
521*bd1f8aebSAndroid Build Coastguard Worker }
522*bd1f8aebSAndroid Build Coastguard Worker
523*bd1f8aebSAndroid Build Coastguard Worker /* net_raw + setuid / net_raw */
524*bd1f8aebSAndroid Build Coastguard Worker cap_get_flag(cap_cur_p, CAP_NET_RAW, CAP_PERMITTED, &cap_ok);
525*bd1f8aebSAndroid Build Coastguard Worker if (cap_ok != CAP_CLEAR) {
526*bd1f8aebSAndroid Build Coastguard Worker cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_net_raw, CAP_SET);
527*bd1f8aebSAndroid Build Coastguard Worker cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap_net_raw, CAP_SET);
528*bd1f8aebSAndroid Build Coastguard Worker }
529*bd1f8aebSAndroid Build Coastguard Worker
530*bd1f8aebSAndroid Build Coastguard Worker cap_get_flag(cap_cur_p, CAP_SETUID, CAP_PERMITTED, &cap_ok);
531*bd1f8aebSAndroid Build Coastguard Worker if (cap_ok != CAP_CLEAR)
532*bd1f8aebSAndroid Build Coastguard Worker cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuid, CAP_SET);
533*bd1f8aebSAndroid Build Coastguard Worker
534*bd1f8aebSAndroid Build Coastguard Worker if (cap_set_proc(cap_p) < 0) {
535*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_set_proc: %s\n", strerror(errno));
536*bd1f8aebSAndroid Build Coastguard Worker if (errno != EPERM)
537*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
538*bd1f8aebSAndroid Build Coastguard Worker }
539*bd1f8aebSAndroid Build Coastguard Worker
540*bd1f8aebSAndroid Build Coastguard Worker if (prctl(PR_SET_KEEPCAPS, 1) < 0) {
541*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "prctl: %s\n", strerror(errno));
542*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
543*bd1f8aebSAndroid Build Coastguard Worker }
544*bd1f8aebSAndroid Build Coastguard Worker
545*bd1f8aebSAndroid Build Coastguard Worker cap_free(cap_cur_p);
546*bd1f8aebSAndroid Build Coastguard Worker cap_free(cap_p);
547*bd1f8aebSAndroid Build Coastguard Worker #else
548*bd1f8aebSAndroid Build Coastguard Worker euid = geteuid();
549*bd1f8aebSAndroid Build Coastguard Worker #endif
550*bd1f8aebSAndroid Build Coastguard Worker }
551*bd1f8aebSAndroid Build Coastguard Worker
drop_capabilities(void)552*bd1f8aebSAndroid Build Coastguard Worker static void drop_capabilities(void)
553*bd1f8aebSAndroid Build Coastguard Worker {
554*bd1f8aebSAndroid Build Coastguard Worker #ifdef HAVE_LIBCAP
555*bd1f8aebSAndroid Build Coastguard Worker cap_t cap_p;
556*bd1f8aebSAndroid Build Coastguard Worker
557*bd1f8aebSAndroid Build Coastguard Worker cap_p = cap_init();
558*bd1f8aebSAndroid Build Coastguard Worker if (!cap_p) {
559*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_init: %s\n", strerror(errno));
560*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
561*bd1f8aebSAndroid Build Coastguard Worker }
562*bd1f8aebSAndroid Build Coastguard Worker
563*bd1f8aebSAndroid Build Coastguard Worker /* setuid / setuid */
564*bd1f8aebSAndroid Build Coastguard Worker if (cap_ok != CAP_CLEAR) {
565*bd1f8aebSAndroid Build Coastguard Worker cap_set_flag(cap_p, CAP_PERMITTED, 1, &cap_setuid, CAP_SET);
566*bd1f8aebSAndroid Build Coastguard Worker cap_set_flag(cap_p, CAP_EFFECTIVE, 1, &cap_setuid, CAP_SET);
567*bd1f8aebSAndroid Build Coastguard Worker
568*bd1f8aebSAndroid Build Coastguard Worker if (cap_set_proc(cap_p) < 0) {
569*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_set_proc: %s\n", strerror(errno));
570*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
571*bd1f8aebSAndroid Build Coastguard Worker }
572*bd1f8aebSAndroid Build Coastguard Worker }
573*bd1f8aebSAndroid Build Coastguard Worker
574*bd1f8aebSAndroid Build Coastguard Worker if (seteuid(opt_u ? opt_u : getuid()) < 0) {
575*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setuid: %s\n", strerror(errno));
576*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
577*bd1f8aebSAndroid Build Coastguard Worker }
578*bd1f8aebSAndroid Build Coastguard Worker
579*bd1f8aebSAndroid Build Coastguard Worker if (prctl(PR_SET_KEEPCAPS, 0) < 0) {
580*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "prctl: %s\n", strerror(errno));
581*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
582*bd1f8aebSAndroid Build Coastguard Worker }
583*bd1f8aebSAndroid Build Coastguard Worker
584*bd1f8aebSAndroid Build Coastguard Worker cap_clear(cap_p);
585*bd1f8aebSAndroid Build Coastguard Worker if (cap_set_proc(cap_p) < 0) {
586*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "cap_set_proc: %s\n", strerror(errno));
587*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
588*bd1f8aebSAndroid Build Coastguard Worker }
589*bd1f8aebSAndroid Build Coastguard Worker
590*bd1f8aebSAndroid Build Coastguard Worker cap_free(cap_p);
591*bd1f8aebSAndroid Build Coastguard Worker #else
592*bd1f8aebSAndroid Build Coastguard Worker if (setuid(getuid()) < 0) {
593*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "setuid: %s\n", strerror(errno));
594*bd1f8aebSAndroid Build Coastguard Worker exit(-1);
595*bd1f8aebSAndroid Build Coastguard Worker }
596*bd1f8aebSAndroid Build Coastguard Worker #endif
597*bd1f8aebSAndroid Build Coastguard Worker }
598*bd1f8aebSAndroid Build Coastguard Worker
599*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
parse_args(int argc,char ** argv)600*bd1f8aebSAndroid Build Coastguard Worker static void parse_args(int argc, char **argv)
601*bd1f8aebSAndroid Build Coastguard Worker {
602*bd1f8aebSAndroid Build Coastguard Worker int c;
603*bd1f8aebSAndroid Build Coastguard Worker unsigned long val;
604*bd1f8aebSAndroid Build Coastguard Worker char *ep;
605*bd1f8aebSAndroid Build Coastguard Worker
606*bd1f8aebSAndroid Build Coastguard Worker /* parse options */
607*bd1f8aebSAndroid Build Coastguard Worker while ((c = getopt(argc, argv, "dhvp:u:")) != -1) {
608*bd1f8aebSAndroid Build Coastguard Worker switch(c) {
609*bd1f8aebSAndroid Build Coastguard Worker case 'd': /* debug */
610*bd1f8aebSAndroid Build Coastguard Worker opt_d = 1;
611*bd1f8aebSAndroid Build Coastguard Worker break;
612*bd1f8aebSAndroid Build Coastguard Worker case 'v': /* verbose */
613*bd1f8aebSAndroid Build Coastguard Worker opt_v = 1;
614*bd1f8aebSAndroid Build Coastguard Worker break;
615*bd1f8aebSAndroid Build Coastguard Worker case 'p':
616*bd1f8aebSAndroid Build Coastguard Worker opt_p = optarg;
617*bd1f8aebSAndroid Build Coastguard Worker break;
618*bd1f8aebSAndroid Build Coastguard Worker case 'u':
619*bd1f8aebSAndroid Build Coastguard Worker val = strtoul(optarg, &ep, 10);
620*bd1f8aebSAndroid Build Coastguard Worker if (!optarg || *ep) {
621*bd1f8aebSAndroid Build Coastguard Worker struct passwd *pw = getpwnam(optarg);
622*bd1f8aebSAndroid Build Coastguard Worker if (!pw) {
623*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "No such user: %s", optarg);
624*bd1f8aebSAndroid Build Coastguard Worker exit(1);
625*bd1f8aebSAndroid Build Coastguard Worker }
626*bd1f8aebSAndroid Build Coastguard Worker opt_u = pw->pw_uid;
627*bd1f8aebSAndroid Build Coastguard Worker } else
628*bd1f8aebSAndroid Build Coastguard Worker opt_u = val;
629*bd1f8aebSAndroid Build Coastguard Worker break;
630*bd1f8aebSAndroid Build Coastguard Worker case 'h': /* help */
631*bd1f8aebSAndroid Build Coastguard Worker default:
632*bd1f8aebSAndroid Build Coastguard Worker opt_h = 1;
633*bd1f8aebSAndroid Build Coastguard Worker break;
634*bd1f8aebSAndroid Build Coastguard Worker }
635*bd1f8aebSAndroid Build Coastguard Worker }
636*bd1f8aebSAndroid Build Coastguard Worker
637*bd1f8aebSAndroid Build Coastguard Worker argc -= optind;
638*bd1f8aebSAndroid Build Coastguard Worker #if 0
639*bd1f8aebSAndroid Build Coastguard Worker argv += optind;
640*bd1f8aebSAndroid Build Coastguard Worker #endif
641*bd1f8aebSAndroid Build Coastguard Worker
642*bd1f8aebSAndroid Build Coastguard Worker if (argc)
643*bd1f8aebSAndroid Build Coastguard Worker opt_h = 1;
644*bd1f8aebSAndroid Build Coastguard Worker }
645*bd1f8aebSAndroid Build Coastguard Worker
print_copying(void)646*bd1f8aebSAndroid Build Coastguard Worker static void print_copying(void) {
647*bd1f8aebSAndroid Build Coastguard Worker fprintf(stderr,
648*bd1f8aebSAndroid Build Coastguard Worker "Node Information Daemon\n"
649*bd1f8aebSAndroid Build Coastguard Worker "Copyright (C)2002 USAGI/WIDE Project. All Rights Reserved.\n"
650*bd1f8aebSAndroid Build Coastguard Worker "\n"
651*bd1f8aebSAndroid Build Coastguard Worker );
652*bd1f8aebSAndroid Build Coastguard Worker }
653*bd1f8aebSAndroid Build Coastguard Worker
print_usage(void)654*bd1f8aebSAndroid Build Coastguard Worker static void print_usage(void) {
655*bd1f8aebSAndroid Build Coastguard Worker fprintf(stderr,
656*bd1f8aebSAndroid Build Coastguard Worker "Usage: %s [-d] [-p pidfile] [-u user] [-h] [-v]\n\n",
657*bd1f8aebSAndroid Build Coastguard Worker appname
658*bd1f8aebSAndroid Build Coastguard Worker );
659*bd1f8aebSAndroid Build Coastguard Worker }
660*bd1f8aebSAndroid Build Coastguard Worker
661*bd1f8aebSAndroid Build Coastguard Worker /* --------- */
main(int argc,char ** argv)662*bd1f8aebSAndroid Build Coastguard Worker int main (int argc, char **argv)
663*bd1f8aebSAndroid Build Coastguard Worker {
664*bd1f8aebSAndroid Build Coastguard Worker int sock_errno = 0;
665*bd1f8aebSAndroid Build Coastguard Worker int ret;
666*bd1f8aebSAndroid Build Coastguard Worker
667*bd1f8aebSAndroid Build Coastguard Worker appname = argv[0];
668*bd1f8aebSAndroid Build Coastguard Worker set_logfile();
669*bd1f8aebSAndroid Build Coastguard Worker
670*bd1f8aebSAndroid Build Coastguard Worker limit_capabilities();
671*bd1f8aebSAndroid Build Coastguard Worker
672*bd1f8aebSAndroid Build Coastguard Worker sock = open_sock();
673*bd1f8aebSAndroid Build Coastguard Worker if (sock < 0)
674*bd1f8aebSAndroid Build Coastguard Worker sock_errno = errno;
675*bd1f8aebSAndroid Build Coastguard Worker
676*bd1f8aebSAndroid Build Coastguard Worker parse_args(argc, argv);
677*bd1f8aebSAndroid Build Coastguard Worker
678*bd1f8aebSAndroid Build Coastguard Worker drop_capabilities();
679*bd1f8aebSAndroid Build Coastguard Worker
680*bd1f8aebSAndroid Build Coastguard Worker if (opt_h || opt_v)
681*bd1f8aebSAndroid Build Coastguard Worker print_copying();
682*bd1f8aebSAndroid Build Coastguard Worker if (opt_h) {
683*bd1f8aebSAndroid Build Coastguard Worker print_usage();
684*bd1f8aebSAndroid Build Coastguard Worker exit(1);
685*bd1f8aebSAndroid Build Coastguard Worker }
686*bd1f8aebSAndroid Build Coastguard Worker
687*bd1f8aebSAndroid Build Coastguard Worker if (sock_errno) {
688*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_ERR, "socket: %s\n", strerror(sock_errno));
689*bd1f8aebSAndroid Build Coastguard Worker exit(1);
690*bd1f8aebSAndroid Build Coastguard Worker }
691*bd1f8aebSAndroid Build Coastguard Worker
692*bd1f8aebSAndroid Build Coastguard Worker /* initialize */
693*bd1f8aebSAndroid Build Coastguard Worker if (init_sock(sock) < 0)
694*bd1f8aebSAndroid Build Coastguard Worker exit(1);
695*bd1f8aebSAndroid Build Coastguard Worker
696*bd1f8aebSAndroid Build Coastguard Worker setup_sighandlers();
697*bd1f8aebSAndroid Build Coastguard Worker if (!opt_d)
698*bd1f8aebSAndroid Build Coastguard Worker do_daemonize();
699*bd1f8aebSAndroid Build Coastguard Worker
700*bd1f8aebSAndroid Build Coastguard Worker init_core(1);
701*bd1f8aebSAndroid Build Coastguard Worker
702*bd1f8aebSAndroid Build Coastguard Worker /* main loop */
703*bd1f8aebSAndroid Build Coastguard Worker while (!got_signal) {
704*bd1f8aebSAndroid Build Coastguard Worker struct packetcontext *p;
705*bd1f8aebSAndroid Build Coastguard Worker struct icmp6_hdr *icmph;
706*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
707*bd1f8aebSAndroid Build Coastguard Worker char saddrbuf[NI_MAXHOST];
708*bd1f8aebSAndroid Build Coastguard Worker int gni;
709*bd1f8aebSAndroid Build Coastguard Worker #endif
710*bd1f8aebSAndroid Build Coastguard Worker
711*bd1f8aebSAndroid Build Coastguard Worker init_core(0);
712*bd1f8aebSAndroid Build Coastguard Worker
713*bd1f8aebSAndroid Build Coastguard Worker p = ni_malloc(sizeof(*p));
714*bd1f8aebSAndroid Build Coastguard Worker if (!p) {
715*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_WARNING, "%s(): failed to allocate packet context; sleep 1 sec.\n",
716*bd1f8aebSAndroid Build Coastguard Worker __func__);
717*bd1f8aebSAndroid Build Coastguard Worker sleep(1);
718*bd1f8aebSAndroid Build Coastguard Worker continue;
719*bd1f8aebSAndroid Build Coastguard Worker }
720*bd1f8aebSAndroid Build Coastguard Worker
721*bd1f8aebSAndroid Build Coastguard Worker while (!got_signal) {
722*bd1f8aebSAndroid Build Coastguard Worker memset(p, 0, sizeof(*p));
723*bd1f8aebSAndroid Build Coastguard Worker p->sock = sock;
724*bd1f8aebSAndroid Build Coastguard Worker
725*bd1f8aebSAndroid Build Coastguard Worker if (ni_recv(p) < 0) {
726*bd1f8aebSAndroid Build Coastguard Worker if (got_signal)
727*bd1f8aebSAndroid Build Coastguard Worker break;
728*bd1f8aebSAndroid Build Coastguard Worker if (errno == EAGAIN || errno == EINTR)
729*bd1f8aebSAndroid Build Coastguard Worker continue;
730*bd1f8aebSAndroid Build Coastguard Worker /* XXX: syslog */
731*bd1f8aebSAndroid Build Coastguard Worker continue;
732*bd1f8aebSAndroid Build Coastguard Worker }
733*bd1f8aebSAndroid Build Coastguard Worker break;
734*bd1f8aebSAndroid Build Coastguard Worker }
735*bd1f8aebSAndroid Build Coastguard Worker
736*bd1f8aebSAndroid Build Coastguard Worker #if ENABLE_DEBUG
737*bd1f8aebSAndroid Build Coastguard Worker gni = getnameinfo((struct sockaddr *)&p->addr,
738*bd1f8aebSAndroid Build Coastguard Worker p->addrlen,
739*bd1f8aebSAndroid Build Coastguard Worker saddrbuf, sizeof(saddrbuf),
740*bd1f8aebSAndroid Build Coastguard Worker NULL, 0,
741*bd1f8aebSAndroid Build Coastguard Worker NI_NUMERICHOST);
742*bd1f8aebSAndroid Build Coastguard Worker if (gni)
743*bd1f8aebSAndroid Build Coastguard Worker sprintf(saddrbuf, "???");
744*bd1f8aebSAndroid Build Coastguard Worker #endif
745*bd1f8aebSAndroid Build Coastguard Worker init_core(0);
746*bd1f8aebSAndroid Build Coastguard Worker
747*bd1f8aebSAndroid Build Coastguard Worker if (p->querylen < sizeof(struct icmp6_hdr)) {
748*bd1f8aebSAndroid Build Coastguard Worker ni_free(p);
749*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_WARNING, "Too short icmp message from %s\n", saddrbuf);
750*bd1f8aebSAndroid Build Coastguard Worker continue;
751*bd1f8aebSAndroid Build Coastguard Worker }
752*bd1f8aebSAndroid Build Coastguard Worker
753*bd1f8aebSAndroid Build Coastguard Worker icmph = (struct icmp6_hdr *)p->query;
754*bd1f8aebSAndroid Build Coastguard Worker
755*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_DEBUG,
756*bd1f8aebSAndroid Build Coastguard Worker "type=%d, code=%d, cksum=0x%04x\n",
757*bd1f8aebSAndroid Build Coastguard Worker icmph->icmp6_type, icmph->icmp6_code,
758*bd1f8aebSAndroid Build Coastguard Worker ntohs(icmph->icmp6_cksum));
759*bd1f8aebSAndroid Build Coastguard Worker
760*bd1f8aebSAndroid Build Coastguard Worker if (icmph->icmp6_type != ICMP6_NI_QUERY) {
761*bd1f8aebSAndroid Build Coastguard Worker DEBUG(LOG_WARNING,
762*bd1f8aebSAndroid Build Coastguard Worker "Strange icmp type %d from %s\n",
763*bd1f8aebSAndroid Build Coastguard Worker icmph->icmp6_type, saddrbuf);
764*bd1f8aebSAndroid Build Coastguard Worker ni_free(p);
765*bd1f8aebSAndroid Build Coastguard Worker continue;
766*bd1f8aebSAndroid Build Coastguard Worker }
767*bd1f8aebSAndroid Build Coastguard Worker
768*bd1f8aebSAndroid Build Coastguard Worker pr_nodeinfo(p); /* this frees p */
769*bd1f8aebSAndroid Build Coastguard Worker }
770*bd1f8aebSAndroid Build Coastguard Worker
771*bd1f8aebSAndroid Build Coastguard Worker cleanup_pidfile();
772*bd1f8aebSAndroid Build Coastguard Worker
773*bd1f8aebSAndroid Build Coastguard Worker exit(0);
774*bd1f8aebSAndroid Build Coastguard Worker }
775*bd1f8aebSAndroid Build Coastguard Worker
776