diff options
Diffstat (limited to 'src/dhcpv6.h')
-rw-r--r-- | src/dhcpv6.h | 162 |
1 files changed, 162 insertions, 0 deletions
diff --git a/src/dhcpv6.h b/src/dhcpv6.h new file mode 100644 index 0000000..004c3cf --- /dev/null +++ b/src/dhcpv6.h @@ -0,0 +1,162 @@ +/** + * Copyright (C) 2012 Steven Barth <steven@midlink.org> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 + * as published by the Free Software Foundation. + * + * 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 version 2 for more details. + * + */ +#pragma once + +#define ALL_DHCPV6_RELAYS {{{0xff, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x02}}} + +#define ALL_DHCPV6_SERVERS {{{0xff, 0x05, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,\ + 0x00, 0x00, 0x00, 0x00, 0x00, 0x01, 0x00, 0x03}}} + +#define DHCPV6_CLIENT_PORT 546 +#define DHCPV6_SERVER_PORT 547 + +#define DHCPV6_MSG_SOLICIT 1 +#define DHCPV6_MSG_ADVERTISE 2 +#define DHCPV6_MSG_REQUEST 3 +#define DHCPV6_MSG_CONFIRM 4 +#define DHCPV6_MSG_RENEW 5 +#define DHCPV6_MSG_REBIND 6 +#define DHCPV6_MSG_REPLY 7 +#define DHCPV6_MSG_RELEASE 8 +#define DHCPV6_MSG_DECLINE 9 +#define DHCPV6_MSG_RECONFIGURE 10 +#define DHCPV6_MSG_INFORMATION_REQUEST 11 +#define DHCPV6_MSG_RELAY_FORW 12 +#define DHCPV6_MSG_RELAY_REPL 13 + +#define DHCPV6_OPT_CLIENTID 1 +#define DHCPV6_OPT_SERVERID 2 +#define DHCPV6_OPT_IA_NA 3 +#define DHCPV6_OPT_IA_ADDR 5 +#define DHCPV6_OPT_STATUS 13 +#define DHCPV6_OPT_RELAY_MSG 9 +#define DHCPV6_OPT_AUTH 11 +#define DHCPV6_OPT_INTERFACE_ID 18 +#define DHCPV6_OPT_RECONF_MSG 19 +#define DHCPV6_OPT_RECONF_ACCEPT 20 +#define DHCPV6_OPT_DNS_SERVERS 23 +#define DHCPV6_OPT_DNS_DOMAIN 24 +#define DHCPV6_OPT_IA_PD 25 +#define DHCPV6_OPT_IA_PREFIX 26 +#define DHCPV6_OPT_INFO_REFRESH 32 +#define DHCPV6_OPT_FQDN 39 + +#define DHCPV6_DUID_VENDOR 2 + +#define DHCPV6_STATUS_OK 0 +#define DHCPV6_STATUS_NOADDRSAVAIL 2 +#define DHCPV6_STATUS_NOBINDING 3 +#define DHCPV6_STATUS_NOTONLINK 4 +#define DHCPV6_STATUS_NOPREFIXAVAIL 6 + +// I just remembered I have an old one lying around... +#define DHCPV6_ENT_NO 30462 +#define DHCPV6_ENT_TYPE 1 + + +#define DHCPV6_HOP_COUNT_LIMIT 32 + +struct dhcpv6_client_header { + uint8_t msg_type; + uint8_t transaction_id[3]; +} __attribute__((packed)); + +struct dhcpv6_relay_header { + uint8_t msg_type; + uint8_t hop_count; + struct in6_addr link_address; + struct in6_addr peer_address; + uint8_t options[]; +} __attribute__((packed)); + +struct dhcpv6_relay_forward_envelope { + uint8_t msg_type; + uint8_t hop_count; + struct in6_addr link_address; + struct in6_addr peer_address; + uint16_t interface_id_type; + uint16_t interface_id_len; + uint32_t interface_id_data; + uint16_t relay_message_type; + uint16_t relay_message_len; +} __attribute__((packed)); + +struct dhcpv6_auth_reconfigure { + uint16_t type; + uint16_t len; + uint8_t protocol; + uint8_t algorithm; + uint8_t rdm; + uint32_t replay[2]; + uint8_t reconf_type; + uint8_t key[16]; +} _packed; + +struct dhcpv6_ia_hdr { + uint16_t type; + uint16_t len; + uint32_t iaid; + uint32_t t1; + uint32_t t2; +} _packed; + +struct dhcpv6_ia_prefix { + uint16_t type; + uint16_t len; + uint32_t preferred; + uint32_t valid; + uint8_t prefix; + struct in6_addr addr; +} _packed; + +struct dhcpv6_ia_addr { + uint16_t type; + uint16_t len; + struct in6_addr addr; + uint32_t preferred; + uint32_t valid; +} _packed; + +struct dhcpv6_assignment { + struct list_head head; + struct sockaddr_in6 peer; + time_t valid_until; + time_t reconf_sent; + int reconf_cnt; + char *hostname; + uint8_t key[16]; + uint32_t assigned; + uint32_t iaid; + uint8_t mac[6]; + uint8_t length; // length == 128 -> IA_NA, length <= 64 -> IA_PD + bool accept_reconf; + uint8_t clid_len; + uint8_t clid_data[]; +}; + + + +#define dhcpv6_for_each_option(start, end, otype, olen, odata)\ + for (uint8_t *_o = (uint8_t*)(start); _o + 4 <= (end) &&\ + ((otype) = _o[0] << 8 | _o[1]) && ((odata) = (void*)&_o[4]) &&\ + ((olen) = _o[2] << 8 | _o[3]) + (odata) <= (end); \ + _o += 4 + (_o[2] << 8 | _o[3])) + +int dhcpv6_init_ia(struct interface *iface, int socket); +size_t dhcpv6_handle_ia(uint8_t *buf, size_t buflen, struct interface *iface, + const struct sockaddr_in6 *addr, const void *data, const uint8_t *end); +int dhcpv6_ia_init(int dhcpv6_socket); +int setup_dhcpv6_ia_interface(struct interface *iface, bool enable); +void dhcpv6_write_statefile(void); |