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 * 367f3dea24SPeter Wemm * $FreeBSD$ 379906480aSPeter Wemm */ 389906480aSPeter Wemm 398b222425SRyan Moeller #pragma once 408b222425SRyan Moeller 418b222425SRyan Moeller #include <libifconfig.h> 42982cd5aeSAlexander V. Chernikov #include <stdbool.h> 438b222425SRyan Moeller 445faf8dcbSSam Leffler #define __constructor __attribute__((constructor)) 459906480aSPeter Wemm 465faf8dcbSSam Leffler struct afswtch; 475faf8dcbSSam Leffler struct cmd; 485faf8dcbSSam Leffler 495faf8dcbSSam Leffler typedef void c_func(const char *cmd, int arg, int s, const struct afswtch *afp); 507541a95aSKonstantin Belousov typedef void c_func2(const char *arg1, const char *arg2, int s, 517541a95aSKonstantin Belousov const struct afswtch *afp); 5242d5cb09SKonstantin Belousov typedef void c_func3(const char *cmd, const char *arg, int s, 5342d5cb09SKonstantin Belousov const struct afswtch *afp); 545faf8dcbSSam Leffler 555faf8dcbSSam Leffler struct cmd { 565faf8dcbSSam Leffler const char *c_name; 575faf8dcbSSam Leffler int c_parameter; 585faf8dcbSSam Leffler #define NEXTARG 0xffffff /* has following arg */ 595faf8dcbSSam Leffler #define NEXTARG2 0xfffffe /* has 2 following args */ 605faf8dcbSSam Leffler #define OPTARG 0xfffffd /* has optional following arg */ 6142d5cb09SKonstantin Belousov #define SPARAM 0xfffffc /* parameter is string c_sparameter */ 6242d5cb09SKonstantin Belousov const char *c_sparameter; 635faf8dcbSSam Leffler union { 645faf8dcbSSam Leffler c_func *c_func; 655faf8dcbSSam Leffler c_func2 *c_func2; 6642d5cb09SKonstantin Belousov c_func3 *c_func3; 67c508bf7aSStefan Farfeleder } c_u; 682fa02c5fSSam Leffler int c_iscloneop; 695faf8dcbSSam Leffler struct cmd *c_next; 705faf8dcbSSam Leffler }; 715faf8dcbSSam Leffler void cmd_register(struct cmd *); 725faf8dcbSSam Leffler 7358ac5e5bSSam Leffler typedef void callback_func(int s, void *); 7458ac5e5bSSam Leffler void callback_register(callback_func *, void *); 7558ac5e5bSSam Leffler 765faf8dcbSSam Leffler /* 775faf8dcbSSam Leffler * Macros for declaring command functions and initializing entries. 785faf8dcbSSam Leffler */ 795faf8dcbSSam Leffler #define DECL_CMD_FUNC(name, cmd, arg) \ 805faf8dcbSSam Leffler void name(const char *cmd, int arg, int s, const struct afswtch *afp) 815faf8dcbSSam Leffler #define DECL_CMD_FUNC2(name, arg1, arg2) \ 827541a95aSKonstantin Belousov void name(const char *arg1, const char *arg2, int s, \ 837541a95aSKonstantin Belousov const struct afswtch *afp) 845faf8dcbSSam Leffler 857aecd12dSKonstantin Belousov #define DEF_CMD(name, param, func) { \ 867aecd12dSKonstantin Belousov .c_name = (name), \ 877aecd12dSKonstantin Belousov .c_parameter = (param), \ 887aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 897aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 9042d5cb09SKonstantin Belousov .c_next = NULL, \ 917aecd12dSKonstantin Belousov } 927aecd12dSKonstantin Belousov #define DEF_CMD_ARG(name, func) { \ 937aecd12dSKonstantin Belousov .c_name = (name), \ 947aecd12dSKonstantin Belousov .c_parameter = NEXTARG, \ 957aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 967aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 977aecd12dSKonstantin Belousov .c_next = NULL, \ 987aecd12dSKonstantin Belousov } 997aecd12dSKonstantin Belousov #define DEF_CMD_OPTARG(name, func) { \ 1007aecd12dSKonstantin Belousov .c_name = (name), \ 1017aecd12dSKonstantin Belousov .c_parameter = OPTARG, \ 1027aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1037aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 1047aecd12dSKonstantin Belousov .c_next = NULL, \ 1057aecd12dSKonstantin Belousov } 1067aecd12dSKonstantin Belousov #define DEF_CMD_ARG2(name, func) { \ 1077aecd12dSKonstantin Belousov .c_name = (name), \ 1087aecd12dSKonstantin Belousov .c_parameter = NEXTARG2, \ 1097aecd12dSKonstantin Belousov .c_u = { .c_func2 = (func) }, \ 1107aecd12dSKonstantin Belousov .c_iscloneop = 0, \ 1117aecd12dSKonstantin Belousov .c_next = NULL, \ 1127aecd12dSKonstantin Belousov } 11342d5cb09SKonstantin Belousov #define DEF_CMD_SARG(name, sparam, func) { \ 11442d5cb09SKonstantin Belousov .c_name = (name), \ 11542d5cb09SKonstantin Belousov .c_parameter = SPARAM, \ 11642d5cb09SKonstantin Belousov .c_sparameter = (sparam), \ 11742d5cb09SKonstantin Belousov .c_u = { .c_func3 = (func) }, \ 11842d5cb09SKonstantin Belousov .c_iscloneop = 0, \ 11942d5cb09SKonstantin Belousov .c_next = NULL, \ 12042d5cb09SKonstantin Belousov } 1217aecd12dSKonstantin Belousov #define DEF_CLONE_CMD(name, param, func) { \ 1227aecd12dSKonstantin Belousov .c_name = (name), \ 1237aecd12dSKonstantin Belousov .c_parameter = (param), \ 1247aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1257aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1267aecd12dSKonstantin Belousov .c_next = NULL, \ 1277aecd12dSKonstantin Belousov } 1287aecd12dSKonstantin Belousov #define DEF_CLONE_CMD_ARG(name, func) { \ 1297aecd12dSKonstantin Belousov .c_name = (name), \ 1307aecd12dSKonstantin Belousov .c_parameter = NEXTARG, \ 1317aecd12dSKonstantin Belousov .c_u = { .c_func = (func) }, \ 1327aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1337aecd12dSKonstantin Belousov .c_next = NULL, \ 1347aecd12dSKonstantin Belousov } 1357aecd12dSKonstantin Belousov #define DEF_CLONE_CMD_ARG2(name, func) { \ 1367aecd12dSKonstantin Belousov .c_name = (name), \ 1377aecd12dSKonstantin Belousov .c_parameter = NEXTARG2, \ 1387aecd12dSKonstantin Belousov .c_u = { .c_func2 = (func) }, \ 1397aecd12dSKonstantin Belousov .c_iscloneop = 1, \ 1407aecd12dSKonstantin Belousov .c_next = NULL, \ 1417aecd12dSKonstantin Belousov } 1425faf8dcbSSam Leffler 143cb8c905aSSam Leffler struct ifaddrs; 1445faf8dcbSSam Leffler struct addrinfo; 1455faf8dcbSSam Leffler 1465faf8dcbSSam Leffler enum { 1475faf8dcbSSam Leffler RIDADDR, 1485faf8dcbSSam Leffler ADDR, 1495faf8dcbSSam Leffler MASK, 1505faf8dcbSSam Leffler DSTADDR, 1515faf8dcbSSam Leffler }; 1525faf8dcbSSam Leffler 153*4c91a5dfSAlexander V. Chernikov struct snl_state; 154*4c91a5dfSAlexander V. Chernikov struct snl_parsed_addr; 155*4c91a5dfSAlexander V. Chernikov struct snl_parsed_link; 156*4c91a5dfSAlexander V. Chernikov typedef struct snl_parsed_link if_link_t; 157*4c91a5dfSAlexander V. Chernikov typedef struct snl_parsed_addr if_addr_t; 158*4c91a5dfSAlexander V. Chernikov struct ifconfig_args; 159*4c91a5dfSAlexander V. Chernikov struct io_handler { 160*4c91a5dfSAlexander V. Chernikov int s; /* socket to use for ioctls */ 161*4c91a5dfSAlexander V. Chernikov struct snl_state *ss; /* NETLINK_ROUTE snl(3) socket */ 162*4c91a5dfSAlexander V. Chernikov }; 163*4c91a5dfSAlexander V. Chernikov 164*4c91a5dfSAlexander V. Chernikov typedef void af_status_nl_f(struct ifconfig_args *args, struct io_handler *h, 165*4c91a5dfSAlexander V. Chernikov if_link_t *link, if_addr_t *ifa); 166*4c91a5dfSAlexander V. Chernikov 1675faf8dcbSSam Leffler struct afswtch { 1685faf8dcbSSam Leffler const char *af_name; /* as given on cmd line, e.g. "inet" */ 1695faf8dcbSSam Leffler short af_af; /* AF_* */ 17090c4b74cSSam Leffler /* 17190c4b74cSSam Leffler * Status is handled one of two ways; if there is an 17290c4b74cSSam Leffler * address associated with the interface then the 17390c4b74cSSam Leffler * associated address family af_status method is invoked 17490c4b74cSSam Leffler * with the appropriate addressin info. Otherwise, if 17590c4b74cSSam Leffler * all possible info is to be displayed and af_other_status 17690c4b74cSSam Leffler * is defined then it is invoked after all address status 17790c4b74cSSam Leffler * is presented. 17890c4b74cSSam Leffler */ 179*4c91a5dfSAlexander V. Chernikov #ifndef WITHOUT_NETLINK 180*4c91a5dfSAlexander V. Chernikov af_status_nl_f *af_status_nl; 181*4c91a5dfSAlexander V. Chernikov #else 182cb8c905aSSam Leffler void (*af_status)(int, const struct ifaddrs *); 183*4c91a5dfSAlexander V. Chernikov #endif 18490c4b74cSSam Leffler void (*af_other_status)(int); 1855faf8dcbSSam Leffler /* parse address method */ 1865faf8dcbSSam Leffler void (*af_getaddr)(const char *, int); 1875faf8dcbSSam Leffler /* parse prefix method (IPv6) */ 1885faf8dcbSSam Leffler void (*af_getprefix)(const char *, int); 189d8237b95SMike Karels void (*af_postproc)(int s, const struct afswtch *, 190d8237b95SMike Karels int newaddr, int ifflags); 1915faf8dcbSSam Leffler u_long af_difaddr; /* set dst if address ioctl */ 1925faf8dcbSSam Leffler u_long af_aifaddr; /* set if address ioctl */ 1935faf8dcbSSam Leffler void *af_ridreq; /* */ 1945faf8dcbSSam Leffler void *af_addreq; /* */ 1955faf8dcbSSam Leffler struct afswtch *af_next; 1965faf8dcbSSam Leffler 1975faf8dcbSSam Leffler /* XXX doesn't fit model */ 1985faf8dcbSSam Leffler void (*af_status_tunnel)(int); 1995faf8dcbSSam Leffler void (*af_settunnel)(int s, struct addrinfo *srcres, 2005faf8dcbSSam Leffler struct addrinfo *dstres); 2015faf8dcbSSam Leffler }; 2025faf8dcbSSam Leffler void af_register(struct afswtch *); 2035faf8dcbSSam Leffler 204982cd5aeSAlexander V. Chernikov struct ifconfig_args { 205982cd5aeSAlexander V. Chernikov bool all; /* Match everything */ 206982cd5aeSAlexander V. Chernikov bool downonly; /* Down-only items */ 207982cd5aeSAlexander V. Chernikov bool uponly; /* Up-only items */ 208982cd5aeSAlexander V. Chernikov bool namesonly; /* Output only names */ 209982cd5aeSAlexander V. Chernikov bool noload; /* Do not load relevant kernel modules */ 210982cd5aeSAlexander V. Chernikov bool supmedia; /* Supported media */ 211982cd5aeSAlexander V. Chernikov bool printkeys; /* Print security keys */ 212d1cd0344SAlexander V. Chernikov bool allfamilies; /* Print all families */ 213982cd5aeSAlexander V. Chernikov int verbose; /* verbosity level */ 214982cd5aeSAlexander V. Chernikov int argc; 215982cd5aeSAlexander V. Chernikov char **argv; 216a3cb80bcSAlexander V. Chernikov const char *ifname; /* Requested interface name */ 217982cd5aeSAlexander V. Chernikov const char *matchgroup; /* Group name to match */ 218982cd5aeSAlexander V. Chernikov const char *nogroup; /* Group name to exclude */ 219982cd5aeSAlexander V. Chernikov const struct afswtch *afp; /* AF we're operating on */ 220982cd5aeSAlexander V. Chernikov }; 221982cd5aeSAlexander V. Chernikov 2225faf8dcbSSam Leffler struct option { 2235faf8dcbSSam Leffler const char *opt; 2245faf8dcbSSam Leffler const char *opt_usage; 2255faf8dcbSSam Leffler void (*cb)(const char *arg); 2265faf8dcbSSam Leffler struct option *next; 2275faf8dcbSSam Leffler }; 2285faf8dcbSSam Leffler void opt_register(struct option *); 2295faf8dcbSSam Leffler 2308b222425SRyan Moeller extern ifconfig_handle_t *lifh; 2315faf8dcbSSam Leffler extern struct ifreq ifr; 232a4fa9864SBrooks Davis extern char name[IFNAMSIZ]; /* name of interface */ 2339906480aSPeter Wemm extern int allmedia; 234b7eb47e2SRobert Watson extern int printkeys; 2355faf8dcbSSam Leffler extern int newaddr; 2365faf8dcbSSam Leffler extern int verbose; 2376fe2e176SKristof Provost extern int printifname; 23847528c67SAndrew Gallatin extern int exit_code; 239982cd5aeSAlexander V. Chernikov extern struct ifconfig_args args; 2409906480aSPeter Wemm 2415faf8dcbSSam Leffler void setifcap(const char *, int value, int s, const struct afswtch *); 2426ca418e4SKonstantin Belousov void setifcapnv(const char *vname, const char *arg, int s, 2436ca418e4SKonstantin Belousov const struct afswtch *afp); 24497ed1257SBill Paul 2455faf8dcbSSam Leffler void Perror(const char *cmd); 2465faf8dcbSSam Leffler void printb(const char *s, unsigned value, const char *bits); 247419d8080SPoul-Henning Kamp 248982cd5aeSAlexander V. Chernikov void ifmaybeload(struct ifconfig_args *args, const char *name); 2495faf8dcbSSam Leffler 250c7cffd65SAlexander V. Chernikov typedef int clone_match_func(const char *); 251db82353dSSam Leffler typedef void clone_callback_func(int, struct ifreq *); 252c7cffd65SAlexander V. Chernikov void clone_setdefcallback_prefix(const char *, clone_callback_func *); 253c7cffd65SAlexander V. Chernikov void clone_setdefcallback_filter(clone_match_func *, clone_callback_func *); 2548f3591a5SSam Leffler 255f732123eSAlexander V. Chernikov void sfp_status(int s, struct ifreq *ifr, int verbose); 256f732123eSAlexander V. Chernikov 257d1cd0344SAlexander V. Chernikov struct sockaddr_dl; 258d1cd0344SAlexander V. Chernikov bool match_ether(const struct sockaddr_dl *sdl); 259*4c91a5dfSAlexander V. Chernikov bool match_if_flags(struct ifconfig_args *args, int if_flags); 260*4c91a5dfSAlexander V. Chernikov int ifconfig(int argc, char *const *argv, int iscreate, const struct afswtch *uafp); 261*4c91a5dfSAlexander V. Chernikov bool group_member(const char *ifname, const char *match, const char *nomatch); 262*4c91a5dfSAlexander V. Chernikov void print_ifcap(struct ifconfig_args *args, int s); 263*4c91a5dfSAlexander V. Chernikov void tunnel_status(int s); 264*4c91a5dfSAlexander V. Chernikov struct afswtch *af_getbyfamily(int af); 265*4c91a5dfSAlexander V. Chernikov void af_other_status(int s); 266*4c91a5dfSAlexander V. Chernikov void print_ifstatus(int s); 267*4c91a5dfSAlexander V. Chernikov void print_metric(int s); 268*4c91a5dfSAlexander V. Chernikov 269*4c91a5dfSAlexander V. Chernikov /* Netlink-related functions */ 270*4c91a5dfSAlexander V. Chernikov void list_interfaces_nl(struct ifconfig_args *args); 271*4c91a5dfSAlexander V. Chernikov 2728f3591a5SSam Leffler /* 2738f3591a5SSam Leffler * XXX expose this so modules that neeed to know of any pending 2748f3591a5SSam Leffler * operations on ifmedia can avoid cmd line ordering confusion. 2758f3591a5SSam Leffler */ 2762803fa47SRyan Moeller struct ifmediareq *ifmedia_getstate(void); 27708b68b0eSGleb Smirnoff 27808b68b0eSGleb Smirnoff void print_vhid(const struct ifaddrs *, const char *); 27908b68b0eSGleb Smirnoff 28005952067SHans Petter Selasky void ioctl_ifcreate(int s, struct ifreq *); 281