ifconfig.c (7906a3e0) ifconfig.c (69bb4bb4)
1/*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5/*
6 * Copyright (c) 1983 Regents of the University of California.
7 * All rights reserved. The Berkeley software License Agreement
8 * specifies the terms and conditions for redistribution.

--- 56 unchanged lines hidden (view full) ---

65 { IFF_STANDBY, "STANDBY" },
66 { IFF_INACTIVE, "INACTIVE" },
67 { IFF_OFFLINE, "OFFLINE" },
68 { IFF_XRESOLV, "XRESOLV" },
69 { IFF_COS_ENABLED, "CoS" },
70 { IFF_PREFERRED, "PREFERRED" },
71 { IFF_TEMPORARY, "TEMPORARY" },
72 { IFF_FIXEDMTU, "FIXEDMTU" },
1/*
2 * Copyright 2006 Sun Microsystems, Inc. All rights reserved.
3 * Use is subject to license terms.
4 */
5/*
6 * Copyright (c) 1983 Regents of the University of California.
7 * All rights reserved. The Berkeley software License Agreement
8 * specifies the terms and conditions for redistribution.

--- 56 unchanged lines hidden (view full) ---

65 { IFF_STANDBY, "STANDBY" },
66 { IFF_INACTIVE, "INACTIVE" },
67 { IFF_OFFLINE, "OFFLINE" },
68 { IFF_XRESOLV, "XRESOLV" },
69 { IFF_COS_ENABLED, "CoS" },
70 { IFF_PREFERRED, "PREFERRED" },
71 { IFF_TEMPORARY, "TEMPORARY" },
72 { IFF_FIXEDMTU, "FIXEDMTU" },
73 { IFF_VIRTUAL, "VIRTUAL"}
73 { IFF_VIRTUAL, "VIRTUAL" },
74 { IFF_DUPLICATE, "DUPLICATE" }
74};
75
76static struct lifreq lifr;
77/* current interface name a particular function is accessing */
78static char name[LIFNAMSIZ];
79/* foreach interface saved name */
80static char origname[LIFNAMSIZ];
81static char savedname[LIFNAMSIZ]; /* For addif */

--- 85 unchanged lines hidden (view full) ---

167/*
168 * Misc support functions
169 */
170static int devfs_entry(di_node_t node, di_minor_t minor, void *arg);
171static void foreachinterface(void (*func)(), int argc, char *argv[],
172 int af, int64_t onflags, int64_t offflags,
173 int64_t lifc_flags);
174static void ifconfig(int argc, char *argv[], int af, struct lifreq *lifrp);
75};
76
77static struct lifreq lifr;
78/* current interface name a particular function is accessing */
79static char name[LIFNAMSIZ];
80/* foreach interface saved name */
81static char origname[LIFNAMSIZ];
82static char savedname[LIFNAMSIZ]; /* For addif */

--- 85 unchanged lines hidden (view full) ---

168/*
169 * Misc support functions
170 */
171static int devfs_entry(di_node_t node, di_minor_t minor, void *arg);
172static void foreachinterface(void (*func)(), int argc, char *argv[],
173 int af, int64_t onflags, int64_t offflags,
174 int64_t lifc_flags);
175static void ifconfig(int argc, char *argv[], int af, struct lifreq *lifrp);
175static int ifdad(char *ifname, struct sockaddr_in6 *laddr);
176static boolean_t in_getmask(struct sockaddr_in *saddr,
177 boolean_t addr_set);
178static int in_getprefixlen(char *addr, boolean_t slash, int plen);
179static boolean_t in_prefixlentomask(int prefixlen, int maxlen,
180 uchar_t *mask);
181static int settaddr(char *, int (*)(icfg_handle_t,
182 const struct sockaddr *, socklen_t));
183static void status(void);

--- 817 unchanged lines hidden (view full) ---

1001 setaddr++;
1002 /* save copy of netmask to restore in case of error */
1003 (void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
1004 if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0)
1005 Perror0_exit("SIOCGLIFNETMASK");
1006 sav_netmask = lifr.lifr_addr;
1007
1008 /*
176static boolean_t in_getmask(struct sockaddr_in *saddr,
177 boolean_t addr_set);
178static int in_getprefixlen(char *addr, boolean_t slash, int plen);
179static boolean_t in_prefixlentomask(int prefixlen, int maxlen,
180 uchar_t *mask);
181static int settaddr(char *, int (*)(icfg_handle_t,
182 const struct sockaddr *, socklen_t));
183static void status(void);

--- 817 unchanged lines hidden (view full) ---

1001 setaddr++;
1002 /* save copy of netmask to restore in case of error */
1003 (void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
1004 if (ioctl(s, SIOCGLIFNETMASK, (caddr_t)&lifr) < 0)
1005 Perror0_exit("SIOCGLIFNETMASK");
1006 sav_netmask = lifr.lifr_addr;
1007
1008 /*
1009 * Catch set of address for AF_INET6 to perform
1010 * duplicate address detection. Check that the interface is
1011 * up.
1012 */
1013 if (afp->af_af == AF_INET6) {
1014 if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr) < 0) {
1015 Perror0_exit("ifsetaddr: SIOCGLIFFLAGS");
1016 }
1017 if (lifr.lifr_flags & IFF_UP) {
1018 if (debug)
1019 (void) printf(
1020 "setifaddr: Calling ifdad flags %llx\n",
1021 lifr.lifr_flags);
1022 if (ifdad(name, (struct sockaddr_in6 *)&laddr) == -1)
1023 exit(3);
1024 }
1025 }
1026
1027 /*
1028 * If setting the address and not the mask, clear any existing mask
1029 * and the kernel will then assign the default (netmask has been set
1030 * to 0 in this case). If setting both (either by using a prefix or
1031 * using the netmask command), set the mask first, so the address will
1032 * be interpreted correctly.
1033 */
1034 set_mask_lifreq(&lifr, &laddr, &netmask);
1035 if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)

