summaryrefslogtreecommitdiff
path: root/sbin/dhcpleased
AgeCommit message (Collapse)Author
2021-07-26The SIOCAIFADDR ioctl could lose a race against another processFlorian Obser
configuring the same IP. Found the hard way by afresh1
2021-07-25If the lease didn't contain renewal or rebinding options set theFlorian Obser
defaults before validating the times to prevent excessive logging. Found the hard way & OK brynet
2021-07-23When dhcpleasectl asks to send a new request on an interface we areFlorian Obser
probably stuck in some way and the user wants a mostly clean slate. If we already have an IP address transition to state REBOOTING so that we no longer unicast dhcp requests. We will then try to reacquire our lease twice before giving up and transition to INIT and send dhcp discover messages accepting any IP address.
2021-07-22Make dhcpleased(8) always configure provided routes, regardless ofStefan Sperling
whether the address we received in our lease is already configured. In the case I observed, no default route was added to the routing table even though the server provided both an address and a route option. As it happened the leased address was already configured on the interface. This should not prevent routing table updates, but it did. ok florian
2021-07-21Use exclusive lock under /dev/, silence expected errors in installerkn
resolvd(8), slaacd(8) and dhcpleased(8) are different from other daemons in that there must only be a single instance. resolvd already does this, adjust slaacd and dhcpleased accordingly while moving the lockfile paths under /dev/ such that they work early on boot and don't run into races should /var be (un)mounted between daemon starts. Locking is especially required in the installer where all three daemons are started every time the "(I)nstall, (U)pgrade, (A)utoinstall or (S)hell? " prompt is entered, i.e. restarting installation or dropping into a shell and back into the prompt again would start multiple instances. To avoid expected lockfile error messages in between installer prompts, discard standard error when starting the autoconf daemons; none of them has other potential failure cases in installer mode before daemon(3)izing. Input sthen deraadt OK deraadt
2021-07-18Ignore routers option when a classless static routes option is presentFlorian Obser
as mandated by RFC3442. Pointed out by, initial diff, testing & OK bket@
2021-07-12Change the error reporting pattern throughout the tree when unveilBob Beck
fails to report the path that the failure occured on. Suggested by deraadt@ after some tech discussion. Work done and verified by Ashton Fagg <ashton@fagg.id.au> ok deraadt@ semarie@ claudio@
2021-06-20Put (boot) filename, next-server, host-name and domain-name into leaseFlorian Obser
file for the installer.
2021-06-18fix SMALL buildFlorian Obser
2021-06-16Actually request classless static routes from the dhcp server; missedFlorian Obser
in previous.
2021-06-16Implement classless static routes dhcp option.Florian Obser
For this we need to be able to handle multiple routes being sent from the engine to the main process as well as to the control tool. The configuration of the various cases (default route, directly connected routes, non-default route via a gateway) was inspired by dhclient's set_routes() and should behave the same way. Tested by Uwe Werler
2021-05-01In singel user mode / is mounted ro. Just warn if we can't createFlorian Obser
the control socket instead of fatal(). OK deraadt
2021-05-01Allow running in single user mode where /var/empty doesn't exist byFlorian Obser
switching from chroot("/var/empty") to unveil("/", ""). This is just an extra pair of suspenders since these processes pledge(2) to not access the filesystem. OK deraadt
2021-04-14my fingers cannot avoid KNF'ing as I review codeTheo de Raadt
2021-04-10Make sure the ip header lands on a 4 byte alignment by adding 2 bytesFlorian Obser
padding because the ethernet header in front is only 14 bytes. Found the hard way by me while testing on sparc64. Solution suggested by & OK deraadt
2021-04-09When a DHCP server sends an invalid T1 or T2 default back to the defaultMartijn van Duren
values as specified in RFC2131 section 4.4.5. Allows my Comtrend VI-3223u to work. OK florian@
2021-04-08Do not request unused "classless-static-routes" dhcp-options(5)kn
Doing so implies support for it, but dhcpleased(8) currently ingores it entirely and does not configure any route from it. As per RFC 3442 servers SHOULD NOT respond with a "routers" option when "classless-static-routes" is set. dhcpd(8)/dhcpd.conf(5) follows that, hence requesting but not using static routes results in not installing any routes at all. Stop signaling support for this option and only request "routers" such that dhcpleased continues to install a default route and properly ignores the unsupported option if used by the server. Report from Uwe Werler <uwe @ werler dot is> about a default route not being set when requesting the "classless-static-routes" dhcp-options(5) from dhcpd(8), thanks! OK florian
2021-03-27If we want to configure default routes over multiple interfaces weFlorian Obser
need to provide the address of the interface behind which the default router is in case they are on the same subnet otherwise the kernel can't figure out which route we are talking about This happens for example when your wifi and wired networks are bridged. Pointed out by claudio some time ago.
2021-03-22BOOTP has a minimum packet length of 300 bytes. Since DHCP isFlorian Obser
interoperable with BOOTP we should also send packets that have a minimum size of 300. I haven't seen a DHCP server that actually enforces this except the one in vmd(8), but it doesn't cost us much and prevents hair pulling later on when we find one in the wild. OK deraadt
2021-03-22Avoid overflow by writing x = (y * 7) / 8 as x = y - (y / 8); ok florianOtto Moerbeek
2021-03-19RTM_IFINFO is providing the mac address now, no need to go throughFlorian Obser
getifaddrs on every route message. This also allows us to drop the route pledge since we only need to fetch the interface state with getifaddrs on startup.
2021-03-17Split off init_ifaces from update_iface. init_ifaces discovers theFlorian Obser
state of the machine on startup using ioctl(2) and getifaddrs(3). We can then update this state with information provided by route messages. We still need getifaddrs(3) to check if the layer 2 address has changed. This simplifies error handling (what should we do if ioctl(2) fails?), reduces kernel round trips (no need to ask the kernel again for information RTM_IFINFO provided already) and prevents a theoretical race between RTM_IFINFO and getaddrinfo(3). In a fast link state UP -> DOWN -> UP transition RTM_IFINFO informs us that the link went down but we were not using this information but rather looked at getifaddrs(3) information which might see the link as already up again. We would then do nothing while we should try to get a new lease. By storing all interface information in the frontend process we can skip imsgs to the engine process if we get an RTM_IFINFO without relevant changes for us.
2021-03-16Don't (try to) deconfigure an interface that was never configured.Florian Obser
2021-03-16We can't learn anything interesting from RTM_NEWADDR, stop handlingFlorian Obser
it.
2021-03-14Since we are doing getifaddrs() anyway we can get the rdomain out ofFlorian Obser
AF_LINK and skip one ioctl. OK benno
2021-03-07Reduce debug logging by moving protocol level debug logFlorian Obser
behind -vv or by deleting unneeded output. While here reword some debug output to make it more useful. (There is more to be done here.)
2021-03-07No need to cap the exponential backoff here, iface_timeout() alreadyFlorian Obser
handles this for us by doing a state transition if we have been stuck in "rebooting" or "requesting" for too long. Makes the code a bit simpler and we only have one place were we need to special case the timeout cap.
2021-03-06Turns out there are dhcp servers that ignore DHCPREQUEST messages whenFlorian Obser
they don't like them instead of sending a DHCPNAK. Found the hard way by benno who didn't want to wait 127 seconds. Due to another bug dhcpleased would have exit through a fatal() in the frontend process if he had waited long enough for a Rebooting -> Init transition because we didn't deconfigure our IP address and thus didn't close our UDP socket. Upon configuring a new IP address we would open a new UDP socket send it to the frontend which would then fatal() due to an unexpected fd passed in. Aproporiate timings are rather underspecified in RFC 2131. Instead of doing an exponential backoff up to 64 in the "Rebooting" and "Requesting" state only go up to 2 for a total of 3 packets and total timeout of 3 seconds before going into "Init" state and sending a DHCPDISCOVER. To prevent the fatal() in the frontend process we reshuffle the state transition into the "Init" state and deconfigure the IP when appropriate.
2021-03-02Only attach a fully configured bpf filter to a network interface.Florian Obser
I'm worried we could see packets we shouldn't during a small time window.
2021-03-02Must include netinet/in.h before netinet/ip.h or bad things happen.Claudio Jeker
2021-03-02Make unveiling the lease directory a warning instead of a fatal errorFlorian Obser
when the lease directory does not exist. This means that dhcpleased(8) will no longer request a previously configured IP address from the dhcp server and will fall back to DHCPDISCOVER which requests any IP address from the dhcp server. This likely makes diskless(8) work with dhcpleased(8). A normal diskless(8) setup has only / mounted via nfs when dhcpleased(8) starts. /var exists but nothing is mounted there yet, meaning /var/db/dhcpleased does not exist so lease files are disabled. dhcpleased(8) sends a DHCPDISCOVER to request any IP address but since the dhcp server has (very likely) a 'fixed-address' configured we get the same IP back that is already configured. If /var/db/dhcpleased/ exists on / (and /var is *NOT* mounted later) in a diskless(8) setup, care must be taken that the root file system is not shared between machines. If /var/db/dhcpleased/ exists on / and /var on NFS is mounted over this later bad things probably happen. This is a configuration error and must befixed. discussed with deraadt@ Actuall tests on existing diskless(8) setups would be appreciated.
2021-03-02Better unveil error messages; requested by deraadt some time ago.Florian Obser
2021-03-02remove uneeded md5.h includeJonathan Gray
ok florian@
2021-03-01Log adding and deleting of IP addresses as well as nameservers.Florian Obser
deraadt@ pointed out that dhcpleased is too quiet.
2021-03-01We really must handle all possible enumeration values inFlorian Obser
state_transition() and iface_timeout(). Let the compiler help us by emitting a warning when we missed one (-Wswitch). Reminded by jsg who pointed out that gcc is quite confused and thinks there is an out of bounds access in if_state_name[] in the default case. There is not, if_state_name[] and enum if_state have to be kept in sync. (Note that -Wswitch is not a silver bullet, it just happens to work here.)
2021-03-01Let send_rdns_withdraw and send_deconfigure_interface clean up afterFlorian Obser
themselves. This way the iface object is in a consistent state. For consistency we should also withdraw rdns first, then deconfigure the interface. Lastly make sure we parse the lease file on a down -> up transition if we had a lease before and it had expired while the interface was in down state. Otherwise we'd send a dhcpdiscover requesting any IP address while we really should send a dhcprequest asking for our previous IP back.
2021-02-28Introduce #defines for exponential backoff, explain where they comeFlorian Obser
from and explain why we are a bit more agressive during startup. While here make the math a bit easier on the eyes.
2021-02-27Restore ability to handle default routes on multiple interfaces, thisFlorian Obser
got lost shortly before initial import. While here explicitly delete the default route when deconfiguring an interface. There might be corner cases where the stack will not tear it down for us when we remove the IP address.
2021-02-27Path #defines are traditionally prefixed with _PATH.Florian Obser
pointed out by deraadt
2021-02-27Read the lease file into a statically sized buffer and pass it over toFlorian Obser
the engine process for parsing instead of passing an fd. Let's us tighten the engine's pledge back down to "stdio".
2021-02-26Sort SEE ALSO and fix its punctuation.Theo Buehler
2021-02-26Import dhcpleased(8) - a dhcp daemon to acquire IPv4 address leasesFlorian Obser
from servers. dhcpleased(8) follows the well known three process design of all our privsep daemons. It uses pledge(2) and unveil(2) to restrict access further. In particular the "engine" process, responsible for parsing of untrusted data, is pledge'd "stdio". It cannot access the outside world nor the filesystem at all. Like slaacd(8) for IPv6 it will be always running and acquire addresses for all interface with the autoconf4 flag set. The flag can be set by "ifconfig $if inet autoconf" or by adding "inet autoconf" to /etc/hostname.if. An existing "dhcp" line should be removed. Various iterations tested by deraadt@ The hardest part, finding a name, was handled by jmatthew@ & otto@ "get to it :)" deraadt@