diff --git a/Makefile b/Makefile index 7d7d377..37004f5 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,7 @@ # Makefile to generate dhtest CC=gcc -# CFLAGS=-Wall +CFLAGS=-Wall -O3 -g -fno-strict-aliasing dhtest: dhtest.o functions.o $(CC) dhtest.o functions.o -o dhtest diff --git a/dhtest.c b/dhtest.c index b07b86a..f84cd19 100644 --- a/dhtest.c +++ b/dhtest.c @@ -4,16 +4,18 @@ * Author - Saravanakumar.G E-mail: saravana815@gmail.com */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "headers.h" int sock_packet, iface = 2; /* Socket descripter & transmit interface index */ @@ -34,7 +36,6 @@ u_char dhcp_packet_request[1518] = { 0 }; u_char dhcp_packet_ack[1518] = { 0 }; u_char dhcp_packet_release[1518] = { 0 }; -u_char dhopt_buff[500] = { 0 }; u_int32_t dhopt_size = { 0 }; u_char dhmac[ETHER_ADDR_LEN] = { 0 }; u_char dmac[ETHER_ADDR_LEN]; @@ -45,12 +46,12 @@ char ip_str[128]; u_int8_t dhmac_flag = 0; u_int32_t server_id = { 0 }, option50_ip = { 0 }; u_int32_t dhcp_xid = 0; -u_int16_t bcast_flag = 0; /* DHCP broadcast flag */ -u_int8_t vci_buff[256] = { 0 }; /* VCI buffer*/ +int bcast_flag = 0; /* DHCP broadcast flag */ +const char *vci_buff; u_int16_t vci_flag = 0; -u_int8_t hostname_buff[256] = { 0 }; /* Hostname buffer*/ +const char *hostname_buff; u_int16_t hostname_flag = 0; -u_int8_t fqdn_buff[256] = { 0 }; /* FQDN buffer*/ +const char *fqdn_buff; u_int16_t fqdn_flag = 0; u_int16_t fqdn_n = 0; u_int16_t fqdn_s = 0; @@ -58,8 +59,8 @@ u_int32_t option51_lease_time = 0; u_int32_t port = 67; u_int8_t unicast_flag = 0; u_int8_t nagios_flag = 0; -u_char *giaddr = "0.0.0.0"; -u_char *server_addr = "255.255.255.255"; +char *giaddr = "0.0.0.0"; +char *server_addr = "255.255.255.255"; /* Pointers for all layer data structures */ struct ethernet_hdr *eth_hg = { 0 }; @@ -73,7 +74,7 @@ u_int8_t *dhopt_pointer_g = { 0 }; u_int8_t verbose = 0; u_int8_t dhcp_release_flag = 0; u_int8_t padding_flag = 0; -u_int16_t timeout = 0; +int timeout = 0; time_t time_now, time_last; /* Used for ip listening functionality */ @@ -243,30 +244,30 @@ int main(int argc, char *argv[]) break; case 'o': - if(strlen(optarg) > 256) { + if(strlen(optarg) >= 256) { fprintf(stdout, "VCI string size should be less than 256\n"); exit(2); } vci_flag = 1; - memcpy(vci_buff, optarg, sizeof(vci_buff)); + vci_buff = optarg; break; case 'h': - if(strlen(optarg) > 256) { + if(strlen(optarg) >= 256) { fprintf(stdout, "Hostname string size should be less than 256\n"); exit(2); } hostname_flag = 1; - memcpy(hostname_buff, optarg, sizeof(hostname_buff)); + hostname_buff = optarg; break; case 'd': - if(strlen(optarg) > 256) { - fprintf(stdout, "FQDN domain name string size should be less than 256\n"); + if(strlen(optarg) >= 253) { + fprintf(stdout, "FQDN domain name string size should be less than 253\n"); exit(2); } fqdn_flag = 1; - memcpy(fqdn_buff, optarg, sizeof(fqdn_buff)); + fqdn_buff = optarg; break; case 'n': diff --git a/functions.c b/functions.c index ce82972..e187b1f 100644 --- a/functions.c +++ b/functions.c @@ -1,63 +1,24 @@ -#include -#include -#include -#include -#include /* To set non blocking on socket */ -#include /* Generic socket calls */ -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include /* To set non blocking on socket */ +#include /* Generic socket calls */ +#include +#include +#include +#include +#include +#include +#include +#include +#include #include "headers.h" -//Defined in dhtest.c -extern int sock_packet; -extern struct sockaddr_ll ll; -extern int iface; -extern u_int16_t vlan; -extern u_int8_t l3_tos; - -extern u_int16_t l2_hdr_size; -extern u_int16_t l3_hdr_size; -extern u_int16_t l4_hdr_size; -extern u_int16_t dhcp_hdr_size; -extern u_int16_t fqdn_n; -extern u_int16_t fqdn_s; - -extern u_char dhcp_packet_disc[1514]; -extern u_char dhcp_packet_offer[1514]; -extern u_char dhcp_packet_request[1514]; -extern u_char dhcp_packet_ack[1514]; -extern u_char dhcp_packet_release[1514]; - -extern u_int8_t dhopt_buff[500]; -extern u_int32_t dhopt_size; -extern u_int32_t dhcp_xid; -extern u_int32_t bcast_flag; -extern u_int8_t timeout; -extern u_int8_t padding_flag; -extern u_int8_t vci_buff[256]; -extern u_int8_t hostname_buff[256]; -extern u_int8_t fqdn_buff[256]; -extern u_int32_t option51_lease_time; -extern u_int32_t port; -extern u_int8_t unicast_flag; -extern u_int8_t nagios_flag; -extern u_char *giaddr; -extern u_char *server_addr; - -extern struct ethernet_hdr *eth_hg; -extern struct vlan_hdr *vlan_hg; -extern struct iphdr *iph_g; -extern struct udphdr *uh_g; -extern struct dhcpv4_hdr *dhcph_g; -extern u_int8_t *dhopt_pointer_g; - -struct arp_hdr *arp_hg; -struct icmp_hdr *icmp_hg; + +static unsigned char dhopt_buff[500]; +static struct arp_hdr *arp_hg; +static struct icmp_hdr *icmp_hg; extern u_char dhmac[ETHER_ADDR_LEN]; extern u_char dmac[ETHER_ADDR_LEN]; @@ -70,13 +31,21 @@ extern u_int8_t dhcp_release_flag; extern u_int32_t unicast_ip_address; extern u_int32_t ip_address; -extern ip_listen_flag; +extern u_char ip_listen_flag; extern u_char arp_icmp_packet[1514]; extern u_char arp_icmp_reply[1514]; extern u_int16_t icmp_len; extern struct timeval tval_listen; extern u_int32_t listen_timeout; +/* DHCP packet, option buffer and size of option buffer */ +static unsigned char dhcp_packet_disc[1518] = { 0 }; +static unsigned char dhcp_packet_offer[1518] = { 0 }; +static unsigned char dhcp_packet_request[1518] = { 0 }; +static unsigned char dhcp_packet_ack[1518] = { 0 }; +static unsigned char dhcp_packet_release[1518] = { 0 }; + + /* * Opens PF_PACKET socket and return error if socket * opens fails @@ -84,7 +53,6 @@ extern u_int32_t listen_timeout; int open_socket() { - int sock_new, non_block, tmp; sock_packet = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); if(sock_packet < 0) { perror("--Error on creating the socket--"); @@ -131,6 +99,7 @@ int set_promisc() perror("Error on setting promisc"); exit(2); } + return 0; } int clear_promisc() @@ -218,6 +187,8 @@ int send_packet(int pkt_type) (struct sockaddr *) &ll,\ sizeof(ll)); } + else + abort(); if(ret < 0) { if (nagios_flag) @@ -258,7 +229,8 @@ int send_packet(int pkt_type) int recv_packet(int pkt_type) { - int ret, sock_len, retval, chk_pkt_state, tmp = 0; + int ret, retval, chk_pkt_state; + socklen_t sock_len; fd_set read_fd; struct timeval tval; tval.tv_sec = 5; @@ -282,6 +254,8 @@ int recv_packet(int pkt_type) (struct sockaddr *)&ll, &sock_len); } + else + abort(); if(ret >= 60) { chk_pkt_state = check_packet(DHCP_MSGOFFER); if(chk_pkt_state == DHCP_OFFR_RCVD) { @@ -308,6 +282,8 @@ int recv_packet(int pkt_type) (struct sockaddr *)&ll, &sock_len); } + else + abort(); if(ret >= 60) { chk_pkt_state = check_packet(DHCP_MSGACK); if(chk_pkt_state == DHCP_ACK_RCVD) { @@ -336,6 +312,8 @@ int recv_packet(int pkt_type) (struct sockaddr *)&ll, &sock_len); } + else + abort(); if(ret >= 60) { chk_pkt_state = check_packet(ARP_ICMP_RCV); if(chk_pkt_state == ARP_RCVD) { @@ -349,6 +327,7 @@ int recv_packet(int pkt_type) } return LISTEN_TIMOUET; } + return 0; } /* Debug function - Prints the buffer on HEX format */ @@ -465,34 +444,9 @@ u_int16_t l4_sum(u_int16_t *buff, int words, u_int16_t *srcaddr, u_int16_t *dsta */ int build_option53(int msg_type) { - if(msg_type == DHCP_MSGDISCOVER) { - u_int8_t msgtype = DHCP_MESSAGETYPE; - u_int8_t msglen = 1; - u_int8_t msg = DHCP_MSGDISCOVER; - - memcpy(dhopt_buff, &msgtype, 1); - strncpy((dhopt_buff + 1), &msglen, 1); - strncpy((dhopt_buff + 2), &msg, 1); - dhopt_size = dhopt_size + 3; - } else if(msg_type == DHCP_MSGREQUEST) { - u_int8_t msgtype = DHCP_MESSAGETYPE; - u_int8_t msglen = 1; - u_int8_t msg = DHCP_MSGREQUEST; - - memcpy(dhopt_buff, &msgtype, 1); - strncpy((dhopt_buff + 1), &msglen, 1); - strncpy((dhopt_buff + 2), &msg, 1); - dhopt_size = dhopt_size + 3; - } else if(msg_type == DHCP_MSGRELEASE) { - u_int8_t msgtype = DHCP_MESSAGETYPE; - u_int8_t msglen = 1; - u_int8_t msg = DHCP_MSGRELEASE; - - memcpy(dhopt_buff, &msgtype, 1); - strncpy((dhopt_buff + 1), &msglen, 1); - strncpy((dhopt_buff + 2), &msg, 1); - dhopt_size = dhopt_size + 3; - } + dhopt_buff[dhopt_size++] = DHCP_MESSAGETYPE; + dhopt_buff[dhopt_size++] = 1; + dhopt_buff[dhopt_size++] = (unsigned char) msg_type; return 0; } @@ -501,14 +455,10 @@ int build_option53(int msg_type) */ int build_option50() { - u_int8_t msgtype = DHCP_REQUESTEDIP; - u_int8_t msglen = 4; - u_int32_t msg = option50_ip; - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), &msg, 4); - dhopt_size = dhopt_size + 6; + dhopt_buff[dhopt_size++] = DHCP_REQUESTEDIP; + dhopt_buff[dhopt_size++] = 4; + memcpy(dhopt_buff + dhopt_size, &option50_ip, 4); + dhopt_size += 4; return 0; } @@ -517,14 +467,10 @@ int build_option50() */ int build_option51() { - u_int8_t msgtype = DHCP_LEASETIME; - u_int8_t msglen = 4; - u_int32_t msg = htonl(option51_lease_time); - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), &msg, 4); - dhopt_size = dhopt_size + 6; + dhopt_buff[dhopt_size++] = DHCP_LEASETIME; + dhopt_buff[dhopt_size++] = 4; + memcpy(dhopt_buff + dhopt_size, &option50_ip, 4); + dhopt_size += 4; return 0; } /* @@ -532,14 +478,11 @@ int build_option51() */ int build_option54() { - u_int8_t msgtype = DHCP_SERVIDENT; - u_int8_t msglen = 4; - u_int32_t msg = server_id; - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), &msg, 4); - dhopt_size = dhopt_size + 6; + dhopt_buff[dhopt_size++] = DHCP_SERVIDENT; + dhopt_buff[dhopt_size++] = 4; + memcpy(dhopt_buff + dhopt_size, &option50_ip, 4); + dhopt_size += 4; + return 0; } /* @@ -547,19 +490,12 @@ int build_option54() */ int build_option55() { - u_int32_t msgtype = DHCP_PARAMREQUEST; - u_int32_t msglen = 4; - u_int8_t msg[4] = { 0 }; - msg[0] = DHCP_SUBNETMASK; - msg[1] = DHCP_ROUTER; - msg[2] = DHCP_DOMAINNAME; - msg[3] = DHCP_DNS; - /* msg[4] = DHCP_LOGSERV; */ - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), msg, 4); - dhopt_size = dhopt_size + 6; + dhopt_buff[dhopt_size++] = DHCP_PARAMREQUEST; + dhopt_buff[dhopt_size++] = 4; + dhopt_buff[dhopt_size++] = DHCP_SUBNETMASK; + dhopt_buff[dhopt_size++] = DHCP_ROUTER; + dhopt_buff[dhopt_size++] = DHCP_DOMAINNAME; + dhopt_buff[dhopt_size++] = DHCP_DNS; return 0; } @@ -568,14 +504,10 @@ int build_option55() */ int build_option60_vci() { - u_int32_t msgtype = DHCP_CLASSSID; - u_int32_t msglen = strlen(vci_buff); - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), vci_buff, strlen(vci_buff)); - - dhopt_size = dhopt_size + 2 + strlen(vci_buff); + dhopt_buff[dhopt_size++] = DHCP_CLASSID; + dhopt_buff[dhopt_size++] = (unsigned char) strlen(vci_buff); + memcpy(dhopt_buff + dhopt_size, vci_buff, strlen(vci_buff)); + dhopt_size += strlen(vci_buff); return 0; } @@ -584,14 +516,10 @@ int build_option60_vci() */ int build_option12_hostname() { - u_int32_t msgtype = DHCP_HOSTNAME; - u_int32_t msglen = strlen(hostname_buff); - - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), hostname_buff, strlen(hostname_buff)); - - dhopt_size = dhopt_size + 2 + strlen(hostname_buff); + dhopt_buff[dhopt_size++] = DHCP_HOSTNAME; + dhopt_buff[dhopt_size++] = (unsigned char) strlen(hostname_buff); + memcpy(dhopt_buff + dhopt_size, hostname_buff, strlen(hostname_buff)); + dhopt_size += strlen(hostname_buff); return 0; } @@ -601,25 +529,21 @@ int build_option12_hostname() */ int build_option81_fqdn() { - u_int32_t msgtype = DHCP_FQDN; - u_int8_t flags = 0; - u_int8_t rcode1 = 0; - u_int8_t rcode2 = 0; - u_int32_t msglen = strlen(fqdn_buff) + 3; + unsigned char flags = 0; if (fqdn_n) flags |= FQDN_N_FLAG; if (fqdn_s) flags |= FQDN_S_FLAG; - memcpy((dhopt_buff + dhopt_size), &msgtype, 1); - memcpy((dhopt_buff + dhopt_size + 1), &msglen, 1); - memcpy((dhopt_buff + dhopt_size + 2), &flags, 1); - memcpy((dhopt_buff + dhopt_size + 3), &rcode1, 1); - memcpy((dhopt_buff + dhopt_size + 4), &rcode2, 1); - memcpy((dhopt_buff + dhopt_size + 5), fqdn_buff, strlen(fqdn_buff)); + dhopt_buff[dhopt_size++] = DHCP_FQDN; + dhopt_buff[dhopt_size++] = (unsigned char) strlen(fqdn_buff) + 3; + dhopt_buff[dhopt_size++] = flags; + dhopt_buff[dhopt_size++] = 0; + dhopt_buff[dhopt_size++] = 0; + memcpy(dhopt_buff + dhopt_size, fqdn_buff, strlen(fqdn_buff)); + dhopt_size += strlen(fqdn_buff); - dhopt_size = dhopt_size + 2 + msglen; return 0; } @@ -628,9 +552,7 @@ int build_option81_fqdn() */ int build_optioneof() { - u_int8_t eof = 0xff; - memcpy((dhopt_buff + dhopt_size), &eof, 1); - dhopt_size = dhopt_size + 1; + dhopt_buff[dhopt_size++] = 0xff; return 0; } @@ -857,6 +779,7 @@ int build_dhpacket(int pkt_type) /* UDP checksum is done here */ uh->check = l4_sum((u_int16_t *) (dhcp_packet_release + l2_hdr_size + l3_hdr_size), ((dhcp_hdr_size + dhopt_size + l4_hdr_size) / 2), (u_int16_t *)&iph->saddr, (u_int16_t *)&iph->daddr, htons(l4_proto), htons(l4_len)); } + return 0; } /* @@ -1019,6 +942,7 @@ int check_packet(int pkt_type) } return UNKNOWN_PACKET; } + return 0; } /* @@ -1223,7 +1147,7 @@ int get_dhinfo() { FILE *dh_file; u_char aux_dmac[ETHER_ADDR_LEN]; - char mac_tmp[20], acq_ip_tmp[20], serv_id_tmp[20], dmac_tmp[20], ip_listen_tmp[10]; + char mac_tmp[20], acq_ip_tmp[20], serv_id_tmp[20], ip_listen_tmp[10]; pid_t dh_pid; dh_file = fopen(dhmac_fname, "r"); if(dh_file == NULL) { diff --git a/headers.h b/headers.h index 2b79e26..0335e4c 100644 --- a/headers.h +++ b/headers.h @@ -237,7 +237,7 @@ struct dhcpv4_hdr #define DHCP_MAXMSGSIZE 0x39 #define DHCP_RENEWTIME 0x3a #define DHCP_REBINDTIME 0x3b -#define DHCP_CLASSSID 0x3c +#define DHCP_CLASSID 0x3c #define DHCP_CLIENTID 0x3d #define DHCP_NISPLUSDOMAIN 0x40 #define DHCP_NISPLUSSERVERS 0x41 @@ -305,6 +305,61 @@ struct dhcpv4_hdr */ #define MINIMUM_PACKET_SIZE 300 +//Defined in dhtest.c +extern int sock_packet; +extern struct sockaddr_ll ll; +extern int iface; +extern u_int16_t vlan; +extern u_int8_t l3_tos; + +extern u_int16_t l2_hdr_size; +extern u_int16_t l3_hdr_size; +extern u_int16_t l4_hdr_size; +extern u_int16_t dhcp_hdr_size; +extern u_int16_t fqdn_n; +extern u_int16_t fqdn_s; + +extern u_int32_t dhopt_size; +extern u_int32_t dhcp_xid; +extern int bcast_flag; +extern int timeout; +extern u_int8_t padding_flag; +extern const char *vci_buff; +extern const char *hostname_buff; +extern const char *fqdn_buff; +extern u_int32_t option51_lease_time; +extern u_int32_t port; +extern u_int8_t unicast_flag; +extern u_int8_t nagios_flag; +extern char *giaddr; +extern char *server_addr; + +extern struct ethernet_hdr *eth_hg; +extern struct vlan_hdr *vlan_hg; +extern struct iphdr *iph_g; +extern struct udphdr *uh_g; +extern struct dhcpv4_hdr *dhcph_g; +extern u_int8_t *dhopt_pointer_g; + +extern u_char dhmac[ETHER_ADDR_LEN]; +extern u_char dmac[ETHER_ADDR_LEN]; + +extern char dhmac_fname[20]; +extern char iface_name[30]; +extern char ip_str[128]; +extern u_int32_t server_id, option50_ip; +extern u_int8_t dhcp_release_flag; + +extern u_int32_t unicast_ip_address; +extern u_int32_t ip_address; +extern u_char ip_listen_flag; +extern u_char arp_icmp_packet[1514]; +extern u_char arp_icmp_reply[1514]; +extern u_int16_t icmp_len; +extern struct timeval tval_listen; +extern u_int32_t listen_timeout; + + #endif /* __HEADERS_H */ /* EOF */