GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.sbin/rarpd/rarpd.c Lines: 0 269 0.0 %
Date: 2017-11-07 Branches: 0 180 0.0 %

Line Branch Exec Source
1
/*	$OpenBSD: rarpd.c,v 1.72 2017/04/19 05:36:13 natano Exp $ */
2
/*	$NetBSD: rarpd.c,v 1.25 1998/04/23 02:48:33 mrg Exp $	*/
3
4
/*
5
 * Copyright (c) 1990 The Regents of the University of California.
6
 * All rights reserved.
7
 *
8
 * Redistribution and use in source and binary forms, with or without
9
 * modification, are permitted provided that: (1) source code distributions
10
 * retain the above copyright notice and this paragraph in its entirety, (2)
11
 * distributions including binary code include the above copyright notice and
12
 * this paragraph in its entirety in the documentation or other materials
13
 * provided with the distribution, and (3) all advertising materials mentioning
14
 * features or use of this software display the following acknowledgement:
15
 * ``This product includes software developed by the University of California,
16
 * Lawrence Berkeley Laboratory and its contributors.'' Neither the name of
17
 * the University nor the names of its contributors may be used to endorse
18
 * or promote products derived from this software without specific prior
19
 * written permission.
20
 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
21
 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
22
 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
23
 */
24
25
/*
26
 * rarpd - Reverse ARP Daemon
27
 */
28
29
#include <sys/time.h>
30
#include <sys/file.h>
31
#include <sys/socket.h>
32
#include <sys/ioctl.h>
33
#include <net/bpf.h>
34
#include <net/if.h>
35
#include <net/if_dl.h>
36
#include <net/if_types.h>
37
#include <netinet/in.h>
38
#include <netinet/if_ether.h>
39
40
#include <stdio.h>
41
#include <stdlib.h>
42
#include <syslog.h>
43
#include <string.h>
44
#include <stdarg.h>
45
#include <unistd.h>
46
#include <limits.h>
47
#include <errno.h>
48
#include <netdb.h>
49
#include <arpa/inet.h>
50
#include <dirent.h>
51
#include <poll.h>
52
#include <ifaddrs.h>
53
#include <paths.h>
54
55
/*
56
 * The structures for each interface.
57
 */
58
struct if_addr {
59
	in_addr_t ia_ipaddr;		/* IP address of this interface */
60
	in_addr_t ia_netmask;		/* subnet or net mask */
61
	struct if_addr *ia_next;
62
};
63
64
struct if_info {
65
	int	ii_fd;			/* BPF file descriptor */
66
	char	ii_name[IFNAMSIZ];	/* if name, e.g. "en0" */
67
	u_char	ii_eaddr[ETHER_ADDR_LEN];	/* Ethernet address of this iface */
68
	struct if_addr *ii_addrs;	/* Networks this interface is on */
69
	struct if_info *ii_next;
70
};
71
/*
72
 * The list of all interfaces that are being listened to.  rarp_loop()
73
 * "selects" on the descriptors in this list.
74
 */
75
struct if_info *iflist;
76
77
int    rarp_open(char *);
78
void   init_one(char *);
79
void   init_all(void);
80
void   rarp_loop(void);
81
void   lookup_addrs(char *, struct if_info *);
82
__dead void   usage(void);
83
void   rarp_process(struct if_info *, u_char *);
84
void   rarp_reply(struct if_info *, struct if_addr *,
85
	    struct ether_header *, u_int32_t, struct hostent *);
