aboutsummaryrefslogtreecommitdiff
path: root/networking/udhcp/dhcpd.c
diff options
context:
space:
mode:
Diffstat (limited to 'networking/udhcp/dhcpd.c')
-rw-r--r--networking/udhcp/dhcpd.c35
1 files changed, 25 insertions, 10 deletions
diff --git a/networking/udhcp/dhcpd.c b/networking/udhcp/dhcpd.c
index 91f70970a..0f5edb75c 100644
--- a/networking/udhcp/dhcpd.c
+++ b/networking/udhcp/dhcpd.c
@@ -27,7 +27,7 @@
27//kbuild:lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o 27//kbuild:lib-$(CONFIG_FEATURE_UDHCP_RFC3397) += domain_codec.o
28 28
29//usage:#define udhcpd_trivial_usage 29//usage:#define udhcpd_trivial_usage
30//usage: "[-fS] [-I ADDR]" IF_FEATURE_UDHCP_PORT(" [-P PORT]") " [CONFFILE]" 30//usage: "[-fS] [-I ADDR] [-a MSEC]" IF_FEATURE_UDHCP_PORT(" [-P PORT]") " [CONFFILE]"
31//usage:#define udhcpd_full_usage "\n\n" 31//usage:#define udhcpd_full_usage "\n\n"
32//usage: "DHCP server\n" 32//usage: "DHCP server\n"
33//usage: "\n -f Run in foreground" 33//usage: "\n -f Run in foreground"
@@ -451,6 +451,8 @@ static NOINLINE void read_config(const char *file)
451 451
452 server_data.start_ip = ntohl(server_data.start_ip); 452 server_data.start_ip = ntohl(server_data.start_ip);
453 server_data.end_ip = ntohl(server_data.end_ip); 453 server_data.end_ip = ntohl(server_data.end_ip);
454 if (server_data.start_ip > server_data.end_ip)
455 bb_error_msg_and_die("bad start/end IP range in %s", file);
454} 456}
455 457
456static void write_leases(void) 458static void write_leases(void)
@@ -612,6 +614,10 @@ static void send_packet_to_relay(struct dhcp_packet *dhcp_pkt)
612 udhcp_send_kernel_packet(dhcp_pkt, 614 udhcp_send_kernel_packet(dhcp_pkt,
613 server_data.server_nip, SERVER_PORT, 615 server_data.server_nip, SERVER_PORT,
614 dhcp_pkt->gateway_nip, SERVER_PORT, 616 dhcp_pkt->gateway_nip, SERVER_PORT,
617 /* Yes, relay agents receive (and send) all their packets on SERVER_PORT,
618 * even those which are clients' requests and would normally
619 * (i.e. without relay) use CLIENT_PORT. See RFC 1542.
620 */
615 server_data.interface); 621 server_data.interface);
616} 622}
617 623
@@ -858,7 +864,6 @@ int udhcpd_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
858int udhcpd_main(int argc UNUSED_PARAM, char **argv) 864int udhcpd_main(int argc UNUSED_PARAM, char **argv)
859{ 865{
860 int server_socket = -1, retval; 866 int server_socket = -1, retval;
861 uint8_t *state;
862 unsigned timeout_end; 867 unsigned timeout_end;
863 unsigned num_ips; 868 unsigned num_ips;
864 unsigned opt; 869 unsigned opt;
@@ -877,6 +882,12 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
877 /* Setup the signal pipe on fds 3,4 - must be before openlog() */ 882 /* Setup the signal pipe on fds 3,4 - must be before openlog() */
878 udhcp_sp_setup(); 883 udhcp_sp_setup();
879 884
885#define OPT_f (1 << 0)
886#define OPT_S (1 << 1)
887#define OPT_I (1 << 2)
888#define OPT_v (1 << 3)
889#define OPT_a (1 << 4)
890#define OPT_P (1 << 5)
880 opt = getopt32(argv, "^" 891 opt = getopt32(argv, "^"
881 "fSI:va:"IF_FEATURE_UDHCP_PORT("P:") 892 "fSI:va:"IF_FEATURE_UDHCP_PORT("P:")
882 "\0" 893 "\0"
@@ -887,24 +898,24 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
887 , &str_a 898 , &str_a
888 IF_FEATURE_UDHCP_PORT(, &str_P) 899 IF_FEATURE_UDHCP_PORT(, &str_P)
889 IF_UDHCP_VERBOSE(, &dhcp_verbose) 900 IF_UDHCP_VERBOSE(, &dhcp_verbose)
890 ); 901 );
891 if (!(opt & 1)) { /* no -f */ 902 if (!(opt & OPT_f)) { /* no -f */
892 bb_daemonize_or_rexec(0, argv); 903 bb_daemonize_or_rexec(0, argv);
893 logmode = LOGMODE_NONE; 904 logmode = LOGMODE_NONE;
894 } 905 }
895 /* update argv after the possible vfork+exec in daemonize */ 906 /* update argv after the possible vfork+exec in daemonize */
896 argv += optind; 907 argv += optind;
897 if (opt & 2) { /* -S */ 908 if (opt & OPT_S) {
898 openlog(applet_name, LOG_PID, LOG_DAEMON); 909 openlog(applet_name, LOG_PID, LOG_DAEMON);
899 logmode |= LOGMODE_SYSLOG; 910 logmode |= LOGMODE_SYSLOG;
900 } 911 }
901 if (opt & 4) { /* -I */ 912 if (opt & OPT_I) {
902 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET); 913 len_and_sockaddr *lsa = xhost_and_af2sockaddr(str_I, 0, AF_INET);
903 server_data.server_nip = lsa->u.sin.sin_addr.s_addr; 914 server_data.server_nip = lsa->u.sin.sin_addr.s_addr;
904 free(lsa); 915 free(lsa);
905 } 916 }
906#if ENABLE_FEATURE_UDHCP_PORT 917#if ENABLE_FEATURE_UDHCP_PORT
907 if (opt & 32) { /* -P */ 918 if (opt & OPT_P) {
908 SERVER_PORT = xatou16(str_P); 919 SERVER_PORT = xatou16(str_P);
909 CLIENT_PORT = SERVER_PORT + 1; 920 CLIENT_PORT = SERVER_PORT + 1;
910 } 921 }
@@ -960,6 +971,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
960 struct dhcp_packet packet; 971 struct dhcp_packet packet;
961 int bytes; 972 int bytes;
962 int tv; 973 int tv;
974 uint8_t *msg_type;
963 uint8_t *server_id_opt; 975 uint8_t *server_id_opt;
964 uint8_t *requested_ip_opt; 976 uint8_t *requested_ip_opt;
965 uint32_t requested_nip; 977 uint32_t requested_nip;
@@ -1017,6 +1029,9 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
1017 * socket read inside this call is restarted on caught signals. 1029 * socket read inside this call is restarted on caught signals.
1018 */ 1030 */
1019 bytes = udhcp_recv_kernel_packet(&packet, server_socket); 1031 bytes = udhcp_recv_kernel_packet(&packet, server_socket);
1032//NB: we do not check source port here. Should we?
1033//It should be CLIENT_PORT for clients,
1034//or SERVER_PORT for relay agents (in which case giaddr must be != 0.0.0.0)
1020 if (bytes < 0) { 1035 if (bytes < 0) {
1021 /* bytes can also be -2 ("bad packet data") */ 1036 /* bytes can also be -2 ("bad packet data") */
1022 if (bytes == -1 && errno != EINTR) { 1037 if (bytes == -1 && errno != EINTR) {
@@ -1034,8 +1049,8 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
1034 bb_info_msg("not a REQUEST%s", ", ignoring packet"); 1049 bb_info_msg("not a REQUEST%s", ", ignoring packet");
1035 continue; 1050 continue;
1036 } 1051 }
1037 state = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE); 1052 msg_type = udhcp_get_option(&packet, DHCP_MESSAGE_TYPE);
1038 if (state == NULL || state[0] < DHCP_MINTYPE || state[0] > DHCP_MAXTYPE) { 1053 if (!msg_type || msg_type[0] < DHCP_MINTYPE || msg_type[0] > DHCP_MAXTYPE) {
1039 bb_info_msg("no or bad message type option%s", ", ignoring packet"); 1054 bb_info_msg("no or bad message type option%s", ", ignoring packet");
1040 continue; 1055 continue;
1041 } 1056 }
@@ -1071,7 +1086,7 @@ int udhcpd_main(int argc UNUSED_PARAM, char **argv)
1071 move_from_unaligned32(requested_nip, requested_ip_opt); 1086 move_from_unaligned32(requested_nip, requested_ip_opt);
1072 } 1087 }
1073 1088
1074 switch (state[0]) { 1089 switch (msg_type[0]) {
1075 1090
1076 case DHCPDISCOVER: 1091 case DHCPDISCOVER:
1077 log1("received %s", "DISCOVER"); 1092 log1("received %s", "DISCOVER");