I ran into a problem with the 'pump' program. My LAN subnet has only 8 addresses.
I have several machines and every DHCP address is accounted for. When I dual-booted
between linux and windoze, I found that I had ran out of DHCP addresses.

The problem turned out to be that Windoze specifies a ClientIdentifer when it registers
its DHCP address. Pump wasn't doing that.

This patch (attached) solves the problem.

-Bruce


p.s. Is the proper way to submit a problem and a fix?
Only in .: DIFF
diff -c orig/pump-0.7.6/dhcp.c ./dhcp.c
*** orig/pump-0.7.6/dhcp.c      Thu Feb  3 07:50:16 2000
--- ./dhcp.c    Sun Feb 27 15:27:57 2000
***************
*** 55,60 ****
--- 55,61 ----
  #define DHCP_OPTION_OPTIONREQ         55
  #define DHCP_OPTION_MAXSIZE           57
  #define DHCP_OPTION_T1                        58
+ #define DHCP_OPTION_CLIENTIDENTIFER   61
  
  #define BOOTP_CLIENT_PORT     68
  #define BOOTP_SERVER_PORT     67
***************
*** 112,117 ****
--- 113,120 ----
                                struct sockaddr_in * respondant,
                                int useBootPacket, int dhcpResponseType);
  static int dhcpMessageType(struct bootpRequest * response);
+ static void addVendorCode(struct bootpRequest * breq, unsigned char option,
+                         unsigned char length, void * data);
  static int newKernel(void);
  static char * getInterfaceInfo(struct pumpNetIntf * intf, int s);
  static char * perrorstr(char * msg);
***************
*** 558,563 ****
--- 561,572 ----
      struct ifreq req;
      int i;
  
+ #define IDENTCODE_SIZE (IFHWADDRLEN+1)
+     struct {
+       unsigned char   hwident;
+       unsigned char   hwaddr[IFHWADDRLEN];
+     } identCode;
+ 
      memset(breq, 0, sizeof(*breq));
  
      breq->opcode = BOOTP_OPCODE_REQUEST;
***************
*** 581,586 ****
--- 590,604 ----
  
      initVendorCodes(breq);
  
+     /*
+      * Microsoft uses a client identifier field of the 802.3 address with a
+      * pre-byte of a "1".  In order to re-use the DHCP address that they set
+      * for this interface, we have to mimic their identifier.
+      */
+     identCode.hwident = 1;
+     memcpy(&identCode.hwaddr, req.ifr_hwaddr.sa_data, IFHWADDRLEN);
+     addVendorCode(breq, DHCP_OPTION_CLIENTIDENTIFER, IDENTCODE_SIZE, &identCode);
+ 
      return NULL;
  }
  
***************
*** 637,643 ****
      address.s_addr = breq->bootp_gw_ip;
      syslog (LOG_DEBUG, "%s: bootp_gw_ip: %s", name, inet_ntoa (address));
      
!     syslog (LOG_DEBUG, "%s: hwaddr: %s", name, breq->hwaddr);
      syslog (LOG_DEBUG, "%s: servername: %s", name, breq->servername);
      syslog (LOG_DEBUG, "%s: bootfile: %s", name, breq->bootfile);
      
--- 655,665 ----
      address.s_addr = breq->bootp_gw_ip;
      syslog (LOG_DEBUG, "%s: bootp_gw_ip: %s", name, inet_ntoa (address));
      
!     syslog (LOG_DEBUG, "%s: hwaddr: %8.8x%8.8x%8.8x%8.8x",
!       name,
!       *(unsigned *)&breq->hwaddr[0], *(unsigned *)&breq->hwaddr[4],
!       *(unsigned *)&breq->hwaddr[8], *(unsigned *)&breq->hwaddr[12]);
! 
      syslog (LOG_DEBUG, "%s: servername: %s", name, breq->servername);
      syslog (LOG_DEBUG, "%s: bootfile: %s", name, breq->bootfile);
      
***************
*** 832,839 ****
                continue;
            }
            if (memcmp(bresp->hwaddr, breq->hwaddr, bresp->hwlength)) {
!               syslog(LOG_DEBUG, "reject: hwaddr: %s <--> %s",
!                       breq->hwaddr, bresp->hwaddr);
                continue;
            }
            i = dhcpMessageType(bresp);
--- 854,865 ----
                continue;
            }
            if (memcmp(bresp->hwaddr, breq->hwaddr, bresp->hwlength)) {
!               syslog(LOG_DEBUG, "reject: hwaddr: "
!               "%8.8x%8.8x%8.8x%8.8x <--> %8.8x%8.8x%8.8x%8.8x",
!               *(unsigned *)&breq->hwaddr[0], *(unsigned *)&breq->hwaddr[4],
!               *(unsigned *)&breq->hwaddr[8], *(unsigned *)&breq->hwaddr[12],
!               *(unsigned *)&bresp->hwaddr[0], *(unsigned *)&bresp->hwaddr[4],
!               *(unsigned *)&bresp->hwaddr[8], *(unsigned *)&bresp->hwaddr[12]);
                continue;
            }
            i = dhcpMessageType(bresp);
***************
*** 1185,1191 ****
           field this time. This makes me rfc compliant. */
        syslog (LOG_DEBUG, "got dhcp offer\n");
  
!       initVendorCodes(&breq);
  
        aShort = ntohs(sizeof(struct bootpRequest));
        addVendorCode(&breq, DHCP_OPTION_MAXSIZE, 2, &aShort);
--- 1211,1222 ----
           field this time. This makes me rfc compliant. */
        syslog (LOG_DEBUG, "got dhcp offer\n");
  
! 
!       if ((chptr = prepareRequest(&breq, s, intf->device, startTime))) {
!           close(s);
!           pumpDisableInterface(intf->device);
!           return chptr;
!       }
  
        aShort = ntohs(sizeof(struct bootpRequest));
        addVendorCode(&breq, DHCP_OPTION_MAXSIZE, 2, &aShort);



diff -c orig/pump-0.7.6/pump.c ./pump.c
*** orig/pump-0.7.6/pump.c      Thu Feb  3 08:54:33 2000
--- ./pump.c    Sun Feb 27 08:58:55 2000
***************
*** 125,131 ****
            return strdup(start);
        }
  
!       while (*start && (*start != "\n")) start++;
      }
  
      return NULL;
--- 125,131 ----
            return strdup(start);
        }
  
!       while (*start && (*start != '\n')) start++;
      }
  
      return NULL;

Reply via email to