2 * Copyright (c) 1990, 1991, 1992, 1993, 1996
3 * The Regents of the University of California. All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that: (1) source code distributions
7 * retain the above copyright notice and this paragraph in its entirety, (2)
8 * distributions including binary code include the above copyright notice and
9 * this paragraph in its entirety in the documentation or other materials
10 * provided with the distribution
12 * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
13 * WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
14 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
16 * @(#) Copyright (c) 1990, 1991, 1992, 1993, 1996 The Regents of the University of California. All rights reserved.
17 * $FreeBSD: src/usr.sbin/rarpd/rarpd.c,v 1.41 2004/08/07 04:28:54 imp Exp $
21 * rarpd - Reverse ARP Daemon
23 * Usage: rarpd -a [-dfsv] [-t directory] [hostname]
24 * rarpd [-dfsv] [-t directory] interface [hostname]
26 * 'hostname' is optional solely for backwards compatibility with Sun's rarpd.
27 * Currently, the argument is ignored.
29 #include <sys/param.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
36 #include <net/ethernet.h>
38 #include <net/if_types.h>
39 #include <net/if_dl.h>
40 #include <net/route.h>
42 #include <netinet/in.h>
43 #include <netinet/if_ether.h>
45 #include <arpa/inet.h>
58 /* Cast a struct sockaddr to a struct sockaddr_in */
59 #define SATOSIN(sa) ((struct sockaddr_in *)(sa))
62 #define TFTP_DIR "/tftpboot"
65 #define ARPSECS (20 * 60) /* as per code in netinet/if_ether.c */
66 #define REVARP_REQUEST ARPOP_REVREQUEST
67 #define REVARP_REPLY ARPOP_REVREPLY
70 * The structure for each interface.
73 struct if_info
*ii_next
;
74 int ii_fd
; /* BPF file descriptor */
75 in_addr_t ii_ipaddr
; /* IP address */
76 in_addr_t ii_netmask
; /* subnet or net mask */
77 u_char ii_eaddr
[ETHER_ADDR_LEN
]; /* ethernet address */
78 char ii_ifname
[IF_NAMESIZE
];
82 * The list of all interfaces that are being listened to. rarp_loop()
83 * "selects" on the descriptors in this list.
85 struct if_info
*iflist
;
87 int verbose
; /* verbose messages */
88 const char *tftp_dir
= TFTP_DIR
; /* tftp directory */
90 int dflag
; /* messages to stdout/stderr, not syslog(3) */
91 int sflag
; /* ignore /tftpboot */
93 static u_char zero
[6];
95 static int bpf_open(void);
96 static in_addr_t
choose_ipaddr(in_addr_t
**, in_addr_t
, in_addr_t
);
97 static char *eatoa(u_char
*);
98 static int expand_syslog_m(const char *fmt
, char **newfmt
);
99 static void init(char *);
100 static void init_one(struct ifaddrs
*, char *, int);
101 static char *intoa(in_addr_t
);
102 static in_addr_t
ipaddrtonetmask(in_addr_t
);
103 static void logmsg(int, const char *, ...) __printflike(2, 3);
104 static int rarp_bootable(in_addr_t
);
105 static int rarp_check(u_char
*, u_int
);
106 static void rarp_loop(void);
107 static int rarp_open(char *);
108 static void rarp_process(struct if_info
*, u_char
*, u_int
);
109 static void rarp_reply(struct if_info
*, struct ether_header
*,
111 static void update_arptab(u_char
*, in_addr_t
);
112 static void usage(void);
115 main(int argc
, char *argv
[])
120 int aflag
= 0; /* listen on "all" interfaces */
121 int fflag
= 0; /* don't fork */
123 if ((name
= strrchr(argv
[0], '/')) != NULL
)
131 * All error reporting is done through syslog, unless -d is specified
133 openlog(name
, LOG_PID
| LOG_CONS
, LOG_DAEMON
);
136 while ((op
= getopt(argc
, argv
, "adfst:v")) != -1)
169 ifname
= (aflag
== 0) ? argv
[0] : NULL
;
171 if ((aflag
&& ifname
) || (!aflag
&& ifname
== NULL
))
178 logmsg(LOG_ERR
, "cannot fork");
187 * Add to the interface list.
190 init_one(struct ifaddrs
*ifa
, char *target
, int pass1
)
192 struct if_info
*ii
, *ii2
;
193 struct sockaddr_dl
*ll
;
196 family
= ifa
->ifa_addr
->sa_family
;
200 /* Consider only AF_LINK during pass1. */
204 if (!(ifa
->ifa_flags
& IFF_UP
) ||
205 (ifa
->ifa_flags
& (IFF_LOOPBACK
| IFF_POINTOPOINT
)))
212 /* Don't bother going any further if not the target interface */
213 if (target
!= NULL
&& strcmp(ifa
->ifa_name
, target
) != 0)
216 /* Look for interface in list */
217 for (ii
= iflist
; ii
!= NULL
; ii
= ii
->ii_next
)
218 if (strcmp(ifa
->ifa_name
, ii
->ii_ifname
) == 0)
221 if (pass1
&& ii
!= NULL
)
222 /* We've already seen that interface once. */
225 /* Allocate a new one if not found */
227 ii
= (struct if_info
*)malloc(sizeof(*ii
));
229 logmsg(LOG_ERR
, "malloc: %m");
232 bzero(ii
, sizeof(*ii
));
234 strlcpy(ii
->ii_ifname
, ifa
->ifa_name
, sizeof(ii
->ii_ifname
));
235 ii
->ii_next
= iflist
;
237 } else if (!pass1
&& ii
->ii_ipaddr
!= 0) {
239 * Second AF_INET definition for that interface: clone
240 * the existing one, and work on that cloned one.
241 * This must be another IP address for this interface,
242 * so avoid killing the previous configuration.
244 ii2
= (struct if_info
*)malloc(sizeof(*ii2
));
246 logmsg(LOG_ERR
, "malloc: %m");
249 memcpy(ii2
, ii
, sizeof(*ii2
));
251 ii2
->ii_next
= iflist
;
259 ii
->ii_ipaddr
= SATOSIN(ifa
->ifa_addr
)->sin_addr
.s_addr
;
260 ii
->ii_netmask
= SATOSIN(ifa
->ifa_netmask
)->sin_addr
.s_addr
;
261 if (ii
->ii_netmask
== 0)
262 ii
->ii_netmask
= ipaddrtonetmask(ii
->ii_ipaddr
);
264 ii
->ii_fd
= rarp_open(ii
->ii_ifname
);
268 ll
= (struct sockaddr_dl
*)ifa
->ifa_addr
;
269 if (ll
->sdl_type
== IFT_ETHER
)
270 bcopy(LLADDR(ll
), ii
->ii_eaddr
, 6);
275 * Initialize all "candidate" interfaces that are in the system
276 * configuration list. A "candidate" is up, not loopback and not
282 struct if_info
*ii
, *nii
, *lii
;
283 struct ifaddrs
*ifhead
, *ifa
;
286 error
= getifaddrs(&ifhead
);
288 logmsg(LOG_ERR
, "getifaddrs: %m");
292 * We make two passes over the list we have got. In the first
293 * one, we only collect AF_LINK interfaces, and initialize our
294 * list of interfaces from them. In the second pass, we
295 * collect the actual IP addresses from the AF_INET
296 * interfaces, and allow for the same interface name to appear
297 * multiple times (in case of more than one IP address).
299 for (ifa
= ifhead
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
300 init_one(ifa
, target
, 1);
301 for (ifa
= ifhead
; ifa
!= NULL
; ifa
= ifa
->ifa_next
)
302 init_one(ifa
, target
, 0);
305 /* Throw away incomplete interfaces */
307 for (ii
= iflist
; ii
!= NULL
; ii
= nii
) {
309 if (ii
->ii_ipaddr
== 0 ||
310 bcmp(ii
->ii_eaddr
, zero
, 6) == 0) {
325 for (ii
= iflist
; ii
!= NULL
; ii
= ii
->ii_next
)
326 logmsg(LOG_DEBUG
, "%s %s 0x%08x %s",
327 ii
->ii_ifname
, intoa(ntohl(ii
->ii_ipaddr
)),
328 (in_addr_t
)ntohl(ii
->ii_netmask
), eatoa(ii
->ii_eaddr
));
334 fprintf(stderr
, "%s\n%s\n",
335 "usage: rarpd -a [-dfsv] [-t directory]",
336 " rarpd [-dfsv] [-t directory] interface");
345 char device
[sizeof "/dev/bpf000"];
348 * Go through all the minors and find one that isn't in use.
351 sprintf(device
, "/dev/bpf%d", n
++);
352 fd
= open(device
, O_RDWR
);
353 } while ((fd
== -1) && (errno
== EBUSY
));
356 logmsg(LOG_ERR
, "%s: %m", device
);
363 * Open a BPF file and attach it to the interface named 'device'.
364 * Set immediate mode, and set a filter that accepts only RARP requests.
367 rarp_open(char *device
)
374 static struct bpf_insn insns
[] = {
375 BPF_STMT(BPF_LD
|BPF_H
|BPF_ABS
, 12),
376 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, ETHERTYPE_REVARP
, 0, 3),
377 BPF_STMT(BPF_LD
|BPF_H
|BPF_ABS
, 20),
378 BPF_JUMP(BPF_JMP
|BPF_JEQ
|BPF_K
, REVARP_REQUEST
, 0, 1),
379 BPF_STMT(BPF_RET
|BPF_K
, sizeof(struct ether_arp
) +
380 sizeof(struct ether_header
)),
381 BPF_STMT(BPF_RET
|BPF_K
, 0),
383 static struct bpf_program filter
= {
390 * Set immediate mode so packets are processed as they arrive.
393 if (ioctl(fd
, BIOCIMMEDIATE
, &immediate
) == -1) {
394 logmsg(LOG_ERR
, "BIOCIMMEDIATE: %m");
397 strlcpy(ifr
.ifr_name
, device
, sizeof(ifr
.ifr_name
));
398 if (ioctl(fd
, BIOCSETIF
, (caddr_t
)&ifr
) == -1) {
399 logmsg(LOG_ERR
, "BIOCSETIF: %m");
403 * Check that the data link layer is an Ethernet; this code won't
404 * work with anything else.
406 if (ioctl(fd
, BIOCGDLT
, (caddr_t
)&dlt
) == -1) {
407 logmsg(LOG_ERR
, "BIOCGDLT: %m");
410 if (dlt
!= DLT_EN10MB
) {
411 logmsg(LOG_ERR
, "%s is not an ethernet", device
);
415 * Set filter program.
417 if (ioctl(fd
, BIOCSETF
, (caddr_t
)&filter
) == -1) {
418 logmsg(LOG_ERR
, "BIOCSETF: %m");
425 * Perform various sanity checks on the RARP request packet. Return
426 * false on failure and log the reason.
429 rarp_check(u_char
*p
, u_int len
)
431 struct ether_header
*ep
= (struct ether_header
*)p
;
432 struct ether_arp
*ap
= (struct ether_arp
*)(p
+ sizeof(*ep
));
434 if (len
< sizeof(*ep
) + sizeof(*ap
)) {
435 logmsg(LOG_ERR
, "truncated request, got %u, expected %lu",
436 len
, (u_long
)(sizeof(*ep
) + sizeof(*ap
)));
440 * XXX This test might be better off broken out...
442 if (ntohs(ep
->ether_type
) != ETHERTYPE_REVARP
||
443 ntohs(ap
->arp_hrd
) != ARPHRD_ETHER
||
444 ntohs(ap
->arp_op
) != REVARP_REQUEST
||
445 ntohs(ap
->arp_pro
) != ETHERTYPE_IP
||
446 ap
->arp_hln
!= 6 || ap
->arp_pln
!= 4) {
447 logmsg(LOG_DEBUG
, "request fails sanity check");
450 if (bcmp((char *)&ep
->ether_shost
, (char *)&ap
->arp_sha
, 6) != 0) {
451 logmsg(LOG_DEBUG
, "ether/arp sender address mismatch");
454 if (bcmp((char *)&ap
->arp_sha
, (char *)&ap
->arp_tha
, 6) != 0) {
455 logmsg(LOG_DEBUG
, "ether/arp target address mismatch");
462 * Loop indefinitely listening for RARP requests on the
463 * interfaces in 'iflist'.
468 u_char
*buf
, *bp
, *ep
;
470 fd_set fds
, listeners
;
471 int bufsize
, maxfd
= 0;
474 if (iflist
== NULL
) {
475 logmsg(LOG_ERR
, "no interfaces");
478 if (ioctl(iflist
->ii_fd
, BIOCGBLEN
, (caddr_t
)&bufsize
) == -1) {
479 logmsg(LOG_ERR
, "BIOCGBLEN: %m");
482 buf
= malloc(bufsize
);
484 logmsg(LOG_ERR
, "malloc: %m");
490 * Find the highest numbered file descriptor for select().
491 * Initialize the set of descriptors to listen to.
494 for (ii
= iflist
; ii
!= NULL
; ii
= ii
->ii_next
) {
495 FD_SET(ii
->ii_fd
, &fds
);
496 if (ii
->ii_fd
> maxfd
)
500 if (select(maxfd
+ 1, &listeners
, NULL
, NULL
, NULL
) == -1) {
501 /* Don't choke when we get ptraced */
504 logmsg(LOG_ERR
, "select: %m");
507 for (ii
= iflist
; ii
!= NULL
; ii
= ii
->ii_next
) {
509 if (!FD_ISSET(fd
, &listeners
))
512 cc
= read(fd
, (char *)buf
, bufsize
);
513 /* Don't choke when we get ptraced */
514 if ((cc
== -1) && (errno
== EINTR
))
517 /* Loop through the packet(s) */
518 #define bhp ((struct bpf_hdr *)bp)
522 u_int caplen
, hdrlen
;
524 caplen
= bhp
->bh_caplen
;
525 hdrlen
= bhp
->bh_hdrlen
;
526 if (rarp_check(bp
+ hdrlen
, caplen
))
527 rarp_process(ii
, bp
+ hdrlen
, caplen
);
528 bp
+= BPF_WORDALIGN(hdrlen
+ caplen
);
536 * True if this server can boot the host whose IP address is 'addr'.
537 * This check is made by looking in the tftp directory for the
538 * configuration file.
541 rarp_bootable(in_addr_t addr
)
546 static DIR *dd
= NULL
;
548 sprintf(ipname
, "%08X", (in_addr_t
)ntohl(addr
));
551 * If directory is already open, rewind it. Otherwise, open it.
553 if ((d
= dd
) != NULL
)
556 if (chdir(tftp_dir
) == -1) {
557 logmsg(LOG_ERR
, "chdir: %s: %m", tftp_dir
);
562 logmsg(LOG_ERR
, "opendir: %m");
567 while ((dent
= readdir(d
)) != NULL
)
568 if (strncmp(dent
->d_name
, ipname
, 8) == 0)
574 * Given a list of IP addresses, 'alist', return the first address that
575 * is on network 'net'; 'netmask' is a mask indicating the network portion
579 choose_ipaddr(in_addr_t
**alist
, in_addr_t net
, in_addr_t netmask
)
581 for (; *alist
; ++alist
)
582 if ((**alist
& netmask
) == net
)
588 * Answer the RARP request in 'pkt', on the interface 'ii'. 'pkt' has
589 * already been checked for validity. The reply is overlaid on the request.
592 rarp_process(struct if_info
*ii
, u_char
*pkt
, u_int len
)
594 struct ether_header
*ep
;
596 in_addr_t target_ipaddr
;
599 ep
= (struct ether_header
*)pkt
;
600 /* should this be arp_tha? */
601 if (ether_ntohost(ename
, (struct ether_addr
*)&ep
->ether_shost
) != 0) {
602 logmsg(LOG_ERR
, "cannot map %s to name",
603 eatoa(ep
->ether_shost
));
607 if ((hp
= gethostbyname(ename
)) == NULL
) {
608 logmsg(LOG_ERR
, "cannot map %s to IP address", ename
);
613 * Choose correct address from list.
615 if (hp
->h_addrtype
!= AF_INET
) {
616 logmsg(LOG_ERR
, "cannot handle non IP addresses for %s",
620 target_ipaddr
= choose_ipaddr((in_addr_t
**)hp
->h_addr_list
,
621 ii
->ii_ipaddr
& ii
->ii_netmask
,
623 if (target_ipaddr
== 0) {
624 logmsg(LOG_ERR
, "cannot find %s on net %s",
625 ename
, intoa(ntohl(ii
->ii_ipaddr
& ii
->ii_netmask
)));
628 if (sflag
|| rarp_bootable(target_ipaddr
))
629 rarp_reply(ii
, ep
, target_ipaddr
, len
);
630 else if (verbose
> 1)
631 logmsg(LOG_INFO
, "%s %s at %s DENIED (not bootable)",
633 eatoa(ep
->ether_shost
),
634 intoa(ntohl(target_ipaddr
)));
638 * Poke the kernel arp tables with the ethernet/ip address combinataion
639 * given. When processing a reply, we must do this so that the booting
640 * host (i.e. the guy running rarpd), won't try to ARP for the hardware
641 * address of the guy being booted (he cannot answer the ARP).
643 struct sockaddr_inarp sin_inarp
= {
644 sizeof(struct sockaddr_inarp
), AF_INET
, 0,
649 struct sockaddr_dl sin_dl
= {
650 sizeof(struct sockaddr_dl
), AF_LINK
, 0, IFT_ETHER
, 0, 6,
654 struct rt_msghdr rthdr
;
659 update_arptab(u_char
*ep
, in_addr_t ipaddr
)
662 struct sockaddr_inarp
*ar
, *ar2
;
663 struct sockaddr_dl
*ll
, *ll2
;
664 struct rt_msghdr
*rt
;
671 r
= socket(PF_ROUTE
, SOCK_RAW
, 0);
673 logmsg(LOG_ERR
, "raw route socket: %m");
679 ar
->sin_addr
.s_addr
= ipaddr
;
681 bcopy(ep
, LLADDR(ll
), 6);
683 /* Get the type and interface index */
685 bzero(rt
, sizeof(rtmsg
));
686 rt
->rtm_version
= RTM_VERSION
;
687 rt
->rtm_addrs
= RTA_DST
;
688 rt
->rtm_type
= RTM_GET
;
690 ar2
= (struct sockaddr_inarp
*)rtmsg
.rtspace
;
691 bcopy(ar
, ar2
, sizeof(*ar
));
692 rt
->rtm_msglen
= sizeof(*rt
) + sizeof(*ar
);
694 if ((write(r
, rt
, rt
->rtm_msglen
) == -1) && (errno
!= ESRCH
)) {
695 logmsg(LOG_ERR
, "rtmsg get write: %m");
700 cc
= read(r
, rt
, sizeof(rtmsg
));
701 } while (cc
> 0 && (rt
->rtm_seq
!= seq
|| rt
->rtm_pid
!= pid
));
703 logmsg(LOG_ERR
, "rtmsg get read: %m");
707 ll2
= (struct sockaddr_dl
*)((u_char
*)ar2
+ ar2
->sin_len
);
708 if (ll2
->sdl_family
!= AF_LINK
) {
710 * XXX I think this means the ip address is not on a
711 * directly connected network (the family is AF_INET in
714 logmsg(LOG_ERR
, "bogus link family (%d) wrong net for %08X?\n",
715 ll2
->sdl_family
, ipaddr
);
719 xtype
= ll2
->sdl_type
;
720 xindex
= ll2
->sdl_index
;
722 clock_gettime(CLOCK_MONOTONIC
, &sp
);
724 /* Set the new arp entry */
725 bzero(rt
, sizeof(rtmsg
));
726 rt
->rtm_version
= RTM_VERSION
;
727 rt
->rtm_addrs
= RTA_DST
| RTA_GATEWAY
;
728 rt
->rtm_inits
= RTV_EXPIRE
;
729 rt
->rtm_rmx
.rmx_expire
= sp
.tv_sec
+ ARPSECS
;
730 rt
->rtm_flags
= RTF_HOST
| RTF_STATIC
;
731 rt
->rtm_type
= RTM_ADD
;
734 bcopy(ar
, ar2
, sizeof(*ar
));
736 ll2
= (struct sockaddr_dl
*)((u_char
*)ar2
+ sizeof(*ar2
));
737 bcopy(ll
, ll2
, sizeof(*ll
));
738 ll2
->sdl_type
= xtype
;
739 ll2
->sdl_index
= xindex
;
741 rt
->rtm_msglen
= sizeof(*rt
) + sizeof(*ar2
) + sizeof(*ll2
);
743 if ((write(r
, rt
, rt
->rtm_msglen
) == -1) && (errno
!= EEXIST
)) {
744 logmsg(LOG_ERR
, "rtmsg add write: %m");
749 cc
= read(r
, rt
, sizeof(rtmsg
));
750 } while (cc
> 0 && (rt
->rtm_seq
!= seq
|| rt
->rtm_pid
!= pid
));
753 logmsg(LOG_ERR
, "rtmsg add read: %m");
759 * Build a reverse ARP packet and sent it out on the interface.
760 * 'ep' points to a valid REVARP_REQUEST. The REVARP_REPLY is built
761 * on top of the request, then written to the network.
763 * RFC 903 defines the ether_arp fields as follows. The following comments
764 * are taken (more or less) straight from this document.
768 * arp_sha is the hardware address of the sender of the packet.
769 * arp_spa is undefined.
770 * arp_tha is the 'target' hardware address.
771 * In the case where the sender wishes to determine his own
772 * protocol address, this, like arp_sha, will be the hardware
773 * address of the sender.
774 * arp_tpa is undefined.
778 * arp_sha is the hardware address of the responder (the sender of the
780 * arp_spa is the protocol address of the responder (see the note below).
781 * arp_tha is the hardware address of the target, and should be the same as
782 * that which was given in the request.
783 * arp_tpa is the protocol address of the target, that is, the desired address.
785 * Note that the requirement that arp_spa be filled in with the responder's
786 * protocol is purely for convenience. For instance, if a system were to use
787 * both ARP and RARP, then the inclusion of the valid protocol-hardware
788 * address pair (arp_spa, arp_sha) may eliminate the need for a subsequent
792 rarp_reply(struct if_info
*ii
, struct ether_header
*ep
, in_addr_t ipaddr
,
796 struct ether_arp
*ap
= (struct ether_arp
*)(ep
+ 1);
798 update_arptab((u_char
*)&ap
->arp_sha
, ipaddr
);
801 * Build the rarp reply by modifying the rarp request in place.
803 ap
->arp_op
= htons(REVARP_REPLY
);
806 ep
->ether_type
= ETHERTYPE_REVARP
;
808 bcopy((char *)&ap
->arp_sha
, (char *)&ep
->ether_dhost
, 6);
809 bcopy((char *)ii
->ii_eaddr
, (char *)&ep
->ether_shost
, 6);
810 bcopy((char *)ii
->ii_eaddr
, (char *)&ap
->arp_sha
, 6);
812 bcopy((char *)&ipaddr
, (char *)ap
->arp_tpa
, 4);
813 /* Target hardware is unchanged. */
814 bcopy((char *)&ii
->ii_ipaddr
, (char *)ap
->arp_spa
, 4);
816 /* Zero possible garbage after packet. */
817 bzero((char *)ep
+ (sizeof(*ep
) + sizeof(*ap
)),
818 len
- (sizeof(*ep
) + sizeof(*ap
)));
819 n
= write(ii
->ii_fd
, (char *)ep
, len
);
821 logmsg(LOG_ERR
, "write: only %d of %d bytes written", n
, len
);
823 logmsg(LOG_INFO
, "%s %s at %s REPLIED", ii
->ii_ifname
,
825 intoa(ntohl(ipaddr
)));
829 * Get the netmask of an IP address. This routine is used if
830 * SIOCGIFNETMASK doesn't work.
833 ipaddrtonetmask(in_addr_t addr
)
837 return htonl(IN_CLASSA_NET
);
839 return htonl(IN_CLASSB_NET
);
841 return htonl(IN_CLASSC_NET
);
842 logmsg(LOG_DEBUG
, "unknown IP address class: %08X", addr
);
843 return htonl(0xffffffff);
847 * A faster replacement for inet_ntoa().
850 intoa(in_addr_t addr
)
855 static char buf
[sizeof(".xxx.xxx.xxx.xxx")];
857 cp
= &buf
[sizeof buf
];
863 *--cp
= byte
% 10 + '0';
866 *--cp
= byte
% 10 + '0';
881 static char buf
[sizeof("xx:xx:xx:xx:xx:xx")];
883 sprintf(buf
, "%x:%x:%x:%x:%x:%x",
884 ea
[0], ea
[1], ea
[2], ea
[3], ea
[4], ea
[5]);
889 logmsg(int pri
, const char *fmt
, ...)
901 if (expand_syslog_m(fmt
, &newfmt
) == -1) {
902 vfprintf(fp
, fmt
, v
);
904 vfprintf(fp
, newfmt
, v
);
910 vsyslog(pri
, fmt
, v
);
916 expand_syslog_m(const char *fmt
, char **newfmt
)
923 while ((m
= strstr(str
, "%m")) != NULL
) {
924 asprintf(&np
, "%s%.*s%s", p
, (int)(m
- str
),
925 str
, strerror(errno
));
936 asprintf(&np
, "%s%s", p
, str
);