1 1.9 thorpej /* $NetBSD: ether.c,v 1.9 2020/06/07 06:02:58 thorpej Exp $ */ 2 1.1 msaitoh 3 1.1 msaitoh /* 4 1.1 msaitoh * Copyright (c) 1983, 1993 5 1.1 msaitoh * The Regents of the University of California. All rights reserved. 6 1.1 msaitoh * 7 1.1 msaitoh * Redistribution and use in source and binary forms, with or without 8 1.1 msaitoh * modification, are permitted provided that the following conditions 9 1.1 msaitoh * are met: 10 1.1 msaitoh * 1. Redistributions of source code must retain the above copyright 11 1.1 msaitoh * notice, this list of conditions and the following disclaimer. 12 1.1 msaitoh * 2. Redistributions in binary form must reproduce the above copyright 13 1.1 msaitoh * notice, this list of conditions and the following disclaimer in the 14 1.1 msaitoh * documentation and/or other materials provided with the distribution. 15 1.1 msaitoh * 3. Neither the name of the University nor the names of its contributors 16 1.1 msaitoh * may be used to endorse or promote products derived from this software 17 1.1 msaitoh * without specific prior written permission. 18 1.1 msaitoh * 19 1.1 msaitoh * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND 20 1.1 msaitoh * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 21 1.1 msaitoh * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 22 1.1 msaitoh * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE 23 1.1 msaitoh * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 24 1.1 msaitoh * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 25 1.1 msaitoh * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 26 1.1 msaitoh * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 27 1.1 msaitoh * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 28 1.1 msaitoh * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 29 1.1 msaitoh * SUCH DAMAGE. 30 1.1 msaitoh */ 31 1.1 msaitoh 32 1.1 msaitoh #include <sys/cdefs.h> 33 1.1 msaitoh #ifndef lint 34 1.9 thorpej __RCSID("$NetBSD: ether.c,v 1.9 2020/06/07 06:02:58 thorpej Exp $"); 35 1.1 msaitoh #endif /* not lint */ 36 1.1 msaitoh 37 1.7 msaitoh #include <sys/param.h> 38 1.7 msaitoh #include <sys/ioctl.h> 39 1.1 msaitoh 40 1.7 msaitoh #include <net/if.h> 41 1.1 msaitoh #include <net/if_ether.h> 42 1.1 msaitoh 43 1.3 msaitoh #include <assert.h> 44 1.1 msaitoh #include <ctype.h> 45 1.1 msaitoh #include <err.h> 46 1.1 msaitoh #include <errno.h> 47 1.1 msaitoh #include <string.h> 48 1.1 msaitoh #include <stdlib.h> 49 1.1 msaitoh #include <stdio.h> 50 1.1 msaitoh #include <util.h> 51 1.1 msaitoh 52 1.1 msaitoh #include "env.h" 53 1.1 msaitoh #include "parse.h" 54 1.1 msaitoh #include "extern.h" 55 1.1 msaitoh #include "prog_ops.h" 56 1.1 msaitoh 57 1.1 msaitoh static void ether_status(prop_dictionary_t, prop_dictionary_t); 58 1.1 msaitoh static void ether_constructor(void) __attribute__((constructor)); 59 1.3 msaitoh static int setethercaps(prop_dictionary_t, prop_dictionary_t); 60 1.1 msaitoh 61 1.1 msaitoh static status_func_t status; 62 1.3 msaitoh static cmdloop_branch_t branch; 63 1.1 msaitoh 64 1.2 pgoyette #define MAX_PRINT_LEN 55 65 1.2 pgoyette 66 1.3 msaitoh static const struct kwinst ethercapskw[] = { 67 1.5 msaitoh IFKW("vlan-hwfilter", ETHERCAP_VLAN_HWFILTER), 68 1.5 msaitoh IFKW("vlan-hwtagging", ETHERCAP_VLAN_HWTAGGING), 69 1.5 msaitoh IFKW("eee", ETHERCAP_EEE) 70 1.3 msaitoh }; 71 1.3 msaitoh 72 1.3 msaitoh struct pkw ethercaps = PKW_INITIALIZER(ðercaps, "ethercaps", setethercaps, 73 1.3 msaitoh "ethercap", ethercapskw, __arraycount(ethercapskw), 74 1.3 msaitoh &command_root.pb_parser); 75 1.3 msaitoh 76 1.3 msaitoh void 77 1.3 msaitoh do_setethercaps(prop_dictionary_t env) 78 1.3 msaitoh { 79 1.3 msaitoh struct eccapreq eccr; 80 1.3 msaitoh prop_data_t d; 81 1.3 msaitoh 82 1.3 msaitoh d = (prop_data_t )prop_dictionary_get(env, "ethercaps"); 83 1.3 msaitoh if (d == NULL) 84 1.3 msaitoh return; 85 1.3 msaitoh 86 1.3 msaitoh assert(sizeof(eccr) == prop_data_size(d)); 87 1.3 msaitoh 88 1.9 thorpej memcpy(&eccr, prop_data_value(d), sizeof(eccr)); 89 1.3 msaitoh if (direct_ioctl(env, SIOCSETHERCAP, &eccr) == -1) 90 1.3 msaitoh err(EXIT_FAILURE, "SIOCSETHERCAP"); 91 1.3 msaitoh } 92 1.3 msaitoh 93 1.3 msaitoh static int 94 1.3 msaitoh getethercaps(prop_dictionary_t env, prop_dictionary_t oenv, 95 1.3 msaitoh struct eccapreq *oeccr) 96 1.3 msaitoh { 97 1.3 msaitoh bool rc; 98 1.3 msaitoh struct eccapreq eccr; 99 1.3 msaitoh const struct eccapreq *tmpeccr; 100 1.3 msaitoh prop_data_t capdata; 101 1.3 msaitoh 102 1.3 msaitoh capdata = (prop_data_t)prop_dictionary_get(env, "ethercaps"); 103 1.3 msaitoh 104 1.3 msaitoh if (capdata != NULL) { 105 1.9 thorpej tmpeccr = prop_data_value(capdata); 106 1.3 msaitoh *oeccr = *tmpeccr; 107 1.3 msaitoh return 0; 108 1.3 msaitoh } 109 1.3 msaitoh 110 1.3 msaitoh (void)direct_ioctl(env, SIOCGETHERCAP, &eccr); 111 1.3 msaitoh *oeccr = eccr; 112 1.3 msaitoh 113 1.9 thorpej capdata = prop_data_create_copy(&eccr, sizeof(eccr)); 114 1.3 msaitoh 115 1.3 msaitoh rc = prop_dictionary_set(oenv, "ethercaps", capdata); 116 1.3 msaitoh 117 1.3 msaitoh prop_object_release((prop_object_t)capdata); 118 1.3 msaitoh 119 1.3 msaitoh return rc ? 0 : -1; 120 1.3 msaitoh } 121 1.3 msaitoh 122 1.3 msaitoh static int 123 1.3 msaitoh setethercaps(prop_dictionary_t env, prop_dictionary_t oenv) 124 1.3 msaitoh { 125 1.3 msaitoh int64_t ethercap; 126 1.3 msaitoh bool rc; 127 1.3 msaitoh prop_data_t capdata; 128 1.3 msaitoh struct eccapreq eccr; 129 1.3 msaitoh 130 1.3 msaitoh rc = prop_dictionary_get_int64(env, "ethercap", ðercap); 131 1.3 msaitoh assert(rc); 132 1.3 msaitoh 133 1.3 msaitoh if (getethercaps(env, oenv, &eccr) == -1) 134 1.3 msaitoh return -1; 135 1.3 msaitoh 136 1.3 msaitoh if (ethercap < 0) { 137 1.3 msaitoh ethercap = -ethercap; 138 1.3 msaitoh eccr.eccr_capenable &= ~ethercap; 139 1.3 msaitoh } else 140 1.3 msaitoh eccr.eccr_capenable |= ethercap; 141 1.3 msaitoh 142 1.9 thorpej if ((capdata = prop_data_create_copy(&eccr, sizeof(eccr))) == NULL) 143 1.3 msaitoh return -1; 144 1.3 msaitoh 145 1.3 msaitoh rc = prop_dictionary_set(oenv, "ethercaps", capdata); 146 1.3 msaitoh prop_object_release((prop_object_t)capdata); 147 1.3 msaitoh 148 1.3 msaitoh return rc ? 0 : -1; 149 1.3 msaitoh } 150 1.3 msaitoh 151 1.1 msaitoh void 152 1.1 msaitoh ether_status(prop_dictionary_t env, prop_dictionary_t oenv) 153 1.1 msaitoh { 154 1.1 msaitoh struct eccapreq eccr; 155 1.1 msaitoh char fbuf[BUFSIZ]; 156 1.2 pgoyette char *bp; 157 1.1 msaitoh 158 1.1 msaitoh memset(&eccr, 0, sizeof(eccr)); 159 1.1 msaitoh 160 1.1 msaitoh if (direct_ioctl(env, SIOCGETHERCAP, &eccr) == -1) 161 1.1 msaitoh return; 162 1.1 msaitoh 163 1.1 msaitoh if (eccr.eccr_capabilities != 0) { 164 1.2 pgoyette (void)snprintb_m(fbuf, sizeof(fbuf), ECCAPBITS, 165 1.2 pgoyette eccr.eccr_capabilities, MAX_PRINT_LEN); 166 1.2 pgoyette bp = fbuf; 167 1.2 pgoyette while (*bp != '\0') { 168 1.8 ryo printf("\tec_capabilities=%s\n", bp); 169 1.2 pgoyette bp += strlen(bp) + 1; 170 1.2 pgoyette } 171 1.2 pgoyette (void)snprintb_m(fbuf, sizeof(fbuf), ECCAPBITS, 172 1.2 pgoyette eccr.eccr_capenable, MAX_PRINT_LEN); 173 1.2 pgoyette bp = fbuf; 174 1.2 pgoyette while (*bp != '\0') { 175 1.8 ryo printf("\tec_enabled=%s\n", bp); 176 1.2 pgoyette bp += strlen(bp) + 1; 177 1.2 pgoyette } 178 1.1 msaitoh } 179 1.1 msaitoh } 180 1.1 msaitoh 181 1.1 msaitoh static void 182 1.1 msaitoh ether_constructor(void) 183 1.1 msaitoh { 184 1.1 msaitoh 185 1.3 msaitoh cmdloop_branch_init(&branch, ðercaps.pk_parser); 186 1.3 msaitoh register_cmdloop_branch(&branch); 187 1.1 msaitoh status_func_init(&status, ether_status); 188 1.1 msaitoh register_status(&status); 189 1.1 msaitoh } 190