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;