Пример #1
0
static int dlpi_get_ifmib(struct dlpi_driver_data *dlpi, int ppa, mib_ifEntry *mib) {
  dl_get_statistics_req_t stats_req;
  dl_get_statistics_ack_t *stats_ack;
  int len;

  /* first attach to PPA */
  if (!dlpi_attach(dlpi, ppa))
    return 0;

  /* grab stats */
  stats_req.dl_primitive = DL_GET_STATISTICS_REQ;
  if (!dlpi_req(dlpi, &stats_req, sizeof(dl_get_statistics_req_t), 
		DL_GET_STATISTICS_ACK, (void **) &stats_ack, &len))
    return 0;

  if (len < sizeof(dl_get_statistics_ack_t) ||
      stats_ack->dl_stat_offset < 0 || 
      stats_ack->dl_stat_offset + sizeof(mib_ifEntry) > len) {
    ifstat_error("dlpi: invalid data returned by stats ack");
  }

  memcpy(mib, (char *) stats_ack + stats_ack->dl_stat_offset,
	 sizeof(mib_ifEntry));

  return 1;
}
Пример #2
0
static int dlpi_map_ifs(struct dlpi_driver_data *dlpi,
			int (*mapf)(mib_ifEntry *mib, int ppa, char *name,
				    void *mdata),
			void *mdata) {
  dl_hp_ppa_req_t ppa_req;
  dl_hp_ppa_ack_t *ppa_ack;
  dl_hp_ppa_info_t *ppa_info;
  mib_ifEntry mib;
  void *buf;
  int len, i, ofs;
  char ifname[sizeof(ppa_info->dl_module_id_1) + 12];

  if (!dlpi_attach(dlpi, DLPI_NO_PPA))
    return 0;

  ppa_req.dl_primitive = DL_HP_PPA_REQ;
  if (!dlpi_req(dlpi, &ppa_req, sizeof(ppa_req),
		DL_HP_PPA_ACK, (void **) &ppa_ack, &len))
    return 0;

  if (len < sizeof(dl_hp_ppa_ack_t)) {
    ifstat_error("dlpi: short read for ppa ack");
    return 0;
  }

  /* copy buffer since used by later calls */
  if ((buf = malloc(len)) == NULL) {
    perror("malloc");
    return 0;
  }
  memcpy(buf, (void *) ppa_ack, len);
  ppa_ack = buf;
  
  /* browse interface list */
  ofs = ppa_ack->dl_offset;
  for(i = 0; i < ppa_ack->dl_count; i++) {
    if (ofs < 0 || ofs + sizeof(dl_hp_ppa_info_t) > len) {
      ifstat_error("dlpi: data returned by ppa ack exceeds data buffer");
      free(buf);
      return 0;
    }

    ppa_info = (dl_hp_ppa_info_t *) ((char *) ppa_ack + ofs);

    if (dlpi_get_ifmib(dlpi, ppa_info->dl_ppa, &mib)) {
      sprintf(ifname, "%s%d", ppa_info->dl_module_id_1, ppa_info->dl_instance_num);
      if (!mapf(&mib, ppa_info->dl_ppa, ifname, mdata)) {
	free(buf);
	return 0;
      }
    }
    
    ofs = ppa_ack->dl_offset + ppa_info->dl_next_offset;
  }

  free(buf);
  return 1;
}
Пример #3
0
int
main(int argc, char **argv)
{
	char cnambuf[MAXPATHLEN];
	struct scc_mode sm;
	struct strioctl sioc;
	int fd, speed;
	char *arg, *cp;
	char loopchange = 0;
	char echochange = 0;
	char clockchange = 0;
	char *devstr =  "/dev/";
	int devstrlen;
	ulong_t ppa;

	if (argc == 1) {
		usage();
		exit(1);
	}
	argc--;
	argv++;
	devstrlen = strlen(devstr);
	if (strncmp(devstr, argv[0], devstrlen) != 0) {
		if (snprintf(cnambuf, sizeof (cnambuf), "%s%s", devstr,
		    argv[0]) >= sizeof (cnambuf)) {
			(void) fprintf(stderr,
			    "syncinit: invalid device name (too long) %s\n",
			    argv[0]);
			exit(1);
		}
	}
	cp = cnambuf;
	while (*cp)			/* find the end of the name */
		cp++;
	cp--;
	if (!isdigit(*cp)) {
		(void) fprintf(stderr,
			"syncinit: %s missing minor device number\n", argv[0]);
		exit(1);
	}
	while (isdigit(*(cp - 1)))
		cp--;
	ppa = strtoul(cp, NULL, 10);
	*cp = '\0';	/* drop number, leaving name of clone device. */
	fd = open(cnambuf, O_RDWR|O_EXCL, 0);
	if (fd < 0) {
		perror("syncinit: open");
		exit(1);
	}

	if (dlpi_attach(fd, MAXWAIT, ppa) != 0) {
		perror("syncinit: dlpi_attach");
		exit(1);
	}

	(void) printf("device: %s  ppa: %d\n", cnambuf, (int)ppa);

	argc--;
	argv++;
	if (argc) {	/* setting things */
		sioc.ic_cmd = S_IOCGETMODE;
		sioc.ic_timout = -1;
		sioc.ic_len = sizeof (struct scc_mode);
		sioc.ic_dp = (char *)&sm;
		if (ioctl(fd, I_STR, &sioc) < 0) {
			perror("S_IOCGETMODE");
			(void) fprintf(stderr,
				"syncinit: can't get sync mode info for %s\n",
				cnambuf);
			exit(1);
		}
		while (argc-- > 0) {
			arg = *argv++;
			if (sscanf(arg, "%d", &speed) == 1)
				sm.sm_baudrate = speed;
			else if (strchr(arg, '=')) {
				if (prefix(arg, "loop")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_LPBK;
					else
						sm.sm_config &= ~CONN_LPBK;
					loopchange++;
				} else if (prefix(arg, "echo")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_ECHO;
					else
						sm.sm_config &= ~CONN_ECHO;
					echochange++;
				} else if (prefix(arg, "nrzi")) {
					if (lookup(yesno, arg))
						sm.sm_config |= CONN_NRZI;
					else
						sm.sm_config &= ~CONN_NRZI;
				} else if (prefix(arg, "txc")) {
					sm.sm_txclock = lookup(txnames, arg);
					clockchange++;
				} else if (prefix(arg, "rxc")) {
					sm.sm_rxclock = lookup(rxnames, arg);
					clockchange++;
				} else if (prefix(arg, "speed")) {
					arg = strchr(arg, '=') + 1;
					if (sscanf(arg, "%d", &speed) == 1) {
						sm.sm_baudrate = speed;
					} else
						(void) fprintf(stderr,
						    "syncinit: %s %s\n",
						    "bad speed:", arg);
				}
			} else if (equal(arg, "external")) {
				sm.sm_txclock = TXC_IS_TXC;
				sm.sm_rxclock = RXC_IS_RXC;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "sender")) {
				sm.sm_txclock = TXC_IS_BAUD;
				sm.sm_rxclock = RXC_IS_RXC;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "internal")) {
				sm.sm_txclock = TXC_IS_PLL;
				sm.sm_rxclock = RXC_IS_PLL;
				sm.sm_config &= ~CONN_LPBK;
			} else if (equal(arg, "stop")) {
				sm.sm_baudrate = 0;
			} else
				(void) fprintf(stderr, "Bad arg: %s\n", arg);
		}

		/*
		 * If we're going to change the state of loopback, and we
		 * don't have our own plans for clock sources, use defaults.
		 */
		if (loopchange && !clockchange) {
			if (sm.sm_config & CONN_LPBK) {
				sm.sm_txclock = TXC_IS_BAUD;
				sm.sm_rxclock = RXC_IS_BAUD;
			} else {
				sm.sm_txclock = TXC_IS_TXC;
				sm.sm_rxclock = RXC_IS_RXC;
			}
		}
		sioc.ic_cmd = S_IOCSETMODE;
		sioc.ic_timout = -1;
		sioc.ic_len = sizeof (struct scc_mode);
		sioc.ic_dp = (char *)&sm;
		if (ioctl(fd, I_STR, &sioc) < 0) {
			perror("S_IOCSETMODE");
			(void) ioctl(fd, S_IOCGETMODE, &sm);
			(void) fprintf(stderr,
				"syncinit: ioctl failure code = %x\n",
				sm.sm_retval);
			exit(1);
		}
	}

	/* Report State */
	sioc.ic_cmd = S_IOCGETMODE;
	sioc.ic_timout = -1;
	sioc.ic_len = sizeof (struct scc_mode);
	sioc.ic_dp = (char *)&sm;
	if (ioctl(fd, I_STR, &sioc) < 0) {
		perror("S_IOCGETMODE");
		(void) fprintf(stderr,
			"syncinit: can't get sync mode info for %s\n",
			cnambuf);
		exit(1);
	}
	(void) printf(
"speed=%d, loopback=%s, echo=%s, nrzi=%s, txc=%s, rxc=%s\n",
		sm.sm_baudrate,
		yesno[((int)(sm.sm_config & CONN_LPBK) > 0)],
		yesno[((int)(sm.sm_config & CONN_ECHO) > 0)],
		yesno[((int)(sm.sm_config & CONN_NRZI) > 0)],
		txnames[sm.sm_txclock],
		rxnames[sm.sm_rxclock]);
	return (0);
}