⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 sys-solaris.c

📁 自己精简过的PPPD代码。在嵌入中应用可以更好的发挥。比原先的小了很多
💻 C
📖 第 1 页 / 共 5 页
字号:
}/* * get_hw_addr_dlpi - obtain the hardware address using DLPI */static intget_hw_addr_dlpi(name, hwaddr)    char *name;    struct sockaddr *hwaddr;{    char *p, *q;    int unit, iffd, adrlen;    unsigned char *adrp;    char ifdev[24];    struct {	union DL_primitives prim;	char space[64];    } reply;    /*     * We have to open the device and ask it for its hardware address.     * First split apart the device name and unit.     */    slprintf(ifdev, sizeof(ifdev), "/dev/%s", name);    for (q = ifdev + strlen(ifdev); --q >= ifdev; )	if (!isdigit(*q))	    break;    unit = atoi(q+1);    q[1] = 0;    /*     * Open the device and do a DLPI attach and phys_addr_req.     */    iffd = open(ifdev, O_RDWR);    if (iffd < 0) {	error("Can't open %s: %m", ifdev);	return 0;    }    if (dlpi_attach(iffd, unit) < 0	|| dlpi_get_reply(iffd, &reply.prim, DL_OK_ACK, sizeof(reply)) < 0	|| dlpi_info_req(iffd) < 0	|| dlpi_get_reply(iffd, &reply.prim, DL_INFO_ACK, sizeof(reply)) < 0) {	close(iffd);	return 0;    }    adrlen = reply.prim.info_ack.dl_addr_length;    adrp = (unsigned char *)&reply + reply.prim.info_ack.dl_addr_offset;#if DL_CURRENT_VERSION >= 2    if (reply.prim.info_ack.dl_sap_length < 0)	adrlen += reply.prim.info_ack.dl_sap_length;    else	adrp += reply.prim.info_ack.dl_sap_length;#endif    hwaddr->sa_family = AF_UNSPEC;    memcpy(hwaddr->sa_data, adrp, adrlen);    return 1;}/* * get_hw_addr - obtain the hardware address for a named interface. */static intget_hw_addr(name, ina, hwaddr)    char *name;    u_int32_t ina;    struct sockaddr *hwaddr;{    /* New way - get the address by doing an arp request. */    int s;    struct arpreq req;    s = socket(AF_INET, SOCK_DGRAM, 0);    if (s < 0)	return 0;    memset(&req, 0, sizeof(req));    req.arp_pa.sa_family = AF_INET;    INET_ADDR(req.arp_pa) = ina;    if (ioctl(s, SIOCGARP, &req) < 0) {	error("Couldn't get ARP entry for %s: %m", ip_ntoa(ina));	return 0;    }    *hwaddr = req.arp_ha;    hwaddr->sa_family = AF_UNSPEC;    return 1;}static intdlpi_attach(fd, ppa)    int fd, ppa;{    dl_attach_req_t req;    struct strbuf buf;    req.dl_primitive = DL_ATTACH_REQ;    req.dl_ppa = ppa;    buf.len = sizeof(req);    buf.buf = (void *) &req;    return putmsg(fd, &buf, NULL, RS_HIPRI);}static intdlpi_info_req(fd)    int fd;{    dl_info_req_t req;    struct strbuf buf;    req.dl_primitive = DL_INFO_REQ;    buf.len = sizeof(req);    buf.buf = (void *) &req;    return putmsg(fd, &buf, NULL, RS_HIPRI);}static intdlpi_get_reply(fd, reply, expected_prim, maxlen)    union DL_primitives *reply;    int fd, expected_prim, maxlen;{    struct strbuf buf;    int flags, n;    struct pollfd pfd;    /*     * Use poll to wait for a message with a timeout.     */    pfd.fd = fd;    pfd.events = POLLIN | POLLPRI;    do {	n = poll(&pfd, 1, 1000);    } while (n == -1 && errno == EINTR);    if (n <= 0)	return -1;    /*     * Get the reply.     */    buf.maxlen = maxlen;    buf.buf = (void *) reply;    flags = 0;    if (getmsg(fd, &buf, NULL, &flags) < 0)	return -1;    if (buf.len < sizeof(ulong)) {	if (debug)	    dbglog("dlpi response short (len=%d)\n", buf.len);	return -1;    }    if (reply->dl_primitive == expected_prim)	return 0;    if (debug) {	if (reply->dl_primitive == DL_ERROR_ACK) {	    dbglog("dlpi error %d (unix errno %d) for prim %x\n",		   reply->error_ack.dl_errno, reply->error_ack.dl_unix_errno,		   reply->error_ack.dl_error_primitive);	} else {	    dbglog("dlpi unexpected response prim %x\n",		   reply->dl_primitive);	}    }    return -1;}/* * Return user specified netmask, modified by any mask we might determine * for address `addr' (in network byte order). * Here we scan through the system's list of interfaces, looking for * any non-point-to-point interfaces which might appear to be on the same * network as `addr'.  If we find any, we OR in their netmask to the * user-specified netmask. */u_int32_tGetMask(addr)    u_int32_t addr;{    u_int32_t mask, nmask, ina;    struct ifreq *ifr, *ifend, ifreq;    int nif;    struct ifconf ifc;    addr = ntohl(addr);    if (IN_CLASSA(addr))	/* determine network mask for address class */	nmask = IN_CLASSA_NET;    else if (IN_CLASSB(addr))	nmask = IN_CLASSB_NET;    else	nmask = IN_CLASSC_NET;    /* class D nets are disallowed by bad_ip_adrs */    mask = netmask | htonl(nmask);    /*     * Scan through the system's network interfaces.     */#ifdef SIOCGIFNUM    if (ioctl(ipfd, SIOCGIFNUM, &nif) < 0)#endif	nif = MAX_IFS;    ifc.ifc_len = nif * sizeof(struct ifreq);    ifc.ifc_buf = (caddr_t) malloc(ifc.ifc_len);    if (ifc.ifc_buf == 0)	return mask;    if (ioctl(ipfd, SIOCGIFCONF, &ifc) < 0) {	warn("Couldn't get system interface list: %m");	free(ifc.ifc_buf);	return mask;    }    ifend = (struct ifreq *) (ifc.ifc_buf + ifc.ifc_len);    for (ifr = ifc.ifc_req; ifr < ifend; ++ifr) {	/*	 * Check the interface's internet address.	 */	if (ifr->ifr_addr.sa_family != AF_INET)	    continue;	ina = INET_ADDR(ifr->ifr_addr);	if ((ntohl(ina) & nmask) != (addr & nmask))	    continue;	/*	 * Check that the interface is up, and not point-to-point or loopback.	 */	strlcpy(ifreq.ifr_name, ifr->ifr_name, sizeof(ifreq.ifr_name));	if (ioctl(ipfd, SIOCGIFFLAGS, &ifreq) < 0)	    continue;	if ((ifreq.ifr_flags & (IFF_UP|IFF_POINTOPOINT|IFF_LOOPBACK))	    != IFF_UP)	    continue;	/*	 * Get its netmask and OR it into our mask.	 */	if (ioctl(ipfd, SIOCGIFNETMASK, &ifreq) < 0)	    continue;	mask |= INET_ADDR(ifreq.ifr_addr);    }    free(ifc.ifc_buf);    return mask;}/* * logwtmp - write an accounting record to the /var/adm/wtmp file. */voidlogwtmp(line, name, host)    const char *line, *name, *host;{    static struct utmpx utmpx;    if (name[0] != 0) {	/* logging in */	strncpy(utmpx.ut_user, name, sizeof(utmpx.ut_user));	strncpy(utmpx.ut_id, ifname, sizeof(utmpx.ut_id));	strncpy(utmpx.ut_line, line, sizeof(utmpx.ut_line));	utmpx.ut_pid = getpid();	utmpx.ut_type = USER_PROCESS;    } else {	utmpx.ut_type = DEAD_PROCESS;    }    gettimeofday(&utmpx.ut_tv, NULL);    updwtmpx("/var/adm/wtmpx", &utmpx);}/* * get_host_seed - return the serial number of this machine. */intget_host_seed(){    char buf[32];    if (sysinfo(SI_HW_SERIAL, buf, sizeof(buf)) < 0) {	error("sysinfo: %m");	return 0;    }    return (int) strtoul(buf, NULL, 16);}static intstrioctl(fd, cmd, ptr, ilen, olen)    int fd, cmd, ilen, olen;    void *ptr;{    struct strioctl str;    str.ic_cmd = cmd;    str.ic_timout = 0;    str.ic_len = ilen;    str.ic_dp = ptr;    if (ioctl(fd, I_STR, &str) == -1)	return -1;    if (str.ic_len != olen)	dbglog("strioctl: expected %d bytes, got %d for cmd %x\n",	       olen, str.ic_len, cmd);    return 0;}#if 0/* * lock - create a lock file for the named lock device */#define LOCK_PREFIX	"/var/spool/locks/LK."static char lock_file[40];	/* name of lock file created */intlock(dev)    char *dev;{    int n, fd, pid;    struct stat sbuf;    char ascii_pid[12];    if (stat(dev, &sbuf) < 0) {	error("Can't get device number for %s: %m", dev);	return -1;    }    if ((sbuf.st_mode & S_IFMT) != S_IFCHR) {	error("Can't lock %s: not a character device", dev);	return -1;    }    slprintf(lock_file, sizeof(lock_file), "%s%03d.%03d.%03d",	     LOCK_PREFIX, major(sbuf.st_dev),	     major(sbuf.st_rdev), minor(sbuf.st_rdev));    while ((fd = open(lock_file, O_EXCL | O_CREAT | O_RDWR, 0644)) < 0) {	if (errno == EEXIST	    && (fd = open(lock_file, O_RDONLY, 0)) >= 0) {	    /* Read the lock file to find out who has the device locked */	    n = read(fd, ascii_pid, 11);	    if (n <= 0) {		error("Can't read pid from lock file %s", lock_file);		close(fd);	    } else {		ascii_pid[n] = 0;		pid = atoi(ascii_pid);		if (pid > 0 && kill(pid, 0) == -1 && errno == ESRCH) {		    /* pid no longer exists - remove the lock file */		    if (unlink(lock_file) == 0) {			close(fd);			notice("Removed stale lock on %s (pid %d)",			       dev, pid);			continue;		    } else			warn("Couldn't remove stale lock on %s",			       dev);		} else		    notice("Device %s is locked by pid %d",			   dev, pid);	    }	    close(fd);	} else	    error("Can't create lock file %s: %m", lock_file);	lock_file[0] = 0;	return -1;    }    slprintf(ascii_pid, sizeof(ascii_pid), "%10d\n", getpid());    write(fd, ascii_pid, 11);    close(fd);    return 1;}/* * unlock - remove our lockfile */voidunlock(){    if (lock_file[0]) {	unlink(lock_file);	lock_file[0] = 0;    }}#endif/* * cifroute - delete a route through the addresses given. */intcifroute(u, our, his)    int u;    u_int32_t our, his;{    struct rtentry rt;    memset(&rt, 0, sizeof(rt));    rt.rt_dst.sa_family = AF_INET;    INET_ADDR(rt.rt_dst) = his;    rt.rt_gateway.sa_family = AF_INET;    INET_ADDR(rt.rt_gateway) = our;    rt.rt_flags = RTF_HOST;    if (ioctl(ipfd, SIOCDELRT, &rt) < 0) {	error("Can't delete route: %m");	return 0;    }    return 1;}/* * have_route_to - determine if the system has a route to the specified * IP address.  Returns 0 if not, 1 if so, -1 if we can't tell. * `addr' is in network byte order. * For demand mode to work properly, we have to ignore routes * through our own interface. */#ifndef T_CURRENT		/* needed for Solaris 2.5 */#define T_CURRENT	MI_T_CURRENT#endifinthave_route_to(addr)    u_int32_t addr;{#ifdef SOL2    int fd, r, flags, i;    struct {	struct T_optmgmt_req req;	struct opthdr hdr;    } req;    union {	struct T_optmgmt_ack ack;	unsigned char space[64];    } ack;    struct opthdr *rh;    struct strbuf cbuf, dbuf;    int nroutes;    mib2_ipRouteEntry_t routes[8];    mib2_ipRouteEntry_t *rp;    fd = open(mux_dev_name, O_RDWR);    if (fd < 0) {	warn("have_route_to: couldn't open %s: %m", mux_dev_name);	return -1;    }    req.req.PRIM_type = T_OPTMGMT_REQ;    req.req.OPT_offset = (char *) &req.hdr - (char *) &req;    req.req.OPT_length = sizeof(req.hdr);    req.req.MGMT_flags = T_CURRENT;    req.hdr.level = MIB2_IP;    req.hdr.name = 0;    req.hdr.len = 0;    cbuf.buf = (char *) &req;    cbuf.len = sizeof(req);    if (putmsg(fd, &cbuf, NULL, 0) == -1) {	warn("have_route_to: putmsg: %m");	close(fd);	return -1;    }    for (;;) {	cbuf.buf = (char *) &ack;	cbuf.maxlen = sizeof(ack);	dbuf.buf = (char *) routes;	dbuf.maxlen = sizeof(routes);	flags = 0;	r = getmsg(fd, &cbuf, &dbuf, &flags);	if (r == -1) {	    warn("have_route_to: getmsg: %m");	    close(fd);	    return -1;	}	if (cbuf.len < sizeof(struct T_optmgmt_ack)	    || ack.ack.PRIM_type != T_OPTMGMT_ACK	    || ack.ack.MGMT_flags != T_SUCCESS	    || ack.ack.OPT_length < sizeof(struct opthdr)) {	    dbglog("have_route_to: bad message len=%d prim=%d",		   cbuf.len, ack.ack.PRIM_type);	    close(fd);	    return -1;	}	rh = (struct opthdr *) ((char *)&ack + ack.ack.OPT_offset);	if (rh->level == 0 && rh->name == 0)	    break;	if (rh->level != MIB2_IP || rh->name != MIB2_IP_21) {	    while (r == MOREDATA)		r = getmsg(fd, NULL, &dbuf, &flags);	    continue;	}	for (;;) {	    nroutes = dbuf.len / sizeof(mib2_ipRouteEntry_t);	    for (rp = routes, i = 0; i < nroutes; ++i, ++rp) {		if (rp->ipRouteMask != ~0) {		    dbglog("have_route_to: dest=%x gw=%x mask=%x\n",			   rp->ipRouteDest, rp->ipRouteNextHop,			   rp->ipRouteMask);		    if (((addr ^ rp->ipRouteDest) & rp->ipRouteMask) == 0			&& rp->ipRouteNextHop != remote_addr)			return 1;		}	    }	    if (r == 0)		break;	    r = getmsg(fd, NULL, &dbuf, &flags);	}    }    close(fd);    return 0;#else    return -1;#endif /* SOL2 */}/* * get_pty - get a pty master/slave pair and chown the slave side to * the uid given.  Assumes slave_name points to MAXPATHLEN bytes of space. */intget_pty(master_fdp, slave_fdp, slave_name, uid)    int *master_fdp;    int *slave_fdp;    char *slave_name;    int uid;{    int mfd, sfd;    char *pty_name;    struct termios tios;    mfd = open("/dev/ptmx", O_RDWR);    if (mfd < 0) {	error("Couldn't open pty master: %m");	return 0;    }    pty_name = ptsname(mfd);    if (pty_name == NULL) {	error("Couldn't get name of pty slave");	close(mfd);	return 0;    }    if (chown(pty_name, uid, -1) < 0)	warn("Couldn't change owner of pty slave: %m");    if (chmod(pty_name, S_IRUSR | S_IWUSR) < 0)	warn("Couldn't change permissions on pty slave: %m");    if (unlockpt(mfd) < 0)	warn("Couldn't unlock pty

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -