154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley/* dhcp6.c - DHCP6 client for dynamic network configuration. 254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley * 354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley * Copyright 2015 Rajni Kant <rajnikant12345@gmail.com> 454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley * 554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley * Not in SUSv4. 654a13f9ef4380501d3b12bb1f04408f5607d46eeRob LandleyUSE_DHCP6(NEWTOY(dhcp6, "r:A#<0T#<0t#<0s:p:i:SRvqnbf", TOYFLAG_SBIN|TOYFLAG_ROOTONLY)) 754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleyconfig DHCP6 954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley bool "dhcp6" 1054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley default n 1154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley help 1254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley usage: dhcp6 [-fbnqvR] [-i IFACE] [-r IP] [-s PROG] [-p PIDFILE] 1354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 1454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley Configure network dynamicaly using DHCP. 1554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 1654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -i Interface to use (default eth0) 1754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -p Create pidfile 1854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -s Run PROG at DHCP events 1954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -t Send up to N Solicit packets 2054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -T Pause between packets (default 3 seconds) 2154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -A Wait N seconds after failure (default 20) 2254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -f Run in foreground 2354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -b Background if lease is not obtained 2454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -n Exit if lease is not obtained 2554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -q Exit after obtaining lease 2654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -R Release IP on exit 2754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -S Log to syslog too 2854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -r Request this IP address 2954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley -v Verbose 3054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 3154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley Signals: 3254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley USR1 Renew current lease 3354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley USR2 Release current lease 3454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley*/ 3554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define FOR_dhcp6 3654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include "toys.h" 3754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <linux/sockios.h> 3854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <linux/if_ether.h> 3954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <netinet/ip.h> 4054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <netinet/ip6.h> 4154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <netinet/udp.h> 4254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <linux/if_packet.h> 4354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#include <syslog.h> 4454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 4554a13f9ef4380501d3b12bb1f04408f5607d46eeRob LandleyGLOBALS( 4654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley char *interface_name, *pidfile, *script; 4754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley long retry, timeout, errortimeout; 4854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley char *req_ip; 4954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int length, state, request_length, sock, sock1, status, retval, retries; 5054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct timeval tv; 5154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t transction_id[3]; 5254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct sockaddr_in6 input_socket6; 5354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley) 5454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 5554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6SOLICIT 1 5654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6ADVERTISE 2 // server -> client 5754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6REQUEST 3 5854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6CONFIRM 4 5954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6RENEW 5 6054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6REBIND 6 6154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6REPLY 7 // server -> client 6254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6RELEASE 8 6354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6DECLINE 9 6454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6RECONFIGURE 10 // server -> client 6554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6INFOREQUEST 11 6654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6RELAYFLOW 12 // relay -> relay/server 6754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6RELAYREPLY 13 // server/relay -> relay 6854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 6954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// DHCPv6 option codes (partial). See RFC 3315 7054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_CLIENTID 1 7154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_SERVERID 2 7254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_IA_NA 3 7354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_IA_ADDR 5 7454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_ORO 6 7554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_PREFERENCE 7 7654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_ELAPSED_TIME 8 7754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_RELAY_MSG 9 7854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_STATUS_CODE 13 7954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_IA_PD 25 8054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_OPT_IA_PREFIX 26 8154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 8254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_STATUS_SUCCESS 0 8354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_STATUS_NOADDRSAVAIL 2 8454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 8554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_DUID_LLT 1 8654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_DUID_EN 2 8754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_DUID_LL 3 8854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCP6_DUID_UUID 4 8954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 9054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCPC_SERVER_PORT 547 9154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define DHCPC_CLIENT_PORT 546 9254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 9354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define LOG_SILENT 0x0 9454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define LOG_CONSOLE 0x1 9554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley#define LOG_SYSTEM 0x2 9654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 9754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleytypedef struct __attribute__((packed)) dhcp6_msg_s { 9854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t msgtype, transaction_id[3], options[524]; 9954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} dhcp6_msg_t; 10054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 10154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleytypedef struct __attribute__((packed)) optval_duid_llt { 10254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t type; 10354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t hwtype; 10454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint32_t time; 10554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t lladdr[6]; 10654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} DUID; 10754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 10854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleytypedef struct __attribute__((packed)) optval_ia_na { 10954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint32_t iaid, t1, t2; 11054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} IA_NA; 11154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 11254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleytypedef struct __attribute__((packed)) dhcp6_raw_s { 11354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct ip6_hdr iph; 11454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct udphdr udph; 11554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp6_msg_t dhcp6; 11654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} dhcp6_raw_t; 11754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 11854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleytypedef struct __attribute__((packed)) dhcp_data_client { 11954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t status_code; 12054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint32_t iaid , t1,t2, pf_lf, va_lf; 12154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t ipaddr[17] ; 12254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} DHCP_DATA; 12354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 12454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic DHCP_DATA dhcp_data; 12554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic dhcp6_raw_t *mymsg; 12654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic dhcp6_msg_t mesg; 12754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic DUID *duid; 12854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 12954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void (*dbg)(char *format, ...); 13054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void dummy(char *format, ...) 13154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 13254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return; 13354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 13454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 13554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void logit(char *format, ...) 13654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 13754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int used; 13854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley char *msg; 13954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley va_list p, t; 14054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t infomode = LOG_SILENT; 14154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 142547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_S) infomode |= LOG_SYSTEM; 143547c9167565cf8a2bba8bd79850889101866814aRob Landley if(toys.optflags & FLAG_v) infomode |= LOG_CONSOLE; 14454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley va_start(p, format); 14554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley va_copy(t, p); 14654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley used = vsnprintf(NULL, 0, format, t); 14754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley used++; 14854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley va_end(t); 14954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 15054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley msg = xmalloc(used); 15154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley vsnprintf(msg, used, format, p); 15254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley va_end(p); 15354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 15454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (infomode & LOG_SYSTEM) syslog(LOG_INFO, "%s", msg); 15554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (infomode & LOG_CONSOLE) printf("%s", msg); 15654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley free(msg); 15754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return; 15854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 15954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 16054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void get_mac(uint8_t *mac, char *interface) 16154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 16254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int fd; 16354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct ifreq req; 16454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 16554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!mac) return; 16654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fd = xsocket(AF_INET6, SOCK_RAW, IPPROTO_RAW); 16754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley req.ifr_addr.sa_family = AF_INET6; 16854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xstrncpy(req.ifr_name, interface, IFNAMSIZ); 16954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xioctl(fd, SIOCGIFHWADDR, &req); 17054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(mac, req.ifr_hwaddr.sa_data, 6); 17154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(fd); 17254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 17354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 17454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void fill_option(uint16_t option_id, uint16_t option_len, uint8_t **dhmesg) 17554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 17654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *tmp = *dhmesg; 17754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 17854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *((uint16_t*)tmp) = htons(option_id); 17954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *(uint16_t*)(tmp+2) = htons(option_len); 18054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *dhmesg += 4; 18154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length += 4; 18254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 18354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 18454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void fill_clientID() 18554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 18654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *tmp = &mesg.options[TT.length]; 18754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 18854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if(!duid) { 18954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t mac[7] = {0,}; 19054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley duid = (DUID*)malloc(sizeof(DUID)); 19154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley duid->type = htons(1); 19254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley duid->hwtype = htons(1); 19354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley duid->time = htonl((uint32_t)(time(NULL) - 946684800) & 0xffffffff); 19454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_option(DHCP6_OPT_CLIENTID,14,&tmp); 19554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley get_mac(mac, TT.interface_name); 19654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(duid->lladdr,mac, 6); 19754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(tmp,(uint8_t*)duid,sizeof(DUID)); 19854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 19954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley else { 20054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_option(DHCP6_OPT_CLIENTID,14,&tmp); 20154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(tmp,(uint8_t*)duid,sizeof(DUID)); 20254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 20354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length += sizeof(DUID); 20454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 20554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 20654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// TODO: make it generic for multiple options. 20754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void fill_optionRequest() 20854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 20954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *tmp = &mesg.options[TT.length]; 21054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 21154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_option(DHCP6_OPT_ORO,4,&tmp); 21254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *(uint16_t*)(tmp+4) = htons(23); 21354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *(uint16_t*)(tmp+6) = htons(24); 21454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length += 4; 21554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 21654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 21754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void fill_elapsedTime() 21854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 21954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *tmp = &mesg.options[TT.length]; 22054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 22154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_option(DHCP6_OPT_ELAPSED_TIME, 2, &tmp); 22254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley *(uint16_t*)(tmp+6) = htons(0); 22354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length += 2; 22454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 22554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 22654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void fill_iaid() 22754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 22854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley IA_NA iana; 22954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *tmp = &mesg.options[TT.length]; 23054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 23154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_option(DHCP6_OPT_IA_NA, 12, &tmp); 23254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana.iaid = rand(); 23354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana.t1 = 0xffffffff; 23454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana.t2 = 0xffffffff; 23554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(tmp, (uint8_t*)&iana, sizeof(IA_NA)); 23654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length += sizeof(IA_NA); 23754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 23854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 23954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley//static void mode_raw(int *sock_t) 24054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void mode_raw() 24154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 24254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int constone = 1; 24354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct sockaddr_ll sockll; 24454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 24554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.sock > 0) xclose(TT.sock); 24654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.sock = xsocket(PF_PACKET, SOCK_DGRAM, htons(ETH_P_IPV6)); 24754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 24854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memset(&sockll, 0, sizeof(sockll)); 24954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sockll.sll_family = AF_PACKET; 25054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sockll.sll_protocol = htons(ETH_P_IPV6); 25154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sockll.sll_ifindex = if_nametoindex(TT.interface_name); 25254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (bind(TT.sock, (struct sockaddr *) &sockll, sizeof(sockll))) { 25354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock); 25454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley error_exit("MODE RAW : Bind fail.\n"); 25554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 25654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (setsockopt(TT.sock, SOL_PACKET, PACKET_HOST,&constone, sizeof(int)) < 0) { 25754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (errno != ENOPROTOOPT) error_exit("MODE RAW : Bind fail.\n"); 25854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 25954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 26054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 26154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void generate_transection_id() 26254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 26354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int i, r = rand() % 0xffffff; 26454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 26554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley for (i=0; i<3; i++) { 26654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.transction_id[i] = r%0xff; 26754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley r = r/10; 26854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 26954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 27054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 27154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void set_timeout(int seconds) 27254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 27354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.tv.tv_sec = seconds; 27454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.tv.tv_usec = 100000; 27554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 27654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 27754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void send_msg(int type) 27854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 27954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct sockaddr_in6 addr6; 28054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int sendlength = 0; 28154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 28254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memset(&addr6, 0, sizeof(addr6)); 28354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley addr6.sin6_family = AF_INET6; 28454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley addr6.sin6_port = htons(DHCPC_SERVER_PORT); //SERVER_PORT 28554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley inet_pton(AF_INET6, "ff02::1:2", &addr6.sin6_addr); 28654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley mesg.msgtype = type; 28754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley generate_transection_id(); 28854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(mesg.transaction_id, TT.transction_id, 3); 28954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 29054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (type == DHCP6SOLICIT) { 29154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.length = 0; 29254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_clientID(); 29354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_optionRequest(); 29454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_elapsedTime(); 29554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fill_iaid(); 29654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sendlength = sizeof(dhcp6_msg_t) - 524 + TT.length; 29754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else if (type == DHCP6REQUEST || type == DHCP6RELEASE || type == DHCP6RENEW) 29854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sendlength = TT.request_length; 29954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Sending message type: %d\n", type); 30054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sendlength = sendto(TT.sock1, &mesg, sendlength , 0,(struct sockaddr *)&addr6, 30154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sizeof(struct sockaddr_in6 )); 30254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (sendlength <= 0) dbg("Error in sending message type: %d\n", type); 30354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 30454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 30554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleyuint8_t *get_msg_ptr(uint8_t *data, int data_length, int msgtype) 30654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 30754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t type = *((uint16_t*)data), length = *((uint16_t*)(data+2)); 30854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 30954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley type = ntohs(type); 31054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (type == msgtype) return data; 31154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley length = ntohs(length); 31254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley while (type != msgtype) { 31354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley data_length -= (4 + length); 31454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (data_length <= 0) break; 31554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley data = data + 4 + length; 31654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley type = ntohs(*((uint16_t*)data)); 31754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley length = ntohs(*((uint16_t*)(data+2))); 31854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (type == msgtype) return data; 31954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 32054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return NULL; 32154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 32254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 32354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic uint8_t *check_server_id(uint8_t *data, int data_length) 32454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 32554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return get_msg_ptr(data, data_length, DHCP6_OPT_SERVERID); 32654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 32754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 32854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic int check_client_id(uint8_t *data, int data_length) 32954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 33054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if ((data = get_msg_ptr(data, data_length, DHCP6_OPT_CLIENTID))) { 33154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley DUID one = *((DUID*)(data+4)); 33254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley DUID two = *((DUID*)&mesg.options[4]); 33354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 33454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!memcmp(&one, &two, sizeof(DUID))) return 1; 33554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 33654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return 0; 33754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 33854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 33954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic int validate_ids() 34054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 34154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!check_server_id(mymsg->dhcp6.options, 34254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.status - ((char*)&mymsg->dhcp6.options[0] - (char*)mymsg) )) { 34354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid server id: %d\n"); 34454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return 0; 34554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 34654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!check_client_id(mymsg->dhcp6.options, 34754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.status - ((char*)&mymsg->dhcp6.options[0] - (char*)mymsg) )) { 34854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid client id: %d\n"); 34954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return 0; 35054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 35154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return 1; 35254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 35354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 35454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void parse_ia_na(uint8_t *data, int data_length) 35554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 35654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint8_t *t = get_msg_ptr(data, data_length, DHCP6_OPT_IA_NA); 35754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t iana_len, content_len = 0; 35854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 35954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memset(&dhcp_data,0,sizeof(dhcp_data)); 36054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!t) return; 36154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 36254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana_len = ntohs(*((uint16_t*)(t+2))); 36354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.iaid = ntohl(*((uint32_t*)(t+4))); 36454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.t1 = ntohl(*((uint32_t*)(t+8))); 36554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.t2 = ntohl(*((uint32_t*)(t+12))); 36654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley t += 16; 36754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana_len -= 12; 36854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 36954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley while(iana_len > 0) { 37054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley uint16_t sub_type = ntohs(*((uint16_t*)(t))); 37154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 37254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley switch (sub_type) { 37354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case DHCP6_OPT_IA_ADDR: 37454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley content_len = ntohs(*((uint16_t*)(t+2))); 37554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(dhcp_data.ipaddr,t+4,16); 37654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state == DHCP6SOLICIT) { 37754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.req_ip) { 37854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct addrinfo *res = NULL; 37954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 38054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if(!getaddrinfo(TT.req_ip, NULL, NULL,&res)) { 38154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Requesting IP: %s\n", TT.req_ip); 38254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy (&TT.input_socket6, res->ai_addr, res->ai_addrlen); 38354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy(t+4, TT.input_socket6.sin6_addr.__in6_u.__u6_addr8, 16); 38454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else xprintf("Invalid IP: %s\n",TT.req_ip); 38554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley freeaddrinfo(res); 38654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 38754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 38854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.pf_lf = ntohl(*((uint32_t*)(t+20))); 38954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.va_lf = ntohl(*((uint32_t*)(t+24))); 39054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana_len -= (content_len + 4); 39154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley t += (content_len + 4); 39254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 39354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case DHCP6_OPT_STATUS_CODE: 39454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley content_len = ntohs(*((uint16_t*)(t+2))); 39554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dhcp_data.status_code = ntohs(*((uint16_t*)(t+4))); 39654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana_len -= (content_len + 4); 39754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley t += (content_len + 4); 39854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 39954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley default: 40054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley content_len = ntohs(*((uint16_t*)(t+2))); 40154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley iana_len -= (content_len + 4); 40254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley t += (content_len + 4); 40354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 40454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 40554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 40654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 40754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 40854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void write_pid(char *path) 40954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 41054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int pidfile = open(path, O_CREAT | O_WRONLY | O_TRUNC, 0666); 41154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 41254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (pidfile > 0) { 41354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley char pidbuf[12]; 41454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 41554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sprintf(pidbuf, "%u", (unsigned)getpid()); 41654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley write(pidfile, pidbuf, strlen(pidbuf)); 41754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley close(pidfile); 41854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 41954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 42054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 42154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// Creates environment pointers from RES to use in script 42254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic int fill_envp(DHCP_DATA *res) 42354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 42454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int ret = setenv("interface", TT.interface_name, 1); 42554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 42654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (ret) return ret; 42754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley inet_ntop(AF_INET6, res->ipaddr, toybuf, INET6_ADDRSTRLEN); 42854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley ret = setenv("ip",(const char*)toybuf , 1); 42954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return ret; 43054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 43154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 43254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// Executes Script NAME. 43354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void run_script(DHCP_DATA *res, char *name) 43454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 43554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley volatile int error = 0; 43654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct stat sts; 43754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley pid_t pid; 43854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley char *argv[3]; 439547c9167565cf8a2bba8bd79850889101866814aRob Landley char *script = (toys.optflags & FLAG_s) ? TT.script 440547c9167565cf8a2bba8bd79850889101866814aRob Landley : "/usr/share/dhcp/default.script"; 44154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 44254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (stat(script, &sts) == -1 && errno == ENOENT) return; 44354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!res || fill_envp(res)) { 44454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Failed to create environment variables.\n"); 44554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return; 44654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 44754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Executing %s %s\n", script, name); 44854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley argv[0] = (char*)script; 44954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley argv[1] = (char*)name; 45054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley argv[2] = NULL; 45154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fflush(NULL); 45254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 45354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley pid = vfork(); 45454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (pid < 0) { 45554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Fork failed.\n"); 45654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return; 45754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 45854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!pid) { 45954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley execvp(argv[0], argv); 46054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley error = errno; 46154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley _exit(111); 46254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 46354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (error) { 46454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley waitpid(pid, NULL, 0); 46554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley errno = error; 46654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley perror_msg("script exec failed"); 46754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 46854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("script complete.\n"); 46954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 47054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 47154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void lease_fail() 47254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 47354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Lease failed.\n"); 47454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley run_script(NULL, "leasefail"); 475547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_n) { 47654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock); 47754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock1); 47854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley error_exit("Lease Failed, Exiting."); 47954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 480547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_b) { 48154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Lease failed. Going to daemon mode.\n"); 48254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (daemon(0,0)) perror_exit("daemonize"); 483547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_p) write_pid(TT.pidfile); 48454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley toys.optflags &= ~FLAG_b; 48554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley toys.optflags |= FLAG_f; 48654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 48754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 48854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 48954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// Generic signal handler real handling is done in main funcrion. 49054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic void signal_handler(int sig) 49154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 49254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Caught signal: %d\n", sig); 49354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley switch (sig) { 49454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case SIGUSR1: 49554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("SIGUSR1.\n"); 49654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state == DHCP6RELEASE || TT.state == DHCP6REQUEST ) { 49754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6SOLICIT; 49854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(0); 49954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return; 50054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 50154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("SIGUSR1 sending renew.\n"); 50254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley send_msg(DHCP6RENEW); 50354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6RENEW; 50454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries = 0; 50554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(0); 50654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 50754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case SIGUSR2: 50854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("SIGUSR2.\n"); 50954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state == DHCP6RELEASE) return; 51054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state != DHCP6CONFIRM ) return; 51154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("SIGUSR2 sending release.\n"); 51254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley send_msg(DHCP6RELEASE); 51354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6RELEASE; 51454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries = 0; 51554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(0); 51654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 51754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case SIGTERM: 51854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley case SIGINT: 51954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg((sig == SIGTERM)?"SIGTERM.\n":"SIGINT.\n"); 520547c9167565cf8a2bba8bd79850889101866814aRob Landley if ((toys.optflags & FLAG_R) && TT.state == DHCP6CONFIRM) 521547c9167565cf8a2bba8bd79850889101866814aRob Landley send_msg(DHCP6RELEASE); 52254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if(sig == SIGINT) exit(0); 52354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 52454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley default: break; 52554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 52654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 52754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 52854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley// signal setup for SIGUSR1 SIGUSR2 SIGTERM 52954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleystatic int setup_signal() 53054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 53154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley signal(SIGUSR1, signal_handler); 53254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley signal(SIGUSR2, signal_handler); 53354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley signal(SIGTERM, signal_handler); 53454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley signal(SIGINT, signal_handler); 53554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley return 0; 53654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 53754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 53854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landleyvoid dhcp6_main(void) 53954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley{ 54054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley struct sockaddr_in6 sinaddr6; 54154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int constone = 1; 54254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley fd_set rfds; 54354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 54454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley srand(time(NULL)); 54554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley setlinebuf(stdout); 54654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg = dummy; 54754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6SOLICIT; 54854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 549547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_v) dbg = logit; 55054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!TT.interface_name) TT.interface_name = "eth0"; 551547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_p) write_pid(TT.pidfile); 55254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!TT.retry) TT.retry = 3; 55354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!TT.timeout) TT.timeout = 3; 55454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!TT.errortimeout) TT.errortimeout = 20; 555547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_S) { 55654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley openlog("DHCP6 :", LOG_PID, LOG_DAEMON); 55754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg = logit; 55854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 55954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 56054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Interface: %s\n", TT.interface_name); 56154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("pid file: %s\n", TT.pidfile); 56254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Retry count: %d\n", TT.retry); 56354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Timeout : %d\n", TT.timeout); 56454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Error timeout: %d\n", TT.errortimeout); 56554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 56654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 56754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 56854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley setup_signal(); 56954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.sock1 = xsocket(PF_INET6, SOCK_DGRAM, 0); 57054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memset(&sinaddr6, 0, sizeof(sinaddr6)); 57154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sinaddr6.sin6_family = AF_INET6; 57254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sinaddr6.sin6_port = htons(DHCPC_CLIENT_PORT); 57354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sinaddr6.sin6_scope_id = if_nametoindex(TT.interface_name); 57454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley sinaddr6.sin6_addr = in6addr_any ; 57554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 57654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xsetsockopt(TT.sock1, SOL_SOCKET, SO_REUSEADDR, &constone, sizeof(constone)); 57754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 57854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (bind(TT.sock1, (struct sockaddr *)&sinaddr6, sizeof(sinaddr6))) { 57954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock1); 58054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley error_exit("bind failed"); 58154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 58254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 58354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley mode_raw(); 58454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(0); 58554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley for (;;) { 58654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley int maxfd = TT.sock; 58754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley 58854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.sock >= 0) FD_SET(TT.sock, &rfds); 58954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retval = 0; 59054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if ((TT.retval = select(maxfd + 1, &rfds, NULL, NULL, &TT.tv)) < 0) { 59154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if(errno == EINTR) continue; 59254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley perror_exit("Error in select"); 59354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 59454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!TT.retval) { 59554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state == DHCP6SOLICIT || TT.state == DHCP6CONFIRM) { 59654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("State is solicit, sending solicit packet\n"); 59754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley run_script(NULL, "deconfig"); 59854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley send_msg(DHCP6SOLICIT); 59954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6SOLICIT; 60054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries++; 60154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if(TT.retries > TT.retry) set_timeout(TT.errortimeout); 60254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley else if (TT.retries == TT.retry) { 60354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("State is solicit, retry count is max.\n"); 60454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley lease_fail(); 60554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(TT.errortimeout); 60654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else set_timeout(TT.timeout); 60754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 60854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else if (TT.state == DHCP6REQUEST || TT.state == DHCP6RENEW || 60954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state == DHCP6RELEASE) { 61054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("State is %d , sending packet\n", TT.state); 61154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley send_msg(TT.state); 61254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries++; 61354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.retries > TT.retry) set_timeout(TT.errortimeout); 61454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley else if (TT.retries == TT.retry) { 61554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley lease_fail(); 61654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(TT.errortimeout); 61754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else set_timeout(TT.timeout); 61854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 61954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 62054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else if (FD_ISSET(TT.sock, &rfds)) { 62154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if ((TT.status = read(TT.sock, toybuf, sizeof(toybuf))) <= 0) continue; 62254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley mymsg = (dhcp6_raw_t*)toybuf; 62354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (ntohs(mymsg->udph.dest) == 546 && 62454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley !memcmp(mymsg->dhcp6.transaction_id, TT.transction_id, 3)) { 62554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (TT.state == DHCP6SOLICIT) { 62654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (mymsg->dhcp6.msgtype == DHCP6ADVERTISE ) { 62754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!validate_ids()) { 62854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid id recieved, solicit.\n"); 62954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6SOLICIT; 63054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 63154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 63254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Got reply to request or solicit.\n"); 63354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries = 0; 63454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(0); 63554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.request_length = TT.status - ((char*)&mymsg->dhcp6 - (char*)mymsg); 63654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy((uint8_t*)&mesg, &mymsg->dhcp6, TT.request_length); 63754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley parse_ia_na(mesg.options, TT.request_length); 63854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Status code:%d\n", dhcp_data.status_code); 63954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley inet_ntop(AF_INET6, dhcp_data.ipaddr, toybuf, INET6_ADDRSTRLEN); 64054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Advertiesed IP: %s\n", toybuf); 64154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6REQUEST; 64254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else { 64354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid solicit.\n"); 64454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 64554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 64654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else if (TT.state == DHCP6REQUEST || TT.state == DHCP6RENEW ) { 64754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (mymsg->dhcp6.msgtype == DHCP6REPLY) { 64854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (!validate_ids()) { 64954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid id recieved, %d.\n", TT.state); 65054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6REQUEST; 65154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 65254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 65354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Got reply to request or renew.\n"); 65454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.request_length = TT.status - ((char*)&mymsg->dhcp6 - (char*)mymsg); 65554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley memcpy((uint8_t*)&mesg, &mymsg->dhcp6, TT.request_length); 65654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley parse_ia_na(mymsg->dhcp6.options, TT.request_length); 65754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Status code:%d\n", dhcp_data.status_code); 65854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley inet_ntop(AF_INET6, dhcp_data.ipaddr, toybuf, INET6_ADDRSTRLEN); 65954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Got IP: %s\n", toybuf); 66054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.retries = 0; 66154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley run_script(&dhcp_data, (TT.state == DHCP6REQUEST) ? 66254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley "request" : "renew"); 663547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_q) { 664547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_R) send_msg(DHCP6RELEASE); 66554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley break; 66654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 66754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley TT.state = DHCP6CONFIRM; 66854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout((dhcp_data.va_lf)?dhcp_data.va_lf:INT_MAX); 66954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Setting timeout to intmax."); 670547c9167565cf8a2bba8bd79850889101866814aRob Landley if (TT.state == DHCP6REQUEST || !(toys.optflags & FLAG_f)) { 67154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Making it a daemon\n"); 67254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley if (daemon(0,0)) perror_exit("daemonize"); 67354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley toys.optflags |= FLAG_f; 674547c9167565cf8a2bba8bd79850889101866814aRob Landley if (toys.optflags & FLAG_p) write_pid(TT.pidfile); 67554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 67654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Making it a foreground.\n"); 67754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 67854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else { 67954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Invalid reply.\n"); 68054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley continue; 68154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 68254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } else if (TT.state == DHCP6RELEASE) { 68354a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley dbg("Got reply to release.\n"); 68454a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley run_script(NULL, "release"); 68554a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley set_timeout(INT_MAX); 68654a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 68754a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 68854a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 68954a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley } 69054a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock1); 69154a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley xclose(TT.sock); 69254a13f9ef4380501d3b12bb1f04408f5607d46eeRob Landley} 693