1 2 /* ******************************************************************** * 3 * ni_funct.h version 0.04 3-7-09 * 4 * * 5 * COPYRIGHT 2008-2009 Michael Robinton <michael@bizsystems.com> * 6 * * 7 * This program is free software; you can redistribute it and/or modify * 8 * it under the terms of either: * 9 * * 10 * a) the GNU General Public License as published by the Free * 11 * Software Foundation; either version 2, or (at your option) any * 12 * later version, or * 13 * * 14 * b) the "Artistic License" which comes with this distribution. * 15 * * 16 * This program is distributed in the hope that it will be useful, * 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of * 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See either * 19 * the GNU General Public License or the Artistic License for more * 20 * details. * 21 * * 22 * You should have received a copy of the Artistic License with this * 23 * distribution, in the file named "Artistic". If not, I'll be glad * 24 * to provide one. * 25 * * 26 * You should also have received a copy of the GNU General Public * 27 * License along with this program in the file named "Copying". If not, * 28 * write to the * 29 * * 30 * Free Software Foundation, Inc. * 31 * 59 Temple Place, Suite 330 * 32 * Boston, MA 02111-1307, USA * 33 * * 34 * or visit their web page on the internet at: * 35 * * 36 * http://www.gnu.org/copyleft/gpl.html. * 37 * ******************************************************************** */ 38 39 #ifndef _NI_FUNC_H 40 #define _NI_FUNC_H 1 41 42 #ifndef _NI_FIXUPS_H 43 #error NEED 'ni_fixups' first 44 #endif 45 46 /* **************************************************** * 47 * checking and printing the MAC address * 48 * **************************************************** */ 49 50 #define NI_PRINT_MAC(__macp) printf("MAC addr %02X:%02X:%02X:%02X:%02X:%02X", \ 51 (u_char)__macp[0],(u_char)__macp[1],(u_char)__macp[2], \ 52 (u_char)__macp[3],(u_char)__macp[4],(u_char)__macp[5]) 53 54 #define NI_MAC_NOT_ZERO(__macp) (((u_int32_t *)(__macp))[0] != 0 || ((u_int16_t *)(__macp))[2] != 0) 55 56 /* **************************************************** * 57 * text table definition * 58 * **************************************************** */ 59 60 typedef struct ni_IFF_table_entry { 61 u_int64_t iff_val; 62 char *iff_nam; 63 } ni_iff_t; 64 65 /* **************************************************** * 66 * print ipV6 address - full length * 67 * **************************************************** */ 68 #ifdef LOCAL_SIZEOF_SOCKADDR_IN6 69 #define NI_PRINT_IPV6(__sin6_addr) \ 70 printf("%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X:%02X%02X", \ 71 (__sin6_addr).s6_addr[0], \ 72 (__sin6_addr).s6_addr[1], \ 73 (__sin6_addr).s6_addr[2], \ 74 (__sin6_addr).s6_addr[3], \ 75 (__sin6_addr).s6_addr[4], \ 76 (__sin6_addr).s6_addr[5], \ 77 (__sin6_addr).s6_addr[6], \ 78 (__sin6_addr).s6_addr[7], \ 79 (__sin6_addr).s6_addr[8], \ 80 (__sin6_addr).s6_addr[9], \ 81 (__sin6_addr).s6_addr[10], \ 82 (__sin6_addr).s6_addr[11], \ 83 (__sin6_addr).s6_addr[12], \ 84 (__sin6_addr).s6_addr[13], \ 85 (__sin6_addr).s6_addr[14], \ 86 (__sin6_addr).s6_addr[15]) 87 #endif 88 89 /* **************************************************** * 90 * free the appropriate mememory for getifaddrs * 91 * **************************************************** */ 92 93 void 94 ni_free_gifa(struct ifaddrs * ifap, int flavor); 95 96 /* **************************************************** * 97 * local multi-platform get_ifaddrs function * 98 * **************************************************** */ 99 100 int 101 ni_getifaddrs(struct ifaddrs **ifap, int flavor); 102 103 /* **************************************************** * 104 * conditionally close and reopen socket * 105 * **************************************************** */ 106 int 107 ni_clos_reopn_dgrm(int fd, u_int af); 108 109 110 /* **************************************************** * 111 * allocate memory for a duplicate of the * 112 * memory chunck at 'memp' of 'size' and * 113 * return a pointer. MUST free(newptr) * 114 * On error returns NULL and sets ENOMEM * 115 * **************************************************** */ 116 117 void * 118 ni_memdup(void * memp, int size); 119 120 /* **************************************************** * 121 * generate a netmask from a prefix length * 122 * **************************************************** */ 123 124 void 125 ni_plen2mask(void * in_addr, int plen, int sizeofaddr); 126 127 /* **************************************************** * 128 * calculate the length of netmask prefix * 129 * **************************************************** */ 130 /* pointer to bytes, size in bytes of address */ 131 132 int 133 ni_prefix(void * ap, int sz); 134 135 /* **************************************************** * 136 * some OS lose scope on the particular device/addr * 137 * handle when certain ioctl's are performed. this * 138 * function refreshs the ifconf chain and positions * 139 * the pointers in the exact same spot with fresh scope * 140 * **************************************************** */ 141 142 struct ni_ifconf_flavor; 143 144 int 145 ni_refresh_ifreq(int fd, struct ifconf * ifc, void ** ifr, void ** lifr, struct ni_ifconf_flavor * nip); 146 147 /* **************************************************** * 148 * define access to various types of fields * 149 * in 'ifreq', 'in6_ifreq', and 'lifreq' * 150 * structures * 151 * **************************************************** */ 152 153 /* ******************************************** * 154 * function to return MAC address if it * 155 * is not present in a DL or LL record * 156 * ******************************************** */ 157 158 unsigned char * 159 ni_fallbackhwaddr(u_int af, void * ifr); 160 161 /* ******************************************** * 162 * the semi-standard version of getifaddrs * 163 * ******************************************** */ 164 165 int 166 nifreq_gifaddrs(struct ifaddrs **ifap, struct ni_ifconf_flavor * nifp); 167 168 /* a sane amount of memory for interface descriptors */ 169 #define NI_IFREQ_MEM_MAX 1048576 170 171 struct nifreq { 172 char ni_ifr_name[IFNAMSIZ]; 173 union { 174 struct sockaddr ifr_saddr; 175 struct sockaddr_in ifr_sin; 176 struct sockaddr_storage ifr_stor; 177 #ifdef LOCAL_SIZEOF_SOCKADDR_IN6 178 struct sockaddr_in6 ifr_sin6; 179 #endif 180 short ifr_short; 181 unsigned short ifr_ushort; 182 int ifr_int; 183 char ifr_char[2]; 184 /* this is really a char * */ 185 caddr_t ifr_cadt_data; 186 unsigned char ifr_uchar[2]; 187 int ifr_iary[2]; 188 unsigned int ifr_uint; 189 u_int32_t ifr_uint32; 190 u_int64_t ifr_uint64; 191 u_int32_t ifr_uiary[2]; 192 #ifdef HAVE_STRUCT_IN6_IFREQ 193 struct in6_addrlifetime ifru_lifetime; 194 struct in6_ifstat ifru_stat; 195 struct icmp6_ifstat ifru_icmp6stat; 196 #endif 197 #ifdef HAVE_STRUCT_LIFREQ 198 char lifreq_pad[NI_LIFREQ_PAD]; 199 #endif 200 } ni_ifru; 201 202 /* convenience definitions */ 203 # 204 #define ni_saddr ni_ifru.ifr_saddr /* any sockaddr */ 205 #define ni_sin ni_ifru.ifr_sin /* any sockaddr_in */ 206 #define ni_stor ni_ifru.ifr_stor /* and sockaddr_storage */ 207 #ifdef LOCAL_SIZEOF_SOCKADDR_IN6 208 # define ni_sin6 ni_ifru.ifr_sin6 /* any sockaddr_in6 */ 209 #endif 210 #define ni_short ni_ifru.ifr_short /* any short */ 211 #define ni_ushort ni_ifru.ifr_ushort /* any unsigned short */ 212 #define ni_int ni_ifru.ifr_int /* any int */ 213 #define ni_char ni_ifru.ifr_char /* any char array */ 214 #define ni_data ni_ifru.ifr_cadt_data /* device specific data pointer */ 215 #define ni_uchar ni_ifru.ifr_uchar /* any unsigned char array - hardware mac */ 216 #define ni_iary ni_ifru.ifr_iary /* any int array */ 217 #define ni_uint ni_ifru.ifr_uint /* any uint */ 218 #define ni_uint32 ni_ifru.ifr_uint32 /* any uint32 */ 219 #define ni_uint64 ni_ifru.ifr_uint64 /* any uint64 */ 220 #define ni_uiary ni_ifru.ifr_uiary /* any uint32 array */ 221 #ifdef HAVE_STRUCT_IN6_IFREQ 222 # define ni_lifetime ni_ifru.ifru_lifetime 223 # define ni_stat ni_ifru.ifru_stat 224 # define ni_icmp6 ni_ifru.ifru_icmp6stat 225 #endif 226 }; 227 228 /* **************************************************** * 229 * standard SIOCget functions * 230 * * 231 * execute supported ioctl's * 232 * where a value is requested, return it * 233 * otherwise it is up to the user to retireve * 234 * information via their pointers * 235 * returns -1 on error, sets errno * 236 * **************************************************** */ 237 238 int32_t 239 ni_get_any(int fd, int cmd, void * ifr); 240 241 /* **************************************************** * 242 * standard SIOCset functions * 243 * * 244 * execute supported ioctl's * 245 * returns -1 on error, sets errno * 246 * * 247 * struct nifreq ifr should be prepared, for * 248 * add/modify of a Linux ipV6 address, the * 249 * PREFIX/CIDR value should be stored at: * 250 * * 251 * ifr->ni_sin6.sin6_port * 252 * * 253 * **************************************************** */ 254 255 int 256 ni_set_any(int fd, int cmd, struct nifreq * ifr); 257 258 #ifdef LOCAL_SIZEOF_SOCKADDR_IN6 259 260 /* ******************************************** * 261 * get scope id from struct scope index * 262 * or KAME bits, correct bits as needed * 263 * ******************************************** */ 264 265 u_int 266 ni_get_scopeid(struct sockaddr_in6 * sin6); 267 268 #endif 269 270 /* ******************************************** * 271 * IPV6_ADDR_xxxx definitions from * 272 * linux kernel include/net/ipv6.h * 273 * these are the bits for the byte in * 274 * /proc/net/if_net6 * 275 * ******************************************** * 276 * 277 * with credits to kernel and USAGI developer team 278 * basic information was taken from "kernel/include/net/ipv6.h" 279 * 280 281 * Addr type 282 * 283 * type - unicast | multicast | anycast 284 * scope - local | site | global 285 * v4 - compat 286 * v4mapped 287 * any 288 * loopback 289 */ 290 291 /* 292 * make sure and include changes to this table in the 293 * _lx_types function in Interfaces.xs 294 */ 295 296 #define IPV6_ADDR_ANY (u_int32_t) 0x0000u 297 #define IPV6_ADDR_UNICAST (u_int32_t) 0x0001u 298 #define IPV6_ADDR_MULTICAST (u_int32_t) 0x0002u 299 #define IPV6_ADDR_ANYCAST (u_int32_t) 0x0004u 300 #define IPV6_ADDR_LOOPBACK (u_int32_t) 0x0010u 301 #define IPV6_ADDR_LINKLOCAL (u_int32_t) 0x0020u 302 #define IPV6_ADDR_SITELOCAL (u_int32_t) 0x0040u 303 #define IPV6_ADDR_COMPATv4 (u_int32_t) 0x0080u 304 #define IPV6_ADDR_SCOPE_MASK (u_int32_t) 0x00f0u 305 #define IPV6_ADDR_MAPPED (u_int32_t) 0x1000u 306 #define IPV6_ADDR_RESERVED (u_int32_t) 0x2000u /* reserved address space */ 307 #define IPV6_ADDR_ULUA (u_int32_t) 0x4000u /* Unique Local Unicast Address */ 308 #define IPV6_ADDR_6TO4 (u_int32_t) 0x00010000u 309 #define IPV6_ADDR_6BONE (u_int32_t) 0x00020000u 310 #define IPV6_ADDR_AGU (u_int32_t) 0x00040000u 311 #define IPV6_ADDR_UNSPECIFIED (u_int32_t) 0x00080000u 312 #define IPV6_ADDR_SOLICITED_NODE (u_int32_t) 0x00100000u 313 #define IPV6_ADDR_ISATAP (u_int32_t) 0x00200000u /* RFC 4214 */ 314 #define IPV6_ADDR_PRODUCTIVE (u_int32_t) 0x00400000u 315 #define IPV6_ADDR_6TO4_MICROSOFT (u_int32_t) 0x00800000u 316 #define IPV6_ADDR_TEREDO (u_int32_t) 0x01000000u /* RFC 4380 */ 317 #define IPV6_ADDR_ORCHID (u_int32_t) 0x02000000u /* RFC 4843 */ 318 #define IPV6_ADDR_NON_ROUTE_DOC (u_int32_t) 0x08000000u /* RFC 3849 */ 319 320 /* **************************************************** * 321 * return size of format table for linux_scope2txt * 322 * **************************************************** */ 323 324 int 325 ni_sizeof_type2txt(); 326 327 /* **************************************************** * 328 * This function maps I<Linux> style scope * 329 * bits to their RFC-2373 equivalent. * 330 * * 331 * scope flags rfc-2373 * 332 * 0 reserved * 333 * 1 node-local (aka loopback, interface-local) * 334 * 2 link-local * 335 * 3 unassigned * 336 * 4 unassigned * 337 * 5 site-local * 338 * 6 unassigned * 339 * 7 unassigned * 340 * 8 organization-local * 341 * 9 unassigned * 342 * A unassigned * 343 * B unassigned * 344 * C unassigned * 345 * D unassigned * 346 * E global scope * 347 * F reserved * 348 * * 349 * Linux rfc-2373 * 350 * 0x0000 0xe GLOBAL * 351 * 0x0010u 0x1 NODELOCAL, LOOPBACK, INTERFACELOCAL * 352 * 0x0020u 0x2 LINKLOCAL * 353 * 0x0040u 0x5 SITELOCAL * 354 * 0x0080u is mapped out of range to 0x10 * 355 * **************************************************** */ 356 357 int 358 ni_lx_type2scope(int lscope); 359 360 /* **************************************************** * 361 * value definitions for above * 362 * **************************************************** */ 363 364 #define RFC2373_GLOBAL 0xeu 365 #define RFC2373_ORGLOCAL 0x8u 366 #define RFC2373_SITELOCAL 0x5u 367 #define RFC2373_LINKLOCAL 0x2u 368 #define RFC2373_NODELOCAL 0x1u 369 #define LINUX_COMPATv4 0x10u 370 371 /* **************************************************** * 372 * print statement for internal linux format flags * 373 * **************************************************** */ 374 375 void 376 ni_linux_scope2txt(u_int32_t flags); 377 378 /* **************************************************** * 379 * returns attribute bits for extended linux scope * 380 * **************************************************** */ 381 382 u_int32_t 383 ni_in6_classify(unsigned char * s6_bytes); 384 385 /* **************************************************** * 386 * support for variants of ifreq * 387 * **************************************************** */ 388 389 /* 390 * IF / WHEN YOU CHANGE THIS STRUCT, 391 * UPDATE IT IN THE SUPPORTED FLAVOR MODULES! 392 * 393 * Currently support flavors: 394 */ 395 396 enum ni_FLAVOR { 397 NI_NULL, 398 NI_IFREQ, 399 NI_LIFREQ, 400 NI_IN6_IFREQ, 401 NI_LINUXPROC 402 }; 403 404 static int 405 developer(void * ifr); 406 407 struct ni_ifconf_flavor { 408 enum ni_FLAVOR ni_type; 409 int siocgifindex; 410 int siocsifaddr; 411 int siocgifaddr; 412 int siocdifaddr; 413 int siocaifaddr; 414 int siocsifdstaddr; 415 int siocgifdstaddr; 416 int siocsifflags; 417 int siocgifflags; 418 int siocsifmtu; 419 int siocgifmtu; 420 int siocsifbrdaddr; 421 int siocgifbrdaddr; 422 int siocsifnetmask; 423 int siocgifnetmask; 424 int siocsifmetric; 425 int siocgifmetric; 426 int ifr_offset; 427 int (*gifaddrs)(struct ifaddrs **ifap, struct ni_ifconf_flavor * nifp); 428 void (*fifaddrs)(struct ifaddrs *ifa); 429 int (*refreshifr)(int fd, struct ifconf * ifc, void ** oifr, void ** olifr, struct ni_ifconf_flavor * nip); 430 void * (*getifreqs)(int fd, void * ifc); 431 int (*developer)(void * whatever); 432 struct ni_ifconf_flavor * ni_ifcf_next; 433 }; 434 435 struct ni_ifconf_flavor * 436 ni_ifcf_get(enum ni_FLAVOR type); 437 438 /* return flavor pointer for NI_IFREQ if flavor is unknown */ 439 struct ni_ifconf_flavor * 440 ni_safe_ifcf_get(enum ni_FLAVOR type); 441 442 void 443 ni_ifcf_register(struct ni_ifconf_flavor * nip); 444 445 struct ni_af_flavor; 446 struct ni_af_flavor { 447 int ni_af_family; 448 int32_t (*af_get_any)(int fd, int cmd, void * ifr); 449 int (*af_getifaddrs)(int fd, struct ifaddrs * thisif, struct nifreq * ifr,...); 450 struct ni_af_flavor * ni_aff_next; 451 }; 452 453 struct ni_af_flavor * 454 ni_af_get(int af); 455 456 void 457 ni_af_register(struct ni_af_flavor * nafp); 458 459 /* ************************************************************ * 460 * Certain broken Solaris headers cause build * 461 * errors with the syntax for constructors. * 462 * i.e. * 463 * void __attribute__((constructor)) * 464 * constructor_function () * 465 * { * 466 * code.... * 467 * }; * 468 * * 469 * line 249: syntax error before or at: ( * 470 * line 251: warning: old-style declaration or incorrect type * 471 * cc: acomp failed [filename.c] * 472 * *** Error code 2 * 473 * make: Fatal error: Command failed for target 'filename.o' * 474 * * 475 * The various constructors are declared here and called * 476 * during module load as a work-around to this problem * 477 * ************************************************************ */ 478 479 void ni_ifreq_ctor(); 480 void ni_in6_ifreq_ctor(); 481 void ni_lifreq_ctor(); 482 void ni_linuxproc_ctor(); 483 484 /* **************************************************** * 485 * developer support, not for production * 486 * **************************************************** */ 487 488 int 489 ni_developer(enum ni_FLAVOR type); 490 491 void 492 ni_getifaddrs_dump(int flavor, struct ifaddrs * ifap); 493 494 #endif 495