1 /* vi: set sw=4 ts=4: */
3 * DHCP server client/server socket creation
6 * Copyright (C) 1999 Matthew Ramsay <matthewr@moreton.com.au>
7 * Chris Trew <ctrew@moreton.com.au>
9 * Rewrite by Russ Dill <Russ.Dill@asu.edu> July 2001
11 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
21 * You should have received a copy of the GNU General Public License
22 * along with this program; if not, write to the Free Software
23 * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
26 #if (defined(__GLIBC__) && __GLIBC__ >= 2 && __GLIBC_MINOR__ >= 1) || defined _NEWLIB_VERSION
27 # include <netpacket/packet.h>
28 # include <net/ethernet.h>
30 # include <asm/types.h>
31 # include <linux/if_packet.h>
32 # include <linux/if_ether.h>
37 int FAST_FUNC
udhcp_read_interface(const char *interface
, int *ifindex
, uint32_t *nip
, uint8_t *mac
, uint16_t *mtu
)
40 /* char buffer instead of bona-fide struct avoids aliasing warning */
41 char ifr_buf
[sizeof(struct ifreq
)];
42 struct ifreq
*const ifr
= (void *)ifr_buf
;
45 struct sockaddr_in
*our_ip
;
47 memset(ifr
, 0, sizeof(*ifr
));
48 fd
= xsocket(AF_INET
, SOCK_RAW
, IPPROTO_RAW
);
50 ifr
->ifr_addr
.sa_family
= AF_INET
;
51 strncpy_IFNAMSIZ(ifr
->ifr_name
, interface
);
53 if (ioctl_or_perror(fd
, SIOCGIFADDR
, ifr
,
54 "is interface %s up and configured?", interface
)
59 our_ip
= (struct sockaddr_in
*) &ifr
->ifr_addr
;
60 *nip
= our_ip
->sin_addr
.s_addr
;
61 log1("IP %s", inet_ntoa(our_ip
->sin_addr
));
65 if (ioctl_or_warn(fd
, SIOCGIFINDEX
, ifr
) != 0) {
69 log1("Adapter index %d", ifr
->ifr_ifindex
);
70 *ifindex
= ifr
->ifr_ifindex
;
74 if (ioctl_or_warn(fd
, SIOCGIFHWADDR
, ifr
) != 0) {
78 memcpy(mac
, ifr
->ifr_hwaddr
.sa_data
, 6);
79 log1("MAC %02x:%02x:%02x:%02x:%02x:%02x",
80 mac
[0], mac
[1], mac
[2], mac
[3], mac
[4], mac
[5]);
84 if (ioctl_or_warn(fd
, SIOCGIFMTU
, ifr
) != 0) {
88 log1("Adapter mtu %d", ifr
->ifr_mtu
);
96 /* 1. None of the callers expects it to ever fail */
97 /* 2. ip was always INADDR_ANY */
98 int FAST_FUNC
udhcp_listen_socket(/*uint32_t ip,*/ int port
, const char *inf
)
101 struct sockaddr_in addr
;
103 log1("Opening listen socket on *:%d %s", port
, inf
);
104 fd
= xsocket(PF_INET
, SOCK_DGRAM
, IPPROTO_UDP
);
106 setsockopt_reuseaddr(fd
);
107 if (setsockopt_broadcast(fd
) == -1)
108 bb_perror_msg_and_die("SO_BROADCAST");
110 /* NB: bug 1032 says this doesn't work on ethernet aliases (ethN:M) */
111 if (setsockopt_bindtodevice(fd
, inf
))
112 xfunc_die(); /* warning is already printed */
114 memset(&addr
, 0, sizeof(addr
));
115 addr
.sin_family
= AF_INET
;
116 addr
.sin_port
= htons(port
);
117 /* addr.sin_addr.s_addr = ip; - all-zeros is INADDR_ANY */
118 xbind(fd
, (struct sockaddr
*)&addr
, sizeof(addr
));