+ safe_strncpy(host, *argv, (sizeof host));
+#ifdef CONFIG_FEATURE_IPV6
+ if ((prefix = strchr(host, '/'))) {
+ if (safe_strtoi(prefix + 1, &prefix_len) ||
+ (prefix_len < 0) || (prefix_len > 128))
+ {
+ ++goterr;
+ goto LOOP;
+ }
+ *prefix = 0;
+ }
+#endif
+
+ sai.sin_family = AF_INET;
+ sai.sin_port = 0;
+ if (!strcmp(host, bb_INET_default)) {
+ /* Default is special, meaning 0.0.0.0. */
+ sai.sin_addr.s_addr = INADDR_ANY;
+#ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
+ } else if (((host[0] == '+') && !host[1]) && (mask & A_BROADCAST) &&
+ (did_flags & (A_NETMASK|A_HOSTNAME)) == (A_NETMASK|A_HOSTNAME)) {
+ /* + is special, meaning broadcast is derived. */
+ sai.sin_addr.s_addr = (~sai_netmask) | (sai_hostname & sai_netmask);
+#endif
+#ifdef CONFIG_FEATURE_IPV6
+ } else if (inet_pton(AF_INET6, host, &sai6.sin6_addr) > 0) {
+ int sockfd6;
+ struct in6_ifreq ifr6;
+
+ memcpy((char *) &ifr6.ifr6_addr,
+ (char *) &sai6.sin6_addr,
+ sizeof(struct in6_addr));
+
+ /* Create a channel to the NET kernel. */
+ if ((sockfd6 = socket(AF_INET6, SOCK_DGRAM, 0)) < 0) {
+ bb_perror_msg_and_die("socket6");
+ }
+ if (ioctl(sockfd6, SIOGIFINDEX, &ifr) < 0) {
+ perror("SIOGIFINDEX");
+ ++goterr;
+ continue;
+ }
+ ifr6.ifr6_ifindex = ifr.ifr_ifindex;
+ ifr6.ifr6_prefixlen = prefix_len;
+ if (ioctl(sockfd6, a1op->selector, &ifr6) < 0) {
+ perror(a1op->name);
+ ++goterr;
+ }
+ continue;
+#endif
+ } else if (inet_aton(host, &sai.sin_addr) == 0) {
+ /* It's not a dotted quad. */
+ struct hostent *hp;
+ if ((hp = gethostbyname(host)) == (struct hostent *)NULL) {
+ ++goterr;
+ continue;
+ }
+ memcpy((char *) &sai.sin_addr, (char *) hp->h_addr_list[0],
+ sizeof(struct in_addr));
+ }
+#ifdef CONFIG_FEATURE_IFCONFIG_BROADCAST_PLUS
+ if (mask & A_HOSTNAME) {
+ sai_hostname = sai.sin_addr.s_addr;
+ }
+ if (mask & A_NETMASK) {
+ sai_netmask = sai.sin_addr.s_addr;
+ }
+#endif
+ p = (char *) &sai;
+#ifdef CONFIG_FEATURE_IFCONFIG_HW
+ } else { /* A_CAST_HOST_COPY_IN_ETHER */
+ /* This is the "hw" arg case. */
+ if (strcmp("ether", *argv) || (*++argv == NULL)) {
+ bb_show_usage();
+ }
+ safe_strncpy(host, *argv, (sizeof host));
+ if (in_ether(host, &sa)) {
+ bb_error_msg("invalid hw-addr %s", host);
+ ++goterr;
+ continue;
+ }
+ p = (char *) &sa;
+ }
+#endif
+ memcpy((((char *) (&ifr)) + a1op->ifr_offset),
+ p, sizeof(struct sockaddr));
+ } else {
+ unsigned long i = strtoul(*argv, NULL, 0);
+
+ p = ((char *) (&ifr)) + a1op->ifr_offset;
+#ifdef CONFIG_FEATURE_IFCONFIG_MEMSTART_IOADDR_IRQ
+ if (mask & A_MAP_TYPE) {
+ if (ioctl(sockfd, SIOCGIFMAP, &ifr) < 0) {
+ ++goterr;
+ continue;
+ }
+ if ((mask & A_MAP_UCHAR) == A_MAP_UCHAR) {
+ *((unsigned char *) p) = i;
+ } else if (mask & A_MAP_USHORT) {
+ *((unsigned short *) p) = i;
+ } else {
+ *((unsigned long *) p) = i;
+ }
+ } else
+#endif
+ if (mask & A_CAST_CHAR_PTR) {
+ *((caddr_t *) p) = (caddr_t) i;
+ } else { /* A_CAST_INT */
+ *((int *) p) = i;
+ }