/* Copyright (c) 2007 Simon Kelley

   This program is free software; you can redistribute it and/or modify
   it under the terms of the GNU General Public License as published by
   the Free Software Foundation; version 2 dated June, 1991.

   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
   GNU General Public License for more details.
*/

/* dhcp_lease_time <address> */

/* Send a DHCPINFORM message to a dnsmasq server running on the local host
   and print (to stdout) the time remaining in any lease for the given
   address. The time is given as string printed to stdout.

   If an error occurs or no lease exists for the given address, 
   nothing is sent to stdout a message is sent to stderr and a
   non-zero error code is returned.

   This version requires dnsmasq 2.67 or later. 
*/

#include <sys/types.h> 
#include <netinet/in.h>
#include <net/if.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <unistd.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <net/if_arp.h>
#include <sys/ioctl.h>
#include <linux/types.h>
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <errno.h>

#define DHCP_CHADDR_MAX          16
#define BOOTREQUEST              1
#define DHCP_COOKIE              0x63825363
#define OPTION_PAD               0
#define OPTION_LEASE_TIME        51
#define OPTION_OVERLOAD          52
#define OPTION_MESSAGE_TYPE      53
#define OPTION_REQUESTED_OPTIONS 55
#define OPTION_END               255
#define DHCPINFORM               8
#define DHCP_SERVER_PORT         67

#define option_len(opt) ((int)(((unsigned char *)(opt))[1]))
#define option_ptr(opt) ((void *)&(((unsigned char *)(opt))[2]))


typedef unsigned char u8;
typedef unsigned short u16;
typedef unsigned int u32;

struct dhcp_packet {
  u8 op, htype, hlen, hops;
  u32 xid;
  u16 secs, flags;
  struct in_addr ciaddr, yiaddr, siaddr, giaddr;
  u8 chaddr[DHCP_CHADDR_MAX], sname[64], file[128];
  u32 cookie;
  unsigned char options[308];
};

static unsigned char *option_find1(unsigned char *p, unsigned char *end, int opt, int minsize)
{
  while (*p != OPTION_END) 
    {
      if (p >= end)
        return NULL; /* malformed packet */
      else if (*p == OPTION_PAD)
        p++;
      else 
        { 
          int opt_len;
          if (p >= end - 2)
            return NULL; /* malformed packet */
          opt_len = option_len(p);
          if (end - p < (2 + opt_len))
            return NULL; /* malformed packet */
          if (*p == opt && opt_len >= minsize)
            return p;
          p += opt_len + 2;
        }
    }
  
  return opt == OPTION_END ? p : NULL;
}
 
static unsigned char *option_find(struct dhcp_packet *mess, size_t size, int opt_type, int minsize)
{
  unsigned char *ret, *overload;
  
  /* skip over DHCP cookie; */
  if ((ret = option_find1(&mess->options[0], ((unsigned char *)mess) + size, opt_type, minsize)))
    return ret;

  /* look for overload option. */
  if (!(overload = option_find1(&mess->options[0], ((unsigned char *)mess) + size, OPTION_OVERLOAD, 1)))
    return NULL;
  
  /* Can we look in filename area ? */
  if ((overload[2] & 1) &&
      (ret = option_find1(&mess->file[0], &mess->file[128], opt_type, minsize)))
    return ret;

  /* finally try sname area */
  if ((overload[2] & 2) &&
      (ret = option_find1(&mess->sname[0], &mess->sname[64], opt_type, minsize)))
    return ret;

  return NULL;
}

static unsigned int option_uint(unsigned char *opt, int size)
{
  /* this worries about unaligned data and byte order */
  unsigned int ret = 0;
  int i;
  unsigned char *p = option_ptr(opt);
  
  for (i = 0; i < size; i++)
    ret = (ret << 8) | *p++;

  return ret;
}

int main(int argc, char **argv)
{ 
  struct in_addr lease;
  struct dhcp_packet packet;
  unsigned char *p = packet.options;
  struct sockaddr_in dest;
  int fd = socket(PF_INET, SOCK_DGRAM, IPPROTO_UDP);
  ssize_t rc;
  
  if (argc < 2)
    { 
      fprintf(stderr, "usage: dhcp_lease_time <address>\n");
      exit(1);
    }

  if (fd == -1)
    {
      perror("cannot create socket");
      exit(1);
    }
 
  lease.s_addr = inet_addr(argv[1]);
   
  memset(&packet, 0, sizeof(packet));
 
  packet.hlen = 0;
  packet.htype = 0;

  packet.op = BOOTREQUEST;
  packet.ciaddr = lease;
  packet.cookie = htonl(DHCP_COOKIE);

  *(p++) = OPTION_MESSAGE_TYPE;
  *(p++) = 1;
  *(p++) = DHCPINFORM;

  /* Explicitly request the lease time, it won't be sent otherwise:
     this is a dnsmasq extension, not standard. */
  *(p++) = OPTION_REQUESTED_OPTIONS;
  *(p++) = 1;
  *(p++) = OPTION_LEASE_TIME;
  
  *(p++) = OPTION_END;
 
  dest.sin_family = AF_INET; 
  dest.sin_addr.s_addr = inet_addr("127.0.0.1");
  dest.sin_port = ntohs(DHCP_SERVER_PORT);
  
  if (sendto(fd, &packet, sizeof(packet), 0, 
	     (struct sockaddr *)&dest, sizeof(dest)) == -1)
    {
      perror("sendto failed");
      exit(1);
    }

  alarm(3); /* noddy timeout. */

  rc = recv(fd, &packet, sizeof(packet), 0);
  
  if (rc < (ssize_t)(sizeof(packet) - sizeof(packet.options)))
    {
      perror("recv failed");
      exit(1);
    }

  if ((p = option_find(&packet, (size_t)rc, OPTION_LEASE_TIME, 4)))
    {
      unsigned int t = option_uint(p, 4);
      if (t == 0xffffffff)
	printf("infinite");
      else
	{
	  unsigned int x;
	  if ((x = t/86400))
	    printf("%ud", x);
	  if ((x = (t/3600)%24))
	    printf("%uh", x);
	  if ((x = (t/60)%60))
	    printf("%um", x);
	  if ((x = t%60))
	    printf("%us", x);
	}
      return 0;
    }

  return 1; /* no lease */
}