--- 445 unchanged lines hidden (view full) ---

1481 strncmp(name, origname, phyintlen) != 0) {
1482 (void) fprintf(stderr, "ifconfig: can't set -failover "
1483 "on failed/standby/offlined interface %s\n",
1484 origname);
1485 exit(1);
1486 }
1487 }
1488
1009 * If setting the address and not the mask, clear any existing mask
1010 * and the kernel will then assign the default (netmask has been set
1011 * to 0 in this case). If setting both (either by using a prefix or
1012 * using the netmask command), set the mask first, so the address will
1013 * be interpreted correctly.
1014 */
1015 set_mask_lifreq(&lifr, &laddr, &netmask);
1016 if (ioctl(s, SIOCSLIFNETMASK, (caddr_t)&lifr) < 0)

--- 445 unchanged lines hidden (view full) ---

1462 strncmp(name, origname, phyintlen) != 0) {
1463 (void) fprintf(stderr, "ifconfig: can't set -failover "
1464 "on failed/standby/offlined interface %s\n",
1465 origname);
1466 exit(1);
1467 }
1468 }
1469
1489 /*
1490 * Catch "up" transition for AF_INET6 to perform duplicate address
1491 * detection. ifdad checks if an address has been set.
1492 */
1493 if (afp->af_af == AF_INET6 && !(lifr.lifr_flags & IFF_UP) &&
1494 value == IFF_UP) {
1495 if (debug)
1496 (void) printf(
1497 "setifaddr:Calling ifdad flags %llx value 0x%llx\n",
1498 lifr.lifr_flags, value);
1499 if (ifdad(name, NULL) == -1)
1500 exit(1);
1501 }
1502
1503 if (value < 0) {
1504 value = -value;
1505 lifr.lifr_flags &= ~value;
1470 if (value < 0) {
1471 value = -value;
1472 lifr.lifr_flags &= ~value;
1506 } else
1473 if ((value & IFF_UP) && (lifr.lifr_flags & IFF_DUPLICATE)) {
1474 /*
1475 * If the user is trying to mark an interface with a
1476 * duplicate address as "down," then fetch the address
1477 * and set it. This will cause IP to clear the
1478 * IFF_DUPLICATE flag and stop the automatic recovery
1479 * timer.
1480 */
1481 value = lifr.lifr_flags;
1482 if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr) >= 0)
1483 (void) ioctl(s, SIOCSLIFADDR, (caddr_t)&lifr);
1484 lifr.lifr_flags = value;
1485 }
1486 } else {
1507 lifr.lifr_flags |= value;
1487 lifr.lifr_flags |= value;
1488 }
1508 (void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
1509 if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
1510 Perror0_exit("setifflags: SIOCSLIFFLAGS");
1511 }
1512 return (0);
1513}
1514
1515/* ARGSUSED */

--- 437 unchanged lines hidden (view full) ---

1953 exit(1);
1954 }
1955 Perror0_exit("removeif: SIOCLIFREMOVEIF");
1956 }
1957 return (0);
1958}
1959
1960/*
1489 (void) strncpy(lifr.lifr_name, name, sizeof (lifr.lifr_name));
1490 if (ioctl(s, SIOCSLIFFLAGS, (caddr_t)&lifr) < 0) {
1491 Perror0_exit("setifflags: SIOCSLIFFLAGS");
1492 }
1493 return (0);
1494}
1495
1496/* ARGSUSED */

--- 437 unchanged lines hidden (view full) ---

