Package: udhcp Version: 0.9.8cvs20050303-2 Severity: wishlist Tags: patch -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA1
Hi, a while ago, I wrote a simpledhcpd binary inside the udhcp code: http://www.joachim-breitner.de/blog/archives/243-Spontanious-DHCP-Server-Done..html Some people have shown interest in getting this packaged for Debian. I think it would be unwise to copy the udhcpd code base, so I’m asking for inclusion of the patch in the udhcp package. Of course I’ll be present to reply to bugs in my code, and subscribe to the pts. Greetings and thanks, Joachim - -- System Information: Debian Release: lenny/sid APT prefers unstable APT policy: (500, 'unstable'), (1, 'experimental') Architecture: i386 (i686) Kernel: Linux 2.6.25-2-486 Locale: LANG=de_DE.UTF-8, LC_CTYPE=de_DE.UTF-8 (charmap=UTF-8) Shell: /bin/sh linked to /bin/bash -----BEGIN PGP SIGNATURE----- Version: GnuPG v1.4.9 (GNU/Linux) iEYEARECAAYFAkiyllMACgkQ9ijrk0dDIGztDQCeM+5HFfskwwstOYsW/KjK/D8i idMAn2KsW6/EFuVKR/ZTaJ7xwrblHg+S =QWlB -----END PGP SIGNATURE-----
diff -u udhcp-0.9.8cvs20050303/samples/udhcpd.conf udhcp-0.9.8cvs20050303/samples/udhcpd.conf --- udhcp-0.9.8cvs20050303/dhcpd.c +++ udhcp-0.9.8cvs20050303/dhcpd.c @@ -102,7 +102,7 @@ read_leases(server_config.lease_file); if (read_interface(server_config.interface, &server_config.ifindex, - &server_config.server, server_config.arp) < 0) + &server_config.server, server_config.arp, NULL) < 0) return 1; #ifndef UDHCP_DEBUG diff -u udhcp-0.9.8cvs20050303/Makefile udhcp-0.9.8cvs20050303/Makefile --- udhcp-0.9.8cvs20050303/Makefile +++ udhcp-0.9.8cvs20050303/Makefile @@ -25,6 +25,7 @@ OBJS_SHARED = common.o options.o packet.o pidfile.o signalpipe.o socket.o DHCPD_OBJS = dhcpd.o arpping.o files.o leases.o serverpacket.o static_leases.o DHCPC_OBJS = dhcpc.o clientpacket.o clientsocket.o script.o +SIMPLEDHCPD_OBJS = simpledhcpd.o arpping.o files.o leases.o serverpacket.o static_leases.o ifdef COMBINED_BINARY EXEC1 = udhcpd @@ -41,6 +42,9 @@ EXEC3 = dumpleases OBJS3 = dumpleases.o +EXEC4 = simpledhcpd +OBJS4 = $(SIMPLEDHCPD_OBJS) $(OBJS_SHARED) + BOOT_PROGRAM = udhcpc DAEMON = udhcpd COMMAND = dumpleases @@ -59,11 +63,11 @@ STRIP=$(CROSS_COMPILE)strip endif -all: $(EXEC1) $(EXEC2) $(EXEC3) - $(STRIP) --remove-section=.note --remove-section=.comment $(EXEC1) $(EXEC2) $(EXEC3) +all: $(EXEC1) $(EXEC2) $(EXEC3) $(EXEC4) + $(STRIP) --remove-section=.note --remove-section=.comment $(EXEC1) $(EXEC2) $(EXEC3) $(EXEC4) $(OBJS1) $(OBJS2) $(OBJS3): *.h Makefile -$(EXEC1) $(EXEC2) $(EXEC3): Makefile +$(EXEC1) $(EXEC2) $(EXEC3) $(EXEC4): Makefile .c.o: $(CC) -c $(CFLAGS) $< @@ -77,6 +81,8 @@ $(EXEC3): $(OBJS3) $(LD) $(LDFLAGS) $(OBJS3) -o $(EXEC3) +$(EXEC4): $(OBJS4) + $(LD) $(LDFLAGS) $(OBJS4) -o $(EXEC4) install: all mkdir -p $(USRSBINDIR) $(USRBINDIR) @@ -103 +109 @@ - -rm -f udhcpd udhcpc dumpleases *.o core + -rm -f udhcpd udhcpc dumpleases simpledhcpd *.o core diff -u udhcp-0.9.8cvs20050303/socket.c udhcp-0.9.8cvs20050303/socket.c --- udhcp-0.9.8cvs20050303/socket.c +++ udhcp-0.9.8cvs20050303/socket.c @@ -44,11 +44,12 @@ #include "socket.h" #include "common.h" -int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp) +int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp, uint32_t *mask) { int fd; struct ifreq ifr; struct sockaddr_in *our_ip; + struct sockaddr_in *our_mask; memset(&ifr, 0, sizeof(struct ifreq)); if((fd = socket(AF_INET, SOCK_RAW, IPPROTO_RAW)) >= 0) { @@ -70,0 +72,12 @@ + + if (mask) { + if (ioctl(fd, SIOCGIFNETMASK, &ifr) == 0) { + our_mask = (struct sockaddr_in *) &ifr.ifr_addr; + *mask = our_ip->sin_addr.s_addr; + DEBUG(LOG_INFO, "%s (our mask) = %s", ifr.ifr_name, inet_ntoa(our_mask->sin_addr)); + } else { + LOG(LOG_ERR, "SIOCGIFNETMASK failed, is the interface up and configured?: %m"); + close(fd); + return -1; + } + } reverted: --- udhcp-0.9.8cvs20050303/debian/changelog +++ udhcp-0.9.8cvs20050303/debian/changelog @@ -1,3 +1,9 @@ +udhcp (0.9.8cvs20050303-3) INOFFICIAL; urgency=low + + * Add simpledhcpd + + -- Joachim Breitner <[EMAIL PROTECTED]> Sun, 03 Jun 2007 01:54:07 +0200 + udhcp (0.9.8cvs20050303-2) unstable; urgency=low * Fix correct number of leases (closes: #341139 - thanks to Ferenc Wagner) reverted: --- udhcp-0.9.8cvs20050303/debian/control +++ udhcp-0.9.8cvs20050303/debian/control @@ -34,0 +35,12 @@ + +Package: simpledhcpd +Section: net +Architecture: any +Depends: ${shlibs:Depends} +Description: very small instant DHCP server + DHCP is a protocol like BOOTP (actually dhcpd includes much of + the functionality of BOOTPD!). It assigns IP addresses to clients + based on lease times. + . + You can use this program to quickly assign IP addresses in a + spontanious network, without any configuration file. reverted: --- udhcp-0.9.8cvs20050303/debian/rules +++ udhcp-0.9.8cvs20050303/debian/rules @@ -105,6 +105,33 @@ rm -fr debian/tmp + # Build simpledhcpd package. + install -d -m 755 debian/tmp/DEBIAN + + install -d -m 755 debian/tmp/usr/share/doc/simpledhcpd + #install -m 644 README debian/tmp/usr/share/doc/udhcpd + install -m 644 README.simpledhcpd debian/tmp/usr/share/doc/simpledhcpd/README + install -m 644 ChangeLog debian/tmp/usr/share/doc/simpledhcpd/changelog + install -m 644 debian/changelog debian/tmp/usr/share/doc/simpledhcpd/changelog.Debian + gzip -9v debian/tmp/usr/share/doc/simpledhcpd/* + install -m 644 debian/copyright debian/tmp/usr/share/doc/simpledhcpd + + #install -d -m 755 debian/tmp/usr/share/man/man8 + #install -m 644 udhcpd.8 debian/tmp/usr/share/man/man8 + #gzip -9v debian/tmp/usr/share/man/man8/udhcpd.8 + + install -d -m 755 debian/tmp/usr/sbin + install -m 755 simpledhcpd debian/tmp/usr/sbin/simpledhcpd + strip --remove-section=.comment --remove-section=.note --strip-unneeded debian/tmp/usr/sbin/simpledhcpd + + dpkg-shlibdeps simpledhcpd + dpkg-gencontrol -isp -psimpledhcpd + chown -R root.root debian/tmp + chmod -R go=rX debian/tmp + dpkg --build debian/tmp .. + + rm -fr debian/tmp + define checkdir test -f dhcpc.c -a -f debian/rules endef reverted: --- udhcp-0.9.8cvs20050303.orig/simpledhcpd.c +++ udhcp-0.9.8cvs20050303/simpledhcpd.c @@ -0,0 +1,331 @@ +/* simpledhcpd.c + * + * simpledhcp Server + * Copyright (C) 1999 Matthew Ramsay <[EMAIL PROTECTED]> + * Chris Trew <[EMAIL PROTECTED]> + * + * Rewrite by Russ Dill <[EMAIL PROTECTED]> July 2001 + * + * simpledhcpd copyright (C) 2007 Joachim Breitner <[EMAIL PROTECTED]> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program; if not, write to the Free Software + * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + */ + +#include <fcntl.h> +#include <string.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <arpa/inet.h> +#include <netdb.h> +#include <netinet/in.h> +#include <sys/socket.h> +#include <unistd.h> +#include <signal.h> +#include <errno.h> +#include <sys/ioctl.h> +#include <time.h> +#include <sys/time.h> + +#include "dhcpd.h" +#include "arpping.h" +#include "socket.h" +#include "options.h" +#include "files.h" +#include "serverpacket.h" +#include "common.h" +#include "signalpipe.h" +#include "static_leases.h" + + +/* globals */ +struct dhcpOfferedAddr *leases; +struct server_config_t server_config; + + + +#define READ_BUF_SIZE 80 +int get_dns_server(uint32_t *dns) +{ + FILE *in; + int ret = 1; + char buffer[READ_BUF_SIZE], *token, *addr; + + if (!(in = fopen("/etc/resolv.conf", "r"))) { + LOG(LOG_ERR, "unable to open /etc/resolv"); + return 0; + } + + while (fgets(buffer, READ_BUF_SIZE, in)) { + if (strchr(buffer, '\n')) *(strchr(buffer, '\n')) = '\0'; + if (strchr(buffer, '#')) *(strchr(buffer, '#')) = '\0'; + + if (!(token = strtok(buffer, " \t"))) continue; + if (!strcasecmp(token, "nameserver")) { + if (!(addr = strtok(NULL, ""))) continue; + if (inet_aton(addr,(struct in_addr *)dns)) + ret = 0; + } + } + + fclose(in); + return ret; +} + +int main(int argc, char *argv[]) +{ + fd_set rfds; + struct timeval tv; + int server_socket = -1; + int bytes, retval; + struct dhcpMessage packet; + uint8_t *state; + uint8_t *server_id, *requested; + uint32_t server_id_align, requested_align; + unsigned long timeout_end; + struct option_set *option; + struct dhcpOfferedAddr *lease; + struct dhcpOfferedAddr static_lease; + int max_sock; + unsigned long num_ips; + + uint32_t static_lease_ip; + + memset(&server_config, 0, sizeof(struct server_config_t)); + + if (argc != 2) { + LOG(LOG_ERR, "Usage: Device"); + return(2); + } + + // read_config(argc < 2 ? DHCPD_CONF_FILE : argv[1]); + read_config("/dev/null"); // reads defaults + + server_config.interface = argv[1]; + + /* Start the log, sanitize fd's, and write a pid file */ + // start_log_and_pid("udhcpd", server_config.pidfile); + + if ((option = find_option(server_config.options, DHCP_LEASE_TIME))) { + memcpy(&server_config.lease, option->data + 2, 4); + server_config.lease = ntohl(server_config.lease); + } + else server_config.lease = LEASE_TIME; + + + uint32_t mask; + if (read_interface(server_config.interface, &server_config.ifindex, + &server_config.server, server_config.arp, &mask) < 0) + return 1; + + attach_option(&(server_config.options), &dhcp_options[0], (char *)&(mask), 4); + attach_option(&(server_config.options), &dhcp_options[2], (char *)&(server_config.server), 4); + + uint32_t dns; + if (!get_dns_server(&dns)) { + attach_option(&(server_config.options), &dhcp_options[5], (char *)&(dns), 4); + DEBUG(LOG_INFO, "(dns) = %s", inet_ntoa(*(struct in_addr *)&dns)); + } + + if (server_config.server < (128<<24)) { + server_config.start = server_config.server + (10<<24); + server_config.end = (server_config.server | 255<<24) - (1<<24); + } else { + server_config.start = (server_config.server & ~(255<<24)) + (10<<24); + server_config.end = server_config.server - (1<<24); + } + + DEBUG(LOG_INFO, "(start) = %s", inet_ntoa(*(struct in_addr *)&server_config.start)); + DEBUG(LOG_INFO, "(end) = %s", inet_ntoa(*(struct in_addr *)&server_config.end)); + + /* Sanity check */ + // Let's try to fix http://bugs.debian.org/341139 ([EMAIL PROTECTED] - 16/12/05) + //num_ips = ntohl(server_config.end) - ntohl(server_config.start); + + num_ips = ntohl(server_config.end) - ntohl(server_config.start) + 1; + if (server_config.max_leases > num_ips) { + LOG(LOG_ERR, "max_leases value (%lu) not sane, " + "setting to %lu instead", + server_config.max_leases, num_ips); + server_config.max_leases = num_ips; + } + + leases = xcalloc(server_config.max_leases, sizeof(struct dhcpOfferedAddr)); + + // read_leases(server_config.lease_file); + + /* Setup the signal pipe */ + udhcp_sp_setup(); + + timeout_end = time(0) + server_config.auto_time; + while(1) { /* loop until universe collapses */ + + if (server_socket < 0) + if ((server_socket = listen_socket(INADDR_ANY, SERVER_PORT, server_config.interface)) < 0) { + LOG(LOG_ERR, "FATAL: couldn't create server socket, %m"); + return 2; + } + + max_sock = udhcp_sp_fd_set(&rfds, server_socket); + if (server_config.auto_time) { + tv.tv_sec = timeout_end - time(0); + tv.tv_usec = 0; + } + if (!server_config.auto_time || tv.tv_sec > 0) { + retval = select(max_sock + 1, &rfds, NULL, NULL, + server_config.auto_time ? &tv : NULL); + } else retval = 0; /* If we already timed out, fall through */ + + if (retval == 0) { + write_leases(); + timeout_end = time(0) + server_config.auto_time; + continue; + } else if (retval < 0 && errno != EINTR) { + DEBUG(LOG_INFO, "error on select"); + continue; + } + + switch (udhcp_sp_read(&rfds)) { + case SIGUSR1: + LOG(LOG_INFO, "Received a SIGUSR1"); + write_leases(); + /* why not just reset the timeout, eh */ + timeout_end = time(0) + server_config.auto_time; + continue; + case SIGTERM: + LOG(LOG_INFO, "Received a SIGTERM"); + return 0; + case 0: break; /* no signal */ + default: continue; /* signal or error (probably EINTR) */ + } + + if ((bytes = get_packet(&packet, server_socket)) < 0) { /* this waits for a packet - idle */ + if (bytes == -1 && errno != EINTR) { + DEBUG(LOG_INFO, "error on read, %m, reopening socket"); + close(server_socket); + server_socket = -1; + } + continue; + } + + if ((state = get_option(&packet, DHCP_MESSAGE_TYPE)) == NULL) { + DEBUG(LOG_ERR, "couldn't get option from packet, ignoring"); + continue; + } + + /* Look for a static lease */ + static_lease_ip = getIpByMac(server_config.static_leases, &packet.chaddr); + + if(static_lease_ip) + { + printf("Found static lease: %x\n", static_lease_ip); + + memcpy(&static_lease.chaddr, &packet.chaddr, 16); + static_lease.yiaddr = static_lease_ip; + static_lease.expires = 0; + + lease = &static_lease; + + } + else + { + lease = find_lease_by_chaddr(packet.chaddr); + } + + switch (state[0]) { + case DHCPDISCOVER: + DEBUG(LOG_INFO,"received DISCOVER"); + + if (sendOffer(&packet) < 0) { + LOG(LOG_ERR, "send OFFER failed"); + } + break; + case DHCPREQUEST: + DEBUG(LOG_INFO, "received REQUEST"); + + requested = get_option(&packet, DHCP_REQUESTED_IP); + server_id = get_option(&packet, DHCP_SERVER_ID); + + if (requested) memcpy(&requested_align, requested, 4); + if (server_id) memcpy(&server_id_align, server_id, 4); + + if (lease) { + if (server_id) { + /* SELECTING State */ + DEBUG(LOG_INFO, "server_id = %08x", ntohl(server_id_align)); + if (server_id_align == server_config.server && requested && + requested_align == lease->yiaddr) { + sendACK(&packet, lease->yiaddr); + } + } else { + if (requested) { + /* INIT-REBOOT State */ + if (lease->yiaddr == requested_align) + sendACK(&packet, lease->yiaddr); + else sendNAK(&packet); + } else { + /* RENEWING or REBINDING State */ + if (lease->yiaddr == packet.ciaddr) + sendACK(&packet, lease->yiaddr); + else { + /* don't know what to do!!!! */ + sendNAK(&packet); + } + } + } + + /* what to do if we have no record of the client */ + } else if (server_id) { + /* SELECTING State */ + + } else if (requested) { + /* INIT-REBOOT State */ + if ((lease = find_lease_by_yiaddr(requested_align))) { + if (lease_expired(lease)) { + /* probably best if we drop this lease */ + memset(lease->chaddr, 0, 16); + /* make some contention for this address */ + } else sendNAK(&packet); + } else if (requested_align < server_config.start || + requested_align > server_config.end) { + sendNAK(&packet); + } /* else remain silent */ + + } else { + /* RENEWING or REBINDING State */ + } + break; + case DHCPDECLINE: + DEBUG(LOG_INFO,"received DECLINE"); + if (lease) { + memset(lease->chaddr, 0, 16); + lease->expires = time(0) + server_config.decline_time; + } + break; + case DHCPRELEASE: + DEBUG(LOG_INFO,"received RELEASE"); + if (lease) lease->expires = time(0); + break; + case DHCPINFORM: + DEBUG(LOG_INFO,"received INFORM"); + send_inform(&packet); + break; + default: + LOG(LOG_WARNING, "unsupported DHCP message (%02x) -- ignoring", state[0]); + } + } + + return 0; +} + only in patch2: unchanged: --- udhcp-0.9.8cvs20050303.orig/socket.h +++ udhcp-0.9.8cvs20050303/socket.h @@ -2,7 +2,7 @@ #ifndef _SOCKET_H #define _SOCKET_H -int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp); +int read_interface(char *interface, int *ifindex, uint32_t *addr, uint8_t *arp, uint32_t *mask); int listen_socket(uint32_t ip, int port, char *inf); #endif only in patch2: unchanged: --- udhcp-0.9.8cvs20050303.orig/README.simpledhcpd +++ udhcp-0.9.8cvs20050303/README.simpledhcpd @@ -0,0 +1,24 @@ +== simpledhcpd == + +Usage: + simpledhcpd devicename + e.g. + simpledhcpd eth0 + +Effect: + simpledhcpd will start listening on the given interface + for DHCP requests. These will be answered, handing out + the following information: + * an IP from the same subnet as your own computer + * the netmask as configured on the device + * your IP address as the default gateway + * the first DNS server from /etc/resolv.conf + + This should be sufficient to enable the other computers to + communicate with you and, if you have a connection to the + internet and have set up routing, to share your internet + connection. + +Author: + (c) 2007 Joachim Breitner <[EMAIL PROTECTED]> + Based on the udhcpd code only in patch2: unchanged: --- udhcp-0.9.8cvs20050303.orig/dhcpc.c +++ udhcp-0.9.8cvs20050303/dhcpc.c @@ -290,7 +290,7 @@ start_log_and_pid("udhcpc", client_config.pidfile); if (read_interface(client_config.interface, &client_config.ifindex, - NULL, client_config.arp) < 0) + NULL, client_config.arp, NULL) < 0) return 1; if (!client_config.clientid) {