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;