static int parse_addr(struct in_addr *addr, struct in_addr *net, const char *arg) { char *p; int i; if (arg == NULL || *arg == '\0') { if (addr != NULL) addr->s_addr = 0; if (net != NULL) net->s_addr = 0; return 0; } if ((p = strchr(arg, '/')) != NULL) { *p++ = '\0'; if (net != NULL && (sscanf(p, "%d", &i) != 1 || inet_cidrtoaddr(i, net) != 0)) { syslog(LOG_ERR, "`%s' is not a valid CIDR", p); return -1; } } if (addr != NULL && inet_aton(arg, addr) == 0) { syslog(LOG_ERR, "`%s' is not a valid IP address", arg); return -1; } if (p != NULL) *--p = '/'; else if (net != NULL && addr != NULL) net->s_addr = ipv4_getnetmask(addr->s_addr); return 0; }
/* ARGSUSED */ static int ibd_output(int index, struct inetgram *ogp) { int header_len, result; ipoib_ptxhdr_t eh; struct ip *ip; struct in_addr tmpip, ipdst; int broadcast = FALSE; int size; mblk_t *mp; if (!initialized) prom_panic("IPoIB device is not initialized."); if (ogp->igm_level != MEDIA_LVL) { dprintf("ibd_output: frame type wrong: socket: %d\n", index * SOCKETTYPE); errno = EINVAL; return (-1); } header_len = IPOIB_HDRSIZE + IPOIB_ADDRL; mp = ogp->igm_mp; size = mp->b_wptr - mp->b_rptr; if (size > (mac_state.mac_mtu - IPOIB_ADDRL)) { dprintf("ibd_output: frame size too big: %d\n", size); errno = E2BIG; return (-1); } size += header_len; ip = (struct ip *)(mp->b_rptr); eh.ipoib_rhdr.ipoib_type = htons(ETHERTYPE_IP); eh.ipoib_rhdr.ipoib_mbz = 0; bcopy((caddr_t)&ip->ip_dst, (caddr_t)&ipdst, sizeof (ipdst)); if (ipdst.s_addr == htonl(INADDR_BROADCAST)) broadcast = TRUE; /* limited broadcast */ if (!broadcast) { struct in_addr mask; ipv4_getnetmask(&mask); mask.s_addr = htonl(mask.s_addr); if (mask.s_addr != htonl(INADDR_BROADCAST) && (ipdst.s_addr & ~mask.s_addr) == 0) { broadcast = TRUE; /* directed broadcast */ } else { if (ogp->igm_router.s_addr != htonl(INADDR_ANY)) tmpip.s_addr = ogp->igm_router.s_addr; else tmpip.s_addr = ipdst.s_addr; result = mac_get_arp(&tmpip, (void *)&eh.ipoib_dest, IPOIB_ADDRL, mac_state.mac_arp_timeout); if (!result) { errno = ETIMEDOUT; dprintf("ibd_output: ARP request for %s " "timed out.\n", inet_ntoa(tmpip)); return (-1); } } } if (broadcast) bcopy((caddr_t)&ibdbroadcastaddr, (caddr_t)&eh.ipoib_dest, IPOIB_ADDRL); /* add the ibd header */ mp->b_rptr -= sizeof (eh); bcopy((caddr_t)&eh, mp->b_rptr, sizeof (eh)); #ifdef DEBUG printf("ibd_output(%d): level(%d) frame(0x%x) len(%d)\n", index, ogp->igm_level, mp->b_rptr, size); #endif /* DEBUG */ return (prom_write(mac_state.mac_dev, (char *)mp->b_rptr, size, 0, NETWORK)); }