86
void	arptab_init(void);
87
int    arptab_set(u_char *, u_int32_t);
88
__dead void   error(const char *,...);
89
void   warning(const char *,...);
90
void   debug(const char *,...);
91
u_int32_t ipaddrtonetmask(u_int32_t);
92
int    rarp_bootable(u_int32_t);
93
94
int	aflag = 0;		/* listen on "all" interfaces  */
95
int	dflag = 0;		/* print debugging messages */
96
int	fflag = 0;		/* don't fork */
97
int	lflag = 0;		/* log all replies */
98
int	tflag = 0;		/* tftpboot check */
99
100
int
101
main(int argc, char *argv[])
102
{
103
	extern char *__progname;
104
	extern int optind, opterr;
105
	int op;
106
107
	/* All error reporting is done through syslogs. */
108
	openlog(__progname, LOG_PID | LOG_CONS, LOG_DAEMON);
109
110
	opterr = 0;
111
	while ((op = getopt(argc, argv, "adflt")) != -1) {
112
		switch (op) {
113
		case 'a':
114
			++aflag;
115
			break;
116
		case 'd':
117
			++dflag;
118
			break;
119
		case 'f':
120
			++fflag;
121
			break;
122
		case 'l':
123
			++lflag;
124
			break;
125
		case 't':
126
			++tflag;
127
			break;
128
		default:
129
			usage();
130
		}
131
	}
132
	argc -= optind;
133
	argv += optind;
134
135
	if ((aflag && argc > 0) || (!aflag && argc == 0))
136
		usage();
137
138
	if (aflag)
139
		init_all();
140
	else
141
		while (argc > 0) {
142
			init_one(argv[0]);
143
			argc--;
144
			argv++;
145
		}
146
147
	if ((!fflag) && (!dflag)) {
148
		if (daemon(0, 0) == -1)
149
			error("failed to daemonize: %s", strerror(errno));
150
	}
151
	rarp_loop();
152
	exit(0);
153
}
154
155
/*
156
 * Add 'ifname' to the interface list.  Lookup its IP address and network
157
 * mask and Ethernet address, and open a BPF file for it.
158
 */
159
void
160
init_one(char *ifname)
161
{
162
	struct if_info *p;
163
	int fd;
164
165
	/* first check to see if this "if" was already opened? */
166
	for (p = iflist; p; p = p->ii_next)
167
		if (!strncmp(p->ii_name, ifname, IFNAMSIZ))
168
			return;
169
170
	fd = rarp_open(ifname);
171
	if (fd < 0)
172
		return;
173
174
	p = malloc(sizeof(*p));
175
	if (p == 0)
176
		error("malloc: %s", strerror(errno));
177
178
	p->ii_next = iflist;
179
	iflist = p;
180
181
	p->ii_fd = fd;
182
	strncpy(p->ii_name, ifname, IFNAMSIZ);
183
	p->ii_addrs = NULL;
184
	lookup_addrs(ifname, p);
185
}
186
/*
187
 * Initialize all "candidate" interfaces that are in the system
188
 * configuration list.  A "candidate" is up, not loopback and not
189
 * point to point.
190
 */
191
void
192
init_all(void)
193
{
194
	struct ifaddrs *ifap, *ifa;
195
	struct sockaddr_dl *sdl;
196
197
	if (getifaddrs(&ifap) != 0)
198
		error("getifaddrs: %s", strerror(errno));
199
200
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
201
		sdl = (struct sockaddr_dl *)ifa->ifa_addr;
202
		if (sdl->sdl_family != AF_LINK || sdl->sdl_type != IFT_ETHER ||
203
		    sdl->sdl_alen != 6)
204
			continue;
205
206
		if ((ifa->ifa_flags &
207
		    (IFF_UP | IFF_LOOPBACK | IFF_POINTOPOINT)) != IFF_UP)
208
			continue;
209
		init_one(ifa->ifa_name);
210
	}
211
	freeifaddrs(ifap);
212
}
213
214
__dead void
215
usage(void)
216
{
217
	(void) fprintf(stderr, "usage: rarpd [-adflt] if0 [... ifN]\n");
218
	exit(1);
219
}
220
221
static struct bpf_insn insns[] = {
222
	BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 12),
223
	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ETHERTYPE_REVARP, 0, 3),
224
	BPF_STMT(BPF_LD | BPF_H | BPF_ABS, 20),
225
	BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, ARPOP_REVREQUEST, 0, 1),
226
	BPF_STMT(BPF_RET | BPF_K, sizeof(struct ether_arp) +
227
	    sizeof(struct ether_header)),
228
	BPF_STMT(BPF_RET | BPF_K, 0),
229
};
230
231
static struct bpf_program filter = {
232
	sizeof insns / sizeof(insns[0]),
233
	insns
234
};
235
236
/*
237
 * Open a BPF file and attach it to the interface named 'device'.
238
 * Set immediate mode, and set a filter that accepts only RARP requests.
239
 */
