#include <string.h>
#include <sys/socket.h>
#include <features.h>
#include <asm/types.h>
#include <linux/if_packet.h>
#include <linux/if_ether.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "dhcpd.h"
#include "packet.h"
#include "options.h"
#include "dhcpc.h"
#include "debug.h"
Include dependency graph for clientpacket.c:
Go to the source code of this file.
Functions | |
unsigned long | random_xid (void) |
int | send_discover (unsigned long xid, unsigned long requested) |
int | send_selecting (unsigned long xid, unsigned long server, unsigned long requested) |
int | send_renew (unsigned long xid, unsigned long server, unsigned long ciaddr) |
int | send_release (unsigned long server, unsigned long ciaddr) |
int | get_raw_packet (struct dhcpMessage *payload, int fd) |
int get_raw_packet | ( | struct dhcpMessage * | payload, | |
int | fd | |||
) |
Definition at line 182 of file clientpacket.c.
References checksum(), CLIENT_PORT, dhcpMessage::cookie, udp_dhcp_packet::data, DEBUG, DHCP_MAGIC, udp_dhcp_packet::ip, LOG, LOG_ERR, LOG_INFO, and udp_dhcp_packet::udp.
Referenced by udhcp().
00183 { 00184 int bytes; 00185 struct udp_dhcp_packet packet; 00186 u_int32_t source, dest; 00187 u_int16_t check; 00188 00189 memset(&packet, 0, sizeof(struct udp_dhcp_packet)); 00190 bytes = read(fd, &packet, sizeof(struct udp_dhcp_packet)); 00191 if (bytes < 0) { 00192 DEBUG(LOG_INFO, "couldn't read on raw listening socket -- ignoring"); 00193 usleep(500000); /* possible down interface, looping condition */ 00194 return -1; 00195 } 00196 00197 if (bytes < (int) (sizeof(struct iphdr) + sizeof(struct udphdr))) { 00198 DEBUG(LOG_INFO, "message too short, ignoring"); 00199 return -2; 00200 } 00201 00202 if (bytes < ntohs(packet.ip.tot_len)) { 00203 DEBUG(LOG_INFO, "Truncated packet"); 00204 return -2; 00205 } 00206 00207 /* ignore any extra garbage bytes */ 00208 bytes = ntohs(packet.ip.tot_len); 00209 00210 /* Make sure its the right packet for us, and that it passes sanity checks */ 00211 if (packet.ip.protocol != IPPROTO_UDP || packet.ip.version != IPVERSION || 00212 packet.ip.ihl != sizeof(packet.ip) >> 2 || packet.udp.dest != htons(CLIENT_PORT) || 00213 bytes > (int) sizeof(struct udp_dhcp_packet) || 00214 ntohs(packet.udp.len) != (short) (bytes - sizeof(packet.ip))) { 00215 DEBUG(LOG_INFO, "unrelated/bogus packet"); 00216 return -2; 00217 } 00218 00219 /* check IP checksum */ 00220 check = packet.ip.check; 00221 packet.ip.check = 0; 00222 if (check != checksum(&(packet.ip), sizeof(packet.ip))) { 00223 DEBUG(LOG_INFO, "bad IP header checksum, ignoring"); 00224 return -1; 00225 } 00226 00227 /* verify the UDP checksum by replacing the header with a psuedo header */ 00228 source = packet.ip.saddr; 00229 dest = packet.ip.daddr; 00230 check = packet.udp.check; 00231 packet.udp.check = 0; 00232 memset(&packet.ip, 0, sizeof(packet.ip)); 00233 00234 packet.ip.protocol = IPPROTO_UDP; 00235 packet.ip.saddr = source; 00236 packet.ip.daddr = dest; 00237 packet.ip.tot_len = packet.udp.len; /* cheat on the psuedo-header */ 00238 if (check && check != checksum(&packet, bytes)) { 00239 DEBUG(LOG_ERR, "packet with bad UDP checksum received, ignoring"); 00240 return -2; 00241 } 00242 00243 memcpy(payload, &(packet.data), bytes - (sizeof(packet.ip) + sizeof(packet.udp))); 00244 00245 if (ntohl(payload->cookie) != DHCP_MAGIC) { 00246 LOG(LOG_ERR, "received bogus message (bad magic) -- ignoring"); 00247 return -2; 00248 } 00249 DEBUG(LOG_INFO, "oooooh!!! got some!"); 00250 return bytes - (sizeof(packet.ip) + sizeof(packet.udp)); 00251 00252 }
Here is the call graph for this function:
unsigned long random_xid | ( | void | ) |
Definition at line 52 of file clientpacket.c.
References LOG, and LOG_WARNING.
Referenced by send_release(), and udhcp().
00053 { 00054 static int initialized; 00055 if (!initialized) { 00056 int fd; 00057 unsigned long seed; 00058 00059 fd = open("/dev/urandom", 0); 00060 if (fd < 0 || read(fd, &seed, sizeof(seed)) < 0) { 00061 LOG(LOG_WARNING, "Could not load seed from /dev/urandom: %s", 00062 strerror(errno)); 00063 seed = time(0); 00064 } 00065 if (fd >= 0) close(fd); 00066 srand(seed); 00067 initialized++; 00068 } 00069 return rand(); 00070 }
int send_discover | ( | unsigned long | xid, | |
unsigned long | requested | |||
) |
Definition at line 108 of file clientpacket.c.
References client_config, CLIENT_PORT, DHCP_REQUESTED_IP, DHCPDISCOVER, client_config_t::ifindex, LOG, LOG_DEBUG, MAC_BCAST_ADDR, dhcpMessage::options, raw_packet(), SERVER_PORT, and dhcpMessage::xid.
Referenced by udhcp().
00109 { 00110 struct dhcpMessage packet; 00111 00112 init_packet(&packet, DHCPDISCOVER); 00113 packet.xid = xid; 00114 if (requested) 00115 add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); 00116 00117 add_requests(&packet); 00118 LOG(LOG_DEBUG, "Sending discover..."); 00119 return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, 00120 SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); 00121 }
Here is the call graph for this function:
int send_release | ( | unsigned long | server, | |
unsigned long | ciaddr | |||
) |
Definition at line 165 of file clientpacket.c.
References dhcpMessage::ciaddr, CLIENT_PORT, DHCP_REQUESTED_IP, DHCP_SERVER_ID, DHCPRELEASE, kernel_packet(), LOG, LOG_DEBUG, dhcpMessage::options, random_xid(), SERVER_PORT, and dhcpMessage::xid.
00166 { 00167 struct dhcpMessage packet; 00168 00169 init_packet(&packet, DHCPRELEASE); 00170 packet.xid = random_xid(); 00171 packet.ciaddr = ciaddr; 00172 00173 add_simple_option(packet.options, DHCP_REQUESTED_IP, ciaddr); 00174 add_simple_option(packet.options, DHCP_SERVER_ID, server); 00175 00176 LOG(LOG_DEBUG, "Sending release..."); 00177 return kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); 00178 }
Here is the call graph for this function:
int send_renew | ( | unsigned long | xid, | |
unsigned long | server, | |||
unsigned long | ciaddr | |||
) |
Definition at line 145 of file clientpacket.c.
References dhcpMessage::ciaddr, client_config, CLIENT_PORT, DHCPREQUEST, client_config_t::ifindex, kernel_packet(), LOG, LOG_DEBUG, MAC_BCAST_ADDR, raw_packet(), SERVER_PORT, and dhcpMessage::xid.
Referenced by udhcp().
00146 { 00147 struct dhcpMessage packet; 00148 int ret = 0; 00149 00150 init_packet(&packet, DHCPREQUEST); 00151 packet.xid = xid; 00152 packet.ciaddr = ciaddr; 00153 00154 add_requests(&packet); 00155 LOG(LOG_DEBUG, "Sending renew..."); 00156 if (server) 00157 ret = kernel_packet(&packet, ciaddr, CLIENT_PORT, server, SERVER_PORT); 00158 else ret = raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, 00159 SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); 00160 return ret; 00161 }
Here is the call graph for this function:
int send_selecting | ( | unsigned long | xid, | |
unsigned long | server, | |||
unsigned long | requested | |||
) |
Definition at line 125 of file clientpacket.c.
References client_config, CLIENT_PORT, DHCP_REQUESTED_IP, DHCP_SERVER_ID, DHCPREQUEST, client_config_t::ifindex, LOG, LOG_DEBUG, MAC_BCAST_ADDR, dhcpMessage::options, raw_packet(), SERVER_PORT, and dhcpMessage::xid.
Referenced by udhcp().
00126 { 00127 struct dhcpMessage packet; 00128 struct in_addr addr; 00129 00130 init_packet(&packet, DHCPREQUEST); 00131 packet.xid = xid; 00132 00133 add_simple_option(packet.options, DHCP_REQUESTED_IP, requested); 00134 add_simple_option(packet.options, DHCP_SERVER_ID, server); 00135 00136 add_requests(&packet); 00137 addr.s_addr = requested; 00138 LOG(LOG_DEBUG, "Sending select for %s...", inet_ntoa(addr)); 00139 return raw_packet(&packet, INADDR_ANY, CLIENT_PORT, INADDR_BROADCAST, 00140 SERVER_PORT, MAC_BCAST_ADDR, client_config.ifindex); 00141 }
Here is the call graph for this function: