2004-12-15 Dan Williams <dcbw@redhat.com>
* Rework the DHCP code again to revert to sending full ethernet frames rather then relying on the kernel to do the right thing with our packets. git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@340 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
@@ -1,3 +1,9 @@
|
|||||||
|
2004-12-15 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
|
* Rework the DHCP code again to revert to sending full ethernet frames
|
||||||
|
rather then relying on the kernel to do the right thing with our
|
||||||
|
packets.
|
||||||
|
|
||||||
2004-12-06 Dan Williams <dcbw@redhat.com>
|
2004-12-06 Dan Williams <dcbw@redhat.com>
|
||||||
|
|
||||||
* dhcpcd/client.c
|
* dhcpcd/client.c
|
||||||
|
@@ -15,7 +15,9 @@ libdhcpc_a_SOURCES= \
|
|||||||
client.c \
|
client.c \
|
||||||
client.h \
|
client.h \
|
||||||
dhcpcd.c \
|
dhcpcd.c \
|
||||||
dhcpcd.h
|
dhcpcd.h \
|
||||||
|
udpipgen.c \
|
||||||
|
udpipgen.h
|
||||||
|
|
||||||
bin_PROGRAMS = dhcp_test
|
bin_PROGRAMS = dhcp_test
|
||||||
dhcp_test_SOURCES = dhcp_test.c
|
dhcp_test_SOURCES = dhcp_test.c
|
||||||
|
@@ -28,13 +28,6 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
|
|
||||||
struct packed_ether_header
|
|
||||||
{
|
|
||||||
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
|
|
||||||
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
|
|
||||||
u_int16_t ether_type; /* packet type ID field */
|
|
||||||
} __attribute__((packed));
|
|
||||||
|
|
||||||
typedef struct arpMessage
|
typedef struct arpMessage
|
||||||
{
|
{
|
||||||
struct packed_ether_header ethhdr;
|
struct packed_ether_header ethhdr;
|
||||||
|
@@ -27,13 +27,20 @@
|
|||||||
#include <net/if_arp.h>
|
#include <net/if_arp.h>
|
||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "buildmsg.h"
|
#include "buildmsg.h"
|
||||||
|
#include "udpipgen.h"
|
||||||
|
|
||||||
extern int DebugFlag;
|
extern int DebugFlag;
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void fill_common_fields (dhcp_interface *iface, dhcpMessage *dhcp_msg, int bcast_resp)
|
void fill_common_fields (dhcp_interface *iface, udpipMessage *msg, unsigned char dhost_addr[6], int bcast_resp)
|
||||||
{
|
{
|
||||||
int magic_cookie = htonl (MAGIC_COOKIE);
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
|
int magic_cookie = htonl (MAGIC_COOKIE);
|
||||||
|
|
||||||
|
/* build Ethernet header */
|
||||||
|
memcpy (msg->ethhdr.ether_dhost, dhost_addr, ETH_ALEN);
|
||||||
|
memcpy (msg->ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
|
||||||
|
msg->ethhdr.ether_type = htons (ETHERTYPE_IP);
|
||||||
|
|
||||||
dhcp_msg->op = DHCP_BOOTREQUEST;
|
dhcp_msg->op = DHCP_BOOTREQUEST;
|
||||||
dhcp_msg->htype = ARPHRD_ETHER;
|
dhcp_msg->htype = ARPHRD_ETHER;
|
||||||
@@ -41,7 +48,7 @@ void fill_common_fields (dhcp_interface *iface, dhcpMessage *dhcp_msg, int bcast
|
|||||||
dhcp_msg->xid = iface->xid;
|
dhcp_msg->xid = iface->xid;
|
||||||
dhcp_msg->secs = htons (10);
|
dhcp_msg->secs = htons (10);
|
||||||
|
|
||||||
if ( bcast_resp && iface->client_options->do_broadcast_response )
|
if (bcast_resp && iface->client_options->do_broadcast_response)
|
||||||
dhcp_msg->flags = htons (BROADCAST_FLAG);
|
dhcp_msg->flags = htons (BROADCAST_FLAG);
|
||||||
|
|
||||||
memcpy (dhcp_msg->chaddr, iface->chaddr, ETH_ALEN);
|
memcpy (dhcp_msg->chaddr, iface->chaddr, ETH_ALEN);
|
||||||
@@ -65,6 +72,9 @@ unsigned char *fill_host_and_class_id (dhcp_interface *iface, unsigned char *p)
|
|||||||
*p++ = iface->cls_id_len;
|
*p++ = iface->cls_id_len;
|
||||||
memcpy (p, iface->cls_id, iface->cls_id_len);
|
memcpy (p, iface->cls_id, iface->cls_id_len);
|
||||||
p += iface->cls_id_len;
|
p += iface->cls_id_len;
|
||||||
|
|
||||||
|
*p++ = dhcpClientIdentifier;
|
||||||
|
*p++ = iface->cli_id_len;
|
||||||
memcpy (p, iface->cli_id, iface->cli_id_len);
|
memcpy (p, iface->cli_id, iface->cli_id_len);
|
||||||
p += iface->cli_id_len;
|
p += iface->cli_id_len;
|
||||||
|
|
||||||
@@ -75,18 +85,13 @@ unsigned char *fill_host_and_class_id (dhcp_interface *iface, unsigned char *p)
|
|||||||
unsigned char *fill_param_request (unsigned char *p)
|
unsigned char *fill_param_request (unsigned char *p)
|
||||||
{
|
{
|
||||||
*p++ = dhcpParamRequest;
|
*p++ = dhcpParamRequest;
|
||||||
*p++ = 14;
|
*p++ = 9;
|
||||||
*p++ = subnetMask;
|
*p++ = subnetMask;
|
||||||
*p++ = routersOnSubnet;
|
*p++ = routersOnSubnet;
|
||||||
*p++ = dns;
|
*p++ = dns;
|
||||||
*p++ = hostName;
|
*p++ = hostName;
|
||||||
*p++ = domainName;
|
*p++ = domainName;
|
||||||
*p++ = rootPath;
|
|
||||||
*p++ = defaultIPTTL;
|
|
||||||
*p++ = broadcastAddr;
|
*p++ = broadcastAddr;
|
||||||
*p++ = performMaskDiscovery;
|
|
||||||
*p++ = performRouterDiscovery;
|
|
||||||
*p++ = staticRoute;
|
|
||||||
*p++ = nisDomainName;
|
*p++ = nisDomainName;
|
||||||
*p++ = nisServers;
|
*p++ = nisServers;
|
||||||
*p++ = ntpServers;
|
*p++ = ntpServers;
|
||||||
@@ -138,26 +143,15 @@ unsigned char *fill_message_type (unsigned char request, unsigned char *p)
|
|||||||
return p;
|
return p;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void construct_dest_address (struct sockaddr_in *dest_addr, unsigned int in_addr)
|
udpipMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
if (!dest_addr)
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
return;
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
|
|
||||||
memset (dest_addr, 0, sizeof (struct sockaddr_in));
|
|
||||||
dest_addr->sin_family = AF_INET;
|
|
||||||
dest_addr->sin_port = htons (DHCP_SERVER_PORT);
|
|
||||||
memcpy (&dest_addr->sin_addr, &in_addr, sizeof (dest_addr->sin_addr));
|
|
||||||
}
|
|
||||||
/*****************************************************************************/
|
|
||||||
dhcpMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
|
||||||
{
|
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
unsigned int lease_time = htonl (iface->default_lease_time);
|
unsigned int lease_time = htonl (iface->default_lease_time);
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
p = fill_message_type (DHCP_DISCOVER, p);
|
p = fill_message_type (DHCP_DISCOVER, p);
|
||||||
if ( iface->ciaddr )
|
if ( iface->ciaddr )
|
||||||
{
|
{
|
||||||
@@ -169,20 +163,24 @@ dhcpMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len, struct so
|
|||||||
p = fill_lease_time (&lease_time, p);
|
p = fill_lease_time (&lease_time, p);
|
||||||
p = fill_param_request (p);
|
p = fill_param_request (p);
|
||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p++ = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)p - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
p = fill_message_type (DHCP_REQUEST, p);
|
p = fill_message_type (DHCP_REQUEST, p);
|
||||||
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
|
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
|
||||||
if ( iface->client_options->do_rfc1541 )
|
if ( iface->client_options->do_rfc1541 )
|
||||||
@@ -195,18 +193,22 @@ dhcpMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len, struct soc
|
|||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return udp_msg;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, iface->siaddr);
|
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
dhcp_msg->ciaddr = iface->ciaddr;
|
dhcp_msg->ciaddr = iface->ciaddr;
|
||||||
p = fill_message_type (DHCP_REQUEST, p);
|
p = fill_message_type (DHCP_REQUEST, p);
|
||||||
#if 0
|
#if 0
|
||||||
@@ -217,18 +219,21 @@ dhcpMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len, struct socka
|
|||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
p++;
|
||||||
return (dhcp_msg);
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
dhcp_msg->ciaddr = iface->ciaddr;
|
dhcp_msg->ciaddr = iface->ciaddr;
|
||||||
p = fill_message_type (DHCP_REQUEST, p);
|
p = fill_message_type (DHCP_REQUEST, p);
|
||||||
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
|
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
|
||||||
@@ -237,19 +242,23 @@ dhcpMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len, struct sock
|
|||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, INADDR_BROADCAST, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return udp_msg;
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
unsigned int lease_time = htonl (iface->default_lease_time);
|
unsigned int lease_time = htonl (iface->default_lease_time);
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
p = fill_message_type (DHCP_REQUEST, p);
|
p = fill_message_type (DHCP_REQUEST, p);
|
||||||
if ( iface->client_options->do_rfc1541 )
|
if ( iface->client_options->do_rfc1541 )
|
||||||
dhcp_msg->ciaddr = iface->ciaddr;
|
dhcp_msg->ciaddr = iface->ciaddr;
|
||||||
@@ -260,18 +269,22 @@ dhcpMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len, struct sock
|
|||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, iface->siaddr);
|
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
dhcp_msg->ciaddr = iface->ciaddr;
|
dhcp_msg->ciaddr = iface->ciaddr;
|
||||||
*p++ = dhcpMessageType;
|
*p++ = dhcpMessageType;
|
||||||
*p++ = 1;
|
*p++ = 1;
|
||||||
@@ -281,19 +294,23 @@ dhcpMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len, struct soc
|
|||||||
p += iface->cli_id_len;
|
p += iface->cli_id_len;
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
#ifdef ARPCHECK
|
#ifdef ARPCHECK
|
||||||
dhcpMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, iface->siaddr);
|
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, udp_msg, 1);
|
|
||||||
*p++ = dhcpMessageType;
|
*p++ = dhcpMessageType;
|
||||||
*p++ = 1;
|
*p++ = 1;
|
||||||
*p++ = DHCP_DECLINE;
|
*p++ = DHCP_DECLINE;
|
||||||
@@ -306,25 +323,33 @@ dhcpMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len, struct soc
|
|||||||
p += iface->cli_id_len;
|
p += iface->cli_id_len;
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, iface->siaddr, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
dhcpMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
udpipMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len)
|
||||||
{
|
{
|
||||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||||
|
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||||
register unsigned char *p = dhcp_msg->options + 4;
|
register unsigned char *p = dhcp_msg->options + 4;
|
||||||
|
int dhcp_msg_len;
|
||||||
|
|
||||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||||
|
|
||||||
fill_common_fields (iface, dhcp_msg, 1);
|
|
||||||
dhcp_msg->ciaddr = iface->ciaddr;
|
dhcp_msg->ciaddr = iface->ciaddr;
|
||||||
p = fill_message_type (DHCP_INFORM, p);
|
p = fill_message_type (DHCP_INFORM, p);
|
||||||
p = fill_param_request (p);
|
p = fill_param_request (p);
|
||||||
p = fill_host_and_class_id (iface, p);
|
p = fill_host_and_class_id (iface, p);
|
||||||
*p = endOption;
|
*p = endOption;
|
||||||
|
|
||||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
/* build UDP/IP header */
|
||||||
return (dhcp_msg);
|
p++;
|
||||||
|
dhcp_msg_len = (char *)p - (char *)dhcp_msg;
|
||||||
|
udpipgen((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id, dhcp_msg_len);
|
||||||
|
*msg_len = (char *)(p++) - (char *)udp_msg;
|
||||||
|
return (udp_msg);
|
||||||
}
|
}
|
||||||
|
@@ -23,15 +23,17 @@
|
|||||||
#ifndef BUILDMSG_H
|
#ifndef BUILDMSG_H
|
||||||
#define BUILDMSG_H
|
#define BUILDMSG_H
|
||||||
|
|
||||||
dhcpMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
#include "client.h"
|
||||||
dhcpMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
|
||||||
dhcpMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len);
|
||||||
dhcpMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len);
|
||||||
dhcpMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len);
|
||||||
dhcpMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len);
|
||||||
|
udpipMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len);
|
||||||
|
udpipMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len);
|
||||||
#ifdef ARPCHECK
|
#ifdef ARPCHECK
|
||||||
dhcpMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len);
|
||||||
#endif
|
#endif
|
||||||
dhcpMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
udpipMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@@ -46,6 +46,7 @@
|
|||||||
#include "client.h"
|
#include "client.h"
|
||||||
#include "buildmsg.h"
|
#include "buildmsg.h"
|
||||||
#include "arp.h"
|
#include "arp.h"
|
||||||
|
#include "udpipgen.h"
|
||||||
|
|
||||||
int DebugFlag = 1;
|
int DebugFlag = 1;
|
||||||
#define DEBUG
|
#define DEBUG
|
||||||
@@ -282,6 +283,8 @@ void class_id_setup (dhcp_interface *iface, const char *g_cls_id)
|
|||||||
|
|
||||||
if (!iface) return;
|
if (!iface) return;
|
||||||
|
|
||||||
|
memset (iface->cls_id, 0, DHCP_CLASS_ID_MAX_LEN);
|
||||||
|
|
||||||
if (g_cls_id)
|
if (g_cls_id)
|
||||||
g_cls_id_len = strlen (g_cls_id);
|
g_cls_id_len = strlen (g_cls_id);
|
||||||
|
|
||||||
@@ -297,33 +300,34 @@ void class_id_setup (dhcp_interface *iface, const char *g_cls_id)
|
|||||||
syslog (LOG_ERR,"classIDsetup: uname: %m\n");
|
syslog (LOG_ERR,"classIDsetup: uname: %m\n");
|
||||||
snprintf (iface->cls_id, DHCP_CLASS_ID_MAX_LEN, "%s %s %s",
|
snprintf (iface->cls_id, DHCP_CLASS_ID_MAX_LEN, "%s %s %s",
|
||||||
sname.sysname, sname.release, sname.machine);
|
sname.sysname, sname.release, sname.machine);
|
||||||
|
iface->cls_id_len = strlen (iface->cls_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
void client_id_setup (dhcp_interface *iface, const char *g_cli_id)
|
void client_id_setup (dhcp_interface *iface, const char *g_cli_id)
|
||||||
{
|
{
|
||||||
unsigned int g_cli_id_len = 0;
|
unsigned int g_cli_id_len = 0;
|
||||||
unsigned char *c = iface->cli_id;
|
char *c;
|
||||||
|
|
||||||
if (!iface) return;
|
if (!iface) return;
|
||||||
|
|
||||||
|
memset (iface->cli_id, 0, DHCP_CLIENT_ID_MAX_LEN);
|
||||||
|
c = iface->cli_id;
|
||||||
|
|
||||||
if (g_cli_id)
|
if (g_cli_id)
|
||||||
g_cli_id_len = strlen (g_cli_id);
|
g_cli_id_len = strlen (g_cli_id);
|
||||||
|
|
||||||
*c++ = dhcpClientIdentifier;
|
|
||||||
if ( g_cli_id_len )
|
if ( g_cli_id_len )
|
||||||
{
|
{
|
||||||
*c++ = g_cli_id_len + 1; /* 1 for the field below */
|
*c++ = 0; /* type: string */
|
||||||
*c++ = 0; /* type: string */
|
|
||||||
memcpy (c, g_cli_id, g_cli_id_len);
|
memcpy (c, g_cli_id, g_cli_id_len);
|
||||||
iface->cli_id_len = g_cli_id_len + 3;
|
iface->cli_id_len = g_cli_id_len + 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
*c++ = ETH_ALEN + 1; /* length: 6 (MAC Addr) + 1 (# field) */
|
|
||||||
*c++ = ARPHRD_ETHER; /* type: Ethernet address */
|
*c++ = ARPHRD_ETHER; /* type: Ethernet address */
|
||||||
memcpy (c, iface->chaddr, ETH_ALEN);
|
memcpy (c, iface->chaddr, ETH_ALEN);
|
||||||
iface->cli_id_len = ETH_ALEN + 3;
|
iface->cli_id_len = ETH_ALEN + 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@@ -438,9 +442,9 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
|
|||||||
int recv_sk = -1;
|
int recv_sk = -1;
|
||||||
struct sockaddr_in addr;
|
struct sockaddr_in addr;
|
||||||
int tries = 0;
|
int tries = 0;
|
||||||
int dhcp_send_len, err = RET_DHCP_TIMEOUT;
|
int err = RET_DHCP_TIMEOUT;
|
||||||
dhcpMessage *dhcp_send = NULL;
|
|
||||||
struct timeval recv_timeout, overall_end, diff, current;
|
struct timeval recv_timeout, overall_end, diff, current;
|
||||||
|
udpipMessage *udp_send = NULL;
|
||||||
|
|
||||||
if (!dhcp_return)
|
if (!dhcp_return)
|
||||||
return RET_DHCP_ERROR;
|
return RET_DHCP_ERROR;
|
||||||
@@ -450,13 +454,6 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
|
|||||||
if (!pkt_recv)
|
if (!pkt_recv)
|
||||||
return RET_DHCP_ERROR;
|
return RET_DHCP_ERROR;
|
||||||
|
|
||||||
/* Call the specific DHCP message building routine for this request */
|
|
||||||
if (!(dhcp_send = build_dhcp_msg (iface, &dhcp_send_len, &addr)))
|
|
||||||
{
|
|
||||||
err = RET_DHCP_ERROR;
|
|
||||||
goto out;
|
|
||||||
}
|
|
||||||
|
|
||||||
recv_sk = socket (AF_PACKET, SOCK_DGRAM, ntohs (ETH_P_IP));
|
recv_sk = socket (AF_PACKET, SOCK_DGRAM, ntohs (ETH_P_IP));
|
||||||
if (recv_sk < 0)
|
if (recv_sk < 0)
|
||||||
{
|
{
|
||||||
@@ -476,6 +473,7 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
|
|||||||
syslog (LOG_INFO, "DHCP: Starting request loop");
|
syslog (LOG_INFO, "DHCP: Starting request loop");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
udpipMessage *udp_msg_recv = NULL;
|
||||||
struct iphdr *ip_hdr;
|
struct iphdr *ip_hdr;
|
||||||
struct udphdr *udp_hdr;
|
struct udphdr *udp_hdr;
|
||||||
char *tmp_ip;
|
char *tmp_ip;
|
||||||
@@ -494,7 +492,19 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
|
|||||||
syslog (LOG_INFO, "DHCP: Sending request packet...");
|
syslog (LOG_INFO, "DHCP: Sending request packet...");
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
err = sendto (iface->sk, dhcp_send, dhcp_send_len, MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof (struct sockaddr));
|
int udp_send_len = 0;
|
||||||
|
struct sockaddr addr;
|
||||||
|
|
||||||
|
/* Call the specific DHCP message building routine for this request */
|
||||||
|
if (!(udp_send = build_dhcp_msg (iface, &udp_send_len)))
|
||||||
|
{
|
||||||
|
err = RET_DHCP_ERROR;
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
memset (&addr, 0, sizeof (struct sockaddr));
|
||||||
|
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
|
||||||
|
err = sendto (iface->sk, udp_send, udp_send_len, MSG_DONTWAIT, (struct sockaddr *)&addr, sizeof (struct sockaddr));
|
||||||
if (iface->cease || ((err == -1) && (errno != EAGAIN)))
|
if (iface->cease || ((err == -1) && (errno != EAGAIN)))
|
||||||
{
|
{
|
||||||
syslog (LOG_INFO, "DHCP: error sending, cease = %d, err = %d, errno = %d", iface->cease, err, errno);
|
syslog (LOG_INFO, "DHCP: error sending, cease = %d, err = %d, errno = %d", iface->cease, err, errno);
|
||||||
@@ -657,7 +667,7 @@ int dhcp_handle_transaction (dhcp_interface *iface, unsigned int expected_reply_
|
|||||||
} while (timeval_subtract (&diff, &overall_end, ¤t) == 0);
|
} while (timeval_subtract (&diff, &overall_end, ¤t) == 0);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
free (dhcp_send);
|
free (udp_send);
|
||||||
if (err != RET_DHCP_SUCCESS)
|
if (err != RET_DHCP_SUCCESS)
|
||||||
free (pkt_recv);
|
free (pkt_recv);
|
||||||
if (recv_sk >= 0)
|
if (recv_sk >= 0)
|
||||||
@@ -868,16 +878,16 @@ int dhcp_rebind(dhcp_interface *iface)
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
int dhcp_release(dhcp_interface *iface)
|
int dhcp_release(dhcp_interface *iface)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
udpipMessage *msg;
|
||||||
socklen_t addr_len = sizeof (struct sockaddr_in);
|
struct sockaddr addr;
|
||||||
int len;
|
socklen_t addr_len = sizeof (struct sockaddr);
|
||||||
dhcpMessage *msg;
|
int len;
|
||||||
|
|
||||||
if ( iface->ciaddr == 0 )
|
if ( iface->ciaddr == 0 )
|
||||||
return RET_DHCP_ERROR;
|
return RET_DHCP_ERROR;
|
||||||
|
|
||||||
iface->xid = random();
|
iface->xid = random();
|
||||||
if (!(msg = build_dhcp_release (iface, &len, &addr)))
|
if (!(msg = build_dhcp_release (iface, &len)))
|
||||||
return RET_DHCP_ERROR;
|
return RET_DHCP_ERROR;
|
||||||
|
|
||||||
if (DebugFlag)
|
if (DebugFlag)
|
||||||
@@ -889,7 +899,9 @@ int dhcp_release(dhcp_interface *iface)
|
|||||||
((unsigned char *)&(iface->siaddr))[2], ((unsigned char *)&(iface->siaddr))[3]);
|
((unsigned char *)&(iface->siaddr))[2], ((unsigned char *)&(iface->siaddr))[3]);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (sendto (iface->sk, msg, sizeof (dhcpMessage), 0, (struct sockaddr *)&addr, addr_len))
|
memset (&addr, 0, sizeof (struct sockaddr));
|
||||||
|
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
|
||||||
|
if (sendto (iface->sk, msg, len, 0, (struct sockaddr *)&addr, addr_len))
|
||||||
syslog (LOG_ERR, "dhcpRelease: sendto: %m\n");
|
syslog (LOG_ERR, "dhcpRelease: sendto: %m\n");
|
||||||
free (msg);
|
free (msg);
|
||||||
|
|
||||||
@@ -902,19 +914,21 @@ int dhcp_release(dhcp_interface *iface)
|
|||||||
#ifdef ARPCHECK
|
#ifdef ARPCHECK
|
||||||
int dhcp_decline(dhcp_interface *iface)
|
int dhcp_decline(dhcp_interface *iface)
|
||||||
{
|
{
|
||||||
struct sockaddr_in addr;
|
udpipMessage *msg;
|
||||||
socklen_t addr_len = sizeof (struct sockaddr_in);
|
struct sockaddr addr;
|
||||||
int len;
|
socklen_t addr_len = sizeof (struct sockaddr);
|
||||||
dhcpMessage *msg;
|
int len;
|
||||||
|
|
||||||
iface->xid = random ();
|
iface->xid = random ();
|
||||||
if (!(msg = build_dhcp_decline (iface, &len, &addr)))
|
if (!(msg = build_dhcp_decline (iface, &len)))
|
||||||
return RET_DHCP_ERROR;
|
return RET_DHCP_ERROR;
|
||||||
|
|
||||||
if (DebugFlag)
|
if (DebugFlag)
|
||||||
syslog (LOG_INFO, "Broadcasting DHCP_DECLINE\n");
|
syslog (LOG_INFO, "Broadcasting DHCP_DECLINE\n");
|
||||||
|
|
||||||
if (sendto (iface->sk, msg, sizeof (dhcpMessage), 0, &addr, addr_len))
|
memset (&addr, 0, sizeof (struct sockaddr));
|
||||||
|
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
|
||||||
|
if (sendto (iface->sk, msg, len, 0, &addr, addr_len))
|
||||||
syslog (LOG_ERR,"dhcpDecline: sendto: %m\n");
|
syslog (LOG_ERR,"dhcpDecline: sendto: %m\n");
|
||||||
free (msg);
|
free (msg);
|
||||||
|
|
||||||
|
@@ -88,6 +88,21 @@ typedef struct dhcpOptions
|
|||||||
void *val[256];
|
void *val[256];
|
||||||
} __attribute__((packed)) dhcpOptions;
|
} __attribute__((packed)) dhcpOptions;
|
||||||
|
|
||||||
|
struct packed_ether_header
|
||||||
|
{
|
||||||
|
u_int8_t ether_dhost[ETH_ALEN]; /* destination eth addr */
|
||||||
|
u_int8_t ether_shost[ETH_ALEN]; /* source ether addr */
|
||||||
|
u_int16_t ether_type; /* packet type ID field */
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
#define TOKEN_RING_HEADER_PAD sizeof(struct trh_hdr) + sizeof(struct trllc)
|
||||||
|
typedef struct udpipMessage
|
||||||
|
{
|
||||||
|
struct packed_ether_header ethhdr;
|
||||||
|
char udpipmsg[IPPACKET_SIZE];
|
||||||
|
char pad_for_tokenring_header[TOKEN_RING_HEADER_PAD];
|
||||||
|
} __attribute__((packed)) udpipMessage;
|
||||||
|
|
||||||
|
|
||||||
typedef struct dhcp_interface
|
typedef struct dhcp_interface
|
||||||
{
|
{
|
||||||
@@ -105,6 +120,7 @@ typedef struct dhcp_interface
|
|||||||
int siaddr;
|
int siaddr;
|
||||||
unsigned char shaddr[ETH_ALEN];
|
unsigned char shaddr[ETH_ALEN];
|
||||||
unsigned int xid;
|
unsigned int xid;
|
||||||
|
unsigned short ip_id;
|
||||||
unsigned char cls_id[DHCP_CLASS_ID_MAX_LEN];
|
unsigned char cls_id[DHCP_CLASS_ID_MAX_LEN];
|
||||||
int cls_id_len;
|
int cls_id_len;
|
||||||
unsigned char cli_id[DHCP_CLIENT_ID_MAX_LEN];
|
unsigned char cli_id[DHCP_CLIENT_ID_MAX_LEN];
|
||||||
@@ -186,7 +202,7 @@ static dhcp_option_table dhcp_opt_table[] =
|
|||||||
{ -1, NULL, -1 }
|
{ -1, NULL, -1 }
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef dhcpMessage *(*dhcp_msg_build_proc)(dhcp_interface *, int *msg_len, struct sockaddr_in *dest_addr);
|
typedef udpipMessage *(*dhcp_msg_build_proc)(dhcp_interface *, int *msg_len);
|
||||||
|
|
||||||
int dhcp_reboot(dhcp_interface *iface);
|
int dhcp_reboot(dhcp_interface *iface);
|
||||||
int dhcp_init(dhcp_interface *iface);
|
int dhcp_init(dhcp_interface *iface);
|
||||||
|
@@ -60,7 +60,6 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
dhcp_interface *iface = NULL;
|
dhcp_interface *iface = NULL;
|
||||||
dhcp_client_options *opts = NULL;
|
dhcp_client_options *opts = NULL;
|
||||||
struct rtentry route;
|
struct rtentry route;
|
||||||
struct sockaddr_in *addrp;
|
|
||||||
|
|
||||||
if (!if_name || !in_opts)
|
if (!if_name || !in_opts)
|
||||||
return NULL;
|
return NULL;
|
||||||
@@ -78,12 +77,9 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
memcpy (opts, in_opts, sizeof (dhcp_client_options));
|
memcpy (opts, in_opts, sizeof (dhcp_client_options));
|
||||||
iface->client_options = opts;
|
iface->client_options = opts;
|
||||||
|
|
||||||
class_id_setup (iface, iface->client_options->class_id);
|
|
||||||
client_id_setup (iface, iface->client_options->client_id);
|
|
||||||
|
|
||||||
memset (&ifr, 0, sizeof(struct ifreq));
|
memset (&ifr, 0, sizeof(struct ifreq));
|
||||||
memcpy (ifr.ifr_name, iface->iface, strlen (iface->iface));
|
memcpy (ifr.ifr_name, iface->iface, strlen (iface->iface));
|
||||||
iface->sk = socket (AF_INET, SOCK_DGRAM, 0);
|
iface->sk = socket (AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL));
|
||||||
if (iface->sk == -1)
|
if (iface->sk == -1)
|
||||||
{
|
{
|
||||||
syslog (LOG_ERR,"dhcp_interface_init: socket: %m\n");
|
syslog (LOG_ERR,"dhcp_interface_init: socket: %m\n");
|
||||||
@@ -103,6 +99,9 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
*/
|
*/
|
||||||
do
|
do
|
||||||
{
|
{
|
||||||
|
struct sockaddr_pkt sap;
|
||||||
|
struct sockaddr_in *addrp;
|
||||||
|
|
||||||
if ( ioctl (iface->sk, SIOCGIFHWADDR, &ifr) )
|
if ( ioctl (iface->sk, SIOCGIFHWADDR, &ifr) )
|
||||||
{
|
{
|
||||||
syslog(LOG_ERR,"dhcp_interface_init: ioctl SIOCGIFHWADDR: %m\n");
|
syslog(LOG_ERR,"dhcp_interface_init: ioctl SIOCGIFHWADDR: %m\n");
|
||||||
@@ -148,10 +147,11 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
syslog (LOG_ERR, "dhcp_interface_init: SO_BINDTODEVICE %s (%d) failed: %s", iface->iface, strlen (iface->iface), strerror (errno));
|
syslog (LOG_ERR, "dhcp_interface_init: SO_BINDTODEVICE %s (%d) failed: %s", iface->iface, strlen (iface->iface), strerror (errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
memset (&addr, 0, sizeof (addr));
|
memset (&sap, 0, sizeof(sap));
|
||||||
addr.sin_family = AF_INET;
|
sap.spkt_protocol = htons (ETH_P_ALL);
|
||||||
addr.sin_port = htons (DHCP_CLIENT_PORT);
|
memcpy (sap.spkt_device, iface->iface, strlen (iface->iface));
|
||||||
if (bind (iface->sk, (struct sockaddr *)&addr, sizeof(addr)) != 0)
|
sap.spkt_family = AF_PACKET;
|
||||||
|
if ( bind (iface->sk, (void*)&sap, sizeof(struct sockaddr)) == -1 )
|
||||||
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
|
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
|
||||||
|
|
||||||
if (ioctl (iface->sk, SIOCGIFHWADDR, &ifr))
|
if (ioctl (iface->sk, SIOCGIFHWADDR, &ifr))
|
||||||
@@ -175,6 +175,9 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
|
|
||||||
if (setsockopt (iface->foo_sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)))
|
if (setsockopt (iface->foo_sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)))
|
||||||
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
|
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
|
||||||
|
memset (&addr, 0, sizeof (addr));
|
||||||
|
addr.sin_family = AF_INET;
|
||||||
|
addr.sin_port = htons (DHCP_CLIENT_PORT);
|
||||||
if ( bind (iface->foo_sk, (struct sockaddr *)&addr, sizeof(addr)) )
|
if ( bind (iface->foo_sk, (struct sockaddr *)&addr, sizeof(addr)) )
|
||||||
{
|
{
|
||||||
if (errno != EADDRINUSE)
|
if (errno != EADDRINUSE)
|
||||||
@@ -210,6 +213,14 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
|||||||
goto err_out;
|
goto err_out;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
i = time (NULL) + iface->chaddr[5] + 4*iface->chaddr[4] + 8*iface->chaddr[3] +
|
||||||
|
16*iface->chaddr[2] + 32*iface->chaddr[1] + 64*iface->chaddr[0];
|
||||||
|
srandom (i);
|
||||||
|
iface->ip_id = i & 0xffff;
|
||||||
|
|
||||||
|
class_id_setup (iface, iface->client_options->class_id);
|
||||||
|
client_id_setup (iface, iface->client_options->client_id);
|
||||||
|
|
||||||
return iface;
|
return iface;
|
||||||
|
|
||||||
err_out:
|
err_out:
|
||||||
|
119
dhcpcd/udpipgen.c
Normal file
119
dhcpcd/udpipgen.c
Normal file
@@ -0,0 +1,119 @@
|
|||||||
|
/*
|
||||||
|
* dhcpcd - DHCP client daemon -
|
||||||
|
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
|
||||||
|
*
|
||||||
|
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
#include "udpipgen.h"
|
||||||
|
#include "client.h"
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
unsigned short in_cksum(unsigned short *addr, int len)
|
||||||
|
{
|
||||||
|
register int sum = 0;
|
||||||
|
register u_short *w = addr;
|
||||||
|
register int nleft = len;
|
||||||
|
while ( nleft > 1 )
|
||||||
|
{
|
||||||
|
sum += *w++;
|
||||||
|
nleft -= 2;
|
||||||
|
}
|
||||||
|
if ( nleft == 1 )
|
||||||
|
{
|
||||||
|
u_char a = 0;
|
||||||
|
memcpy(&a,w,1);
|
||||||
|
sum += a;
|
||||||
|
}
|
||||||
|
sum = (sum >> 16) + (sum & 0xffff);
|
||||||
|
sum += (sum >> 16);
|
||||||
|
return ~sum;
|
||||||
|
}
|
||||||
|
/*****************************************************************************/
|
||||||
|
void udpipgen (udpiphdr *udpip, unsigned int saddr, unsigned int daddr, unsigned short *ip_id, int dhcp_msg_len)
|
||||||
|
{
|
||||||
|
/* Use local copy because udpip->ip is not aligned. */
|
||||||
|
struct ip ip_local;
|
||||||
|
struct ip *ip = &ip_local;
|
||||||
|
struct ipovly *io = (struct ipovly *)udpip->ip;
|
||||||
|
struct udphdr *udp = (struct udphdr *)udpip->udp;
|
||||||
|
|
||||||
|
io->ih_next = io->ih_prev = 0;
|
||||||
|
io->ih_x1 = 0;
|
||||||
|
io->ih_pr = IPPROTO_UDP;
|
||||||
|
io->ih_len = htons (dhcp_msg_len + sizeof (struct udphdr));
|
||||||
|
io->ih_src.s_addr = saddr;
|
||||||
|
io->ih_dst.s_addr = daddr;
|
||||||
|
udp->source = htons (DHCP_CLIENT_PORT);
|
||||||
|
udp->dest = htons (DHCP_SERVER_PORT);
|
||||||
|
udp->len = io->ih_len;
|
||||||
|
udp->check = 0;
|
||||||
|
udp->check = in_cksum ((unsigned short *)udpip, dhcp_msg_len + sizeof (udpiphdr));
|
||||||
|
if (udp->check == 0)
|
||||||
|
udp->check = 0xffff;
|
||||||
|
memcpy (ip,(struct ip *)udpip->ip, sizeof (ip_local));
|
||||||
|
ip->ip_hl = 5;
|
||||||
|
ip->ip_v = IPVERSION;
|
||||||
|
ip->ip_tos = 0; /* normal service */
|
||||||
|
ip->ip_len = htons (dhcp_msg_len + sizeof (udpiphdr));
|
||||||
|
ip->ip_id = htons (*ip_id); *ip_id++;
|
||||||
|
ip->ip_off = 0;
|
||||||
|
ip->ip_ttl = IPDEFTTL; /* time to live, 64 by default */
|
||||||
|
ip->ip_p = IPPROTO_UDP;
|
||||||
|
ip->ip_src.s_addr = saddr;
|
||||||
|
ip->ip_dst.s_addr = daddr;
|
||||||
|
ip->ip_sum = 0;
|
||||||
|
memcpy (udpip->ip, ip, sizeof (ip_local));
|
||||||
|
ip->ip_sum = in_cksum ((unsigned short *)&ip_local, sizeof (struct ip));
|
||||||
|
memcpy (udpip->ip, ip, sizeof (ip_local));
|
||||||
|
}
|
||||||
|
/*****************************************************************************/
|
||||||
|
int udpipchk(udpiphdr *udpip)
|
||||||
|
{
|
||||||
|
int hl;
|
||||||
|
struct ip save_ip;
|
||||||
|
struct ip *ip = (struct ip *)udpip->ip;
|
||||||
|
struct ipovly *io = (struct ipovly *)udpip->ip;
|
||||||
|
struct udphdr *udp = (struct udphdr *)udpip->udp;
|
||||||
|
udpiphdr *nudpip = udpip;
|
||||||
|
|
||||||
|
hl = ip->ip_hl<<2;
|
||||||
|
if (in_cksum ((unsigned short *)udpip, hl))
|
||||||
|
return -1;
|
||||||
|
memcpy (&save_ip, udpip->ip, sizeof (struct ip));
|
||||||
|
hl -= sizeof (struct ip);
|
||||||
|
if (hl)
|
||||||
|
{
|
||||||
|
/* thrash IP options */
|
||||||
|
nudpip = (udpiphdr *)((char *)udpip + hl);
|
||||||
|
memmove ((char *)nudpip, udpip, sizeof (struct ip));
|
||||||
|
io = (struct ipovly *)nudpip->ip;
|
||||||
|
ip = (struct ip *)nudpip->ip;
|
||||||
|
udp = (struct udphdr *)nudpip->udp;
|
||||||
|
}
|
||||||
|
if (udp->check == 0)
|
||||||
|
return 0; /* no checksum has been done by sender */
|
||||||
|
io->ih_next = io->ih_prev = 0;
|
||||||
|
io->ih_x1 = 0;
|
||||||
|
io->ih_len = udp->len;
|
||||||
|
hl = ntohs (udp->len) + sizeof (struct ip);
|
||||||
|
if (in_cksum ((unsigned short *)nudpip, hl))
|
||||||
|
return -2;
|
||||||
|
memcpy (udpip->ip, &save_ip, sizeof(struct ip));
|
||||||
|
return 0;
|
||||||
|
}
|
51
dhcpcd/udpipgen.h
Normal file
51
dhcpcd/udpipgen.h
Normal file
@@ -0,0 +1,51 @@
|
|||||||
|
/*
|
||||||
|
* dhcpcd - DHCP client daemon -
|
||||||
|
* Copyright (C) January, 1998 Sergei Viznyuk <sv@phystech.com>
|
||||||
|
*
|
||||||
|
* dhcpcd is an RFC2131 and RFC1541 compliant DHCP client daemon.
|
||||||
|
*
|
||||||
|
* This is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful, but
|
||||||
|
* WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef UDPIPGEN_H
|
||||||
|
#define UDPIPGEN_H
|
||||||
|
|
||||||
|
#include <netinet/ip.h>
|
||||||
|
#include <netinet/udp.h>
|
||||||
|
|
||||||
|
#ifndef IPDEFTTL
|
||||||
|
#define IPDEFTTL 64
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct ipovly
|
||||||
|
{
|
||||||
|
int ih_next,ih_prev;
|
||||||
|
u_char ih_x1;
|
||||||
|
u_char ih_pr;
|
||||||
|
u_short ih_len;
|
||||||
|
struct in_addr ih_src;
|
||||||
|
struct in_addr ih_dst;
|
||||||
|
} __attribute__((packed));
|
||||||
|
|
||||||
|
typedef struct udpiphdr
|
||||||
|
{
|
||||||
|
char ip[sizeof(struct ip)];
|
||||||
|
char udp[sizeof(struct udphdr)];
|
||||||
|
} __attribute__((packed)) udpiphdr;
|
||||||
|
|
||||||
|
void udpipgen (udpiphdr *udpip, unsigned int saddr, unsigned int daddr, unsigned short *ip_id, int dhcp_msg_len);
|
||||||
|
int udpipchk (udpiphdr *udpip);
|
||||||
|
|
||||||
|
#endif
|
Reference in New Issue
Block a user