240
int
241
rarp_open(char *device)
242
{
243
	int	fd, immediate;
244
	struct ifreq ifr;
245
	u_int   dlt;
246
247
	if ((fd = open("/dev/bpf", O_RDWR)) == -1)
248
		error("/dev/bpf: %s", strerror(errno));
249
250
	/* Set immediate mode so packets are processed as they arrive. */
251
	immediate = 1;
252
	if (ioctl(fd, BIOCIMMEDIATE, &immediate) < 0) {
253
		error("BIOCIMMEDIATE: %s", strerror(errno));
254
	}
255
256
	(void) strncpy(ifr.ifr_name, device, sizeof ifr.ifr_name);
257
	if (ioctl(fd, BIOCSETIF, (caddr_t)&ifr) < 0) {
258
		if (aflag) {	/* for -a skip not ethernet interfaces */
259
			close(fd);
260
			return -1;
261
		}
262
		error("BIOCSETIF: %s", strerror(errno));
263
	}
264
265
	/*
266
	 * Check that the data link layer is an Ethernet; this code
267
	 * won't work with anything else.
268
	 */
269
	if (ioctl(fd, BIOCGDLT, (caddr_t) &dlt) < 0)
270
		error("BIOCGDLT: %s", strerror(errno));
271
	if (dlt != DLT_EN10MB) {
272
		if (aflag) {	/* for -a skip not ethernet interfaces */
273
			close(fd);
274
			return -1;
275
		}
276
		error("%s is not an ethernet", device);
277
	}
278
	/* Set filter program. */
279
	if (ioctl(fd, BIOCSETF, (caddr_t)&filter) < 0)
280
		error("BIOCSETF: %s", strerror(errno));
281
	return fd;
282
}
283
/*
284
 * Perform various sanity checks on the RARP request packet.  Return
285
 * false on failure and log the reason.
286
 */
287
static int
288
rarp_check(u_char *p, int len)
289
{
290
	struct ether_header *ep = (struct ether_header *) p;
291
	struct ether_arp *ap = (struct ether_arp *) (p + sizeof(*ep));
292
293
	(void) debug("got a packet");
294
295
	if (len < sizeof(*ep) + sizeof(*ap)) {
296
		warning("truncated request");
297
		return 0;
298
	}
299
	/* XXX This test might be better off broken out... */
300
	if (ntohs (ep->ether_type) != ETHERTYPE_REVARP ||
301
	    ntohs (ap->arp_hrd) != ARPHRD_ETHER ||
302
	    ntohs (ap->arp_op) != ARPOP_REVREQUEST ||
303
	    ntohs (ap->arp_pro) != ETHERTYPE_IP ||
304
	    ap->arp_hln != 6 || ap->arp_pln != 4) {
305
		warning("request fails sanity check");
306
		return 0;
307
	}
308
	if (memcmp((char *) &ep->ether_shost, (char *) &ap->arp_sha, 6) != 0) {
309
		warning("ether/arp sender address mismatch");
310
		return 0;
311
	}
312
	if (memcmp((char *) &ap->arp_sha, (char *) &ap->arp_tha, 6) != 0) {
313
		warning("ether/arp target address mismatch");
314
		return 0;
315
	}
316
	return 1;
317
}
318
319
/*
320
 * Loop indefinitely listening for RARP requests on the
321
 * interfaces in 'iflist'.
322
 */
323
void
324
rarp_loop(void)
325
{
326
	int	cc, fd, numfd = 0, i;
327
	u_int	bufsize;
328
	struct pollfd *pfd;
329
	u_char	*buf, *bp, *ep;
330
	struct if_info *ii;
331
332
	if (iflist == 0)
333
		error("no interfaces");
334
	if (ioctl(iflist->ii_fd, BIOCGBLEN, (caddr_t)&bufsize) < 0)
335
		error("BIOCGBLEN: %s", strerror(errno));
336
337
	arptab_init();
338
339
	if (pledge("stdio rpath dns flock cpath wpath", NULL) == -1)
340
		error("pledge");
341
342
	buf = malloc((size_t) bufsize);
343
	if (buf == 0)
344
		error("malloc: %s", strerror(errno));
345
	/*
346
	 * Initialize the set of descriptors to listen to.
347
	 */
348
	for (ii = iflist; ii; ii = ii->ii_next)
349
		numfd++;
350
	pfd = reallocarray(NULL, numfd, sizeof(*pfd));
351
	if (pfd == NULL)
352
		error("reallocarray: %s", strerror(errno));
353
	for (i = 0, ii = iflist; ii; ii = ii->ii_next, i++) {
354
		pfd[i].fd = ii->ii_fd;
355
		pfd[i].events = POLLIN;
356
	}
357
358
	while (1) {
359
		if (poll(pfd, numfd, -1) == -1) {
360
			if (errno == EINTR)
361
				continue;
362
			error("poll: %s", strerror(errno));
363
		}
364
		for (i = 0, ii = iflist; ii; ii = ii->ii_next, i++) {
365
			if (pfd[i].revents == 0)
366
				continue;
367
			fd = ii->ii_fd;
368
		again:
369
			cc = read(fd, (char *)buf, bufsize);
370
			/* Don't choke when we get ptraced */
371
			if (cc < 0 && errno == EINTR)
372
				goto again;
373
			if (cc < 0)
374
				error("read: %s", strerror(errno));
375
			/* Loop through the packet(s) */
376
#define bhp ((struct bpf_hdr *)bp)
377
			bp = buf;
378
			ep = bp + cc;
379
			while (bp < ep) {
380
				int caplen, hdrlen;
381
382
				caplen = bhp->bh_caplen;
383
				hdrlen = bhp->bh_hdrlen;
384
				if (rarp_check(bp + hdrlen, caplen))
385
					rarp_process(ii, bp + hdrlen);
386
				bp += BPF_WORDALIGN(hdrlen + caplen);
387
			}
388
		}
389
	}
390
	free(pfd);
391
}
392
393
#ifndef TFTP_DIR
394
#define TFTP_DIR "/tftpboot"
395
#endif
396
397
/*
398
 * True if this server can boot the host whose IP address is 'addr'.
399
 * This check is made by looking in the tftp directory for the
400
 * configuration file.
401
 */