1934 exit(1);
1935 }
1936 Perror0_exit("removeif: SIOCLIFREMOVEIF");
1937 }
1938 return (0);
1939}
1940
1941/*
1961 * If laddr is non-NULL it is used - otherwise we use the address on
1962 * the interface.
1963 */
1964/* ARGSUSED */
1965static int
1966ifdad(char *ifname, struct sockaddr_in6 *laddr)
1967{
1968 struct sockaddr_in6 testaddr;
1969 struct lifreq lifr2; /* Avoid overriting lifr */
1970
1971 if (debug)
1972 (void) printf("ifdad(%s)\n", ifname);
1973
1974 assert(afp->af_af == AF_INET6);
1975
1976 /*
1977 * Check the address assigned to the interface.
1978 * Skip the check if IFF_NOLOCAL, IFF_NONUD, IFF_ANYCAST, or
1979 * IFF_LOOPBACK.
1980 * Note that IFF_NONUD turns of both NUD and DAD.
1981 */
1982 (void) strncpy(lifr2.lifr_name, ifname,
1983 sizeof (lifr2.lifr_name));
1984 if (ioctl(s, SIOCGLIFFLAGS, (caddr_t)&lifr2) < 0) {
1985 Perror0_exit("ifdad: SIOCGLIFFLAGS");
1986 }
1987 if (lifr2.lifr_flags & (IFF_NOLOCAL|IFF_LOOPBACK|IFF_NONUD|IFF_ANYCAST))
1988 return (0);
1989
1990 if (laddr != NULL) {
1991 testaddr = *laddr;
1992 } else {
1993 if (ioctl(s, SIOCGLIFADDR, (caddr_t)&lifr2) < 0) {
1994 Perror0_exit("ifdad: SIOCGLIFADDR");
1995 }
1996 testaddr = *(struct sockaddr_in6 *)&lifr2.lifr_addr;
1997 }
1998
1999 if (IN6_IS_ADDR_UNSPECIFIED(&testaddr.sin6_addr))
2000 return (0);
2001
2002 if (do_dad(name, &testaddr) != 0)
2003 return (-1);
2004 else
2005 return (0);
2006}
2007
2008/*
2009 * Set the address token for IPv6.
2010 */
2011/* ARGSUSED */
2012static int
2013setiftoken(char *addr, int64_t param)
2014{
2015 int prefixlen = 0;
2016 struct sockaddr_in6 token;

--- 2112 unchanged lines hidden (view full) ---

4129 * If the last argument is non-NULL allow a <addr>/<n> syntax and
4130 * pass out <n> in *plenp.
4131 * If <n> doesn't parse return BAD_ADDR as *plenp.
4132 * If no /<n> is present return NO_PREFIX as *plenp.
4133 */
4134static void
4135in_getaddr(char *s, struct sockaddr *saddr, int *plenp)
4136{
1942 * Set the address token for IPv6.
1943 */
1944/* ARGSUSED */
1945static int
1946setiftoken(char *addr, int64_t param)
1947{
1948 int prefixlen = 0;
1949 struct sockaddr_in6 token;

--- 2112 unchanged lines hidden (view full) ---

4062 * If the last argument is non-NULL allow a <addr>/<n> syntax and
4063 * pass out <n> in *plenp.
4064 * If <n> doesn't parse return BAD_ADDR as *plenp.
4065 * If no /<n> is present return NO_PREFIX as *plenp.
4066 */
4067static void
4068in_getaddr(char *s, struct sockaddr *saddr, int *plenp)
4069{
4070 /* LINTED: alignment */
4137 struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
4138 struct hostent *hp;
4139 struct netent *np;
4140 char str[BUFSIZ];
4141 int error_num;
4142
4143 (void) strncpy(str, s, sizeof (str));
4144

--- 52 unchanged lines hidden (view full) ---

4197 * If the last argument is non-NULL allow a <addr>/<n> syntax and
4198 * pass out <n> in *plenp.
4199 * If <n> doesn't parse return BAD_ADDR as *plenp.
4200 * If no /<n> is present return NO_PREFIX as *plenp.
4201 */
4202static void
4203in6_getaddr(char *s, struct sockaddr *saddr, int *plenp)
4204{
4071 struct sockaddr_in *sin = (struct sockaddr_in *)saddr;
4072 struct hostent *hp;
4073 struct netent *np;
4074 char str[BUFSIZ];
4075 int error_num;
4076
4077 (void) strncpy(str, s, sizeof (str));
4078

--- 52 unchanged lines hidden (view full) ---

4131 * If the last argument is non-NULL allow a <addr>/<n> syntax and
4132 * pass out <n> in *plenp.
4133 * If <n> doesn't parse return BAD_ADDR as *plenp.
4134 * If no /<n> is present return NO_PREFIX as *plenp.
4135 */
4136static void
4137in6_getaddr(char *s, struct sockaddr *saddr, int *plenp)
4138{
4139 /* LINTED: alignment */
4205 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
4206 struct hostent *hp;
4207 char str[BUFSIZ];
4208 int error_num;
4209
4210 (void) strncpy(str, s, sizeof (str));
4211
4212 /*

--- 446 unchanged lines hidden ---
4140 struct sockaddr_in6 *sin6 = (struct sockaddr_in6 *)saddr;
4141 struct hostent *hp;
4142 char str[BUFSIZ];
4143 int error_num;
4144
4145 (void) strncpy(str, s, sizeof (str));
4146
4147 /*

--- 446 unchanged lines hidden ---