/* * DhcpProbe.cpp * * Created on: 2014. 8. 17. * Author: sound79@gmail.com */
#include "DhcpProbe.h"
DHCPProbe::DHCPProbe(string ethName) : mDHCPPacket(), mEthName(ethName), mDHCPSocket(0), mPacketXID(0) { //초기화 mDHCPPacket }
DHCPProbe::~DHCPProbe() { }
bool DHCPProbe::makeDHCPSocket() { struct sockaddr_in dhcpAddress; struct ifreq interface;
memset(&dhcpAddress, 0, sizeof(dhcpAddress)); dhcpAddress.sin_family=AF_INET; dhcpAddress.sin_port=htons(CLIENT_DHCP_PORT); dhcpAddress.sin_addr.s_addr=INADDR_ANY; memset(&dhcpAddress.sin_zero, 0, sizeof(dhcpAddress.sin_zero));
int sock=socket(AF_INET,SOCK_DGRAM,IPPROTO_UDP); if(sock<0) { fprintf(stderr, "%s %s %d: create socket error!\n", __FILE__, __FUNCTION__, __LINE__); return false; }
int flags = 1; if(setsockopt(sock, SOL_SOCKET, SO_REUSEADDR, (char *)&flags, sizeof(flags)) < 0) { fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno)); return false; }
if(setsockopt(sock, SOL_SOCKET, SO_BROADCAST, (char *)&flags, sizeof flags) < 0) { fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno)); return false; }
memset(&interface.ifr_ifrn.ifrn_name, 0, IFNAMSIZ); if(mEthName.length() > IFNAMSIZ) strncpy(interface.ifr_ifrn.ifrn_name, mEthName.c_str(), IFNAMSIZ); else strncpy(interface.ifr_ifrn.ifrn_name, mEthName.c_str(), mEthName.length());
if(setsockopt(sock, SOL_SOCKET, SO_BINDTODEVICE, (char *)&interface, sizeof(interface)) < 0) { fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno)); return false; }
if(bind(sock, (struct sockaddr *)&dhcpAddress, sizeof(dhcpAddress)) < 0) { fprintf(stderr, "%s %s %d: error=[%s]\n", __FILE__, __FUNCTION__, __LINE__, strerror(errno)); return false; }
mDHCPSocket = sock;
getMacAddress();
return true; }
void DHCPProbe::closeDHCPSocket() { if(mDHCPSocket > 0) close(mDHCPSocket); mDHCPSocket = 0; }
bool DHCPProbe::getMacAddress() { struct ifreq ifr; strncpy((char *)&ifr.ifr_name, mEthName.c_str(), sizeof(ifr.ifr_name));
if(ioctl(mDHCPSocket,SIOCGIFHWADDR,&ifr)<0) { fprintf(stderr, "%s %s %d: couldn't get mac address!\n", __FILE__, __FUNCTION__, __LINE__); return false; } char mac_address[7] = {0,}; memcpy(&mac_address, &ifr.ifr_hwaddr.sa_data, 6); mEthMacAddress = mac_address;
return true; }
bool DHCPProbe::makeDHCPDiscoveryPacket() { mDHCPPacket.clear();
mDHCPPacket.op = 0x01; //boot request mDHCPPacket.htype = 0x01; //ethernet hardware address mDHCPPacket.hlen = 6; mDHCPPacket.hops = 0; srand(time(NULL)); mPacketXID = random(); mDHCPPacket.xid = htonl(mPacketXID); mDHCPPacket.secs = 0xFF; mDHCPPacket.flags = htons(32768); //DHCP Broadcast flag if(mEthMacAddress.length() > 6) memcpy(mDHCPPacket.chaddr, mEthMacAddress.c_str(), mEthMacAddress.length()); else memcpy(mDHCPPacket.chaddr, mEthMacAddress.c_str(), 6);
mDHCPPacket.options[0] = '\x63'; mDHCPPacket.options[1] = '\x82'; mDHCPPacket.options[2] = '\x53'; mDHCPPacket.options[3] = '\x63'; mDHCPPacket.options[4] = 53; mDHCPPacket.options[5] = '\x01'; mDHCPPacket.options[6] = 1;
return true; }
bool DHCPProbe::sendDHCPDiscovery() { makeDHCPDiscoveryPacket();
struct sockaddr_in destAddress;
destAddress.sin_family = AF_INET; destAddress.sin_port = htons(67); destAddress.sin_addr.s_addr = INADDR_BROADCAST; memset(&destAddress.sin_zero, 0, sizeof(destAddress.sin_zero));
int result = sendto(mDHCPSocket, reinterpret_cast<char *>(&mDHCPPacket), sizeof(mDHCPPacket), 0, reinterpret_cast<struct sockaddr *>(&destAddress), sizeof(destAddress)); if(result < 0) return false; else return true; }
int DHCPProbe::recvDHCPOffer(char *buffer, int buffer_size, struct sockaddr_in *sourceAddress) { struct timeval tv; fd_set readfds;
tv.tv_sec = CHECK_WAITTING_DHCP_OFFER_TIME; tv.tv_usec = 0; FD_ZERO(&readfds); FD_SET(mDHCPSocket, &readfds); select(mDHCPSocket+1, &readfds, NULL, NULL, &tv);
if(FD_ISSET(mDHCPSocket, &readfds)) { struct sockaddr_in src_addr; memset(&src_addr, 0, sizeof(src_addr)); socklen_t address_size = sizeof(src_addr); recvfrom(mDHCPSocket,(char *)buffer, buffer_size, MSG_PEEK, (struct sockaddr *)&src_addr, &address_size); recvfrom(mDHCPSocket,(char *)buffer, buffer_size, 0, (struct sockaddr *)&src_addr, &address_size); fprintf(stderr, "%s %s %d:\n", __FILE__, __FUNCTION__, __LINE__); memcpy(sourceAddress, &src_addr, sizeof(src_addr)); } else { fprintf(stderr, "%s %s %d:\n", __FILE__, __FUNCTION__, __LINE__); return 0; }
return 1; }
int DHCPProbe::waitDHCPOfferPacket() { struct sockaddr_in source; time_t start_time; time_t check_time; time(&start_time);
DHCPPacket buffer;
while(1) { time(&check_time); if((check_time - start_time) >= CHECK_WAITTING_DHCP_OFFER_TIME) break; memset(&source, 0, sizeof(source)); if(recvDHCPOffer(reinterpret_cast<char *>(&buffer), sizeof(buffer), &source) > 0) { fprintf(stderr, "%s\n", inet_ntoa(source.sin_addr)); } }
return 1; }
int DHCPProbe::CheckDHCPServerExist() { if(makeDHCPSocket() == false) return 0;
if(sendDHCPDiscovery() == false) return 0;
waitDHCPOfferPacket(); closeDHCPSocket();
return 1; }
int main() { DHCPProbe dhcp("eth0"); dhcp.CheckDHCPServerExist();
return 0; } |