402
int
403
rarp_bootable(u_int32_t addr)
404
{
405
	struct dirent *dent;
406
	char    ipname[40];
407
	static DIR *dd = 0;
408
	DIR *d;
409
410
	(void) snprintf(ipname, sizeof ipname, "%08X", addr);
411
	/* If directory is already open, rewind it.  Otherwise, open it. */
412
	if ((d = dd))
413
		rewinddir(d);
414
	else {
415
		if (chdir(TFTP_DIR) == -1)
416
			error("chdir: %s", strerror(errno));
417
		d = opendir(".");
418
		if (d == 0)
419
			error("opendir: %s", strerror(errno));
420
		dd = d;
421
	}
422
	while ((dent = readdir(d)))
423
		if (strncmp(dent->d_name, ipname, 8) == 0)
424
			return 1;
425
	return 0;
426
}
427
428
429
/*
430
 * Given a list of IP addresses, 'alist', return the first address that
431
 * is on network 'net'; 'netmask' is a mask indicating the network portion
432
 * of the address.
433
 */
434
static u_int32_t
435
choose_ipaddr(u_int32_t **alist, u_int32_t net, u_int32_t netmask)
436
{
437
	for (; *alist; ++alist) {
438
		if ((**alist & netmask) == net)
439
			return **alist;
440
	}
441
	return 0;
442
}
443
/*
444
 * Answer the RARP request in 'pkt', on the interface 'ii'.  'pkt' has
445
 * already been checked for validity.  The reply is overlaid on the request.
446
 */
447
void
448
rarp_process(struct if_info *ii, u_char *pkt)
449
{
450
	char    ename[HOST_NAME_MAX+1];
451
	u_int32_t  target_ipaddr;
452
	struct ether_header *ep;
453
	struct ether_addr *ea;
454
	struct hostent *hp;
455
	struct	in_addr in;
456
	struct if_addr *ia;
457
458
	ep = (struct ether_header *) pkt;
459
	ea = (struct ether_addr *) &ep->ether_shost;
460
461
	debug("%s", ether_ntoa(ea));
462
	if (ether_ntohost(ename, ea) != 0) {
463
		debug("ether_ntohost failed");
464
		return;
465
	}
466
	if ((hp = gethostbyname(ename)) == 0) {
467
		debug("gethostbyname (%s) failed", ename);
468
		return;
469
	}
470
471
	/* Choose correct address from list. */
472
	if (hp->h_addrtype != AF_INET)
473
		error("cannot handle non IP addresses");
474
	for (target_ipaddr = 0, ia = ii->ii_addrs; ia; ia = ia->ia_next) {
475
		target_ipaddr = choose_ipaddr((u_int32_t **) hp->h_addr_list,
476
		    ia->ia_ipaddr & ia->ia_netmask, ia->ia_netmask);
477
		if (target_ipaddr)
478
			break;
479
	}
480
481
	if (target_ipaddr == 0) {
482
		for (ia = ii->ii_addrs; ia; ia = ia->ia_next) {
483
			in.s_addr = ia->ia_ipaddr & ia->ia_netmask;
484
			warning("cannot find %s on net %s",
485
			    ename, inet_ntoa(in));
486
		}
487
		return;
488
	}
489
	if (tflag == 0 || rarp_bootable(htonl(target_ipaddr)))
490
		rarp_reply(ii, ia, ep, target_ipaddr, hp);
491
	debug("reply sent");
492
}
493
494
/*
495
 * Lookup the ethernet address of the interface attached to the BPF
496
 * file descriptor 'fd'; return it in 'eaddr'.
497
 */
