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

📄 pcap-dlpi.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	default:		(void) sprintf(primbuf, "unknown primitive 0x%x", prim);		return (primbuf);	}}static intdlattachreq(int fd, bpf_u_int32 ppa, char *ebuf){	dl_attach_req_t	req;	req.dl_primitive = DL_ATTACH_REQ;	req.dl_ppa = ppa;	return (send_request(fd, (char *)&req, sizeof(req), "attach", ebuf));}static intdlbindreq(int fd, bpf_u_int32 sap, char *ebuf){	dl_bind_req_t	req;	memset((char *)&req, 0, sizeof(req));	req.dl_primitive = DL_BIND_REQ;	/* XXX - what if neither of these are defined? */#if defined(DL_HP_RAWDLS)	req.dl_max_conind = 1;			/* XXX magic number */	req.dl_service_mode = DL_HP_RAWDLS;#elif defined(DL_CLDLS)	req.dl_service_mode = DL_CLDLS;#endif	req.dl_sap = sap;	return (send_request(fd, (char *)&req, sizeof(req), "bind", ebuf));}static intdlbindack(int fd, char *bufp, char *ebuf, int *uerror){	return (recv_ack(fd, DL_BIND_ACK_SIZE, "bind", bufp, ebuf, uerror));}static intdlpromisconreq(int fd, bpf_u_int32 level, char *ebuf){	dl_promiscon_req_t req;	req.dl_primitive = DL_PROMISCON_REQ;	req.dl_level = level;	return (send_request(fd, (char *)&req, sizeof(req), "promiscon", ebuf));}static intdlokack(int fd, const char *what, char *bufp, char *ebuf){	return (recv_ack(fd, DL_OK_ACK_SIZE, what, bufp, ebuf, NULL));}static intdlinforeq(int fd, char *ebuf){	dl_info_req_t req;	req.dl_primitive = DL_INFO_REQ;	return (send_request(fd, (char *)&req, sizeof(req), "info", ebuf));}static intdlinfoack(int fd, char *bufp, char *ebuf){	return (recv_ack(fd, DL_INFO_ACK_SIZE, "info", bufp, ebuf, NULL));}#ifdef DL_HP_RAWDLS/* * There's an ack *if* there's an error. */static intdlrawdatareq(int fd, const u_char *datap, int datalen){	struct strbuf ctl, data;	long buf[MAXDLBUF];	/* XXX - char? */	union DL_primitives *dlp;	int dlen;	dlp = (union DL_primitives*) buf;	dlp->dl_primitive = DL_HP_RAWDATA_REQ;	dlen = DL_HP_RAWDATA_REQ_SIZE;	/*	 * HP's documentation doesn't appear to show us supplying any	 * address pointed to by the control part of the message.	 * I think that's what raw mode means - you just send the raw	 * packet, you don't specify where to send it to, as that's	 * implied by the destination address.	 */	ctl.maxlen = 0;	ctl.len = dlen;	ctl.buf = (void *)buf;	data.maxlen = 0;	data.len = datalen;	data.buf = (void *)datap;	return (putmsg(fd, &ctl, &data, 0));}#endif /* DL_HP_RAWDLS */#ifdef HAVE_SYS_BUFMOD_Hstatic intstrioctl(int fd, int cmd, int len, char *dp){	struct strioctl str;	int rc;	str.ic_cmd = cmd;	str.ic_timout = -1;	str.ic_len = len;	str.ic_dp = dp;	rc = ioctl(fd, I_STR, &str);	if (rc < 0)		return (rc);	else		return (str.ic_len);}#endif#if defined(HAVE_SOLARIS) && defined(HAVE_SYS_BUFMOD_H)static char *get_release(bpf_u_int32 *majorp, bpf_u_int32 *minorp, bpf_u_int32 *microp){	char *cp;	static char buf[32];	*majorp = 0;	*minorp = 0;	*microp = 0;	if (sysinfo(SI_RELEASE, buf, sizeof(buf)) < 0)		return ("?");	cp = buf;	if (!isdigit((unsigned char)*cp))		return (buf);	*majorp = strtol(cp, &cp, 10);	if (*cp++ != '.')		return (buf);	*minorp =  strtol(cp, &cp, 10);	if (*cp++ != '.')		return (buf);	*microp =  strtol(cp, &cp, 10);	return (buf);}#endif#ifdef DL_HP_PPA_REQ/* * Under HP-UX 10 and HP-UX 11, we can ask for the ppa *//* * Determine ppa number that specifies ifname. * * If the "dl_hp_ppa_info_t" doesn't have a "dl_module_id_1" member, * the code that's used here is the old code for HP-UX 10.x. * * However, HP-UX 10.20, at least, appears to have such a member * in its "dl_hp_ppa_info_t" structure, so the new code is used. * The new code didn't work on an old 10.20 system on which Rick * Jones of HP tried it, but with later patches installed, it * worked - it appears that the older system had those members but * didn't put anything in them, so, if the search by name fails, we * do the old search. * * Rick suggests that making sure your system is "up on the latest * lancommon/DLPI/driver patches" is probably a good idea; it'd fix * that problem, as well as allowing libpcap to see packets sent * from the system on which the libpcap application is being run. * (On 10.20, in addition to getting the latest patches, you need * to turn the kernel "lanc_outbound_promisc_flag" flag on with ADB; * a posting to "comp.sys.hp.hpux" at * *	http://www.deja.com/[ST_rn=ps]/getdoc.xp?AN=558092266 * * says that, to see the machine's outgoing traffic, you'd need to * apply the right patches to your system, and also set that variable * with:echo 'lanc_outbound_promisc_flag/W1' | /usr/bin/adb -w /stand/vmunix /dev/kmem * which could be put in, for example, "/sbin/init.d/lan". * * Setting the variable is not necessary on HP-UX 11.x. */static intget_dlpi_ppa(register int fd, register const char *device, register int unit,    register char *ebuf){	register dl_hp_ppa_ack_t *ap;	register dl_hp_ppa_info_t *ipstart, *ip;	register int i;	char dname[100];	register u_long majdev;	struct stat statbuf;	dl_hp_ppa_req_t	req;	char buf[MAXDLBUF];	char *ppa_data_buf;	dl_hp_ppa_ack_t	*dlp;	struct strbuf ctl;	int flags;	int ppa;	memset((char *)&req, 0, sizeof(req));	req.dl_primitive = DL_HP_PPA_REQ;	memset((char *)buf, 0, sizeof(buf));	if (send_request(fd, (char *)&req, sizeof(req), "hpppa", ebuf) < 0)		return (-1);	ctl.maxlen = DL_HP_PPA_ACK_SIZE;	ctl.len = 0;	ctl.buf = (char *)buf;	flags = 0;	/*	 * DLPI may return a big chunk of data for a DL_HP_PPA_REQ. The normal	 * recv_ack will fail because it set the maxlen to MAXDLBUF (8192)	 * which is NOT big enough for a DL_HP_PPA_REQ.	 *	 * This causes libpcap applications to fail on a system with HP-APA	 * installed.	 *	 * To figure out how big the returned data is, we first call getmsg	 * to get the small head and peek at the head to get the actual data	 * length, and  then issue another getmsg to get the actual PPA data.	 */	/* get the head first */	if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));		return (-1);	}	dlp = (dl_hp_ppa_ack_t *)ctl.buf;	if (dlp->dl_primitive != DL_HP_PPA_ACK) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa unexpected primitive ack 0x%x",		    (bpf_u_int32)dlp->dl_primitive);		return (-1);	}	if (ctl.len < DL_HP_PPA_ACK_SIZE) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa ack too small (%d < %lu)",		     ctl.len, (unsigned long)DL_HP_PPA_ACK_SIZE);		return (-1);	}	/* allocate buffer */	if ((ppa_data_buf = (char *)malloc(dlp->dl_length)) == NULL) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa malloc: %s", pcap_strerror(errno));		return (-1);	}	ctl.maxlen = dlp->dl_length;	ctl.len = 0;	ctl.buf = (char *)ppa_data_buf;	/* get the data */	if (getmsg(fd, &ctl, (struct strbuf *)NULL, &flags) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa getmsg: %s", pcap_strerror(errno));		free(ppa_data_buf);		return (-1);	}	if (ctl.len < dlp->dl_length) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "get_dlpi_ppa: hpppa ack too small (%d < %d)",		    ctl.len, dlp->dl_length);		free(ppa_data_buf);		return (-1);	}	ap = (dl_hp_ppa_ack_t *)buf;	ipstart = (dl_hp_ppa_info_t *)ppa_data_buf;	ip = ipstart;#ifdef HAVE_HP_PPA_INFO_T_DL_MODULE_ID_1	/*	 * The "dl_hp_ppa_info_t" structure has a "dl_module_id_1"	 * member that should, in theory, contain the part of the	 * name for the device that comes before the unit number,	 * and should also have a "dl_module_id_2" member that may	 * contain an alternate name (e.g., I think Ethernet devices	 * have both "lan", for "lanN", and "snap", for "snapN", with	 * the former being for Ethernet packets and the latter being	 * for 802.3/802.2 packets).	 *	 * Search for the device that has the specified name and	 * instance number.	 */	for (i = 0; i < ap->dl_count; i++) {		if ((strcmp((const char *)ip->dl_module_id_1, device) == 0 ||		     strcmp((const char *)ip->dl_module_id_2, device) == 0) &&		    ip->dl_instance_num == unit)			break;		ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);	}#else	/*	 * We don't have that member, so the search is impossible; make it	 * look as if the search failed.	 */	i = ap->dl_count;#endif	if (i == ap->dl_count) {		/*		 * Well, we didn't, or can't, find the device by name.		 *		 * HP-UX 10.20, whilst it has "dl_module_id_1" and		 * "dl_module_id_2" fields in the "dl_hp_ppa_info_t",		 * doesn't seem to fill them in unless the system is		 * at a reasonably up-to-date patch level.		 *		 * Older HP-UX 10.x systems might not have those fields		 * at all.		 *		 * Therefore, we'll search for the entry with the major		 * device number of a device with the name "/dev/<dev><unit>",		 * if such a device exists, as the old code did.		 */		snprintf(dname, sizeof(dname), "/dev/%s%d", device, unit);		if (stat(dname, &statbuf) < 0) {			snprintf(ebuf, PCAP_ERRBUF_SIZE, "stat: %s: %s",			    dname, pcap_strerror(errno));			return (-1);		}		majdev = major(statbuf.st_rdev);		ip = ipstart;		for (i = 0; i < ap->dl_count; i++) {			if (ip->dl_mjr_num == majdev &&			    ip->dl_instance_num == unit)				break;			ip = (dl_hp_ppa_info_t *)((u_char *)ipstart + ip->dl_next_offset);		}	}	if (i == ap->dl_count) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "can't find /dev/dlpi PPA for %s%d", device, unit);		return (-1);	}	if (ip->dl_hdw_state == HDW_DEAD) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "%s%d: hardware state: DOWN\n", device, unit);		free(ppa_data_buf);		return (-1);	}	ppa = ip->dl_ppa;	free(ppa_data_buf);	return (ppa);}#endif#ifdef HAVE_HPUX9/* * Under HP-UX 9, there is no good way to determine the ppa. * So punt and read it from /dev/kmem. */static struct nlist nl[] = {#define NL_IFNET 0	{ "ifnet" },	{ "" }};static char path_vmunix[] = "/hp-ux";/* Determine ppa number that specifies ifname */static intget_dlpi_ppa(register int fd, register const char *ifname, register int unit,    register char *ebuf){	register const char *cp;	register int kd;	void *addr;	struct ifnet ifnet;	char if_name[sizeof(ifnet.if_name) + 1];	cp = strrchr(ifname, '/');	if (cp != NULL)		ifname = cp + 1;	if (nlist(path_vmunix, &nl) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "nlist %s failed",		    path_vmunix);		return (-1);	}	if (nl[NL_IFNET].n_value == 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "could't find %s kernel symbol",		    nl[NL_IFNET].n_name);		return (-1);	}	kd = open("/dev/kmem", O_RDONLY);	if (kd < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "kmem open: %s",		    pcap_strerror(errno));		return (-1);	}	if (dlpi_kread(kd, nl[NL_IFNET].n_value,	    &addr, sizeof(addr), ebuf) < 0) {		close(kd);		return (-1);	}	for (; addr != NULL; addr = ifnet.if_next) {		if (dlpi_kread(kd, (off_t)addr,		    &ifnet, sizeof(ifnet), ebuf) < 0 ||		    dlpi_kread(kd, (off_t)ifnet.if_name,		    if_name, sizeof(ifnet.if_name), ebuf) < 0) {			(void)close(kd);			return (-1);		}		if_name[sizeof(ifnet.if_name)] = '\0';		if (strcmp(if_name, ifname) == 0 && ifnet.if_unit == unit)			return (ifnet.if_index);	}	snprintf(ebuf, PCAP_ERRBUF_SIZE, "Can't find %s", ifname);	return (-1);}static intdlpi_kread(register int fd, register off_t addr,    register void *buf, register u_int len, register char *ebuf){	register int cc;	if (lseek(fd, addr, SEEK_SET) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "lseek: %s",		    pcap_strerror(errno));		return (-1);	}	cc = read(fd, buf, len);	if (cc < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "read: %s",		    pcap_strerror(errno));		return (-1);	} else if (cc != len) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "short read (%d != %d)", cc,		    len);		return (-1);	}	return (cc);}#endif

⌨️ 快捷键说明

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