int eth_set(eth_t *e, const eth_addr_t *ea) { union DL_primitives *dlp; u_char buf[2048]; dlp = (union DL_primitives *)buf; dlp->set_physaddr_req.dl_primitive = DL_SET_PHYS_ADDR_REQ; dlp->set_physaddr_req.dl_addr_length = ETH_ADDR_LEN; dlp->set_physaddr_req.dl_addr_offset = DL_SET_PHYS_ADDR_REQ_SIZE; memcpy(buf + DL_SET_PHYS_ADDR_REQ_SIZE, ea, sizeof(*ea)); return (dlpi_msg(e->fd, dlp, DL_SET_PHYS_ADDR_REQ_SIZE + ETH_ADDR_LEN, 0, DL_OK_ACK, DL_OK_ACK_SIZE, sizeof(buf))); }
int eth_get(eth_t *e, eth_addr_t *ea) { union DL_primitives *dlp; u_char buf[2048]; dlp = (union DL_primitives *)buf; dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ; dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR; if (dlpi_msg(e->fd, dlp, DL_PHYS_ADDR_REQ_SIZE, 0, DL_PHYS_ADDR_ACK, DL_PHYS_ADDR_ACK_SIZE, sizeof(buf)) < 0) return (-1); memcpy(ea, buf + dlp->physaddr_ack.dl_addr_offset, sizeof(*ea)); return (0); }
/* * get_hardware_address -- Get the Ethernet MAC address associated * with the given device. * Inputs: * * if_name The name of the network interface * hw_address (output) the Ethernet MAC address * * Returns: * * None */ void get_hardware_address(const char *if_name, unsigned char hw_address[]) { union DL_primitives *dlp; unsigned char buf[MAXDLBUF]; link_t *handle; handle = link_open(if_name); dlp = (union DL_primitives*) buf; dlp->physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ; dlp->physaddr_req.dl_addr_type = DL_CURR_PHYS_ADDR; if (dlpi_msg(handle->fd, dlp, DL_PHYS_ADDR_REQ_SIZE, 0, DL_PHYS_ADDR_ACK, DL_PHYS_ADDR_ACK_SIZE, sizeof(buf)) < 0) { err_msg("dlpi_msg failed"); } link_close(handle); memcpy(hw_address, buf + dlp->physaddr_ack.dl_addr_offset, ETH_ALEN); }
/* * link_open -- Open the specified link-level device * * Inputs: * * device The name of the device to open * * Returns: * * A pointer to a link handle structure. */ static link_t * link_open(const char *device) { union DL_primitives *dlp; unsigned char buf[MAXDLBUF]; char *p; char dev[16]; link_t *handle; int ppa; handle = Malloc(sizeof(*handle)); memset(handle, '\0', sizeof(*handle)); #ifdef HAVE_SYS_DLPIHDR_H if ((handle->fd = open("/dev/streams/dlb", O_RDWR)) < 0) { free(handle); return NULL; } if ((ppa = link_match_ppa(handle, device)) < 0) { link_close(handle); return NULL; } #else handle->fd = -1; snprintf(dev, sizeof(dev), "/dev/%s", device); if ((p = strpbrk(dev, "0123456789")) == NULL) { link_close(handle); return NULL; } ppa = atoi(p); *p = '\0'; if ((handle->fd = open(dev, O_RDWR)) < 0) { snprintf(dev, sizeof(dev), "/dev/%s", device); if ((handle->fd = open(dev, O_RDWR)) < 0) { link_close(handle); return NULL; } } #endif memset(&(handle->ifr), 0, sizeof(struct ifreq)); strlcpy(handle->ifr.ifr_name, device, sizeof(handle->ifr.ifr_name)); dlp = (union DL_primitives *)buf; dlp->info_req.dl_primitive = DL_INFO_REQ; if (dlpi_msg(handle->fd, dlp, DL_INFO_REQ_SIZE, RS_HIPRI, DL_INFO_ACK, DL_INFO_ACK_SIZE, sizeof(buf)) < 0) { link_close(handle); return NULL; } handle->sap_first = (dlp->info_ack.dl_sap_length > 0); if (dlp->info_ack.dl_provider_style == DL_STYLE2) { dlp->attach_req.dl_primitive = DL_ATTACH_REQ; dlp->attach_req.dl_ppa = ppa; if (dlpi_msg(handle->fd, dlp, DL_ATTACH_REQ_SIZE, 0, DL_OK_ACK, DL_OK_ACK_SIZE, sizeof(buf)) < 0) { link_close(handle); return NULL; } } memset(&dlp->bind_req, 0, DL_BIND_REQ_SIZE); dlp->bind_req.dl_primitive = DL_BIND_REQ; #ifdef DL_HP_RAWDLS dlp->bind_req.dl_sap = 24; /* from HP-UX DLPI programmers guide */ dlp->bind_req.dl_service_mode = DL_HP_RAWDLS; #else dlp->bind_req.dl_sap = DL_ETHER; dlp->bind_req.dl_service_mode = DL_CLDLS; #endif if (dlpi_msg(handle->fd, dlp, DL_BIND_REQ_SIZE, 0, DL_BIND_ACK, DL_BIND_ACK_SIZE, sizeof(buf)) < 0) { link_close(handle); return NULL; } #ifdef DLIOCRAW if (strioctl(handle->fd, DLIOCRAW, 0, NULL) < 0) { link_close(handle); return NULL; } #endif return (handle); }
eth_t * eth_open(const char *device) { union DL_primitives *dlp; uint32_t buf[8192]; char *p, dev[16]; eth_t *e; int ppa; if ((e = calloc(1, sizeof(*e))) == NULL) return (NULL); #ifdef HAVE_SYS_DLPIHDR_H if ((e->fd = open("/dev/streams/dlb", O_RDWR)) < 0) return (eth_close(e)); if ((ppa = eth_match_ppa(e, device)) < 0) { errno = ESRCH; return (eth_close(e)); } #else e->fd = -1; snprintf(dev, sizeof(dev), "/dev/%s", device); if ((p = strpbrk(dev, "0123456789")) == NULL) { errno = EINVAL; return (eth_close(e)); } ppa = atoi(p); *p = '\0'; if ((e->fd = open(dev, O_RDWR)) < 0) { snprintf(dev, sizeof(dev), "/dev/%s", device); if ((e->fd = open(dev, O_RDWR)) < 0) return (eth_close(e)); } #endif dlp = (union DL_primitives *)buf; dlp->info_req.dl_primitive = DL_INFO_REQ; if (dlpi_msg(e->fd, dlp, DL_INFO_REQ_SIZE, RS_HIPRI, DL_INFO_ACK, DL_INFO_ACK_SIZE, sizeof(buf)) < 0) return (eth_close(e)); e->sap_len = dlp->info_ack.dl_sap_length; if (dlp->info_ack.dl_provider_style == DL_STYLE2) { dlp->attach_req.dl_primitive = DL_ATTACH_REQ; dlp->attach_req.dl_ppa = ppa; if (dlpi_msg(e->fd, dlp, DL_ATTACH_REQ_SIZE, 0, DL_OK_ACK, DL_OK_ACK_SIZE, sizeof(buf)) < 0) return (eth_close(e)); } memset(&dlp->bind_req, 0, DL_BIND_REQ_SIZE); dlp->bind_req.dl_primitive = DL_BIND_REQ; #ifdef DL_HP_RAWDLS dlp->bind_req.dl_sap = 24; /* from HP-UX DLPI programmers guide */ dlp->bind_req.dl_service_mode = DL_HP_RAWDLS; #else dlp->bind_req.dl_sap = DL_ETHER; dlp->bind_req.dl_service_mode = DL_CLDLS; #endif if (dlpi_msg(e->fd, dlp, DL_BIND_REQ_SIZE, 0, DL_BIND_ACK, DL_BIND_ACK_SIZE, sizeof(buf)) < 0) return (eth_close(e)); #ifdef DLIOCRAW if (strioctl(e->fd, DLIOCRAW, 0, NULL) < 0) return (eth_close(e)); #endif return (e); }