2004-12-05 Dan Williams <dcbw@redhat.com>
* Major rework of the DHCP code, taking some cues from pump. We don't write raw Ethernet packets anymore, which simplifies the code quite a bit. The new code should be more robust, not hang in recvfrom() as much, and generally work better. This also means that we need to force HAL/dbus to use a created GMainContext rather than the default context, since having the DHCP renew/rebind thread using its own GMainContext seemed to give dbus a fit. There is also more debugging information printed from the DHCP loop to help with future problems. * Also, if the DHCP server doesn't give us the "routersOnSubnet" option, assume that the default gateway should be the DHCP server. Patch from Matthew Schick <matt oss-institute org> * src/backends/NetworkManagerGentoo.c - Fix compilation error due to missing "ip4_broadcast" git-svn-id: http://svn-archive.gnome.org/svn/NetworkManager/trunk@336 4912f4e0-d625-0410-9fb7-b9a5a253dbdc
This commit is contained in:
19
ChangeLog
19
ChangeLog
@@ -1,3 +1,22 @@
|
||||
2004-12-05 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* Major rework of the DHCP code, taking some cues from pump. We don't
|
||||
write raw Ethernet packets anymore, which simplifies the code quite
|
||||
a bit. The new code should be more robust, not hang in recvfrom()
|
||||
as much, and generally work better. This also means that we need
|
||||
to force HAL/dbus to use a created GMainContext rather than the
|
||||
default context, since having the DHCP renew/rebind thread using
|
||||
its own GMainContext seemed to give dbus a fit. There is also more
|
||||
debugging information printed from the DHCP loop to help with future
|
||||
problems.
|
||||
|
||||
* Also, if the DHCP server doesn't give us the "routersOnSubnet" option,
|
||||
assume that the default gateway should be the DHCP server.
|
||||
|
||||
Patch from Matthew Schick <matt oss-institute org>
|
||||
* src/backends/NetworkManagerGentoo.c
|
||||
- Fix compilation error due to missing "ip4_broadcast"
|
||||
|
||||
2004-12-03 Dan Williams <dcbw@redhat.com>
|
||||
|
||||
* initscript/Makefile.am
|
||||
|
@@ -8,8 +8,6 @@ AM_CPPFLAGS = \
|
||||
noinst_LIBRARIES = libdhcpc.a
|
||||
|
||||
libdhcpc_a_SOURCES= \
|
||||
udpipgen.c \
|
||||
udpipgen.h \
|
||||
buildmsg.c \
|
||||
buildmsg.h \
|
||||
arp.c \
|
||||
|
40
dhcpcd/arp.c
40
dhcpcd/arp.c
@@ -28,6 +28,13 @@
|
||||
#include "client.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
|
||||
{
|
||||
struct packed_ether_header ethhdr;
|
||||
@@ -57,14 +64,14 @@ int arpCheck(const dhcp_interface *iface)
|
||||
arpMessage arp_msg_send;
|
||||
arpMessage arp_msg_recv;
|
||||
struct sockaddr addr;
|
||||
int j,i=0,len=0;
|
||||
int j,i=0;
|
||||
|
||||
memset (&arp_msg_send, 0, sizeof(arpMessage));
|
||||
memcpy (arp_msg_send.ethhdr.ether_dhost, MAC_BCAST_ADDR, ETH_ALEN);
|
||||
memcpy (arp_msg_send.ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
|
||||
arp_msg_send.ethhdr.ether_type = htons(ETHERTYPE_ARP);
|
||||
|
||||
arp_msg_send.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
|
||||
arp_msg_send.htype = htons(ARPHRD_ETHER);
|
||||
arp_msg_send.ptype = htons(ETHERTYPE_IP);
|
||||
arp_msg_send.hlen = ETH_ALEN;
|
||||
arp_msg_send.plen = 4;
|
||||
@@ -87,11 +94,7 @@ int arpCheck(const dhcp_interface *iface)
|
||||
return 0; /* 5 probes */
|
||||
memset (&addr, 0, sizeof(struct sockaddr));
|
||||
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
|
||||
if ( iface->bTokenRing )
|
||||
len = eth2tr (&arp_msg_send.ethhdr, BasicArpLen(ArpMsgSend));
|
||||
else
|
||||
len = sizeof (arpMessage);
|
||||
if ( sendto(iface->sk, &arp_msg_send, len, 0, &addr, sizeof(struct sockaddr)) == -1 )
|
||||
if ( sendto(iface->sk, &arp_msg_send, sizeof (arpMessage), 0, &addr, sizeof(struct sockaddr)) == -1 )
|
||||
{
|
||||
syslog(LOG_ERR,"arpCheck: sendto: %m\n");
|
||||
return -1;
|
||||
@@ -107,11 +110,6 @@ int arpCheck(const dhcp_interface *iface)
|
||||
syslog(LOG_ERR,"arpCheck: recvfrom: %m\n");
|
||||
return -1;
|
||||
}
|
||||
if ( iface->bTokenRing )
|
||||
{
|
||||
if ( tr2eth (&arp_msg_recv.ethhdr) )
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( arp_msg_recv.ethhdr.ether_type != htons(ETHERTYPE_ARP) )
|
||||
continue;
|
||||
@@ -161,7 +159,6 @@ int arpRelease(const dhcp_interface *iface) /* sends UNARP message, cf. RFC1868
|
||||
{
|
||||
arpMessage ArpMsgSend;
|
||||
struct sockaddr addr;
|
||||
int len;
|
||||
const int inaddr_broadcast = INADDR_BROADCAST;
|
||||
|
||||
/* build Ethernet header */
|
||||
@@ -171,7 +168,7 @@ int arpRelease(const dhcp_interface *iface) /* sends UNARP message, cf. RFC1868
|
||||
ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);
|
||||
|
||||
/* build UNARP message */
|
||||
ArpMsgSend.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
|
||||
ArpMsgSend.htype = htons(ARPHRD_ETHER);
|
||||
ArpMsgSend.ptype = htons(ETHERTYPE_IP);
|
||||
ArpMsgSend.plen = 4;
|
||||
ArpMsgSend.operation= htons(ARPOP_REPLY);
|
||||
@@ -180,11 +177,7 @@ int arpRelease(const dhcp_interface *iface) /* sends UNARP message, cf. RFC1868
|
||||
|
||||
memset(&addr,0,sizeof(struct sockaddr));
|
||||
memcpy(addr.sa_data,iface->iface,strlen (iface->iface));
|
||||
if ( iface->bTokenRing )
|
||||
len = eth2tr (&ArpMsgSend.ethhdr, BasicArpLen(ArpMsgSend));
|
||||
else
|
||||
len = sizeof (arpMessage);
|
||||
if ( sendto (iface->sk, &ArpMsgSend, len, 0, &addr, sizeof(struct sockaddr)) == -1 )
|
||||
if ( sendto (iface->sk, &ArpMsgSend, sizeof (arpMessage), 0, &addr, sizeof(struct sockaddr)) == -1 )
|
||||
{
|
||||
syslog (LOG_ERR,"arpRelease: sendto: %m\n");
|
||||
return -1;
|
||||
@@ -196,7 +189,6 @@ int arpInform(const dhcp_interface *iface)
|
||||
{
|
||||
arpMessage ArpMsgSend;
|
||||
struct sockaddr addr;
|
||||
int len;
|
||||
const int inaddr_broadcast = INADDR_BROADCAST;
|
||||
|
||||
memset (&ArpMsgSend, 0, sizeof(arpMessage));
|
||||
@@ -204,7 +196,7 @@ int arpInform(const dhcp_interface *iface)
|
||||
memcpy (ArpMsgSend.ethhdr.ether_shost, iface->chaddr, ETH_ALEN);
|
||||
ArpMsgSend.ethhdr.ether_type = htons(ETHERTYPE_ARP);
|
||||
|
||||
ArpMsgSend.htype = (iface->bTokenRing) ? htons(ARPHRD_IEEE802_TR) : htons(ARPHRD_ETHER);
|
||||
ArpMsgSend.htype = htons(ARPHRD_ETHER);
|
||||
ArpMsgSend.ptype = htons(ETHERTYPE_IP);
|
||||
ArpMsgSend.hlen = ETH_ALEN;
|
||||
ArpMsgSend.plen = 4;
|
||||
@@ -216,11 +208,7 @@ int arpInform(const dhcp_interface *iface)
|
||||
|
||||
memset (&addr, 0, sizeof(struct sockaddr));
|
||||
memcpy (addr.sa_data, iface->iface, strlen (iface->iface));
|
||||
if ( iface->bTokenRing )
|
||||
len = eth2tr(&ArpMsgSend.ethhdr,BasicArpLen(ArpMsgSend));
|
||||
else
|
||||
len = sizeof(arpMessage);
|
||||
if ( sendto(iface->sk,&ArpMsgSend,len,0, &addr,sizeof(struct sockaddr)) == -1 )
|
||||
if ( sendto (iface->sk, &ArpMsgSend, sizeof (arpMessage), 0, &addr, sizeof(struct sockaddr)) == -1 )
|
||||
{
|
||||
syslog(LOG_ERR,"arpInform: sendto: %m\n");
|
||||
return -1;
|
||||
|
@@ -20,36 +20,28 @@
|
||||
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <netinet/in.h>
|
||||
#include <net/if_arp.h>
|
||||
#include "client.h"
|
||||
#include "buildmsg.h"
|
||||
#include "udpipgen.h"
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
extern int DebugFlag;
|
||||
|
||||
/*****************************************************************************/
|
||||
void fill_common_fields (dhcp_interface *iface, udpipMessage *msg, unsigned char dhost_addr[6], int bcast_rep)
|
||||
void fill_common_fields (dhcp_interface *iface, dhcpMessage *dhcp_msg, int bcast_resp)
|
||||
{
|
||||
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->htype = (iface->bTokenRing) ? ARPHRD_IEEE802_TR : ARPHRD_ETHER;
|
||||
dhcp_msg->htype = ARPHRD_ETHER;
|
||||
dhcp_msg->hlen = ETH_ALEN;
|
||||
dhcp_msg->xid = iface->xid;
|
||||
dhcp_msg->secs = htons(10);
|
||||
dhcp_msg->secs = htons (10);
|
||||
|
||||
if ( bcast_rep && iface->client_options->do_broadcast_response )
|
||||
if ( bcast_resp && iface->client_options->do_broadcast_response )
|
||||
dhcp_msg->flags = htons (BROADCAST_FLAG);
|
||||
|
||||
memcpy (dhcp_msg->chaddr, iface->chaddr, ETH_ALEN);
|
||||
@@ -134,7 +126,7 @@ unsigned char *fill_server_id (unsigned int *server_id, unsigned char *p)
|
||||
/*****************************************************************************/
|
||||
unsigned char *fill_message_type (unsigned char request, unsigned char *p)
|
||||
{
|
||||
const unsigned short dhcpMsgSize = htons(sizeof(dhcpMessage));
|
||||
const unsigned short dhcpMsgSize = htons (sizeof (dhcpMessage));
|
||||
|
||||
*p++ = dhcpMessageType;
|
||||
*p++ = 1;
|
||||
@@ -145,16 +137,27 @@ unsigned char *fill_message_type (unsigned char request, unsigned char *p)
|
||||
p += 2;
|
||||
return p;
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpDiscover(dhcp_interface *iface)
|
||||
void construct_dest_address (struct sockaddr_in *dest_addr, unsigned int in_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
if (!dest_addr)
|
||||
return;
|
||||
|
||||
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;
|
||||
unsigned int lease_time = htonl (iface->default_lease_time);
|
||||
|
||||
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
p = fill_message_type (DHCP_DISCOVER, p);
|
||||
if ( iface->ciaddr )
|
||||
{
|
||||
@@ -168,19 +171,18 @@ udpipMessage *buildDhcpDiscover(dhcp_interface *iface)
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
/* build UDP/IP header */
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpRequest(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_request (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
p = fill_message_type (DHCP_REQUEST, p);
|
||||
p = fill_server_id (iface->dhcp_options.val[dhcpServerIdentifier], p);
|
||||
if ( iface->client_options->do_rfc1541 )
|
||||
@@ -193,19 +195,18 @@ udpipMessage *buildDhcpRequest(dhcp_interface *iface)
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
/* build UDP/IP header */
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
|
||||
|
||||
return udp_msg;
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpRenew(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_renew (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||
construct_dest_address (dest_addr, iface->siaddr);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
dhcp_msg->ciaddr = iface->ciaddr;
|
||||
p = fill_message_type (DHCP_REQUEST, p);
|
||||
#if 0
|
||||
@@ -216,18 +217,18 @@ udpipMessage *buildDhcpRenew(dhcp_interface *iface)
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpRebind(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
dhcp_msg->ciaddr = iface->ciaddr;
|
||||
p = fill_message_type (DHCP_REQUEST, p);
|
||||
if ( iface->dhcp_options.val[dhcpIPaddrLeaseTime] )
|
||||
@@ -236,19 +237,19 @@ udpipMessage *buildDhcpRebind(dhcp_interface *iface)
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, INADDR_BROADCAST, &iface->ip_id);
|
||||
|
||||
return udp_msg;
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpReboot(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
unsigned int lease_time = htonl (iface->default_lease_time);
|
||||
|
||||
fill_common_fields (iface, udp_msg, MAC_BCAST_ADDR, 1);
|
||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
p = fill_message_type (DHCP_REQUEST, p);
|
||||
if ( iface->client_options->do_rfc1541 )
|
||||
dhcp_msg->ciaddr = iface->ciaddr;
|
||||
@@ -259,18 +260,18 @@ udpipMessage *buildDhcpReboot(dhcp_interface *iface)
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpRelease(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||
construct_dest_address (dest_addr, iface->siaddr);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
dhcp_msg->ciaddr = iface->ciaddr;
|
||||
*p++ = dhcpMessageType;
|
||||
*p++ = 1;
|
||||
@@ -280,19 +281,19 @@ udpipMessage *buildDhcpRelease(dhcp_interface *iface)
|
||||
p += iface->cli_id_len;
|
||||
*p = endOption;
|
||||
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), iface->ciaddr, iface->siaddr, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
/*****************************************************************************/
|
||||
#ifdef ARPCHECK
|
||||
udpipMessage *buildDhcpDecline(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||
construct_dest_address (dest_addr, iface->siaddr);
|
||||
|
||||
fill_common_fields (iface, udp_msg, 1);
|
||||
*p++ = dhcpMessageType;
|
||||
*p++ = 1;
|
||||
*p++ = DHCP_DECLINE;
|
||||
@@ -305,26 +306,25 @@ udpipMessage *buildDhcpDecline(dhcp_interface *iface)
|
||||
p += iface->cli_id_len;
|
||||
*p = endOption;
|
||||
|
||||
udpipgen ((udpiphdr *)(udp_msg->udpipmsg), 0, iface->siaddr, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
#endif
|
||||
/*****************************************************************************/
|
||||
udpipMessage *buildDhcpInform(dhcp_interface *iface)
|
||||
dhcpMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr)
|
||||
{
|
||||
udpipMessage *udp_msg = calloc (1, sizeof (udpipMessage));
|
||||
dhcpMessage *dhcp_msg = (dhcpMessage *)&(udp_msg->udpipmsg[sizeof(udpiphdr)]);
|
||||
dhcpMessage *dhcp_msg = calloc (1, sizeof (dhcpMessage));
|
||||
register unsigned char *p = dhcp_msg->options + 4;
|
||||
|
||||
fill_common_fields (iface, udp_msg, iface->shaddr, 1);
|
||||
construct_dest_address (dest_addr, IP_BCAST_ADDR);
|
||||
|
||||
fill_common_fields (iface, dhcp_msg, 1);
|
||||
dhcp_msg->ciaddr = iface->ciaddr;
|
||||
p = fill_message_type (DHCP_INFORM, p);
|
||||
p = fill_param_request (p);
|
||||
p = fill_host_and_class_id (iface, p);
|
||||
*p = endOption;
|
||||
|
||||
udpipgen((udpiphdr *)(udp_msg->udpipmsg), 0, INADDR_BROADCAST, &iface->ip_id);
|
||||
|
||||
return (udp_msg);
|
||||
*msg_len = (char *)(++p) - (char *)dhcp_msg;
|
||||
return (dhcp_msg);
|
||||
}
|
||||
|
@@ -23,13 +23,15 @@
|
||||
#ifndef BUILDMSG_H
|
||||
#define BUILDMSG_H
|
||||
|
||||
udpipMessage *buildDhcpDiscover(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpRequest(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpRenew(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpRebind(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpReboot(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpRelease(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpDecline(dhcp_interface *iface);
|
||||
udpipMessage *buildDhcpInform(dhcp_interface *iface);
|
||||
dhcpMessage *build_dhcp_discover (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
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);
|
||||
dhcpMessage *build_dhcp_rebind (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
dhcpMessage *build_dhcp_reboot (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
dhcpMessage *build_dhcp_release (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
#ifdef ARPCHECK
|
||||
dhcpMessage *build_dhcp_decline (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
#endif
|
||||
dhcpMessage *build_dhcp_inform (dhcp_interface *iface, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
|
||||
#endif
|
||||
|
883
dhcpcd/client.c
883
dhcpcd/client.c
File diff suppressed because it is too large
Load Diff
@@ -34,6 +34,7 @@
|
||||
#define MAGIC_COOKIE 0x63825363
|
||||
#define BROADCAST_FLAG 0x8000
|
||||
#define MAC_BCAST_ADDR "\xff\xff\xff\xff\xff\xff"
|
||||
#define IP_BCAST_ADDR 0xFFFFFFFF
|
||||
#ifndef AF_PACKET
|
||||
#define AF_PACKET 17 /* should have been in socketbits.h */
|
||||
#endif
|
||||
@@ -56,9 +57,10 @@
|
||||
#define DHCP_NAK 6
|
||||
#define DHCP_RELEASE 7
|
||||
#define DHCP_INFORM 8
|
||||
/* DHCP RETRANSMISSION TIMEOUT (microseconds) */
|
||||
#define DHCP_INITIAL_RTO (4*1000000)
|
||||
#define DHCP_MAX_RTO (64*1000000)
|
||||
/* DHCP RETRANSMISSION TIMEOUT (seconds) */
|
||||
#define DHCP_INITIAL_RTO (4)
|
||||
#define DHCP_MAX_RTO (64)
|
||||
#define DHCP_OPTIONS_LENGTH 312
|
||||
|
||||
typedef struct dhcpMessage
|
||||
{
|
||||
@@ -76,24 +78,9 @@ typedef struct dhcpMessage
|
||||
u_char chaddr[16]; /* client's hardware address */
|
||||
u_char sname[64]; /* server host name, null terminated string */
|
||||
u_char file[128]; /* boot file name, null terminated string */
|
||||
u_char options[312]; /* message options */
|
||||
u_char options[DHCP_OPTIONS_LENGTH]; /* message options */
|
||||
} __attribute__((packed)) dhcpMessage;
|
||||
|
||||
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 dhcpOptions
|
||||
{
|
||||
u_char num;
|
||||
@@ -110,9 +97,7 @@ typedef struct dhcp_interface
|
||||
int sk;
|
||||
int foo_sk;
|
||||
short int saved_if_flags;
|
||||
int bTokenRing;
|
||||
unsigned int default_lease_time;
|
||||
time_t req_sent_time;
|
||||
struct in_addr default_router;
|
||||
|
||||
int ciaddr;
|
||||
@@ -120,7 +105,6 @@ typedef struct dhcp_interface
|
||||
int siaddr;
|
||||
unsigned char shaddr[ETH_ALEN];
|
||||
unsigned int xid;
|
||||
unsigned short ip_id;
|
||||
unsigned char cls_id[DHCP_CLASS_ID_MAX_LEN];
|
||||
int cls_id_len;
|
||||
unsigned char cli_id[DHCP_CLIENT_ID_MAX_LEN];
|
||||
@@ -202,7 +186,7 @@ static dhcp_option_table dhcp_opt_table[] =
|
||||
{ -1, NULL, -1 }
|
||||
};
|
||||
|
||||
typedef udpipMessage *(*dhcp_msg_build_proc)(dhcp_interface *);
|
||||
typedef dhcpMessage *(*dhcp_msg_build_proc)(dhcp_interface *, int *msg_len, struct sockaddr_in *dest_addr);
|
||||
|
||||
int dhcp_reboot(dhcp_interface *iface);
|
||||
int dhcp_init(dhcp_interface *iface);
|
||||
|
140
dhcpcd/dhcpcd.c
140
dhcpcd/dhcpcd.c
@@ -32,6 +32,7 @@
|
||||
#include <arpa/inet.h>
|
||||
#include <net/if_packet.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <net/route.h>
|
||||
#include <errno.h>
|
||||
#include <ctype.h>
|
||||
#include "dhcpcd.h"
|
||||
@@ -45,20 +46,21 @@
|
||||
* Location: http://www.phystech.com/download/
|
||||
*/
|
||||
|
||||
void classIDsetup(dhcp_interface *iface, const char *g_cls_id);
|
||||
void clientIDsetup(dhcp_interface *iface, const char *g_cli_id);
|
||||
void releaseDhcpOptions (dhcp_interface *iface);
|
||||
extern void class_id_setup (dhcp_interface *iface, const char *g_cls_id);
|
||||
extern void client_id_setup (dhcp_interface *iface, const char *g_cli_id);
|
||||
extern void release_dhcp_options (dhcp_interface *iface);
|
||||
|
||||
/*****************************************************************************/
|
||||
dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *in_opts)
|
||||
{
|
||||
int o = 1;
|
||||
unsigned i = 0;
|
||||
unsigned i = 3;
|
||||
struct ifreq ifr;
|
||||
struct sockaddr_pkt sap;
|
||||
struct sockaddr_in clientAddr;
|
||||
struct sockaddr_in addr;
|
||||
dhcp_interface *iface = NULL;
|
||||
dhcp_client_options *opts = NULL;
|
||||
struct rtentry route;
|
||||
struct sockaddr_in *addrp;
|
||||
|
||||
if (!if_name || !in_opts)
|
||||
return NULL;
|
||||
@@ -76,60 +78,93 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
||||
memcpy (opts, in_opts, sizeof (dhcp_client_options));
|
||||
iface->client_options = opts;
|
||||
|
||||
classIDsetup (iface, iface->client_options->class_id);
|
||||
clientIDsetup (iface, iface->client_options->client_id);
|
||||
class_id_setup (iface, iface->client_options->class_id);
|
||||
client_id_setup (iface, iface->client_options->client_id);
|
||||
|
||||
memset (&ifr, 0, sizeof(struct ifreq));
|
||||
memcpy (ifr.ifr_name, iface->iface, strlen (iface->iface));
|
||||
iface->sk = socket (AF_PACKET, SOCK_PACKET, htons(ETH_P_ALL));
|
||||
iface->sk = socket (AF_INET, SOCK_DGRAM, 0);
|
||||
if (iface->sk == -1)
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: socket: %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if ( ioctl (iface->sk, SIOCGIFHWADDR, &ifr) )
|
||||
{
|
||||
syslog(LOG_ERR,"dhcpStart: ioctl SIOCGIFHWADDR: %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (setsockopt (iface->sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)) == -1)
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (ioctl (iface->sk, SIOCGIFFLAGS, &ifr))
|
||||
{
|
||||
syslog (LOG_ERR, "dhcp_interface_init: ioctl SIOCGIFFLAGS: %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
iface->saved_if_flags = ifr.ifr_flags;
|
||||
ifr.ifr_flags = iface->saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;
|
||||
if (ioctl (iface->sk, SIOCSIFFLAGS, &ifr))
|
||||
|
||||
/* Try to get a valid MAC address. Sometimes when you bring a card up, especially ones
|
||||
* with downloadable firmware, it takes a couple tries to get a valid MAC address
|
||||
* since the firmware is busy for a bit doing who knows what.
|
||||
*/
|
||||
do
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: ioctl SIOCSIFFLAGS: %m\n");
|
||||
if ( ioctl (iface->sk, SIOCGIFHWADDR, &ifr) )
|
||||
{
|
||||
syslog(LOG_ERR,"dhcp_interface_init: ioctl SIOCGIFHWADDR: %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
memcpy (iface->chaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
|
||||
if (setsockopt (iface->sk, SOL_SOCKET, SO_BROADCAST, &o, sizeof(o)) == -1)
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: setsockopt (SO_BROADCAST): %m\n");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
memset (&sap, 0, sizeof(sap));
|
||||
sap.spkt_protocol = htons (ETH_P_ALL);
|
||||
memcpy (sap.spkt_device, iface->iface, strlen (iface->iface));
|
||||
sap.spkt_family = AF_PACKET;
|
||||
if ( bind (iface->sk, (void*)&sap, sizeof(struct sockaddr)) == -1 )
|
||||
ifr.ifr_flags = iface->saved_if_flags | IFF_UP | IFF_BROADCAST | IFF_NOTRAILERS | IFF_RUNNING;
|
||||
if (ioctl (iface->sk, SIOCSIFFLAGS, &ifr))
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: ioctl SIOCSIFFLAGS: %m");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
memset (&ifr, 0, sizeof (ifr));
|
||||
addrp = (struct sockaddr_in *) &ifr.ifr_addr;
|
||||
strcpy (ifr.ifr_name, iface->iface);
|
||||
addrp->sin_family = AF_INET;
|
||||
addrp->sin_port = 0;
|
||||
memset (&addrp->sin_addr, 0, sizeof (addrp->sin_addr));
|
||||
addrp->sin_addr.s_addr = htonl (0);
|
||||
if (ioctl (iface->sk, SIOCSIFADDR, &ifr))
|
||||
{
|
||||
syslog (LOG_ERR, "dhcp_interface_init: SIOCSIFADDR returned errno %d", errno);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
o = 1;
|
||||
if (setsockopt (iface->sk, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o)) == -1)
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: setsockopt (SO_REUSEADDR): %m");
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
if (setsockopt (iface->sk, SOL_SOCKET, SO_BINDTODEVICE, iface->iface, strlen (iface->iface)+1))
|
||||
{
|
||||
syslog (LOG_ERR, "dhcp_interface_init: SO_BINDTODEVICE %s (%d) failed: %s", iface->iface, strlen (iface->iface), strerror (errno));
|
||||
}
|
||||
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = htons (DHCP_CLIENT_PORT);
|
||||
if ( bind (iface->sk, (struct sockaddr *)&addr, sizeof(addr)) != 0 )
|
||||
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
|
||||
|
||||
memcpy (iface->chaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
fprintf(stdout,"dhcpcd: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
iface->chaddr[0], iface->chaddr[1], iface->chaddr[2],
|
||||
iface->chaddr[3], iface->chaddr[4], iface->chaddr[5]);
|
||||
if (ioctl (iface->sk, SIOCGIFHWADDR, &ifr))
|
||||
{
|
||||
syslog (LOG_ERR,"dhcp_interface_init: ioctl SIOCGIFHWADDR: %m");
|
||||
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;
|
||||
memcpy (iface->chaddr, ifr.ifr_hwaddr.sa_data, ETH_ALEN);
|
||||
syslog (LOG_INFO, "dhcp_interface_init: MAC address = %02x:%02x:%02x:%02x:%02x:%02x\n",
|
||||
iface->chaddr[0], iface->chaddr[1], iface->chaddr[2], iface->chaddr[3], iface->chaddr[4], iface->chaddr[5]);
|
||||
i--;
|
||||
} while (iface->chaddr[0] && iface->chaddr[1] && iface->chaddr[2] && iface->chaddr[3] && iface->chaddr[4] && iface->chaddr[5] && (i > 0));
|
||||
|
||||
iface->foo_sk = socket (AF_INET, SOCK_DGRAM, 0);
|
||||
if ( iface->foo_sk == -1 )
|
||||
@@ -140,10 +175,7 @@ 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)))
|
||||
syslog (LOG_ERR,"dhcp_interface_init: setsockopt: %m\n");
|
||||
memset (&clientAddr.sin_addr, 0, sizeof (&clientAddr.sin_addr));
|
||||
clientAddr.sin_family = AF_INET;
|
||||
clientAddr.sin_port = htons (DHCP_CLIENT_PORT);
|
||||
if ( bind (iface->foo_sk, (struct sockaddr *)&clientAddr, sizeof(clientAddr)) )
|
||||
if ( bind (iface->foo_sk, (struct sockaddr *)&addr, sizeof(addr)) )
|
||||
{
|
||||
if (errno != EADDRINUSE)
|
||||
syslog (LOG_ERR,"dhcp_interface_init: bind: %m\n");
|
||||
@@ -156,6 +188,28 @@ dhcp_interface *dhcp_interface_init (const char *if_name, dhcp_client_options *i
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
/* Set up at least the broadcast route or something */
|
||||
memset (&addr, 0, sizeof (addr));
|
||||
addr.sin_family = AF_INET;
|
||||
addr.sin_port = 0;
|
||||
|
||||
memset (&route, 0, sizeof (route));
|
||||
memcpy (&route.rt_gateway, &addr, sizeof (addr));
|
||||
|
||||
addr.sin_addr.s_addr = INADDR_ANY;
|
||||
memcpy (&route.rt_dst, &addr, sizeof(addr));
|
||||
memcpy (&route.rt_genmask, &addr, sizeof(addr));
|
||||
|
||||
route.rt_dev = iface->iface;
|
||||
route.rt_flags = RTF_UP;
|
||||
route.rt_metric = 0;
|
||||
|
||||
if (ioctl (iface->sk, SIOCADDRT, &route) && (errno != EEXIST))
|
||||
{
|
||||
syslog (LOG_ERR, "dhcp_interface_init: SIOCADDRT failed, errno = %d, dev = %s\n", errno, iface->iface);
|
||||
goto err_out;
|
||||
}
|
||||
|
||||
return iface;
|
||||
|
||||
err_out:
|
||||
@@ -171,7 +225,7 @@ void dhcp_interface_free (dhcp_interface *iface)
|
||||
if (!iface)
|
||||
return;
|
||||
|
||||
releaseDhcpOptions (iface);
|
||||
release_dhcp_options (iface);
|
||||
|
||||
if (iface->foo_sk >= 0)
|
||||
close (iface->foo_sk);
|
||||
|
@@ -1,119 +0,0 @@
|
||||
/*
|
||||
* 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)
|
||||
{
|
||||
/* 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(sizeof(dhcpMessage) + sizeof(struct udphdr));
|
||||
io->ih_src.s_addr = saddr;
|
||||
io->ih_dst.s_addr = daddr;
|
||||
udp->uh_sport = htons(DHCP_CLIENT_PORT);
|
||||
udp->uh_dport = htons(DHCP_SERVER_PORT);
|
||||
udp->uh_ulen = io->ih_len;
|
||||
udp->uh_sum = 0;
|
||||
udp->uh_sum = in_cksum((unsigned short *)udpip, sizeof(dhcpMessage) + sizeof(udpiphdr));
|
||||
if ( udp->uh_sum == 0 )
|
||||
udp->uh_sum = 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(sizeof(dhcpMessage) + 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->uh_sum == 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->uh_ulen;
|
||||
hl = ntohs(udp->uh_ulen)+sizeof(struct ip);
|
||||
if ( in_cksum((unsigned short *)nudpip,hl) )
|
||||
return -2;
|
||||
memcpy(udpip->ip, &save_ip, sizeof(struct ip));
|
||||
return 0;
|
||||
}
|
@@ -1,58 +0,0 @@
|
||||
/*
|
||||
* 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>
|
||||
|
||||
#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));
|
||||
|
||||
struct udphdr
|
||||
{
|
||||
u_int16_t uh_sport;
|
||||
u_int16_t uh_dport;
|
||||
u_int16_t uh_ulen;
|
||||
u_int16_t uh_sum;
|
||||
} __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 udpipchk (udpiphdr *udpip);
|
||||
|
||||
#endif
|
@@ -1,4 +1,3 @@
|
||||
|
||||
INCLUDES = -I${top_srcdir}
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
|
@@ -207,6 +207,11 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
|
||||
} else syslog( LOG_ERR, "nm_remove_device_from_list() could not acquire device list mutex." );
|
||||
}
|
||||
|
||||
/* Hal doesn't really give us any way to pass a GMainContext to our
|
||||
* mainloop integration function unfortunately. So we have to use
|
||||
* a global.
|
||||
*/
|
||||
GMainContext *main_context = NULL;
|
||||
|
||||
/*
|
||||
* nm_hal_mainloop_integration
|
||||
@@ -214,7 +219,7 @@ void nm_remove_device_from_list (NMData *data, const char *udi)
|
||||
*/
|
||||
static void nm_hal_mainloop_integration (LibHalContext *ctx, DBusConnection * dbus_connection)
|
||||
{
|
||||
dbus_connection_setup_with_g_main (dbus_connection, NULL);
|
||||
dbus_connection_setup_with_g_main (dbus_connection, main_context);
|
||||
}
|
||||
|
||||
|
||||
@@ -511,6 +516,9 @@ static NMData *nm_data_new (gboolean enable_test_devices)
|
||||
data->enable_test_devices = enable_test_devices;
|
||||
data->starting_up = TRUE;
|
||||
|
||||
data->main_context = g_main_context_new ();
|
||||
data->main_loop = g_main_loop_new (data->main_context, FALSE);
|
||||
|
||||
return (data);
|
||||
}
|
||||
|
||||
@@ -537,6 +545,9 @@ static void nm_data_free (NMData *data)
|
||||
nm_ap_list_unref (data->allowed_ap_list);
|
||||
nm_ap_list_unref (data->invalid_ap_list);
|
||||
|
||||
g_object_unref (data->main_loop);
|
||||
g_object_unref (data->main_context);
|
||||
|
||||
memset (data, 0, sizeof (NMData));
|
||||
}
|
||||
|
||||
@@ -587,12 +598,10 @@ static void nm_print_usage (void)
|
||||
int main( int argc, char *argv[] )
|
||||
{
|
||||
LibHalContext *ctx = NULL;
|
||||
guint link_source;
|
||||
guint policy_source;
|
||||
guint wireless_scan_source;
|
||||
guint link_source_id, policy_source_id, wscan_source_id;
|
||||
GSource *link_source, *policy_source, *wscan_source;
|
||||
gboolean become_daemon = TRUE;
|
||||
gboolean enable_test_devices = FALSE;
|
||||
GMainLoop *loop = NULL;
|
||||
|
||||
if ((int)getuid() != 0)
|
||||
{
|
||||
@@ -676,6 +685,12 @@ int main( int argc, char *argv[] )
|
||||
nm_data->info_daemon_avail = nm_dbus_is_info_daemon_running (nm_data->dbus_connection);
|
||||
nm_data->update_ap_lists = TRUE;
|
||||
|
||||
/* Right before we init hal, we have to make sure our mainloop integration function
|
||||
* knows about our GMainContext. HAL doesn't give us any way to pass that into its
|
||||
* mainloop integration callback, so its got to be a global.
|
||||
*/
|
||||
main_context = nm_data->main_context;
|
||||
|
||||
/* Initialize libhal. We get a connection to the hal daemon here. */
|
||||
if ((ctx = hal_initialize (&hal_functions, FALSE)) == NULL)
|
||||
{
|
||||
@@ -700,15 +715,21 @@ int main( int argc, char *argv[] )
|
||||
/* Create a watch function that monitors cards for link status (hal doesn't do
|
||||
* this for wireless cards yet).
|
||||
*/
|
||||
link_source = g_timeout_add (5000, nm_link_state_monitor, nm_data);
|
||||
link_source = g_timeout_source_new (5000);
|
||||
g_source_set_callback (link_source, nm_link_state_monitor, nm_data, NULL);
|
||||
link_source_id = g_source_attach (link_source, nm_data->main_context);
|
||||
|
||||
/* Another watch function which handles networking state changes and applies
|
||||
* the correct policy on a change.
|
||||
*/
|
||||
policy_source = g_timeout_add (500, nm_state_modification_monitor, nm_data);
|
||||
policy_source = g_timeout_source_new (500);
|
||||
g_source_set_callback (policy_source, nm_state_modification_monitor, nm_data, NULL);
|
||||
policy_source_id = g_source_attach (policy_source, nm_data->main_context);
|
||||
|
||||
/* Keep a current list of access points */
|
||||
wireless_scan_source = g_timeout_add (10000, nm_wireless_scan_monitor, nm_data);
|
||||
wscan_source = g_timeout_source_new (10000);
|
||||
g_source_set_callback (wscan_source, nm_wireless_scan_monitor, nm_data, NULL);
|
||||
wscan_source_id = g_source_attach (wscan_source, nm_data->main_context);
|
||||
|
||||
if (become_daemon && daemon (0, 0) < 0)
|
||||
{
|
||||
@@ -717,15 +738,14 @@ int main( int argc, char *argv[] )
|
||||
}
|
||||
|
||||
/* Wheeee!!! */
|
||||
loop = g_main_loop_new (NULL, FALSE);
|
||||
g_main_loop_run (loop);
|
||||
g_main_loop_run (nm_data->main_loop);
|
||||
|
||||
syslog (LOG_NOTICE, "exiting");
|
||||
syslog (LOG_NOTICE, "exiting...");
|
||||
|
||||
/* Kill the watch functions */
|
||||
g_source_remove (link_source);
|
||||
g_source_remove (policy_source);
|
||||
g_source_remove (wireless_scan_source);
|
||||
g_source_remove (link_source_id);
|
||||
g_source_remove (policy_source_id);
|
||||
g_source_remove (wscan_source_id);
|
||||
|
||||
/* Cleanup */
|
||||
if (hal_shutdown (nm_data->hal_ctx) != 0)
|
||||
|
@@ -1653,7 +1653,7 @@ DBusConnection *nm_dbus_init (NMData *data)
|
||||
}
|
||||
|
||||
dbus_connection_set_exit_on_disconnect (connection, FALSE);
|
||||
dbus_connection_setup_with_g_main (connection, NULL);
|
||||
dbus_connection_setup_with_g_main (connection, data->main_context);
|
||||
|
||||
success = dbus_connection_register_object_path (connection, NM_DBUS_PATH, &nm_vtable, data);
|
||||
if (!success)
|
||||
|
@@ -1617,6 +1617,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
||||
success = nm_device_activate_wireless (dev);
|
||||
else if (nm_device_is_wired (dev))
|
||||
success = nm_device_activation_configure_ip (dev);
|
||||
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP returned = %d\n", nm_device_get_iface (dev), success);
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (nm_device_activation_should_cancel (dev))
|
||||
@@ -1624,6 +1625,7 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
||||
|
||||
if (!success)
|
||||
{
|
||||
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP unsuccessful! Ending activation...\n", nm_device_get_iface (dev));
|
||||
dev->activating = FALSE;
|
||||
dev->just_activated = FALSE;
|
||||
dev->activation_failed = TRUE;
|
||||
@@ -1635,14 +1637,16 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
||||
dev->activating = FALSE;
|
||||
dev->activation_failed = FALSE;
|
||||
dev->quit_activation = FALSE;
|
||||
syslog (LOG_DEBUG, "Activation (%s) IP configuration/DHCP successful!\n", nm_device_get_iface (dev));
|
||||
|
||||
/* If we were told to quit activation, stop the thread and return */
|
||||
if (nm_device_activation_should_cancel (dev))
|
||||
{
|
||||
syslog (LOG_DEBUG, "Activation (%s) told to cancel. Ending activation...\n", nm_device_get_iface (dev));
|
||||
goto out;
|
||||
}
|
||||
|
||||
nm_device_update_ip4_address (dev);
|
||||
|
||||
syslog (LOG_DEBUG, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
|
||||
syslog (LOG_INFO, "nm_device_activation_worker(%s): device activated", nm_device_get_iface (dev));
|
||||
|
||||
if (!nm_device_config_get_use_dhcp (dev) || !dev->dhcp_iface)
|
||||
goto out;
|
||||
@@ -1658,11 +1662,19 @@ static gpointer nm_device_activation_worker (gpointer user_data)
|
||||
g_source_remove (dev->rebind_timeout);
|
||||
g_main_loop_unref (dev->loop);
|
||||
g_main_context_unref (dev->context);
|
||||
dev->context = NULL;
|
||||
dev->loop = NULL;
|
||||
|
||||
out:
|
||||
dev->context = NULL;
|
||||
dev->loop = NULL;
|
||||
if (dev->dhcp_iface)
|
||||
{
|
||||
dhcp_interface_free (dev->dhcp_iface);
|
||||
dev->dhcp_iface = NULL;
|
||||
}
|
||||
|
||||
nm_device_unref (dev);
|
||||
|
||||
syslog (LOG_DEBUG, "Activation (%s) ending thread.\n", nm_device_get_iface (dev));
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
@@ -33,6 +33,8 @@ typedef struct NMData
|
||||
{
|
||||
LibHalContext *hal_ctx;
|
||||
DBusConnection *dbus_connection;
|
||||
GMainContext *main_context;
|
||||
GMainLoop *main_loop;
|
||||
gboolean info_daemon_avail;
|
||||
gboolean enable_test_devices;
|
||||
gboolean starting_up; /* Hack for not taking down an already-set-up wired device when we launch */
|
||||
|
@@ -82,11 +82,9 @@ gboolean nm_system_device_set_ip4_address (NMDevice *dev, int ip4_address)
|
||||
else
|
||||
{
|
||||
success = TRUE;
|
||||
fprintf(stderr, "Your IP address = %u.%u.%u.%u\n",
|
||||
((unsigned char *)&ip4_address)[0],
|
||||
((unsigned char *)&ip4_address)[1],
|
||||
((unsigned char *)&ip4_address)[2],
|
||||
((unsigned char *)&ip4_address)[3]);
|
||||
syslog (LOG_INFO, "Your IP address = %u.%u.%u.%u\n",
|
||||
((unsigned char *)&ip4_address)[0], ((unsigned char *)&ip4_address)[1],
|
||||
((unsigned char *)&ip4_address)[2], ((unsigned char *)&ip4_address)[3]);
|
||||
}
|
||||
|
||||
close (sk);
|
||||
|
@@ -291,6 +291,7 @@ void nm_system_device_update_config_info (NMDevice *dev)
|
||||
guint32 ip4_address = 0;
|
||||
guint32 ip4_netmask = 0;
|
||||
guint32 ip4_gateway = 0;
|
||||
guint32 ip4_broadcast = 0;
|
||||
|
||||
g_return_if_fail (dev != NULL);
|
||||
|
||||
|
Reference in New Issue
Block a user