1270069b7SAdrian Chadd /* $NetBSD: ifconfig.c,v 1.34 1997/04/21 01:17:58 lukem Exp $ */
2270069b7SAdrian Chadd
3*df57947fSPedro F. Giffuni /*-
4*df57947fSPedro F. Giffuni * SPDX-License-Identifier: BSD-4-Clause
5*df57947fSPedro F. Giffuni *
6270069b7SAdrian Chadd * Copyright (c) 1997 Jason R. Thorpe.
7270069b7SAdrian Chadd * All rights reserved.
8270069b7SAdrian Chadd *
9270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without
10270069b7SAdrian Chadd * modification, are permitted provided that the following conditions
11270069b7SAdrian Chadd * are met:
12270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright
13270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer.
14270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright
15270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the
16270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution.
17270069b7SAdrian Chadd * 3. All advertising materials mentioning features or use of this software
18270069b7SAdrian Chadd * must display the following acknowledgement:
19270069b7SAdrian Chadd * This product includes software developed for the NetBSD Project
20270069b7SAdrian Chadd * by Jason R. Thorpe.
21270069b7SAdrian Chadd * 4. The name of the author may not be used to endorse or promote products
22270069b7SAdrian Chadd * derived from this software without specific prior written permission.
23270069b7SAdrian Chadd *
24270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
25270069b7SAdrian Chadd * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
26270069b7SAdrian Chadd * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
27270069b7SAdrian Chadd * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
28270069b7SAdrian Chadd * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
29270069b7SAdrian Chadd * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
30270069b7SAdrian Chadd * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
31270069b7SAdrian Chadd * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
32270069b7SAdrian Chadd * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
33270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
34270069b7SAdrian Chadd * SUCH DAMAGE.
35270069b7SAdrian Chadd */
36270069b7SAdrian Chadd
37270069b7SAdrian Chadd /*
38270069b7SAdrian Chadd * Copyright (c) 1983, 1993
39270069b7SAdrian Chadd * The Regents of the University of California. All rights reserved.
40270069b7SAdrian Chadd *
41270069b7SAdrian Chadd * Redistribution and use in source and binary forms, with or without
42270069b7SAdrian Chadd * modification, are permitted provided that the following conditions
43270069b7SAdrian Chadd * are met:
44270069b7SAdrian Chadd * 1. Redistributions of source code must retain the above copyright
45270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer.
46270069b7SAdrian Chadd * 2. Redistributions in binary form must reproduce the above copyright
47270069b7SAdrian Chadd * notice, this list of conditions and the following disclaimer in the
48270069b7SAdrian Chadd * documentation and/or other materials provided with the distribution.
49270069b7SAdrian Chadd * 4. Neither the name of the University nor the names of its contributors
50270069b7SAdrian Chadd * may be used to endorse or promote products derived from this software
51270069b7SAdrian Chadd * without specific prior written permission.
52270069b7SAdrian Chadd *
53270069b7SAdrian Chadd * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
54270069b7SAdrian Chadd * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
55270069b7SAdrian Chadd * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
56270069b7SAdrian Chadd * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
57270069b7SAdrian Chadd * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
58270069b7SAdrian Chadd * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
59270069b7SAdrian Chadd * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
60270069b7SAdrian Chadd * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
61270069b7SAdrian Chadd * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
62270069b7SAdrian Chadd * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
63270069b7SAdrian Chadd * SUCH DAMAGE.
64270069b7SAdrian Chadd */
65270069b7SAdrian Chadd /*
66270069b7SAdrian Chadd * based on sbin/ifconfig/ifmedia.c r221954
67270069b7SAdrian Chadd */
68270069b7SAdrian Chadd
69270069b7SAdrian Chadd #include <sys/param.h>
70270069b7SAdrian Chadd #include <sys/ioctl.h>
71270069b7SAdrian Chadd #include <sys/socket.h>
72270069b7SAdrian Chadd #include <sys/sysctl.h>
73270069b7SAdrian Chadd #include <sys/time.h>
74270069b7SAdrian Chadd
75270069b7SAdrian Chadd #include <net/if.h>
76270069b7SAdrian Chadd #include <net/if_dl.h>
77270069b7SAdrian Chadd #include <net/if_types.h>
78270069b7SAdrian Chadd #include <net/if_media.h>
79270069b7SAdrian Chadd #include <net/route.h>
80270069b7SAdrian Chadd
81270069b7SAdrian Chadd #include <ctype.h>
82270069b7SAdrian Chadd #include <err.h>
83270069b7SAdrian Chadd #include <errno.h>
84270069b7SAdrian Chadd #include <fcntl.h>
85270069b7SAdrian Chadd #include <stdio.h>
86270069b7SAdrian Chadd #include <stdlib.h>
87270069b7SAdrian Chadd #include <string.h>
88270069b7SAdrian Chadd #include <unistd.h>
89270069b7SAdrian Chadd
90270069b7SAdrian Chadd void domediaopt(const char *, int, int);
91270069b7SAdrian Chadd int get_media_subtype(int, const char *);
92270069b7SAdrian Chadd int get_media_mode(int, const char *);
93270069b7SAdrian Chadd int get_media_options(int, const char *);
94270069b7SAdrian Chadd int lookup_media_word(struct ifmedia_description *, const char *);
95270069b7SAdrian Chadd void print_media_word(int, int);
96270069b7SAdrian Chadd void print_media_word_ifconfig(int);
97270069b7SAdrian Chadd
98270069b7SAdrian Chadd #if 0
99270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int);
100270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int);
101270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int,
102270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos);
103270069b7SAdrian Chadd
104270069b7SAdrian Chadd #define IFM_OPMODE(x) \
105270069b7SAdrian Chadd ((x) & (IFM_IEEE80211_ADHOC | IFM_IEEE80211_HOSTAP | \
106270069b7SAdrian Chadd IFM_IEEE80211_IBSS | IFM_IEEE80211_WDS | IFM_IEEE80211_MONITOR | \
107270069b7SAdrian Chadd IFM_IEEE80211_MBSS))
108270069b7SAdrian Chadd #define IFM_IEEE80211_STA 0
109270069b7SAdrian Chadd
110270069b7SAdrian Chadd static void
111270069b7SAdrian Chadd media_status(int s)
112270069b7SAdrian Chadd {
113270069b7SAdrian Chadd struct ifmediareq ifmr;
114270069b7SAdrian Chadd int *media_list, i;
115270069b7SAdrian Chadd
116270069b7SAdrian Chadd (void) memset(&ifmr, 0, sizeof(ifmr));
117270069b7SAdrian Chadd (void) strncpy(ifmr.ifm_name, name, sizeof(ifmr.ifm_name));
118270069b7SAdrian Chadd
119270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0) {
120270069b7SAdrian Chadd /*
121270069b7SAdrian Chadd * Interface doesn't support SIOC{G,S}IFMEDIA.
122270069b7SAdrian Chadd */
123270069b7SAdrian Chadd return;
124270069b7SAdrian Chadd }
125270069b7SAdrian Chadd
126270069b7SAdrian Chadd if (ifmr.ifm_count == 0) {
127270069b7SAdrian Chadd warnx("%s: no media types?", name);
128270069b7SAdrian Chadd return;
129270069b7SAdrian Chadd }
130270069b7SAdrian Chadd
131270069b7SAdrian Chadd media_list = (int *)malloc(ifmr.ifm_count * sizeof(int));
132270069b7SAdrian Chadd if (media_list == NULL)
133270069b7SAdrian Chadd err(1, "malloc");
134270069b7SAdrian Chadd ifmr.ifm_ulist = media_list;
135270069b7SAdrian Chadd
136270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)&ifmr) < 0)
137270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA");
138270069b7SAdrian Chadd
139270069b7SAdrian Chadd printf("\tmedia: ");
140270069b7SAdrian Chadd print_media_word(ifmr.ifm_current, 1);
141270069b7SAdrian Chadd if (ifmr.ifm_active != ifmr.ifm_current) {
142270069b7SAdrian Chadd putchar(' ');
143270069b7SAdrian Chadd putchar('(');
144270069b7SAdrian Chadd print_media_word(ifmr.ifm_active, 0);
145270069b7SAdrian Chadd putchar(')');
146270069b7SAdrian Chadd }
147270069b7SAdrian Chadd
148270069b7SAdrian Chadd putchar('\n');
149270069b7SAdrian Chadd
150270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_AVALID) {
151270069b7SAdrian Chadd printf("\tstatus: ");
152270069b7SAdrian Chadd switch (IFM_TYPE(ifmr.ifm_active)) {
153270069b7SAdrian Chadd case IFM_ETHER:
154270069b7SAdrian Chadd case IFM_ATM:
155270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE)
156270069b7SAdrian Chadd printf("active");
157270069b7SAdrian Chadd else
158270069b7SAdrian Chadd printf("no carrier");
159270069b7SAdrian Chadd break;
160270069b7SAdrian Chadd
161270069b7SAdrian Chadd case IFM_IEEE80211:
162270069b7SAdrian Chadd if (ifmr.ifm_status & IFM_ACTIVE) {
163270069b7SAdrian Chadd /* NB: only sta mode associates */
164270069b7SAdrian Chadd if (IFM_OPMODE(ifmr.ifm_active) == IFM_IEEE80211_STA)
165270069b7SAdrian Chadd printf("associated");
166270069b7SAdrian Chadd else
167270069b7SAdrian Chadd printf("running");
168270069b7SAdrian Chadd } else
169270069b7SAdrian Chadd printf("no carrier");
170270069b7SAdrian Chadd break;
171270069b7SAdrian Chadd }
172270069b7SAdrian Chadd putchar('\n');
173270069b7SAdrian Chadd }
174270069b7SAdrian Chadd
175270069b7SAdrian Chadd if (ifmr.ifm_count > 0 && supmedia) {
176270069b7SAdrian Chadd printf("\tsupported media:\n");
177270069b7SAdrian Chadd for (i = 0; i < ifmr.ifm_count; i++) {
178270069b7SAdrian Chadd printf("\t\t");
179270069b7SAdrian Chadd print_media_word_ifconfig(media_list[i]);
180270069b7SAdrian Chadd putchar('\n');
181270069b7SAdrian Chadd }
182270069b7SAdrian Chadd }
183270069b7SAdrian Chadd
184270069b7SAdrian Chadd free(media_list);
185270069b7SAdrian Chadd }
186270069b7SAdrian Chadd
187270069b7SAdrian Chadd struct ifmediareq *
188270069b7SAdrian Chadd ifmedia_getstate(int s)
189270069b7SAdrian Chadd {
190270069b7SAdrian Chadd static struct ifmediareq *ifmr = NULL;
191270069b7SAdrian Chadd int *mwords;
192270069b7SAdrian Chadd
193270069b7SAdrian Chadd if (ifmr == NULL) {
194270069b7SAdrian Chadd ifmr = (struct ifmediareq *)malloc(sizeof(struct ifmediareq));
195270069b7SAdrian Chadd if (ifmr == NULL)
196270069b7SAdrian Chadd err(1, "malloc");
197270069b7SAdrian Chadd
198270069b7SAdrian Chadd (void) memset(ifmr, 0, sizeof(struct ifmediareq));
199270069b7SAdrian Chadd (void) strncpy(ifmr->ifm_name, name,
200270069b7SAdrian Chadd sizeof(ifmr->ifm_name));
201270069b7SAdrian Chadd
202270069b7SAdrian Chadd ifmr->ifm_count = 0;
203270069b7SAdrian Chadd ifmr->ifm_ulist = NULL;
204270069b7SAdrian Chadd
205270069b7SAdrian Chadd /*
206270069b7SAdrian Chadd * We must go through the motions of reading all
207270069b7SAdrian Chadd * supported media because we need to know both
208270069b7SAdrian Chadd * the current media type and the top-level type.
209270069b7SAdrian Chadd */
210270069b7SAdrian Chadd
211270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0) {
212270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA");
213270069b7SAdrian Chadd }
214270069b7SAdrian Chadd
215270069b7SAdrian Chadd if (ifmr->ifm_count == 0)
216270069b7SAdrian Chadd errx(1, "%s: no media types?", name);
217270069b7SAdrian Chadd
218270069b7SAdrian Chadd mwords = (int *)malloc(ifmr->ifm_count * sizeof(int));
219270069b7SAdrian Chadd if (mwords == NULL)
220270069b7SAdrian Chadd err(1, "malloc");
221270069b7SAdrian Chadd
222270069b7SAdrian Chadd ifmr->ifm_ulist = mwords;
223270069b7SAdrian Chadd if (ioctl(s, SIOCGIFMEDIA, (caddr_t)ifmr) < 0)
224270069b7SAdrian Chadd err(1, "SIOCGIFMEDIA");
225270069b7SAdrian Chadd }
226270069b7SAdrian Chadd
227270069b7SAdrian Chadd return ifmr;
228270069b7SAdrian Chadd }
229270069b7SAdrian Chadd
230270069b7SAdrian Chadd static void
231270069b7SAdrian Chadd setifmediacallback(int s, void *arg)
232270069b7SAdrian Chadd {
233270069b7SAdrian Chadd struct ifmediareq *ifmr = (struct ifmediareq *)arg;
234270069b7SAdrian Chadd static int did_it = 0;
235270069b7SAdrian Chadd
236270069b7SAdrian Chadd if (!did_it) {
237270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current;
238270069b7SAdrian Chadd if (ioctl(s, SIOCSIFMEDIA, (caddr_t)&ifr) < 0)
239270069b7SAdrian Chadd err(1, "SIOCSIFMEDIA (media)");
240270069b7SAdrian Chadd free(ifmr->ifm_ulist);
241270069b7SAdrian Chadd free(ifmr);
242270069b7SAdrian Chadd did_it = 1;
243270069b7SAdrian Chadd }
244270069b7SAdrian Chadd }
245270069b7SAdrian Chadd
246270069b7SAdrian Chadd static void
247270069b7SAdrian Chadd setmedia(const char *val, int d, int s, const struct afswtch *afp)
248270069b7SAdrian Chadd {
249270069b7SAdrian Chadd struct ifmediareq *ifmr;
250270069b7SAdrian Chadd int subtype;
251270069b7SAdrian Chadd
252270069b7SAdrian Chadd ifmr = ifmedia_getstate(s);
253270069b7SAdrian Chadd
254270069b7SAdrian Chadd /*
255270069b7SAdrian Chadd * We are primarily concerned with the top-level type.
256270069b7SAdrian Chadd * However, "current" may be only IFM_NONE, so we just look
257270069b7SAdrian Chadd * for the top-level type in the first "supported type"
258270069b7SAdrian Chadd * entry.
259270069b7SAdrian Chadd *
260270069b7SAdrian Chadd * (I'm assuming that all supported media types for a given
261270069b7SAdrian Chadd * interface will be the same top-level type..)
262270069b7SAdrian Chadd */
263270069b7SAdrian Chadd subtype = get_media_subtype(IFM_TYPE(ifmr->ifm_ulist[0]), val);
264270069b7SAdrian Chadd
265270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
266270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & IFM_IMASK) |
267270069b7SAdrian Chadd IFM_TYPE(ifmr->ifm_ulist[0]) | subtype;
268270069b7SAdrian Chadd
269270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media;
270270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr);
271270069b7SAdrian Chadd }
272270069b7SAdrian Chadd
273270069b7SAdrian Chadd static void
274270069b7SAdrian Chadd setmediaopt(const char *val, int d, int s, const struct afswtch *afp)
275270069b7SAdrian Chadd {
276270069b7SAdrian Chadd
277270069b7SAdrian Chadd domediaopt(val, 0, s);
278270069b7SAdrian Chadd }
279270069b7SAdrian Chadd
280270069b7SAdrian Chadd static void
281270069b7SAdrian Chadd unsetmediaopt(const char *val, int d, int s, const struct afswtch *afp)
282270069b7SAdrian Chadd {
283270069b7SAdrian Chadd
284270069b7SAdrian Chadd domediaopt(val, 1, s);
285270069b7SAdrian Chadd }
286270069b7SAdrian Chadd
287270069b7SAdrian Chadd static void
288270069b7SAdrian Chadd domediaopt(const char *val, int clear, int s)
289270069b7SAdrian Chadd {
290270069b7SAdrian Chadd struct ifmediareq *ifmr;
291270069b7SAdrian Chadd int options;
292270069b7SAdrian Chadd
293270069b7SAdrian Chadd ifmr = ifmedia_getstate(s);
294270069b7SAdrian Chadd
295270069b7SAdrian Chadd options = get_media_options(IFM_TYPE(ifmr->ifm_ulist[0]), val);
296270069b7SAdrian Chadd
297270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
298270069b7SAdrian Chadd ifr.ifr_media = ifmr->ifm_current;
299270069b7SAdrian Chadd if (clear)
300270069b7SAdrian Chadd ifr.ifr_media &= ~options;
301270069b7SAdrian Chadd else {
302270069b7SAdrian Chadd if (options & IFM_HDX) {
303270069b7SAdrian Chadd ifr.ifr_media &= ~IFM_FDX;
304270069b7SAdrian Chadd options &= ~IFM_HDX;
305270069b7SAdrian Chadd }
306270069b7SAdrian Chadd ifr.ifr_media |= options;
307270069b7SAdrian Chadd }
308270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media;
309270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr);
310270069b7SAdrian Chadd }
311270069b7SAdrian Chadd
312270069b7SAdrian Chadd static void
313270069b7SAdrian Chadd setmediainst(const char *val, int d, int s, const struct afswtch *afp)
314270069b7SAdrian Chadd {
315270069b7SAdrian Chadd struct ifmediareq *ifmr;
316270069b7SAdrian Chadd int inst;
317270069b7SAdrian Chadd
318270069b7SAdrian Chadd ifmr = ifmedia_getstate(s);
319270069b7SAdrian Chadd
320270069b7SAdrian Chadd inst = atoi(val);
321270069b7SAdrian Chadd if (inst < 0 || inst > (int)IFM_INST_MAX)
322270069b7SAdrian Chadd errx(1, "invalid media instance: %s", val);
323270069b7SAdrian Chadd
324270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
325270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_IMASK) | inst << IFM_ISHIFT;
326270069b7SAdrian Chadd
327270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media;
328270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr);
329270069b7SAdrian Chadd }
330270069b7SAdrian Chadd
331270069b7SAdrian Chadd static void
332270069b7SAdrian Chadd setmediamode(const char *val, int d, int s, const struct afswtch *afp)
333270069b7SAdrian Chadd {
334270069b7SAdrian Chadd struct ifmediareq *ifmr;
335270069b7SAdrian Chadd int mode;
336270069b7SAdrian Chadd
337270069b7SAdrian Chadd ifmr = ifmedia_getstate(s);
338270069b7SAdrian Chadd
339270069b7SAdrian Chadd mode = get_media_mode(IFM_TYPE(ifmr->ifm_ulist[0]), val);
340270069b7SAdrian Chadd
341270069b7SAdrian Chadd strncpy(ifr.ifr_name, name, sizeof(ifr.ifr_name));
342270069b7SAdrian Chadd ifr.ifr_media = (ifmr->ifm_current & ~IFM_MMASK) | mode;
343270069b7SAdrian Chadd
344270069b7SAdrian Chadd ifmr->ifm_current = ifr.ifr_media;
345270069b7SAdrian Chadd callback_register(setifmediacallback, (void *)ifmr);
346270069b7SAdrian Chadd }
347270069b7SAdrian Chadd #endif
348270069b7SAdrian Chadd
349270069b7SAdrian Chadd /**********************************************************************
350270069b7SAdrian Chadd * A good chunk of this is duplicated from sys/net/ifmedia.c
351270069b7SAdrian Chadd **********************************************************************/
352270069b7SAdrian Chadd
353270069b7SAdrian Chadd static struct ifmedia_description ifm_type_descriptions[] =
354270069b7SAdrian Chadd IFM_TYPE_DESCRIPTIONS;
355270069b7SAdrian Chadd
356270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_descriptions[] =
357270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_DESCRIPTIONS;
358270069b7SAdrian Chadd
359270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_aliases[] =
360270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_ALIASES;
361270069b7SAdrian Chadd
362270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ethernet_option_descriptions[] =
363270069b7SAdrian Chadd IFM_SUBTYPE_ETHERNET_OPTION_DESCRIPTIONS;
364270069b7SAdrian Chadd
365270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_descriptions[] =
366270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_DESCRIPTIONS;
367270069b7SAdrian Chadd
368270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_aliases[] =
369270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_ALIASES;
370270069b7SAdrian Chadd
371270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_ieee80211_option_descriptions[] =
372270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_OPTION_DESCRIPTIONS;
373270069b7SAdrian Chadd
374ae824d80SEd Schouten static struct ifmedia_description ifm_subtype_ieee80211_mode_descriptions[] =
375270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_DESCRIPTIONS;
376270069b7SAdrian Chadd
377ae824d80SEd Schouten static struct ifmedia_description ifm_subtype_ieee80211_mode_aliases[] =
378270069b7SAdrian Chadd IFM_SUBTYPE_IEEE80211_MODE_ALIASES;
379270069b7SAdrian Chadd
380270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_descriptions[] =
381270069b7SAdrian Chadd IFM_SUBTYPE_ATM_DESCRIPTIONS;
382270069b7SAdrian Chadd
383270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_aliases[] =
384270069b7SAdrian Chadd IFM_SUBTYPE_ATM_ALIASES;
385270069b7SAdrian Chadd
386270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_atm_option_descriptions[] =
387270069b7SAdrian Chadd IFM_SUBTYPE_ATM_OPTION_DESCRIPTIONS;
388270069b7SAdrian Chadd
389270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_descriptions[] =
390270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_DESCRIPTIONS;
391270069b7SAdrian Chadd
392270069b7SAdrian Chadd static struct ifmedia_description ifm_subtype_shared_aliases[] =
393270069b7SAdrian Chadd IFM_SUBTYPE_SHARED_ALIASES;
394270069b7SAdrian Chadd
395270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_descriptions[] =
396270069b7SAdrian Chadd IFM_SHARED_OPTION_DESCRIPTIONS;
397270069b7SAdrian Chadd
398270069b7SAdrian Chadd static struct ifmedia_description ifm_shared_option_aliases[] =
399270069b7SAdrian Chadd IFM_SHARED_OPTION_ALIASES;
400270069b7SAdrian Chadd
401270069b7SAdrian Chadd struct ifmedia_type_to_subtype {
402270069b7SAdrian Chadd struct {
403270069b7SAdrian Chadd struct ifmedia_description *desc;
404270069b7SAdrian Chadd int alias;
405270069b7SAdrian Chadd } subtypes[5];
406270069b7SAdrian Chadd struct {
407270069b7SAdrian Chadd struct ifmedia_description *desc;
408270069b7SAdrian Chadd int alias;
409270069b7SAdrian Chadd } options[4];
410270069b7SAdrian Chadd struct {
411270069b7SAdrian Chadd struct ifmedia_description *desc;
412270069b7SAdrian Chadd int alias;
413270069b7SAdrian Chadd } modes[3];
414270069b7SAdrian Chadd };
415270069b7SAdrian Chadd
416270069b7SAdrian Chadd /* must be in the same order as IFM_TYPE_DESCRIPTIONS */
417270069b7SAdrian Chadd static struct ifmedia_type_to_subtype ifmedia_types_to_subtypes[] = {
418270069b7SAdrian Chadd {
419270069b7SAdrian Chadd {
420270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 },
421270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 },
422270069b7SAdrian Chadd { &ifm_subtype_ethernet_descriptions[0], 0 },
423270069b7SAdrian Chadd { &ifm_subtype_ethernet_aliases[0], 1 },
424270069b7SAdrian Chadd { NULL, 0 },
425270069b7SAdrian Chadd },
426270069b7SAdrian Chadd {
427270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 },
428270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 },
429270069b7SAdrian Chadd { &ifm_subtype_ethernet_option_descriptions[0], 0 },
430270069b7SAdrian Chadd { NULL, 0 },
431270069b7SAdrian Chadd },
432270069b7SAdrian Chadd {
433270069b7SAdrian Chadd { NULL, 0 },
434270069b7SAdrian Chadd },
435270069b7SAdrian Chadd },
436270069b7SAdrian Chadd {
437270069b7SAdrian Chadd {
438270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 },
439270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 },
440270069b7SAdrian Chadd { &ifm_subtype_ieee80211_descriptions[0], 0 },
441270069b7SAdrian Chadd { &ifm_subtype_ieee80211_aliases[0], 1 },
442270069b7SAdrian Chadd { NULL, 0 },
443270069b7SAdrian Chadd },
444270069b7SAdrian Chadd {
445270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 },
446270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 },
447270069b7SAdrian Chadd { &ifm_subtype_ieee80211_option_descriptions[0], 0 },
448270069b7SAdrian Chadd { NULL, 0 },
449270069b7SAdrian Chadd },
450270069b7SAdrian Chadd {
451270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_descriptions[0], 0 },
452270069b7SAdrian Chadd { &ifm_subtype_ieee80211_mode_aliases[0], 0 },
453270069b7SAdrian Chadd { NULL, 0 },
454270069b7SAdrian Chadd },
455270069b7SAdrian Chadd },
456270069b7SAdrian Chadd {
457270069b7SAdrian Chadd {
458270069b7SAdrian Chadd { &ifm_subtype_shared_descriptions[0], 0 },
459270069b7SAdrian Chadd { &ifm_subtype_shared_aliases[0], 1 },
460270069b7SAdrian Chadd { &ifm_subtype_atm_descriptions[0], 0 },
461270069b7SAdrian Chadd { &ifm_subtype_atm_aliases[0], 1 },
462270069b7SAdrian Chadd { NULL, 0 },
463270069b7SAdrian Chadd },
464270069b7SAdrian Chadd {
465270069b7SAdrian Chadd { &ifm_shared_option_descriptions[0], 0 },
466270069b7SAdrian Chadd { &ifm_shared_option_aliases[0], 1 },
467270069b7SAdrian Chadd { &ifm_subtype_atm_option_descriptions[0], 0 },
468270069b7SAdrian Chadd { NULL, 0 },
469270069b7SAdrian Chadd },
470270069b7SAdrian Chadd {
471270069b7SAdrian Chadd { NULL, 0 },
472270069b7SAdrian Chadd },
473270069b7SAdrian Chadd },
474270069b7SAdrian Chadd };
475270069b7SAdrian Chadd
476270069b7SAdrian Chadd int
get_media_subtype(int type,const char * val)477270069b7SAdrian Chadd get_media_subtype(int type, const char *val)
478270069b7SAdrian Chadd {
479270069b7SAdrian Chadd struct ifmedia_description *desc;
480270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
481270069b7SAdrian Chadd int rval, i;
482270069b7SAdrian Chadd
483270069b7SAdrian Chadd /* Find the top-level interface type. */
484270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
485270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++)
486270069b7SAdrian Chadd if (type == desc->ifmt_word)
487270069b7SAdrian Chadd break;
488270069b7SAdrian Chadd if (desc->ifmt_string == NULL)
489270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type);
490270069b7SAdrian Chadd
491270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
492270069b7SAdrian Chadd rval = lookup_media_word(ttos->subtypes[i].desc, val);
493270069b7SAdrian Chadd if (rval != -1)
494270069b7SAdrian Chadd return (rval);
495270069b7SAdrian Chadd }
496270069b7SAdrian Chadd errx(1, "unknown media subtype: %s", val);
497270069b7SAdrian Chadd /*NOTREACHED*/
498270069b7SAdrian Chadd }
499270069b7SAdrian Chadd
500270069b7SAdrian Chadd int
get_media_mode(int type,const char * val)501270069b7SAdrian Chadd get_media_mode(int type, const char *val)
502270069b7SAdrian Chadd {
503270069b7SAdrian Chadd struct ifmedia_description *desc;
504270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
505270069b7SAdrian Chadd int rval, i;
506270069b7SAdrian Chadd
507270069b7SAdrian Chadd /* Find the top-level interface type. */
508270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
509270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++)
510270069b7SAdrian Chadd if (type == desc->ifmt_word)
511270069b7SAdrian Chadd break;
512270069b7SAdrian Chadd if (desc->ifmt_string == NULL)
513270069b7SAdrian Chadd errx(1, "unknown media mode 0x%x", type);
514270069b7SAdrian Chadd
515270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) {
516270069b7SAdrian Chadd rval = lookup_media_word(ttos->modes[i].desc, val);
517270069b7SAdrian Chadd if (rval != -1)
518270069b7SAdrian Chadd return (rval);
519270069b7SAdrian Chadd }
520270069b7SAdrian Chadd return -1;
521270069b7SAdrian Chadd }
522270069b7SAdrian Chadd
523270069b7SAdrian Chadd int
get_media_options(int type,const char * val)524270069b7SAdrian Chadd get_media_options(int type, const char *val)
525270069b7SAdrian Chadd {
526270069b7SAdrian Chadd struct ifmedia_description *desc;
527270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
528270069b7SAdrian Chadd char *optlist, *optptr;
529270069b7SAdrian Chadd int option = 0, i, rval = 0;
530270069b7SAdrian Chadd
531270069b7SAdrian Chadd /* We muck with the string, so copy it. */
532270069b7SAdrian Chadd optlist = strdup(val);
533270069b7SAdrian Chadd if (optlist == NULL)
534270069b7SAdrian Chadd err(1, "strdup");
535270069b7SAdrian Chadd
536270069b7SAdrian Chadd /* Find the top-level interface type. */
537270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
538270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++)
539270069b7SAdrian Chadd if (type == desc->ifmt_word)
540270069b7SAdrian Chadd break;
541270069b7SAdrian Chadd if (desc->ifmt_string == NULL)
542270069b7SAdrian Chadd errx(1, "unknown media type 0x%x", type);
543270069b7SAdrian Chadd
544270069b7SAdrian Chadd /*
545270069b7SAdrian Chadd * Look up the options in the user-provided comma-separated
546270069b7SAdrian Chadd * list.
547270069b7SAdrian Chadd */
548270069b7SAdrian Chadd optptr = optlist;
549270069b7SAdrian Chadd for (; (optptr = strtok(optptr, ",")) != NULL; optptr = NULL) {
550270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) {
551270069b7SAdrian Chadd option = lookup_media_word(ttos->options[i].desc, optptr);
552270069b7SAdrian Chadd if (option != -1)
553270069b7SAdrian Chadd break;
554270069b7SAdrian Chadd }
555270069b7SAdrian Chadd if (option == 0)
556270069b7SAdrian Chadd errx(1, "unknown option: %s", optptr);
557270069b7SAdrian Chadd rval |= option;
558270069b7SAdrian Chadd }
559270069b7SAdrian Chadd
560270069b7SAdrian Chadd free(optlist);
561270069b7SAdrian Chadd return (rval);
562270069b7SAdrian Chadd }
563270069b7SAdrian Chadd
564270069b7SAdrian Chadd int
lookup_media_word(struct ifmedia_description * desc,const char * val)565270069b7SAdrian Chadd lookup_media_word(struct ifmedia_description *desc, const char *val)
566270069b7SAdrian Chadd {
567270069b7SAdrian Chadd
568270069b7SAdrian Chadd for (; desc->ifmt_string != NULL; desc++)
569270069b7SAdrian Chadd if (strcasecmp(desc->ifmt_string, val) == 0)
570270069b7SAdrian Chadd return (desc->ifmt_word);
571270069b7SAdrian Chadd
572270069b7SAdrian Chadd return (-1);
573270069b7SAdrian Chadd }
574270069b7SAdrian Chadd
get_toptype_desc(int ifmw)575270069b7SAdrian Chadd static struct ifmedia_description *get_toptype_desc(int ifmw)
576270069b7SAdrian Chadd {
577270069b7SAdrian Chadd struct ifmedia_description *desc;
578270069b7SAdrian Chadd
579270069b7SAdrian Chadd for (desc = ifm_type_descriptions; desc->ifmt_string != NULL; desc++)
580270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word)
581270069b7SAdrian Chadd break;
582270069b7SAdrian Chadd
583270069b7SAdrian Chadd return desc;
584270069b7SAdrian Chadd }
585270069b7SAdrian Chadd
get_toptype_ttos(int ifmw)586270069b7SAdrian Chadd static struct ifmedia_type_to_subtype *get_toptype_ttos(int ifmw)
587270069b7SAdrian Chadd {
588270069b7SAdrian Chadd struct ifmedia_description *desc;
589270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
590270069b7SAdrian Chadd
591270069b7SAdrian Chadd for (desc = ifm_type_descriptions, ttos = ifmedia_types_to_subtypes;
592270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++, ttos++)
593270069b7SAdrian Chadd if (IFM_TYPE(ifmw) == desc->ifmt_word)
594270069b7SAdrian Chadd break;
595270069b7SAdrian Chadd
596270069b7SAdrian Chadd return ttos;
597270069b7SAdrian Chadd }
598270069b7SAdrian Chadd
get_subtype_desc(int ifmw,struct ifmedia_type_to_subtype * ttos)599270069b7SAdrian Chadd static struct ifmedia_description *get_subtype_desc(int ifmw,
600270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos)
601270069b7SAdrian Chadd {
602270069b7SAdrian Chadd int i;
603270069b7SAdrian Chadd struct ifmedia_description *desc;
604270069b7SAdrian Chadd
605270069b7SAdrian Chadd for (i = 0; ttos->subtypes[i].desc != NULL; i++) {
606270069b7SAdrian Chadd if (ttos->subtypes[i].alias)
607270069b7SAdrian Chadd continue;
608270069b7SAdrian Chadd for (desc = ttos->subtypes[i].desc;
609270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) {
610270069b7SAdrian Chadd if (IFM_SUBTYPE(ifmw) == desc->ifmt_word)
611270069b7SAdrian Chadd return desc;
612270069b7SAdrian Chadd }
613270069b7SAdrian Chadd }
614270069b7SAdrian Chadd
615270069b7SAdrian Chadd return NULL;
616270069b7SAdrian Chadd }
617270069b7SAdrian Chadd
get_mode_desc(int ifmw,struct ifmedia_type_to_subtype * ttos)618270069b7SAdrian Chadd static struct ifmedia_description *get_mode_desc(int ifmw,
619270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos)
620270069b7SAdrian Chadd {
621270069b7SAdrian Chadd int i;
622270069b7SAdrian Chadd struct ifmedia_description *desc;
623270069b7SAdrian Chadd
624270069b7SAdrian Chadd for (i = 0; ttos->modes[i].desc != NULL; i++) {
625270069b7SAdrian Chadd if (ttos->modes[i].alias)
626270069b7SAdrian Chadd continue;
627270069b7SAdrian Chadd for (desc = ttos->modes[i].desc;
628270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) {
629270069b7SAdrian Chadd if (IFM_MODE(ifmw) == desc->ifmt_word)
630270069b7SAdrian Chadd return desc;
631270069b7SAdrian Chadd }
632270069b7SAdrian Chadd }
633270069b7SAdrian Chadd
634270069b7SAdrian Chadd return NULL;
635270069b7SAdrian Chadd }
636270069b7SAdrian Chadd
637270069b7SAdrian Chadd void
print_media_word(int ifmw,int print_toptype)638270069b7SAdrian Chadd print_media_word(int ifmw, int print_toptype)
639270069b7SAdrian Chadd {
640270069b7SAdrian Chadd struct ifmedia_description *desc;
641270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
642270069b7SAdrian Chadd int seen_option = 0, i;
643270069b7SAdrian Chadd
644270069b7SAdrian Chadd /* Find the top-level interface type. */
645270069b7SAdrian Chadd desc = get_toptype_desc(ifmw);
646270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw);
647270069b7SAdrian Chadd if (desc->ifmt_string == NULL) {
648270069b7SAdrian Chadd printf("<unknown type>");
649270069b7SAdrian Chadd return;
650270069b7SAdrian Chadd } else if (print_toptype) {
651270069b7SAdrian Chadd printf("%s", desc->ifmt_string);
652270069b7SAdrian Chadd }
653270069b7SAdrian Chadd
654270069b7SAdrian Chadd /*
655270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can
656270069b7SAdrian Chadd * change it, or anything.
657270069b7SAdrian Chadd */
658270069b7SAdrian Chadd
659270069b7SAdrian Chadd /* Find subtype. */
660270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos);
661270069b7SAdrian Chadd if (desc == NULL) {
662270069b7SAdrian Chadd printf("<unknown subtype>");
663270069b7SAdrian Chadd return;
664270069b7SAdrian Chadd }
665270069b7SAdrian Chadd
666270069b7SAdrian Chadd if (print_toptype)
667270069b7SAdrian Chadd putchar(' ');
668270069b7SAdrian Chadd
669270069b7SAdrian Chadd printf("%s", desc->ifmt_string);
670270069b7SAdrian Chadd
671270069b7SAdrian Chadd if (print_toptype) {
672270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos);
673270069b7SAdrian Chadd if (desc != NULL && strcasecmp("autoselect", desc->ifmt_string))
674270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string);
675270069b7SAdrian Chadd }
676270069b7SAdrian Chadd
677270069b7SAdrian Chadd /* Find options. */
678270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) {
679270069b7SAdrian Chadd if (ttos->options[i].alias)
680270069b7SAdrian Chadd continue;
681270069b7SAdrian Chadd for (desc = ttos->options[i].desc;
682270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) {
683270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) {
684270069b7SAdrian Chadd if (seen_option == 0)
685270069b7SAdrian Chadd printf(" <");
686270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "",
687270069b7SAdrian Chadd desc->ifmt_string);
688270069b7SAdrian Chadd }
689270069b7SAdrian Chadd }
690270069b7SAdrian Chadd }
691270069b7SAdrian Chadd printf("%s", seen_option ? ">" : "");
692270069b7SAdrian Chadd
693270069b7SAdrian Chadd if (print_toptype && IFM_INST(ifmw) != 0)
694270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw));
695270069b7SAdrian Chadd }
696270069b7SAdrian Chadd
697270069b7SAdrian Chadd void
print_media_word_ifconfig(int ifmw)698270069b7SAdrian Chadd print_media_word_ifconfig(int ifmw)
699270069b7SAdrian Chadd {
700270069b7SAdrian Chadd struct ifmedia_description *desc;
701270069b7SAdrian Chadd struct ifmedia_type_to_subtype *ttos;
702270069b7SAdrian Chadd int seen_option = 0, i;
703270069b7SAdrian Chadd
704270069b7SAdrian Chadd /* Find the top-level interface type. */
705270069b7SAdrian Chadd desc = get_toptype_desc(ifmw);
706270069b7SAdrian Chadd ttos = get_toptype_ttos(ifmw);
707270069b7SAdrian Chadd if (desc->ifmt_string == NULL) {
708270069b7SAdrian Chadd printf("<unknown type>");
709270069b7SAdrian Chadd return;
710270069b7SAdrian Chadd }
711270069b7SAdrian Chadd
712270069b7SAdrian Chadd /*
713270069b7SAdrian Chadd * Don't print the top-level type; it's not like we can
714270069b7SAdrian Chadd * change it, or anything.
715270069b7SAdrian Chadd */
716270069b7SAdrian Chadd
717270069b7SAdrian Chadd /* Find subtype. */
718270069b7SAdrian Chadd desc = get_subtype_desc(ifmw, ttos);
719270069b7SAdrian Chadd if (desc == NULL) {
720270069b7SAdrian Chadd printf("<unknown subtype>");
721270069b7SAdrian Chadd return;
722270069b7SAdrian Chadd }
723270069b7SAdrian Chadd
724270069b7SAdrian Chadd printf("media %s", desc->ifmt_string);
725270069b7SAdrian Chadd
726270069b7SAdrian Chadd desc = get_mode_desc(ifmw, ttos);
727270069b7SAdrian Chadd if (desc != NULL)
728270069b7SAdrian Chadd printf(" mode %s", desc->ifmt_string);
729270069b7SAdrian Chadd
730270069b7SAdrian Chadd /* Find options. */
731270069b7SAdrian Chadd for (i = 0; ttos->options[i].desc != NULL; i++) {
732270069b7SAdrian Chadd if (ttos->options[i].alias)
733270069b7SAdrian Chadd continue;
734270069b7SAdrian Chadd for (desc = ttos->options[i].desc;
735270069b7SAdrian Chadd desc->ifmt_string != NULL; desc++) {
736270069b7SAdrian Chadd if (ifmw & desc->ifmt_word) {
737270069b7SAdrian Chadd if (seen_option == 0)
738270069b7SAdrian Chadd printf(" mediaopt ");
739270069b7SAdrian Chadd printf("%s%s", seen_option++ ? "," : "",
740270069b7SAdrian Chadd desc->ifmt_string);
741270069b7SAdrian Chadd }
742270069b7SAdrian Chadd }
743270069b7SAdrian Chadd }
744270069b7SAdrian Chadd
745270069b7SAdrian Chadd if (IFM_INST(ifmw) != 0)
746270069b7SAdrian Chadd printf(" instance %d", IFM_INST(ifmw));
747270069b7SAdrian Chadd }
748270069b7SAdrian Chadd
749270069b7SAdrian Chadd /**********************************************************************
750270069b7SAdrian Chadd * ...until here.
751270069b7SAdrian Chadd **********************************************************************/
752