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

📄 pcap-dlpi.c

📁 Windows XP下的抓包程序实现
💻 C
📖 第 1 页 / 共 4 页
字号:
	p->selectable_fd = p->fd;	p->read_op = pcap_read_dlpi;	p->inject_op = pcap_inject_dlpi;	p->setfilter_op = install_bpf_program;	/* no kernel filtering */	p->setdirection_op = NULL;	/* Not implemented.*/	p->set_datalink_op = NULL;	/* can't change data link type */	p->getnonblock_op = pcap_getnonblock_fd;	p->setnonblock_op = pcap_setnonblock_fd;	p->stats_op = pcap_stats_dlpi;	p->close_op = pcap_close_dlpi;	return (p);bad:	if (p->fd >= 0)		close(p->fd);	if (p->send_fd >= 0)		close(p->send_fd);	/*	 * Get rid of any link-layer type list we allocated.	 */	if (p->dlt_list != NULL)		free(p->dlt_list);	free(p);	return (NULL);}/* * Split a device name into a device type name and a unit number; * return the a pointer to the beginning of the unit number, which * is the end of the device type name, and set "*unitp" to the unit * number. * * Returns NULL on error, and fills "ebuf" with an error message. */static char *split_dname(char *device, int *unitp, char *ebuf){	char *cp;	char *eos;	long unit;	/*	 * Look for a number at the end of the device name string.	 */	cp = device + strlen(device) - 1;	if (*cp < '0' || *cp > '9') {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s missing unit number",		    device);		return (NULL);	}	/* Digits at end of string are unit number */	while (cp-1 >= device && *(cp-1) >= '0' && *(cp-1) <= '9')		cp--;	errno = 0;	unit = strtol(cp, &eos, 10);	if (*eos != '\0') {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s bad unit number", device);		return (NULL);	}	if (errno == ERANGE || unit > INT_MAX) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number too large",		    device);		return (NULL);	}	if (unit < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "%s unit number is negative",		    device);		return (NULL);	}	*unitp = (int)unit;	return (cp);}static intdl_doattach(int fd, int ppa, char *ebuf){	bpf_u_int32 buf[MAXDLBUF];	if (dlattachreq(fd, ppa, ebuf) < 0 ||	    dlokack(fd, "attach", (char *)buf, ebuf) < 0)		return (-1);	return (0);}#ifdef DL_HP_RAWDLSstatic intdl_dohpuxbind(int fd, char *ebuf){	int hpsap;	int uerror;	bpf_u_int32 buf[MAXDLBUF];	/*	 * XXX - we start at 22 because we used to use only 22, but	 * that was just because that was the value used in some	 * sample code from HP.  With what value *should* we start?	 * Does it matter, given that we're enabling SAP promiscuity	 * on the input FD?	 */	hpsap = 22;	for (;;) {		if (dlbindreq(fd, hpsap, ebuf) < 0)			return (-1);		if (dlbindack(fd, (char *)buf, ebuf, &uerror) >= 0)			break;		/*		 * For any error other than a UNIX EBUSY, give up.		 */		if (uerror != EBUSY) {			/*			 * dlbindack() has already filled in ebuf for			 * this error.			 */			return (-1);		}		/*		 * For EBUSY, try the next SAP value; that means that		 * somebody else is using that SAP.  Clear ebuf so		 * that application doesn't report the "Device busy"		 * error as a warning.		 */		*ebuf = '\0';		hpsap++;		if (hpsap > 100) {			strlcpy(ebuf,			    "All SAPs from 22 through 100 are in use",			    PCAP_ERRBUF_SIZE);			return (-1);		}	}	return (0);}#endifintpcap_platform_finddevs(pcap_if_t **alldevsp, char *errbuf){#ifdef HAVE_SOLARIS	int fd;	union {		u_int nunits;		char pad[516];	/* XXX - must be at least 513; is 516				   in "atmgetunits" */	} buf;	char baname[2+1+1];	u_int i;	/*	 * We may have to do special magic to get ATM devices.	 */	if ((fd = open("/dev/ba", O_RDWR)) < 0) {		/*		 * We couldn't open the "ba" device.		 * For now, just give up; perhaps we should		 * return an error if the problem is neither		 * a "that device doesn't exist" error (ENOENT,		 * ENXIO, etc.) or a "you're not allowed to do		 * that" error (EPERM, EACCES).		 */		return (0);	}	if (strioctl(fd, A_GET_UNITS, sizeof(buf), (char *)&buf) < 0) {		snprintf(errbuf, PCAP_ERRBUF_SIZE, "A_GET_UNITS: %s",		    pcap_strerror(errno));		return (-1);	}	for (i = 0; i < buf.nunits; i++) {		snprintf(baname, sizeof baname, "ba%u", i);		if (pcap_add_if(alldevsp, baname, 0, NULL, errbuf) < 0)			return (-1);	}#endif	return (0);}static intsend_request(int fd, char *ptr, int len, char *what, char *ebuf){	struct	strbuf	ctl;	int	flags;	ctl.maxlen = 0;	ctl.len = len;	ctl.buf = ptr;	flags = 0;	if (putmsg(fd, &ctl, (struct strbuf *) NULL, flags) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "send_request: putmsg \"%s\": %s",		    what, pcap_strerror(errno));		return (-1);	}	return (0);}static intrecv_ack(int fd, int size, const char *what, char *bufp, char *ebuf, int *uerror){	union	DL_primitives	*dlp;	struct	strbuf	ctl;	int	flags;	/*	 * Clear out "*uerror", so it's only set for DL_ERROR_ACK/DL_SYSERR,	 * making that the only place where EBUSY is treated specially.	 */	if (uerror != NULL)		*uerror = 0;	ctl.maxlen = MAXDLBUF;	ctl.len = 0;	ctl.buf = bufp;	flags = 0;	if (getmsg(fd, &ctl, (struct strbuf*)NULL, &flags) < 0) {		snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s getmsg: %s",		    what, pcap_strerror(errno));		return (-1);	}	dlp = (union DL_primitives *) ctl.buf;	switch (dlp->dl_primitive) {	case DL_INFO_ACK:	case DL_BIND_ACK:	case DL_OK_ACK:#ifdef DL_HP_PPA_ACK	case DL_HP_PPA_ACK:#endif		/* These are OK */		break;	case DL_ERROR_ACK:		switch (dlp->error_ack.dl_errno) {		case DL_SYSERR:			if (uerror != NULL)				*uerror = dlp->error_ack.dl_unix_errno;			snprintf(ebuf, PCAP_ERRBUF_SIZE,			    "recv_ack: %s: UNIX error - %s",			    what, pcap_strerror(dlp->error_ack.dl_unix_errno));			break;		default:			snprintf(ebuf, PCAP_ERRBUF_SIZE, "recv_ack: %s: %s",			    what, dlstrerror(dlp->error_ack.dl_errno));			break;		}		return (-1);	default:		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "recv_ack: %s: Unexpected primitive ack %s",		    what, dlprim(dlp->dl_primitive));		return (-1);	}	if (ctl.len < size) {		snprintf(ebuf, PCAP_ERRBUF_SIZE,		    "recv_ack: %s: Ack too small (%d < %d)",		    what, ctl.len, size);		return (-1);	}	return (ctl.len);}static char *dlstrerror(bpf_u_int32 dl_errno){	static char errstring[6+2+8+1];	switch (dl_errno) {	case DL_ACCESS:		return ("Improper permissions for request");	case DL_BADADDR:		return ("DLSAP addr in improper format or invalid");	case DL_BADCORR:		return ("Seq number not from outstand DL_CONN_IND");	case DL_BADDATA:		return ("User data exceeded provider limit");	case DL_BADPPA:#ifdef HAVE_DEV_DLPI		/*		 * With a single "/dev/dlpi" device used for all		 * DLPI providers, PPAs have nothing to do with		 * unit numbers.		 */		return ("Specified PPA was invalid");#else		/*		 * We have separate devices for separate devices;		 * the PPA is just the unit number.		 */		return ("Specified PPA (device unit) was invalid");#endif	case DL_BADPRIM:		return ("Primitive received not known by provider");	case DL_BADQOSPARAM:		return ("QOS parameters contained invalid values");	case DL_BADQOSTYPE:		return ("QOS structure type is unknown/unsupported");	case DL_BADSAP:		return ("Bad LSAP selector");	case DL_BADTOKEN:		return ("Token used not an active stream");	case DL_BOUND:		return ("Attempted second bind with dl_max_conind");	case DL_INITFAILED:		return ("Physical link initialization failed");	case DL_NOADDR:		return ("Provider couldn't allocate alternate address");	case DL_NOTINIT:		return ("Physical link not initialized");	case DL_OUTSTATE:		return ("Primitive issued in improper state");	case DL_SYSERR:		return ("UNIX system error occurred");	case DL_UNSUPPORTED:		return ("Requested service not supplied by provider");	case DL_UNDELIVERABLE:		return ("Previous data unit could not be delivered");	case DL_NOTSUPPORTED:		return ("Primitive is known but not supported");	case DL_TOOMANY:		return ("Limit exceeded");	case DL_NOTENAB:		return ("Promiscuous mode not enabled");	case DL_BUSY:		return ("Other streams for PPA in post-attached");	case DL_NOAUTO:		return ("Automatic handling XID&TEST not supported");	case DL_NOXIDAUTO:		return ("Automatic handling of XID not supported");	case DL_NOTESTAUTO:		return ("Automatic handling of TEST not supported");	case DL_XIDAUTO:		return ("Automatic handling of XID response");	case DL_TESTAUTO:		return ("Automatic handling of TEST response");	case DL_PENDING:		return ("Pending outstanding connect indications");	default:		sprintf(errstring, "Error %02x", dl_errno);		return (errstring);	}}static char *dlprim(bpf_u_int32 prim){	static char primbuf[80];	switch (prim) {	case DL_INFO_REQ:		return ("DL_INFO_REQ");	case DL_INFO_ACK:		return ("DL_INFO_ACK");	case DL_ATTACH_REQ:		return ("DL_ATTACH_REQ");	case DL_DETACH_REQ:		return ("DL_DETACH_REQ");	case DL_BIND_REQ:		return ("DL_BIND_REQ");	case DL_BIND_ACK:		return ("DL_BIND_ACK");	case DL_UNBIND_REQ:		return ("DL_UNBIND_REQ");	case DL_OK_ACK:		return ("DL_OK_ACK");	case DL_ERROR_ACK:		return ("DL_ERROR_ACK");	case DL_SUBS_BIND_REQ:		return ("DL_SUBS_BIND_REQ");	case DL_SUBS_BIND_ACK:		return ("DL_SUBS_BIND_ACK");	case DL_UNITDATA_REQ:		return ("DL_UNITDATA_REQ");	case DL_UNITDATA_IND:		return ("DL_UNITDATA_IND");	case DL_UDERROR_IND:		return ("DL_UDERROR_IND");	case DL_UDQOS_REQ:		return ("DL_UDQOS_REQ");	case DL_CONNECT_REQ:		return ("DL_CONNECT_REQ");	case DL_CONNECT_IND:		return ("DL_CONNECT_IND");	case DL_CONNECT_RES:		return ("DL_CONNECT_RES");	case DL_CONNECT_CON:		return ("DL_CONNECT_CON");	case DL_TOKEN_REQ:		return ("DL_TOKEN_REQ");	case DL_TOKEN_ACK:		return ("DL_TOKEN_ACK");	case DL_DISCONNECT_REQ:		return ("DL_DISCONNECT_REQ");	case DL_DISCONNECT_IND:		return ("DL_DISCONNECT_IND");	case DL_RESET_REQ:		return ("DL_RESET_REQ");	case DL_RESET_IND:		return ("DL_RESET_IND");	case DL_RESET_RES:		return ("DL_RESET_RES");	case DL_RESET_CON:		return ("DL_RESET_CON");

⌨️ 快捷键说明

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