예제 #1
0
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)));
}
예제 #2
0
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);
}
예제 #3
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);
}
예제 #4
0
/*
 *	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);
}
예제 #5
0
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);
}