1 /* vi: set sw=4 ts=4: */ 2 /* 3 * Copyright (C) 2011 Denys Vlasenko. 4 * 5 * Licensed under GPLv2, see file LICENSE in this source tree. 6 */ 7 #ifndef UDHCP_D6_COMMON_H 8 #define UDHCP_D6_COMMON_H 1 9 10 #include <netinet/ip6.h> 11 12 PUSH_AND_SET_FUNCTION_VISIBILITY_TO_HIDDEN 13 14 15 /*** DHCPv6 packet ***/ 16 17 /* DHCPv6 protocol. See RFC 3315 */ 18 #define D6_MSG_SOLICIT 1 19 #define D6_MSG_ADVERTISE 2 20 #define D6_MSG_REQUEST 3 21 #define D6_MSG_CONFIRM 4 22 #define D6_MSG_RENEW 5 23 #define D6_MSG_REBIND 6 24 #define D6_MSG_REPLY 7 25 #define D6_MSG_RELEASE 8 26 #define D6_MSG_DECLINE 9 27 #define D6_MSG_RECONFIGURE 10 28 #define D6_MSG_INFORMATION_REQUEST 11 29 #define D6_MSG_RELAY_FORW 12 30 #define D6_MSG_RELAY_REPL 13 31 32 struct d6_packet { 33 union { 34 uint8_t d6_msg_type; 35 uint32_t d6_xid32; 36 } d6_u; 37 uint8_t d6_options[576 - sizeof(struct ip6_hdr) - sizeof(struct udphdr) - 4 38 + CONFIG_UDHCPC_SLACK_FOR_BUGGY_SERVERS]; 39 } PACKED; 40 #define d6_msg_type d6_u.d6_msg_type 41 #define d6_xid32 d6_u.d6_xid32 42 43 struct ip6_udp_d6_packet { 44 struct ip6_hdr ip6; 45 struct udphdr udp; 46 struct d6_packet data; 47 } PACKED; 48 49 struct udp_d6_packet { 50 struct udphdr udp; 51 struct d6_packet data; 52 } PACKED; 53 54 /*** Options ***/ 55 56 struct d6_option { 57 uint8_t code_hi; 58 uint8_t code; 59 uint8_t len_hi; 60 uint8_t len; 61 uint8_t data[1]; 62 } PACKED; 63 64 #define D6_OPT_CLIENTID 1 65 #define D6_OPT_SERVERID 2 66 #define D6_OPT_IA_NA 3 67 #define D6_OPT_IA_TA 4 68 #define D6_OPT_IAADDR 5 69 #define D6_OPT_ORO 6 70 #define D6_OPT_PREFERENCE 7 71 #define D6_OPT_ELAPSED_TIME 8 72 #define D6_OPT_RELAY_MSG 9 73 #define D6_OPT_AUTH 11 74 #define D6_OPT_UNICAST 12 75 #define D6_OPT_STATUS_CODE 13 76 #define D6_OPT_RAPID_COMMIT 14 77 #define D6_OPT_USER_CLASS 15 78 #define D6_OPT_VENDOR_CLASS 16 79 #define D6_OPT_VENDOR_OPTS 17 80 #define D6_OPT_INTERFACE_ID 18 81 #define D6_OPT_RECONF_MSG 19 82 #define D6_OPT_RECONF_ACCEPT 20 83 84 #define D6_OPT_DNS_SERVERS 23 85 #define D6_OPT_DOMAIN_LIST 24 86 87 #define D6_OPT_IA_PD 25 88 #define D6_OPT_IAPREFIX 26 89 90 /* RFC 4704 "The DHCPv6 Client FQDN Option" 91 * uint16 option-code OPTION_CLIENT_FQDN (39) 92 * uint16 option-len 1 + length of domain name 93 * uint8 flags 94 * char[] domain-name partial or fully qualified domain name 95 * 96 * Flags format is |MBZ|N|O|S| 97 * The "S" bit indicates whether the server SHOULD or SHOULD NOT perform 98 * the AAAA RR (FQDN-to-address) DNS updates. A client sets the bit to 99 * 0 to indicate that the server SHOULD NOT perform the updates and 1 to 100 * indicate that the server SHOULD perform the updates. The state of 101 * the bit in the reply from the server indicates the action to be taken 102 * by the server; if it is 1, the server has taken responsibility for 103 * AAAA RR updates for the FQDN. 104 * The "O" bit indicates whether the server has overridden the client's 105 * preference for the "S" bit. A client MUST set this bit to 0. A 106 * server MUST set this bit to 1 if the "S" bit in its reply to the 107 * client does not match the "S" bit received from the client. 108 * The "N" bit indicates whether the server SHOULD NOT perform any DNS 109 * updates. A client sets this bit to 0 to request that the server 110 * SHOULD perform updates (the PTR RR and possibly the AAAA RR based on 111 * the "S" bit) or to 1 to request that the server SHOULD NOT perform 112 * any DNS updates. A server sets the "N" bit to indicate whether the 113 * server SHALL (0) or SHALL NOT (1) perform DNS updates. If the "N" 114 * bit is 1, the "S" bit MUST be 0. 115 * 116 * If a client knows only part of its name, it MAY send a name that is not 117 * fully qualified, indicating that it knows part of the name but does not 118 * necessarily know the zone in which the name is to be embedded. 119 * To send a fully qualified domain name, the Domain Name field is set 120 * to the DNS-encoded domain name including the terminating zero-length 121 * label. To send a partial name, the Domain Name field is set to the 122 * DNS-encoded domain name without the terminating zero-length label. 123 * A client MAY also leave the Domain Name field empty if it desires the 124 * server to provide a name. 125 */ 126 #define D6_OPT_CLIENT_FQDN 39 127 128 #define D6_OPT_TZ_POSIX 41 129 #define D6_OPT_TZ_NAME 42 130 131 #define D6_OPT_BOOT_URL 59 132 #define D6_OPT_BOOT_PARAM 60 133 134 /*** Other shared functions ***/ 135 136 struct client6_data_t { 137 struct d6_option *server_id; 138 struct d6_option *ia_na; 139 struct d6_option *ia_pd; 140 char **env_ptr; 141 unsigned env_idx; 142 /* link-local IPv6 address */ 143 struct in6_addr ll_ip6; 144 } FIX_ALIASING; 145 146 #define client6_data (*(struct client6_data_t*)(&bb_common_bufsiz1[COMMON_BUFSIZE - sizeof(struct client6_data_t)])) 147 148 int FAST_FUNC d6_read_interface( 149 const char *interface, 150 int *ifindex, 151 struct in6_addr *nip6, 152 uint8_t *mac 153 ); 154 155 int FAST_FUNC d6_listen_socket(int port, const char *inf); 156 157 int FAST_FUNC d6_recv_kernel_packet( 158 struct in6_addr *peer_ipv6, 159 struct d6_packet *packet, int fd 160 ); 161 162 int FAST_FUNC d6_send_raw_packet_from_client_data_ifindex( 163 struct d6_packet *d6_pkt, unsigned d6_pkt_size, 164 struct in6_addr *src_ipv6, int source_port, 165 struct in6_addr *dst_ipv6, int dest_port, const uint8_t *dest_arp 166 ); 167 168 int FAST_FUNC d6_send_kernel_packet_from_client_data_ifindex( 169 struct d6_packet *d6_pkt, unsigned d6_pkt_size, 170 struct in6_addr *src_ipv6, int source_port, 171 struct in6_addr *dst_ipv6, int dest_port 172 ); 173 174 #if defined CONFIG_UDHCP_DEBUG && CONFIG_UDHCP_DEBUG >= 2 175 void FAST_FUNC d6_dump_packet(struct d6_packet *packet); 176 #else 177 # define d6_dump_packet(packet) ((void)0) 178 #endif 179 180 181 POP_SAVED_FUNCTION_VISIBILITY 182 183 #endif 184