patch for dhcp lease query, used in cisco uBRs'

Dmitry V.Sukhodoev raven at chics.ru
Wed Apr 6 03:59:05 PDT 2005


>Submitter-Id:	current-users
>Originator:	Dmitry V. Sukhodoev
>Organization:	JSC Chics
>Confidential:	no 
>Synopsis:	patch for dhcp lease query, used in cisco uBRs'
>Severity:	non-critical
>Priority:	medium
>Category:	ports
>Class:		maintainer-update
>Release:	FreeBSD 5.4-PRERELEASE i386
>Environment:
System: FreeBSD beat.oc.chics.ru 5.4-PRERELEASE FreeBSD 5.4-PRERELEASE #0: Mon Apr 4 20:06:46 YEKST 2005 root at beat.oc.chics.ru:/usr/obj/.amd_mnt/192.168.0.116/usr/nfs/src/sys/beat i386

>Description:
 additional support for dhcp lease, used in cisco uBRs'
>How-To-Repeat:
>Fix:
patch file /usr/ports/net/isc-dhcp3-server/files/patch-dlq:
=== cut ===
diff -ruN ../../work/dhcp-3.0.1rc14/includes/dhcp.h ./includes/dhcp.h
--- ../../work/dhcp-3.0.1rc14/includes/dhcp.h	Thu Jun 10 23:59:29 2004
+++ ./includes/dhcp.h	Mon Sep 27 16:54:40 2004
@@ -168,6 +168,11 @@
 #define DHCPNAK		6
 #define DHCPRELEASE	7
 #define DHCPINFORM	8
+#define DHCPLEASEQUERY		13
+#define DHCPLEASEKNOWN		14
+#define DHCPLEASEUNKNOWN	15
+#define DHCPLEASEACTIVE		16
+#define DHCPUNIMPLEMENTED	17
 
 /* Relay Agent Information option subtypes: */
 #define RAI_CIRCUIT_ID	1
diff -ruN ../../work/dhcp-3.0.1rc14/includes/dhcpd.h ./includes/dhcpd.h
--- ../../work/dhcp-3.0.1rc14/includes/dhcpd.h	Mon Sep 27 17:14:07 2004
+++ ./includes/dhcpd.h	Mon Sep 27 16:56:50 2004
@@ -1374,6 +1374,7 @@
 void dhcprelease PROTO ((struct packet *, int));
 void dhcpdecline PROTO ((struct packet *, int));
 void dhcpinform PROTO ((struct packet *, int));
+void dhcpleasequery PROTO ((struct packet *, int));
 void nak_lease PROTO ((struct packet *, struct iaddr *cip));
 void ack_lease PROTO ((struct packet *, struct lease *,
 		       unsigned int, TIME, char *, int));
diff -ruN ../../work/dhcp-3.0.1rc14/server/Makefile.dist ./server/Makefile.dist
--- ../../work/dhcp-3.0.1rc14/server/Makefile.dist	Mon Sep 27 17:14:07 2004
+++ ./server/Makefile.dist	Mon Sep 27 16:57:54 2004
@@ -25,9 +25,9 @@
 CATMANPAGES = dhcpd.cat8 dhcpd.conf.cat5 dhcpd.leases.cat5
 SEDMANPAGES = dhcpd.man8 dhcpd.conf.man5 dhcpd.leases.man5
 SRCS   = dhcpd.c dhcp.c bootp.c confpars.c db.c class.c failover.c \
-	 omapi.c mdb.c stables.c salloc.c ddns.c
+	 omapi.c mdb.c stables.c salloc.c ddns.c dhcpleasequery.c
 OBJS   = dhcpd.o dhcp.o bootp.o confpars.o db.o class.o failover.o \
-	 omapi.o mdb.o stables.o salloc.o ddns.o
+	 omapi.o mdb.o stables.o salloc.o ddns.o dhcpleasequery.o
 PROG   = dhcpd
 MAN    = dhcpd.8 dhcpd.conf.5 dhcpd.leases.5
 
diff -ruN ../../work/dhcp-3.0.1rc14/server/dhcp.c ./server/dhcp.c
--- ../../work/dhcp-3.0.1rc14/server/dhcp.c	Fri Jun 18 02:54:40 2004
+++ ./server/dhcp.c	Mon Sep 27 16:59:38 2004
@@ -226,7 +226,15 @@
 	      case DHCPACK:
 	      case DHCPOFFER:
 	      case DHCPNAK:
