1 /*- 2 * SPDX-License-Identifier: BSD-4-Clause 3 * 4 * Copyright (c) 1997 Peter Wemm. 5 * All rights reserved. 6 * 7 * Redistribution and use in source and binary forms, with or without 8 * modification, are permitted provided that the following conditions 9 * are met: 10 * 1. Redistributions of source code must retain the above copyright 11 * notice, this list of conditions and the following disclaimer. 12 * 2. Redistributions in binary form must reproduce the above copyright 13 * notice, this list of conditions and the following disclaimer in the 14 * documentation and/or other materials provided with the distribution. 15 * 3. All advertising materials mentioning features or use of this software 16 * must display the following acknowledgement: 17 * This product includes software developed for the FreeBSD Project 18 * by Peter Wemm. 19 * 4. The name of the author may not be used to endorse or promote products 20 * derived from this software without specific prior written permission. 21 * 22 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 23 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 24 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 25 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 26 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, 27 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 28 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 29 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, 30 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 31 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 32 * SUCH DAMAGE. 33 * 34 * so there! 35 * 36 * $FreeBSD$ 37 */ 38 39 #pragma once 40 41 #include <libifconfig.h> 42 #include <stdbool.h> 43 44 #define __constructor __attribute__((constructor)) 45 46 struct afswtch; 47 struct cmd; 48 struct ifconfig_context; 49 50 typedef void c_func(const struct ifconfig_context *ctx, const char *cmd, int arg); 51 typedef void c_func2(const struct ifconfig_context *ctx, const char *arg1, 52 const char *arg2); 53 typedef void c_func3(const struct ifconfig_context *ctx, const char *cmd, 54 const char *arg); 55 56 struct cmd { 57 const char *c_name; 58 int c_parameter; 59 #define NEXTARG 0xffffff /* has following arg */ 60 #define NEXTARG2 0xfffffe /* has 2 following args */ 61 #define OPTARG 0xfffffd /* has optional following arg */ 62 #define SPARAM 0xfffffc /* parameter is string c_sparameter */ 63 const char *c_sparameter; 64 union { 65 c_func *c_func; 66 c_func2 *c_func2; 67 c_func3 *c_func3; 68 } c_u; 69 int c_iscloneop; 70 struct cmd *c_next; 71 }; 72 void cmd_register(struct cmd *); 73 74 typedef void callback_func(int s, void *); 75 void callback_register(callback_func *, void *); 76 77 /* 78 * Macros for initializing command handlers. 79 */ 80 81 #define DEF_CMD(name, param, func) { \ 82 .c_name = (name), \ 83 .c_parameter = (param), \ 84 .c_u = { .c_func = (func) }, \ 85 .c_iscloneop = 0, \ 86 .c_next = NULL, \ 87 } 88 #define DEF_CMD_ARG(name, func) { \ 89 .c_name = (name), \ 90 .c_parameter = NEXTARG, \ 91 .c_u = { .c_func = (func) }, \ 92 .c_iscloneop = 0, \ 93 .c_next = NULL, \ 94 } 95 #define DEF_CMD_OPTARG(name, func) { \ 96 .c_name = (name), \ 97 .c_parameter = OPTARG, \ 98 .c_u = { .c_func = (func) }, \ 99 .c_iscloneop = 0, \ 100 .c_next = NULL, \ 101 } 102 #define DEF_CMD_ARG2(name, func) { \ 103 .c_name = (name), \ 104 .c_parameter = NEXTARG2, \ 105 .c_u = { .c_func2 = (func) }, \ 106 .c_iscloneop = 0, \ 107 .c_next = NULL, \ 108 } 109 #define DEF_CMD_SARG(name, sparam, func) { \ 110 .c_name = (name), \ 111 .c_parameter = SPARAM, \ 112 .c_sparameter = (sparam), \ 113 .c_u = { .c_func3 = (func) }, \ 114 .c_iscloneop = 0, \ 115 .c_next = NULL, \ 116 } 117 #define DEF_CLONE_CMD(name, param, func) { \ 118 .c_name = (name), \ 119 .c_parameter = (param), \ 120 .c_u = { .c_func = (func) }, \ 121 .c_iscloneop = 1, \ 122 .c_next = NULL, \ 123 } 124 #define DEF_CLONE_CMD_ARG(name, func) { \ 125 .c_name = (name), \ 126 .c_parameter = NEXTARG, \ 127 .c_u = { .c_func = (func) }, \ 128 .c_iscloneop = 1, \ 129 .c_next = NULL, \ 130 } 131 #define DEF_CLONE_CMD_ARG2(name, func) { \ 132 .c_name = (name), \ 133 .c_parameter = NEXTARG2, \ 134 .c_u = { .c_func2 = (func) }, \ 135 .c_iscloneop = 1, \ 136 .c_next = NULL, \ 137 } 138 139 struct snl_state; 140 struct ifconfig_args; 141 struct ifconfig_context { 142 struct ifconfig_args *args; 143 const struct afswtch *afp; 144 int io_s; /* fd to use for ioctl() */ 145 struct snl_state *io_ss; /* NETLINK_ROUTE socket */ 146 }; 147 typedef const struct ifconfig_context if_ctx; 148 149 #define ioctl_ctx(ctx, _req, ...) ioctl((ctx)->io_s, _req, ## __VA_ARGS__) 150 151 struct ifaddrs; 152 struct addrinfo; 153 154 enum { 155 RIDADDR, 156 ADDR, 157 MASK, 158 DSTADDR, 159 }; 160 161 struct snl_parsed_addr; 162 struct snl_parsed_link; 163 typedef struct snl_parsed_link if_link_t; 164 typedef struct snl_parsed_addr if_addr_t; 165 166 typedef void af_setvhid_f(int vhid); 167 typedef void af_status_nl_f(if_ctx *ctx, if_link_t *link, if_addr_t *ifa); 168 typedef void af_status_f(if_ctx *ctx, const struct ifaddrs *); 169 typedef void af_other_status_f(if_ctx *ctx); 170 typedef void af_postproc_f(if_ctx *ctx, int newaddr, int ifflags); 171 172 struct afswtch { 173 const char *af_name; /* as given on cmd line, e.g. "inet" */ 174 short af_af; /* AF_* */ 175 /* 176 * Status is handled one of two ways; if there is an 177 * address associated with the interface then the 178 * associated address family af_status method is invoked 179 * with the appropriate addressin info. Otherwise, if 180 * all possible info is to be displayed and af_other_status 181 * is defined then it is invoked after all address status 182 * is presented. 183 */ 184 #ifndef WITHOUT_NETLINK 185 af_status_nl_f *af_status; 186 #else 187 af_status_f *af_status; 188 #endif 189 af_other_status_f *af_other_status; 190 void (*af_getaddr)(const char *, int); 191 /* parse prefix method (IPv6) */ 192 void (*af_getprefix)(const char *, int); 193 af_postproc_f *af_postproc; 194 af_setvhid_f *af_setvhid; /* Set CARP vhid for an address */ 195 u_long af_difaddr; /* set dst if address ioctl */ 196 u_long af_aifaddr; /* set if address ioctl */ 197 void *af_ridreq; /* */ 198 void *af_addreq; /* */ 199 struct afswtch *af_next; 200 201 /* XXX doesn't fit model */ 202 void (*af_status_tunnel)(int); 203 void (*af_settunnel)(int s, struct addrinfo *srcres, 204 struct addrinfo *dstres); 205 }; 206 void af_register(struct afswtch *); 207 208 struct ifconfig_args { 209 bool all; /* Match everything */ 210 bool downonly; /* Down-only items */ 211 bool uponly; /* Up-only items */ 212 bool namesonly; /* Output only names */ 213 bool noload; /* Do not load relevant kernel modules */ 214 bool supmedia; /* Supported media */ 215 bool printkeys; /* Print security keys */ 216 bool allfamilies; /* Print all families */ 217 int verbose; /* verbosity level */ 218 int argc; 219 char **argv; 220 const char *ifname; /* Requested interface name */ 221 const char *matchgroup; /* Group name to match */ 222 const char *nogroup; /* Group name to exclude */ 223 const struct afswtch *afp; /* AF we're operating on */ 224 const char *jail_name; /* Jail name or jail id specified */ 225 }; 226 227 struct option { 228 const char *opt; 229 const char *opt_usage; 230 void (*cb)(const char *arg); 231 struct option *next; 232 }; 233 void opt_register(struct option *); 234 235 extern ifconfig_handle_t *lifh; 236 extern struct ifreq ifr; 237 extern char name[IFNAMSIZ]; /* name of interface */ 238 extern int allmedia; 239 extern int printkeys; 240 extern int newaddr; 241 extern int verbose; 242 extern int printifname; 243 extern int exit_code; 244 extern struct ifconfig_args global_args; 245 extern char *f_inet, *f_inet6, *f_ether, *f_addr; 246 247 void setifcap(if_ctx *ctx, const char *, int value); 248 void setifcapnv(if_ctx *ctx, const char *vname, const char *arg); 249 250 void Perror(const char *cmd); 251 void printb(const char *s, unsigned value, const char *bits); 252 253 void ifmaybeload(struct ifconfig_args *args, const char *name); 254 255 typedef int clone_match_func(const char *); 256 typedef void clone_callback_func(int, struct ifreq *); 257 void clone_setdefcallback_prefix(const char *, clone_callback_func *); 258 void clone_setdefcallback_filter(clone_match_func *, clone_callback_func *); 259 260 void sfp_status(int s, struct ifreq *ifr, int verbose); 261 262 struct sockaddr_dl; 263 bool match_ether(const struct sockaddr_dl *sdl); 264 bool match_if_flags(struct ifconfig_args *args, int if_flags); 265 int ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp); 266 bool group_member(const char *ifname, const char *match, const char *nomatch); 267 void print_ifcap(struct ifconfig_args *args, int s); 268 void tunnel_status(int s); 269 struct afswtch *af_getbyfamily(int af); 270 void af_other_status(if_ctx *ctx); 271 void print_ifstatus(int s); 272 void print_metric(int s); 273 274 /* Netlink-related functions */ 275 void list_interfaces_nl(struct ifconfig_args *args); 276 277 /* 278 * XXX expose this so modules that neeed to know of any pending 279 * operations on ifmedia can avoid cmd line ordering confusion. 280 */ 281 struct ifmediareq *ifmedia_getstate(void); 282 283 void print_vhid(const struct ifaddrs *, const char *); 284 285 void ioctl_ifcreate(int s, struct ifreq *); 286 287 /* Helpers */ 288 struct sockaddr_in; 289 struct sockaddr_in6; 290 struct sockaddr; 291 292 static inline struct sockaddr_in6 * 293 satosin6(struct sockaddr *sa) 294 { 295 return ((struct sockaddr_in6 *)(void *)sa); 296 } 297 298 static inline struct sockaddr_in * 299 satosin(struct sockaddr *sa) 300 { 301 return ((struct sockaddr_in *)(void *)sa); 302 } 303