498
void
499
lookup_addrs(char *ifname, struct if_info *p)
500
{
501
	struct ifaddrs *ifap, *ifa;
502
	struct sockaddr_dl *sdl;
503
	u_char *eaddr = p->ii_eaddr;
504
	struct if_addr *ia, **iap = &p->ii_addrs;
505
	struct in_addr in;
506
	int found = 0;
507
508
	if (getifaddrs(&ifap) != 0)
509
		error("getifaddrs: %s", strerror(errno));
510
511
	for (ifa = ifap; ifa; ifa = ifa->ifa_next) {
512
		if (strcmp(ifa->ifa_name, ifname))
513
			continue;
514
		sdl = (struct sockaddr_dl *) ifa->ifa_addr;
515
		if (sdl->sdl_family == AF_LINK &&
516
		    sdl->sdl_type == IFT_ETHER && sdl->sdl_alen == 6) {
517
			memcpy((caddr_t)eaddr, (caddr_t)LLADDR(sdl), 6);
518
			if (dflag)
519
				fprintf(stderr, "%s: %x:%x:%x:%x:%x:%x\n",
520
				    ifa->ifa_name,
521
				    eaddr[0], eaddr[1], eaddr[2],
522
				    eaddr[3], eaddr[4], eaddr[5]);
523
			found = 1;
524
		} else if (sdl->sdl_family == AF_INET) {
525
			ia = malloc(sizeof (struct if_addr));
526
			if (ia == NULL)
527
				error("lookup_addrs: malloc: %s",
528
				    strerror(errno));
529
			ia->ia_next = NULL;
530
			ia->ia_ipaddr =
531
			    ((struct sockaddr_in *) ifa->ifa_addr)->
532
			    sin_addr.s_addr;
533
			ia->ia_netmask =
534
			    ((struct sockaddr_in *) ifa->ifa_netmask)->
535
			    sin_addr.s_addr;
536
			/* If SIOCGIFNETMASK didn't work,
537
			   figure out a mask from the IP
538
			   address class. */
539
			if (ia->ia_netmask == 0)
540
				ia->ia_netmask =
541
				    ipaddrtonetmask(ia->ia_ipaddr);
542
			if (dflag) {
543
				in.s_addr = ia->ia_ipaddr;
544
				fprintf(stderr, "\t%s\n",
545
				    inet_ntoa(in));
546
			}
547
			*iap = ia;
548
			iap = &ia->ia_next;
549
		}
550
	}
551
	freeifaddrs(ifap);
552
	if (!found)
553
		error("lookup_addrs: Never saw interface `%s'!", ifname);
554
}
555
556
/*
557
 * Build a reverse ARP packet and sent it out on the interface.
558
 * 'ep' points to a valid ARPOP_REVREQUEST.  The ARPOP_REVREPLY is built
559
 * on top of the request, then written to the network.
560
 *
561
 * RFC 903 defines the ether_arp fields as follows.  The following comments
562
 * are taken (more or less) straight from this document.
563
 *
564
 * ARPOP_REVREQUEST
565
 *
566
 * arp_sha is the hardware address of the sender of the packet.
567
 * arp_spa is undefined.
568
 * arp_tha is the 'target' hardware address.
569
 *   In the case where the sender wishes to determine his own
570
 *   protocol address, this, like arp_sha, will be the hardware
571
 *   address of the sender.
572
 * arp_tpa is undefined.
573
 *
574
 * ARPOP_REVREPLY
575
 *
576
 * arp_sha is the hardware address of the responder (the sender of the
577
 *   reply packet).
578
 * arp_spa is the protocol address of the responder (see the note below).
579
 * arp_tha is the hardware address of the target, and should be the same as
580
 *   that which was given in the request.
581
 * arp_tpa is the protocol address of the target, that is, the desired address.
582
 *
583
 * Note that the requirement that arp_spa be filled in with the responder's
584
 * protocol is purely for convenience.  For instance, if a system were to use
585
 * both ARP and RARP, then the inclusion of the valid protocol-hardware
586
 * address pair (arp_spa, arp_sha) may eliminate the need for a subsequent
587
 * ARP request.
588
 */