+	      case DHCPLEASEACTIVE:
+	      case DHCPLEASEKNOWN:
+	      case DHCPLEASEUNKNOWN:
 		break;
+
+	      case DHCPLEASEQUERY:
+		dhcpleasequery(packet, ms_nulltp);
+		log_info("incoming dhcp leased query");
+		break;
 
 	      default:
 		errmsg = "unknown packet type";
diff -ruN ../../work/dhcp-3.0.1rc14/server/dhcpleasequery.c ./server/dhcpleasequery.c
--- ../../work/dhcp-3.0.1rc14/server/dhcpleasequery.c	Thu Jan  1 05:00:00 1970
+++ ./server/dhcpleasequery.c	Thu Sep 16 18:00:09 2004
@@ -0,0 +1,202 @@
+#include "dhcpd.h"
+
+void dhcpleasequery (packet, ms_nulltp)
+struct packet *packet;
+int ms_nulltp;
+{
+
+  //printf("Received LEASEQUERY message\n");
+  struct lease *lease = (struct lease *)0;
+  struct iaddr cip;
+  struct sockaddr_in to;
+  //unsigned packet_length;
+  unsigned char dhcpMsgType;
+  struct dhcp_packet *raw = packet -> raw;
+  struct option_state *options = (struct option_state *)0;
+  struct option_cache *oc = (struct option_cache *)0;
+  struct data_string prl;
+  uint leaseTime;
+
+  option_state_allocate (&options, MDL);
+  cip.len = sizeof packet -> raw -> ciaddr;
+  memcpy (cip.iabuf, &packet -> raw -> ciaddr,
+  sizeof packet -> raw -> ciaddr);
+  //TODO if IP is all zeros, then set dhcp message type to DHCPUNIMPLEMENTED
+  find_lease_by_ip_addr (&lease, cip, MDL);
+
+  if (!lease) {
+    //printf("No lease found.\n");
+    dhcpMsgType = DHCPNAK;
+  } else {
+    if(lease -> binding_state == FTS_ACTIVE) {
+      dhcpMsgType = DHCPACK;
+    } else {
+      dhcpMsgType = DHCPNAK;
+    }
+    //printf("Lease was found.\n");
+
+    /*
+    char * pch = lease -> hardware_addr.hbuf;
+    printf("MAC addr (len=%d): %02x:%02x:%02x:%02x:%02x:%02x\n",
+   lease -> hardware_addr.hlen, pch[1], pch[2], pch[3], pch[4],
+pch[5], pch[6]);
+
+    printf("Lease has agent options: %s\n", (lease -> agent_options ? "yes"
+: "no"));
+    printf("Lease ends at %s\n", ctime(&(lease -> ends)));
+    */
+
+
+    // Set the hardware address fields
+    memcpy (packet -> raw -> chaddr,
+    &lease -> hardware_addr.hbuf [1], sizeof packet -> raw -> chaddr);
+    packet -> raw -> hlen = lease -> hardware_addr.hlen - 1;
+    packet -> raw -> htype = lease -> hardware_addr.hbuf [0];
+
+    // Set lease time option
+    if(dhcpMsgType == DHCPACK && lease -> ends > cur_time) {
+      if (!option_cache_allocate (&oc, MDL)) {
+log_error ("No memory for lease time option.");
+option_state_dereference (&options, MDL);
+return;
+      }
+      //printf("Current Time is %s\n", ctime(&cur_time));
+      leaseTime = htonl(lease -> ends - cur_time);
+      if (!make_const_data (&oc -> expression, (char*)&leaseTime, sizeof
+leaseTime, 0, 0, MDL)) {
+log_error ("No memory for expr_const expression.");
+option_cache_dereference (&oc, MDL);
+option_state_dereference (&options, MDL);
+return;
+      }
+      oc -> option = dhcp_universe.options [DHO_DHCP_LEASE_TIME];
+      save_option (&dhcp_universe, options, oc);
+      option_cache_dereference (&oc, MDL);
+    }
+
+    // Set the relay agent info.
+    if(lease -> agent_options) {
+      pair p;
+      int len = 0;
+      char agent_options[255];
+      for (p = lease -> agent_options -> first; p; p = p -> cdr) {
+oc = (struct option_cache *)p -> car;
+if (oc -> data.len) {
+  memcpy(&agent_options[len], (char*)&oc->option->code, 1);
+  memcpy(&agent_options[len+1], (char*)&oc->data.len, 1);
+  memcpy(&agent_options[len+2], oc->data.data, oc->data.len);
+  len += oc -> data.len + 2;
+}
+      }
+      oc = (struct option_cache *)0;
+      if (!option_cache_allocate (&oc, MDL)) {
+log_error ("No memory for lease time option.");
+option_state_dereference (&options, MDL);
+return;
+      }
+      if (!make_const_data (&oc -> expression, (char*)&agent_options, len,
+0, 0, MDL)) {
+log_error ("No memory for expr_const expression.");
+option_cache_dereference (&oc, MDL);
+option_state_dereference (&options, MDL);
+return;
+      }
+      oc -> option = dhcp_universe.options [DHO_DHCP_AGENT_OPTIONS];
+      save_option(&dhcp_universe, options, oc);
+      option_cache_dereference (&oc, MDL);
+    }
+
+  }
+
+  // Set the message type
+  packet -> raw -> op = BOOTREPLY;
+
+  // Set dhcp message type
+  if (!option_cache_allocate (&oc, MDL)) {
+    log_error ("No memory for dhcp message type.");
+    option_state_dereference (&options, MDL);
+    return;
+  }
+  if (!make_const_data (&oc -> expression, &dhcpMsgType, sizeof dhcpMsgType,
+0, 0, MDL)) {
+      log_error ("No memory for expr_const expression.");
+      option_cache_dereference (&oc, MDL);
+      option_state_dereference (&options, MDL);
+      return;
+  }
+  oc -> option = dhcp_universe.options [DHO_DHCP_MESSAGE_TYPE];
+  save_option (&dhcp_universe, options, oc);
+  option_cache_dereference (&oc, MDL);
+
+
+
+#if 0
+  memset (&prl, 0, sizeof prl);
+
+  /* Use the parameter list from the scope if there is one. */
+  oc = lookup_option (&dhcp_universe, options,
+      DHO_DHCP_PARAMETER_REQUEST_LIST);
+
+  /* Otherwise, if the client has provided a list of options
+     that it wishes returned, use it to prioritize.  Otherwise,
+     prioritize based on the default priority list. */
+
+  if (!oc)
+    oc = lookup_option (&dhcp_universe, packet -> options,
+DHO_DHCP_PARAMETER_REQUEST_LIST);
+
+  if (oc)
+    evaluate_option_cache (&prl, packet, (struct lease *)0,
+   (struct client_state *)0,
+   packet -> options, options,
+   &global_scope, oc, MDL);
+
+  //printf("Parameter Request List length is %d: %d, %d\n", prl.len, prl.data[0], prl.data[1]);
+
+  /* Set up the option buffer... */
+  packet -> packet_length = cons_options (packet, raw, lease,
+  (struct client_state *)0,
+  0, packet -> options, options,
+&global_scope,
+  0, 0, 0,
+  prl.len ? &prl : (struct
+data_string *)0,
+  (char *)0);
+#endif
+
+  /* Set up the option buffer... */
+  packet -> packet_length = cons_options (packet, raw, lease,
+  (struct client_state *)0,
+  0, packet -> options, options,
+&global_scope,
+  0, 0, 0,
+  (struct data_string *)0,
+  (char *)0);
+  option_state_dereference (&options, MDL);
+
+  to.sin_family = AF_INET;
+#ifdef HAVE_SA_LEN
+  to.sin_len = sizeof to;
+#endif
+  memset (to.sin_zero, 0, sizeof to.sin_zero);
+
+
+  /* LEASEQUERY packets must be sent to gateway address */
+  if (packet -> raw -> giaddr.s_addr) {
+    to.sin_addr = packet -> raw -> giaddr;
+    if (packet -> raw -> giaddr.s_addr != htonl (INADDR_LOOPBACK)) {
+      to.sin_port = local_port;
+    } else {
+      to.sin_port = remote_port; /* For debugging. */
+    }
+
+    if (fallback_interface) {
+      send_packet (fallback_interface,
+   (struct packet *)0,
+   packet -> raw, packet -> packet_length,
+   packet -> raw -> siaddr, &to,
+   (struct hardware *)0);
+
+    }
+  }
+}
=== cut ===


More information about the freebsd-ports mailing list