Example #1
0
int main(int argc, char* argv[]) {
  srandomdev();
  if (argc != 2) {
    errx(EX_USAGE, "Usage: %s <device>", argv[0]);
  }
  char* dev = argv[1];
  char errbuf[LIBNET_ERRBUF_SIZE];
  libnet_t* context = libnet_init(LIBNET_LINK, dev, errbuf);
  if (context == NULL) {
    errx(EX_UNAVAILABLE, "libnet_init: %s", errbuf);
  }

  uint8_t buf[MAX_DHCP_SIZE];
  uint16_t size = MAX_DHCP_SIZE;
  build_dhcp_discover(source_mac, "lozenge", buf, &size);

  libnet_ptag_t ether_tag = LIBNET_PTAG_INITIALIZER;
  libnet_ptag_t ip_tag = LIBNET_PTAG_INITIALIZER;
  libnet_ptag_t udp_tag = LIBNET_PTAG_INITIALIZER;

  udp_tag = libnet_build_udp(68, 67, LIBNET_UDP_H + size,
                            0, buf, size,
                            context, udp_tag);

  u_short ipid = random() & 0xffff;
  ip_tag = libnet_build_ipv4(
               LIBNET_IPV4_H + LIBNET_UDP_H + size,
               0, ipid, 0, 0xff,
               IPPROTO_UDP, 0, 0, 0xffffffff,
               NULL, 0, context, ip_tag);

  ether_tag = libnet_build_ethernet(broadcast_mac, source_mac,
                                    ETHERTYPE_IP, NULL, 0, context, ether_tag);

  if (libnet_write(context) == -1) {
    libnet_destroy(context);
    errx(EX_UNAVAILABLE, "libnet_write");
  }
  printf("Wrote\n");
  libnet_destroy(context);

  return 0;
}
Example #2
0
void main(int argc, char** argv)
{
    if(geteuid() != 0)
    {
        fprintf(stderr, "You need root permissions\n");
        exit(1);
    }

    //TODO : Add a debug mode
    char* interface;
    if(argc > 1)
        interface = argv[1];
    else
    {
        fprintf(stderr, "Please specify network interface to use\n");
        exit(1);
    }

//    printf("Interface = %s\n", interface);

    int sock = socket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IP));
	
	//Set receive timeout
	struct timeval tv;
	tv.tv_usec = 0;
	tv.tv_sec = 10; //10 seconds in case of latency on the network
	setsockopt(sock, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof(tv));

    //retrieve ethernet NIC index and HW address
    struct hw_eth_iface iface = find_iface(sock, interface); // TODO : Check interface existency, and print a list of possible NIC

    struct sockaddr_ll target;
    memset(&target, 0, sizeof(target));
    target.sll_family   = PF_PACKET;
    target.sll_protocol = htons(ETH_P_IP);
    target.sll_ifindex  = iface.index;
    target.sll_hatype   = ARPHRD_ETHER;
    target.sll_pkttype  = PACKET_HOST;
    target.sll_halen    = ETH_ALEN;

    memset(target.sll_addr, 0xff, 6);

    char buffer[BUFF_SIZE];

//    struct dhcp_pkt *dhcp = (struct dhcp_pkt*)(buffer + sizeof(struct udpheader) + sizeof(struct ipheader));
    struct dhcp_pkt dhcp;
    int dhcp_len = build_dhcp_discover(&dhcp, iface.hw_addr, iface.addr_len);

    int len = build_ip4_udp_pkt(buffer, BUFF_SIZE, (unsigned char*)&dhcp, dhcp_len, "0.0.0.0", "255.255.255.255", 68, 67, IPPROTO_UDP);

	//Send the packet over the network
    if(sendto(sock, buffer, len, 0, (struct sockaddr *)&target, sizeof(target)) < 0)
    {
        perror("Error while writing to socket");
        exit(1);
    }

	//Now, wait for the server response, and read it

receive:
    memset(buffer, 0, BUFF_SIZE);

	//Read a packet
    int read_len = recvfrom(sock, buffer, BUFF_SIZE, 0, NULL, NULL);
    if(read_len <= 0)
    {
        perror("Cannot read");
        exit(1);
    }

    struct ipheader *rip   = (struct ipheader*) buffer;
    struct udpheader *rudp = (struct udpheader*)(buffer + sizeof(struct ipheader));
    struct dhcp_pkt *rdhcp = (struct dhcp_pkt*)(buffer + sizeof(struct udpheader) + sizeof(struct ipheader));

    //Check packet validity
	// if dest port isn't our or packet is not a dhcp one, drop the packet
    if(rip->iph_protocol != IPPROTO_UDP || rudp->udph_destport != htons(68) || !is_dhcp(rdhcp) || rdhcp->op != OP_BOOT_REPLY)
        goto receive;

//    printf("Data Recieved, length = %d\n", read_len);

	//Find the IP attributed to us by the server
    struct in_addr raddr;
    raddr.s_addr = rdhcp->yi_addr;

    printf("IPADDR=%s\n", inet_ntoa(raddr));

	//Now check DHCP options, and process them
    struct dhcp_opt *opt = NULL;
    int offs = 0;
    opt = get_dhcp_option(rdhcp, &offs);
    while(opt != NULL)
    {
//        printf("OPT FOUND offset = %d\n", offs);
        switch(opt->id)
        {
            case OPTION_ROUTER: // If the option is the gateway address
				if(opt->len == 4)
				{
					raddr.s_addr = char_to_ip(opt->values);
					printf("GATEWAY=%s\n", inet_ntoa(raddr));
				}
                break;

            case OPTION_SUBNET_MASK: // If the option is the netwmask
				if(opt->len == 4)
				{
					raddr.s_addr = char_to_ip(opt->values);
					printf("NETMASK=%s\n", inet_ntoa(raddr));
				}
                break;

            case OPTION_DNS: // If option is the DNS addresses
				if(opt->len % 4 == 0)
				{
					int i = 0;
					printf("NAMESERVER=");
					int max = opt->len / 4;
					for(i = 0; i < max; i++)
					{
						raddr.s_addr = char_to_ip(opt->values + 4*i);
						printf("%s", inet_ntoa(raddr));
						if(i < max - 1)
							printf(",");
					}
					printf("\n");
				}
                break;

            default:
                break;
        }
        opt = get_dhcp_option(rdhcp, &offs);
    }

    close(sock);
    exit(0);
}