589
void
590
rarp_reply(struct if_info *ii, struct if_addr *ia, struct ether_header *ep,
591
    u_int32_t ipaddr, struct hostent *hp)
592
{
593
	struct ether_arp *ap = (struct ether_arp *) (ep + 1);
594
	int len, n;
595
596
	/*
597
	 * Poke the kernel arp tables with the ethernet/ip address
598
	 * combination given.  When processing a reply, we must
599
	 * do this so that the booting host (i.e. the guy running
600
	 * rarpd), won't try to ARP for the hardware address of the
601
	 * guy being booted (he cannot answer the ARP).
602
	 */
603
	if (arptab_set((u_char *)&ap->arp_sha, ipaddr) > 0)
604
		syslog(LOG_ERR, "couldn't update arp table");
605
606
	/* Build the rarp reply by modifying the rarp request in place. */
607
	ep->ether_type = htons(ETHERTYPE_REVARP);
608
	ap->ea_hdr.ar_hrd = htons(ARPHRD_ETHER);
609
	ap->ea_hdr.ar_pro = htons(ETHERTYPE_IP);
610
	ap->arp_op = htons(ARPOP_REVREPLY);
611
612
	memcpy((char *) &ep->ether_dhost, (char *) &ap->arp_sha, 6);
613
	memcpy((char *) &ep->ether_shost, (char *) ii->ii_eaddr, 6);
614
	memcpy((char *) &ap->arp_sha, (char *) ii->ii_eaddr, 6);
615
616
	memcpy((char *) ap->arp_tpa, (char *) &ipaddr, 4);
617
	/* Target hardware is unchanged. */
618
	memcpy((char *) ap->arp_spa, (char *) &ia->ia_ipaddr, 4);
619
620
	if (lflag) {
621
		struct ether_addr ea;
622
623
		memcpy(&ea.ether_addr_octet, &ap->arp_sha, 6);
624
		syslog(LOG_INFO, "%s asked; %s replied", hp->h_name,
625
		    ether_ntoa(&ea));
626
	}
627
628
	len = sizeof(*ep) + sizeof(*ap);
629
	n = write(ii->ii_fd, (char *) ep, len);
630
	if (n != len)
631
		warning("write: only %d of %d bytes written", n, len);
632
}
633
/*
634
 * Get the netmask of an IP address.  This routine is used if
635
 * SIOCGIFNETMASK doesn't work.
636
 */
637
u_int32_t
638
ipaddrtonetmask(u_int32_t addr)
639
{
640
	if (IN_CLASSA(addr))
641
		return IN_CLASSA_NET;
642
	if (IN_CLASSB(addr))
643
		return IN_CLASSB_NET;
644
	if (IN_CLASSC(addr))
645
		return IN_CLASSC_NET;
646
	error("unknown IP address class: %08X", addr);
647
}
648
649
void
650
warning(const char *fmt,...)
651
{
652
	va_list ap;
653
654
	if (dflag) {
655
		(void) fprintf(stderr, "rarpd: warning: ");
656
		va_start(ap, fmt);
657
		(void) vfprintf(stderr, fmt, ap);
658
		va_end(ap);
659
		(void) fprintf(stderr, "\n");
660
	}
661
	va_start(ap, fmt);
662
	vsyslog(LOG_ERR, fmt, ap);
663
	va_end(ap);
664
}
665
666
__dead void
667
error(const char *fmt,...)
668
{
669
	va_list ap;
670
671
	if (dflag) {
672
		(void) fprintf(stderr, "rarpd: error: ");
673
		va_start(ap, fmt);
674
		(void) vfprintf(stderr, fmt, ap);
675
		va_end(ap);
676
		(void) fprintf(stderr, "\n");
677
	}
678
	va_start(ap, fmt);
679
	vsyslog(LOG_ERR, fmt, ap);
680
	va_end(ap);
681
	exit(1);
682
}
683
684
void
685
debug(const char *fmt,...)
686
{
687
	va_list ap;
688
689
	if (dflag) {
690
		va_start(ap, fmt);
691
		(void) fprintf(stderr, "rarpd: ");
692
		(void) vfprintf(stderr, fmt, ap);
693
		va_end(ap);
694
		(void) fprintf(stderr, "\n");
695
	}
696
}