⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 scan_dhcp.c

📁 Linux下无线网卡扫描工具源代码
💻 C
字号:
/* * dhcp.c * * Code to check for a DHCP server. */#include <arpa/inet.h>#include <errno.h>#include <net/if.h>#include <netinet/in.h>#include <stdio.h>#include <stdlib.h>#include <string.h>#include <sys/ioctl.h>#include <sys/socket.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include "skan_config.h"#define SA struct sockaddrstruct dhcp_packet {    unsigned char  op;    unsigned char  htype;    unsigned char  hlen;    unsigned char  hops;    unsigned int   xid;    unsigned short secs;    unsigned short flags;    unsigned int   ciaddr;    unsigned int   yiaddr;    unsigned int   siaddr;    unsigned int   giaddr;    unsigned char  chaddr[16];    unsigned char  sname[64];    unsigned char  file[128];    unsigned int   cookie;    unsigned char  options[336];};extern gtkskan_config_t skan_conf;/* * Returns the minimum length of the packet. */int dhcp_get_length(struct dhcp_packet * pkt){    int i = 0;    if (pkt == NULL) {	return 240 + 1;    }        while (pkt->options[i] != 0xff) {	i++;    }    return 240 + i + 1;}/* * Gets the MAC address for 'dev'. */int dhcp_get_mac(int fd, const char * dev, unsigned char * mac){    struct ifreq ifr;    int retval;    if (dev == NULL) {	return -1;    }    memset(&ifr, 0, sizeof(ifr));    strcpy(ifr.ifr_name, dev);    retval = ioctl(fd, SIOCGIFHWADDR, &ifr);    if (retval < 0) {	return retval;    }    if (mac) {	memcpy(mac, ifr.ifr_hwaddr.sa_data, 6);    }    return 0;}/* * Returns a pointer to the given option. */unsigned char * dhcp_get_opt(struct dhcp_packet * pkt, int opt){    unsigned char * options;    if (pkt == NULL) {	return NULL;    }    options = pkt->options;    for (;;) {	if (*options == opt) {	    return options;	}	if (*options == 0xff) {	    return NULL;	}	options += *(options + 1);    }    return NULL;}/* * Broadcasts a DHCPDISCOVER packet. */int dhcp_discover(int fd, unsigned char * mac){    struct dhcp_packet pkt;    struct sockaddr_in sa;    int retval;    if (fd < 0) {	return fd;    }    memset(&pkt, 0, sizeof(pkt));    pkt.op     = 1; /* BOOTREQUEST */    pkt.htype  = 1; /* Ethernet */    pkt.hlen   = 6; /* ETH_ALEN */    pkt.xid    = htonl(0x12345678);    pkt.cookie = htonl(0x63825363);    if (mac) {	memcpy(pkt.chaddr, mac, 6);    } else {	retval = dhcp_get_mac(fd, "eth0", pkt.chaddr);	if (retval < 0) {	    return retval;	}    }    /*     * This is a discover packet.     */    pkt.options[0] = 53; /* DHCP Message Type */    pkt.options[1] = 1;    pkt.options[2] = 1; /* DHCPDISCOVER */    pkt.options[3] = 0xff;    memset(&sa, 0, sizeof(sa));    sa.sin_family = AF_INET;    sa.sin_addr   = (struct in_addr) { INADDR_BROADCAST };    sa.sin_port   = htons(67);    retval = sendto(fd, &pkt, dhcp_get_length(&pkt), 0, (SA *) &sa, sizeof(sa));    if (retval < 0) {	return retval;    }    return 0;}/* * Receives a DHCP packet. */int dhcp_recv(int fd, struct dhcp_packet * pkt){    int retval;    if (pkt == NULL) {	return -1;    }    retval = recv(fd, pkt, sizeof(*pkt), 0);    if (retval < 0) {	return retval;    }    return retval;}/* * Creates a DHCP socket. */int dhcp_socket(void){    struct sockaddr_in sa;    int fd, on = 1, retval;    fd = socket(AF_INET, SOCK_DGRAM, 0);    if (fd < 0) {	return fd;    }    retval = setsockopt(fd, SOL_SOCKET, SO_BROADCAST, &on, sizeof(on));    if (retval < 0) {	return retval;    }    memset(&sa, 0, sizeof(sa));    sa.sin_family = AF_INET;    sa.sin_addr   = (struct in_addr) { INADDR_ANY };    sa.sin_port   = htons(68);    retval = bind(fd, (SA *) &sa, sizeof(sa));    if (retval < 0) {	return retval;    }    return fd;}void * dhcp_search(void *data){    unsigned char mac[6];    struct timeval tv;    int fd, retval, timeout = 1;    fd_set rfds;    /*     * Create the socket.  Do this early so we can use the socket     * for generic sockopts.     */    fd = (int)data;    if (fd < 0) {	fprintf(stderr, "socket error: %m\n");	exit(1);    }    /*     * Grab the MAC address to use in the 'chaddr' field.     *///    retval = dhcp_get_mac(fd, wvlan_interface, mac);    retval = dhcp_get_mac(fd, skan_conf.interface, mac);    if (retval < 0) {	fprintf(stderr, "dhcp_get_mac error: %m\n");	exit(1);    }    FD_ZERO(&rfds);    memset(&tv, 0, sizeof(tv));    /*     * Send a discover packet every N seconds.     * Also display any packets we see.     */    for (;;) {	FD_SET(fd, &rfds);	retval = select(fd + 1, &rfds, NULL, NULL, &tv);	if (retval < 0) {	    if (errno != EINTR) {		fprintf(stderr, "select error: %m\n");	    }	}	/*	 * Timeout, send a DHCPDISCOVER packet and reset the timer.	 */	if (retval == 0) {	    retval = dhcp_discover(fd, mac);	    if (retval < 0) {		fprintf(stderr, "dhcp_discover error: %m\n");	    }	    tv.tv_sec  = timeout;	    tv.tv_usec = 0;	    continue;	}	/*	 * Receive the packet.	 */	if (FD_ISSET(fd, &rfds)) {	    struct dhcp_packet pkt;	    struct in_addr a;	    unsigned char * opt;	    retval = dhcp_recv(fd, &pkt);	    if (retval < 0) {		fprintf(stderr, "dhcp_recv error: %m\n");		continue;	    }	    a = (struct in_addr) { pkt.yiaddr };	    fprintf(stdout, "received offer for %s\n", inet_ntoa(a));#if 0	    opt = dhcp_get_opt(&pkt, 53);	    if (opt) {		fprintf(stdout, "msgtype: %d\n", *(opt + 2));	    }#endif#if 1	    /* untested */	    opt = dhcp_get_opt(&pkt, 15);	    if (opt) {		fprintf(stdout, "domainname: %s\n", (char *) opt + 2);	    }#endif	    return NULL;	}    }    return NULL;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -