11de7b4b8SPedro F. Giffuni /*- 21de7b4b8SPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause 31de7b4b8SPedro F. Giffuni * 49906480aSPeter Wemm * Copyright (c) 1997 Peter Wemm. 59906480aSPeter Wemm * All rights reserved. 69906480aSPeter Wemm * 79906480aSPeter Wemm * Redistribution and use in source and binary forms, with or without 89906480aSPeter Wemm * modification, are permitted provided that the following conditions 99906480aSPeter Wemm * are met: 109906480aSPeter Wemm * 1. Redistributions of source code must retain the above copyright 119906480aSPeter Wemm * notice, this list of conditions and the following disclaimer. 129906480aSPeter Wemm * 2. Redistributions in binary form must reproduce the above copyright 139906480aSPeter Wemm * notice, this list of conditions and the following disclaimer in the 149906480aSPeter Wemm * documentation and/or other materials provided with the distribution. 159906480aSPeter Wemm * 3. All advertising materials mentioning features or use of this software 169906480aSPeter Wemm * must display the following acknowledgement: 179906480aSPeter Wemm * This product includes software developed for the FreeBSD Project 189906480aSPeter Wemm * by Peter Wemm. 199906480aSPeter Wemm * 4. The name of the author may not be used to endorse or promote products 209906480aSPeter Wemm * derived from this software without specific prior written permission. 219906480aSPeter Wemm * 229906480aSPeter Wemm * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 239906480aSPeter Wemm * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 249906480aSPeter Wemm * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 259906480aSPeter Wemm * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 269906480aSPeter Wemm * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 279906480aSPeter Wemm * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 289906480aSPeter Wemm * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 299906480aSPeter Wemm * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 309906480aSPeter Wemm * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 319906480aSPeter Wemm * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 329906480aSPeter Wemm * SUCH DAMAGE. 339906480aSPeter Wemm * 349906480aSPeter Wemm * so there! 359906480aSPeter Wemm */ 369906480aSPeter Wemm 378b222425SRyan Moeller #pragma once 388b222425SRyan Moeller 398b222425SRyan Moeller #include <libifconfig.h> 40982cd5aeSAlexander V. Chernikov #include <stdbool.h> 4131016aa0SGleb Smirnoff #include <net/if_types.h> 428b222425SRyan Moeller 435faf8dcbSSam Leffler #define __constructor __attribute__((constructor)) 449906480aSPeter Wemm 450c2beef7SAlexander V. Chernikov #ifdef WITHOUT_NETLINK 460c2beef7SAlexander V. Chernikov #define __netlink_used __unused 470c2beef7SAlexander V. Chernikov #define __netlink_unused 480c2beef7SAlexander V. Chernikov #else 490c2beef7SAlexander V. Chernikov #define __netlink_used 500c2beef7SAlexander V. Chernikov #define __netlink_unused __unused 510c2beef7SAlexander V. Chernikov #endif 520c2beef7SAlexander V. Chernikov 535faf8dcbSSam Leffler struct afswtch; 545faf8dcbSSam Leffler struct cmd; 5574b42611SAlexander V. Chernikov struct snl_state; 5674b42611SAlexander V. Chernikov struct ifconfig_args; 5774b42611SAlexander V. Chernikov struct ifconfig_context { 5874b42611SAlexander V. Chernikov struct ifconfig_args *args; 5974b42611SAlexander V. Chernikov const struct afswtch *afp; 6074b42611SAlexander V. Chernikov int io_s; /* fd to use for ioctl() */ 6174b42611SAlexander V. Chernikov struct snl_state *io_ss; /* NETLINK_ROUTE socket */ 6285e0016aSAlexander V. Chernikov const char *ifname; /* Current interface name */ 634106282eSAlexander V. Chernikov char _ifname_storage_ioctl[IFNAMSIZ]; 6474b42611SAlexander V. Chernikov }; 654106282eSAlexander V. Chernikov typedef struct ifconfig_context if_ctx; 665faf8dcbSSam Leffler 6774b42611SAlexander V. Chernikov typedef void c_func(if_ctx *ctx, const char *cmd, int arg); 6874b42611SAlexander V. Chernikov typedef void c_func2(if_ctx *ctx, const char *arg1, const char *arg2); 6974b42611SAlexander V. Chernikov typedef void c_func3(if_ctx *ctx, const char *cmd, const char *arg); 705faf8dcbSSam Leffler 715faf8dcbSSam Leffler struct cmd { 725faf8dcbSSam Leffler const char *c_name; 735faf8dcbSSam Leffler int c_parameter; 745faf8dcbSSam Leffler #define NEXTARG 0xffffff /* has following arg */ 755faf8dcbSSam Leffler #define NEXTARG2 0xfffffe /* has 2 following args */ 765faf8dcbSSam Leffler #define OPTARG 0xfffffd /* has optional following arg */ 7742d5cb09SKonstantin Belousov #define SPARAM 0xfffffc /* parameter is string c_sparameter */ 7842d5cb09SKonstantin Belousov const char *c_sparameter; 795faf8dcbSSam Leffler union { 805faf8dcbSSam Leffler c_func *c_func; 815faf8dcbSSam Leffler c_func2 *c_func2; 8242d5cb09SKonstantin Belousov c_func3 *c_func3; 83c508bf7aSStefan Farfeleder } c_u; 842fa02c5fSSam Leffler int c_iscloneop; 855faf8dcbSSam Leffler struct cmd *c_next; 865faf8dcbSSam Leffler }; 875faf8dcbSSam Leffler void cmd_register(struct cmd *); 885faf8dcbSSam Leffler 8974b42611SAlexander V. Chernikov typedef void callback_func(if_ctx *, void *); 9058ac5e5bSSam Leffler void callback_register(callback_func *, void *); 9158ac5e5bSSam Leffler 925faf8dcbSSam Leffler /* 936e3a9d7fSAlexander V. Chernikov * Macros for initializing command handlers. 945faf8dcbSSam Leffler */ 955faf8dcbSSam Leffler 967aecd12dSKonstantin Belousov #define DEF_CMD(name, param, func) { \ 977aecd12dSKonstantin Belousov .c_name = (name), \ 987aecd12dSKonstantin Belousov .c_parameter = (param), \ 997aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1007aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 10142d5cb09SKonstantin Belousov .c_next = NULL, \ 1027aecd12dSKonstantin Belousov } 1037aecd12dSKonstantin Belousov #define DEF_CMD_ARG(name, func) { \ 1047aecd12dSKonstantin Belousov .c_name = (name), \ 1057aecd12dSKonstantin Belousov .c_parameter = NEXTARG, \ 1067aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1077aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 1087aecd12dSKonstantin Belousov .c_next = NULL, \ 1097aecd12dSKonstantin Belousov } 1107aecd12dSKonstantin Belousov #define DEF_CMD_OPTARG(name, func) { \ 1117aecd12dSKonstantin Belousov .c_name = (name), \ 1127aecd12dSKonstantin Belousov .c_parameter = OPTARG, \ 1137aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1147aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 1157aecd12dSKonstantin Belousov .c_next = NULL, \ 1167aecd12dSKonstantin Belousov } 1177aecd12dSKonstantin Belousov #define DEF_CMD_ARG2(name, func) { \ 1187aecd12dSKonstantin Belousov .c_name = (name), \ 1197aecd12dSKonstantin Belousov .c_parameter = NEXTARG2, \ 1207aecd12dSKonstantin Belousov .c_u = { .c_func2 = (func) }, \ 1217aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 1227aecd12dSKonstantin Belousov .c_next = NULL, \ 1237aecd12dSKonstantin Belousov } 12442d5cb09SKonstantin Belousov #define DEF_CMD_SARG(name, sparam, func) { \ 12542d5cb09SKonstantin Belousov .c_name = (name), \ 12642d5cb09SKonstantin Belousov .c_parameter = SPARAM, \ 12742d5cb09SKonstantin Belousov .c_sparameter = (sparam), \ 12842d5cb09SKonstantin Belousov .c_u = { .c_func3 = (func) }, \ 12942d5cb09SKonstantin Belousov .c_iscloneop = 0, \ 13042d5cb09SKonstantin Belousov .c_next = NULL, \ 13142d5cb09SKonstantin Belousov } 1327aecd12dSKonstantin Belousov #define DEF_CLONE_CMD(name, param, func) { \ 1337aecd12dSKonstantin Belousov .c_name = (name), \ 1347aecd12dSKonstantin Belousov .c_parameter = (param), \ 1357aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1367aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1377aecd12dSKonstantin Belousov .c_next = NULL, \ 1387aecd12dSKonstantin Belousov } 1397aecd12dSKonstantin Belousov #define DEF_CLONE_CMD_ARG(name, func) { \ 1407aecd12dSKonstantin Belousov .c_name = (name), \ 1417aecd12dSKonstantin Belousov .c_parameter = NEXTARG, \ 1427aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1437aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1447aecd12dSKonstantin Belousov .c_next = NULL, \ 1457aecd12dSKonstantin Belousov } 1467aecd12dSKonstantin Belousov #define DEF_CLONE_CMD_ARG2(name, func) { \ 1477aecd12dSKonstantin Belousov .c_name = (name), \ 1487aecd12dSKonstantin Belousov .c_parameter = NEXTARG2, \ 1497aecd12dSKonstantin Belousov .c_u = { .c_func2 = (func) }, \ 1507aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1517aecd12dSKonstantin Belousov .c_next = NULL, \ 1527aecd12dSKonstantin Belousov } 1535faf8dcbSSam Leffler 1546e3a9d7fSAlexander V. Chernikov #define ioctl_ctx(ctx, _req, ...) ioctl((ctx)->io_s, _req, ## __VA_ARGS__) 1557fa282e6SAlexander V. Chernikov int ioctl_ctx_ifr(if_ctx *ctx, unsigned long cmd, struct ifreq *ifr); 1566e3a9d7fSAlexander V. Chernikov 157cb8c905aSSam Leffler struct ifaddrs; 1585faf8dcbSSam Leffler struct addrinfo; 1595faf8dcbSSam Leffler 1605faf8dcbSSam Leffler enum { 1614bf44dd7SAlexander V. Chernikov RIDADDR = 0, 1624bf44dd7SAlexander V. Chernikov ADDR = 1, 1634bf44dd7SAlexander V. Chernikov MASK = 2, 1644bf44dd7SAlexander V. Chernikov DSTADDR = 3, 1654bf44dd7SAlexander V. Chernikov #ifdef WITHOUT_NETLINK 1664bf44dd7SAlexander V. Chernikov BRDADDR = 3, 1674bf44dd7SAlexander V. Chernikov #else 1684bf44dd7SAlexander V. Chernikov BRDADDR = 4, 1694bf44dd7SAlexander V. Chernikov #endif 1705faf8dcbSSam Leffler }; 1715faf8dcbSSam Leffler 1724c91a5dfSAlexander V. Chernikov struct snl_parsed_addr; 1734c91a5dfSAlexander V. Chernikov struct snl_parsed_link; 1744c91a5dfSAlexander V. Chernikov typedef struct snl_parsed_link if_link_t; 1754c91a5dfSAlexander V. Chernikov typedef struct snl_parsed_addr if_addr_t; 1764c91a5dfSAlexander V. Chernikov 177a72b7890SAlexander V. Chernikov typedef void af_setvhid_f(int vhid); 1786e3a9d7fSAlexander V. Chernikov typedef void af_status_nl_f(if_ctx *ctx, if_link_t *link, if_addr_t *ifa); 1796e3a9d7fSAlexander V. Chernikov typedef void af_status_f(if_ctx *ctx, const struct ifaddrs *); 1806e3a9d7fSAlexander V. Chernikov typedef void af_other_status_f(if_ctx *ctx); 1816e3a9d7fSAlexander V. Chernikov typedef void af_postproc_f(if_ctx *ctx, int newaddr, int ifflags); 1824bf44dd7SAlexander V. Chernikov typedef int af_exec_f(if_ctx *ctx, unsigned long action, void *data); 1836d204407SAlexander V. Chernikov typedef void af_copyaddr_f(if_ctx *ctx, int to, int from); 184c6f0602fSAlexander V. Chernikov typedef void af_status_tunnel_f(if_ctx *ctx); 185c6f0602fSAlexander V. Chernikov typedef void af_settunnel_f(if_ctx *ctx, struct addrinfo *srcres, struct addrinfo *dstres); 1864c91a5dfSAlexander V. Chernikov 1875faf8dcbSSam Leffler struct afswtch { 1885faf8dcbSSam Leffler const char *af_name; /* as given on cmd line, e.g. "inet" */ 1895faf8dcbSSam Leffler short af_af; /* AF_* */ 19090c4b74cSSam Leffler /* 19190c4b74cSSam Leffler * Status is handled one of two ways; if there is an 19290c4b74cSSam Leffler * address associated with the interface then the 19390c4b74cSSam Leffler * associated address family af_status method is invoked 19490c4b74cSSam Leffler * with the appropriate addressin info. Otherwise, if 19590c4b74cSSam Leffler * all possible info is to be displayed and af_other_status 19690c4b74cSSam Leffler * is defined then it is invoked after all address status 19790c4b74cSSam Leffler * is presented. 19890c4b74cSSam Leffler */ 1994c91a5dfSAlexander V. Chernikov #ifndef WITHOUT_NETLINK 2006e3a9d7fSAlexander V. Chernikov af_status_nl_f *af_status; 2014c91a5dfSAlexander V. Chernikov #else 2026e3a9d7fSAlexander V. Chernikov af_status_f *af_status; 2034c91a5dfSAlexander V. Chernikov #endif 2046e3a9d7fSAlexander V. Chernikov af_other_status_f *af_other_status; 2055faf8dcbSSam Leffler void (*af_getaddr)(const char *, int); 2066d204407SAlexander V. Chernikov af_copyaddr_f *af_copyaddr; /* Copy address between <RID|*>ADDR */ 2075faf8dcbSSam Leffler /* parse prefix method (IPv6) */ 2085faf8dcbSSam Leffler void (*af_getprefix)(const char *, int); 2096e3a9d7fSAlexander V. Chernikov af_postproc_f *af_postproc; 210a72b7890SAlexander V. Chernikov af_setvhid_f *af_setvhid; /* Set CARP vhid for an address */ 2114bf44dd7SAlexander V. Chernikov af_exec_f *af_exec; /* Handler to interact with kernel */ 2125faf8dcbSSam Leffler u_long af_difaddr; /* set dst if address ioctl */ 2135faf8dcbSSam Leffler u_long af_aifaddr; /* set if address ioctl */ 2145faf8dcbSSam Leffler void *af_ridreq; /* */ 2155faf8dcbSSam Leffler void *af_addreq; /* */ 2165faf8dcbSSam Leffler struct afswtch *af_next; 2175faf8dcbSSam Leffler 2185faf8dcbSSam Leffler /* XXX doesn't fit model */ 219c6f0602fSAlexander V. Chernikov af_status_tunnel_f *af_status_tunnel; 220c6f0602fSAlexander V. Chernikov af_settunnel_f *af_settunnel; 2215faf8dcbSSam Leffler }; 2225faf8dcbSSam Leffler void af_register(struct afswtch *); 2234bf44dd7SAlexander V. Chernikov int af_exec_ioctl(if_ctx *ctx, unsigned long action, void *data); 2245faf8dcbSSam Leffler 225982cd5aeSAlexander V. Chernikov struct ifconfig_args { 226982cd5aeSAlexander V. Chernikov bool all; /* Match everything */ 227982cd5aeSAlexander V. Chernikov bool downonly; /* Down-only items */ 228982cd5aeSAlexander V. Chernikov bool uponly; /* Up-only items */ 229982cd5aeSAlexander V. Chernikov bool namesonly; /* Output only names */ 230982cd5aeSAlexander V. Chernikov bool noload; /* Do not load relevant kernel modules */ 231982cd5aeSAlexander V. Chernikov bool supmedia; /* Supported media */ 232982cd5aeSAlexander V. Chernikov bool printkeys; /* Print security keys */ 233d1cd0344SAlexander V. Chernikov bool allfamilies; /* Print all families */ 234cd201c09SMike Karels bool drivername; /* Print driver name */ 235982cd5aeSAlexander V. Chernikov int verbose; /* verbosity level */ 236982cd5aeSAlexander V. Chernikov int argc; 237982cd5aeSAlexander V. Chernikov char **argv; 238a3cb80bcSAlexander V. Chernikov const char *ifname; /* Requested interface name */ 239982cd5aeSAlexander V. Chernikov const char *matchgroup; /* Group name to match */ 240982cd5aeSAlexander V. Chernikov const char *nogroup; /* Group name to exclude */ 241982cd5aeSAlexander V. Chernikov const struct afswtch *afp; /* AF we're operating on */ 2427e49aa86SYan Ka Chiu const char *jail_name; /* Jail name or jail id specified */ 243982cd5aeSAlexander V. Chernikov }; 244982cd5aeSAlexander V. Chernikov 2455faf8dcbSSam Leffler struct option { 2465faf8dcbSSam Leffler const char *opt; 2475faf8dcbSSam Leffler const char *opt_usage; 2485faf8dcbSSam Leffler void (*cb)(const char *arg); 2495faf8dcbSSam Leffler struct option *next; 2505faf8dcbSSam Leffler }; 2515faf8dcbSSam Leffler void opt_register(struct option *); 2525faf8dcbSSam Leffler 2538b222425SRyan Moeller extern ifconfig_handle_t *lifh; 2549906480aSPeter Wemm extern int allmedia; 25547528c67SAndrew Gallatin extern int exit_code; 25644cd85d4SAlexander V. Chernikov extern char *f_inet, *f_inet6, *f_ether, *f_addr; 2579906480aSPeter Wemm 25808992b20SJohn Baldwin void clearifcap(if_ctx *ctx, const char *, int value); 2596e3a9d7fSAlexander V. Chernikov void setifcap(if_ctx *ctx, const char *, int value); 2606e3a9d7fSAlexander V. Chernikov void setifcapnv(if_ctx *ctx, const char *vname, const char *arg); 26197ed1257SBill Paul 2625faf8dcbSSam Leffler void Perror(const char *cmd); 263*c3e94237SGordon Tetlow void print_bits(const char *btype, uint32_t *v, const int v_count, 264*c3e94237SGordon Tetlow const char **names, const int n_count); 2655faf8dcbSSam Leffler void printb(const char *s, unsigned value, const char *bits); 266419d8080SPoul-Henning Kamp 267982cd5aeSAlexander V. Chernikov void ifmaybeload(struct ifconfig_args *args, const char *name); 2685faf8dcbSSam Leffler 269c7cffd65SAlexander V. Chernikov typedef int clone_match_func(const char *); 27074b42611SAlexander V. Chernikov typedef void clone_callback_func(if_ctx *, struct ifreq *); 271c7cffd65SAlexander V. Chernikov void clone_setdefcallback_prefix(const char *, clone_callback_func *); 272c7cffd65SAlexander V. Chernikov void clone_setdefcallback_filter(clone_match_func *, clone_callback_func *); 2738f3591a5SSam Leffler 2740c2beef7SAlexander V. Chernikov void sfp_status(if_ctx *ctx); 275f732123eSAlexander V. Chernikov 276d1cd0344SAlexander V. Chernikov struct sockaddr_dl; 277d1cd0344SAlexander V. Chernikov bool match_ether(const struct sockaddr_dl *sdl); 2784c91a5dfSAlexander V. Chernikov bool match_if_flags(struct ifconfig_args *args, int if_flags); 279bbad5525SAlexander V. Chernikov int ifconfig_ioctl(if_ctx *ctx, int iscreate, const struct afswtch *uafp); 2804c91a5dfSAlexander V. Chernikov bool group_member(const char *ifname, const char *match, const char *nomatch); 281c6f0602fSAlexander V. Chernikov void tunnel_status(if_ctx *ctx); 2824c91a5dfSAlexander V. Chernikov struct afswtch *af_getbyfamily(int af); 2836e3a9d7fSAlexander V. Chernikov void af_other_status(if_ctx *ctx); 28485e0016aSAlexander V. Chernikov void print_ifstatus(if_ctx *ctx); 2857fa282e6SAlexander V. Chernikov void print_metric(if_ctx *ctx); 28631016aa0SGleb Smirnoff ifType convert_iftype(ifType iftype); 2874c91a5dfSAlexander V. Chernikov 2884c91a5dfSAlexander V. Chernikov /* Netlink-related functions */ 2894c91a5dfSAlexander V. Chernikov void list_interfaces_nl(struct ifconfig_args *args); 290bbad5525SAlexander V. Chernikov int ifconfig_nl(if_ctx *ctx, int iscreate, 2914bf44dd7SAlexander V. Chernikov const struct afswtch *uafp); 2924bf44dd7SAlexander V. Chernikov uint32_t if_nametoindex_nl(struct snl_state *ss, const char *ifname); 2934c91a5dfSAlexander V. Chernikov 2948f3591a5SSam Leffler /* 295b66b2c4dSElyes Haouas * XXX expose this so modules that need to know of any pending 2968f3591a5SSam Leffler * operations on ifmedia can avoid cmd line ordering confusion. 2978f3591a5SSam Leffler */ 29885e0016aSAlexander V. Chernikov struct ifmediareq *ifmedia_getstate(if_ctx *ctx); 29908b68b0eSGleb Smirnoff 3003927d0fbSAlexander V. Chernikov void print_vhid(const struct ifaddrs *); 30108b68b0eSGleb Smirnoff 30274b42611SAlexander V. Chernikov void ifcreate_ioctl(if_ctx *ctx, struct ifreq *ifr); 30344cd85d4SAlexander V. Chernikov 30444cd85d4SAlexander V. Chernikov /* Helpers */ 30544cd85d4SAlexander V. Chernikov struct sockaddr_in; 30644cd85d4SAlexander V. Chernikov struct sockaddr_in6; 30744cd85d4SAlexander V. Chernikov struct sockaddr; 30844cd85d4SAlexander V. Chernikov 30944cd85d4SAlexander V. Chernikov static inline struct sockaddr_in6 * 31044cd85d4SAlexander V. Chernikov satosin6(struct sockaddr *sa) 31144cd85d4SAlexander V. Chernikov { 31244cd85d4SAlexander V. Chernikov return ((struct sockaddr_in6 *)(void *)sa); 31344cd85d4SAlexander V. Chernikov } 31444cd85d4SAlexander V. Chernikov 31544cd85d4SAlexander V. Chernikov static inline struct sockaddr_in * 31644cd85d4SAlexander V. Chernikov satosin(struct sockaddr *sa) 31744cd85d4SAlexander V. Chernikov { 31844cd85d4SAlexander V. Chernikov return ((struct sockaddr_in *)(void *)sa); 31944cd85d4SAlexander V. Chernikov } 320a3930cd4SAlexander V. Chernikov 321a3930cd4SAlexander V. Chernikov static inline struct sockaddr_dl * 322a3930cd4SAlexander V. Chernikov satosdl(struct sockaddr *sa) 323a3930cd4SAlexander V. Chernikov { 324a3930cd4SAlexander V. Chernikov return ((struct sockaddr_dl *)(void *)sa); 325a3930cd4SAlexander V. Chernikov } 326a3930cd4SAlexander V. Chernikov 327a3930cd4SAlexander V. Chernikov static inline const struct sockaddr_dl * 328a3930cd4SAlexander V. Chernikov satosdl_c(const struct sockaddr *sa) 329a3930cd4SAlexander V. Chernikov { 330a3930cd4SAlexander V. Chernikov return ((const struct sockaddr_dl *)(const void *)sa); 331a3930cd4SAlexander V. Chernikov } 332