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

📄 dlpi.c

📁 DHCP服务器源码
💻 C
📖 第 1 页 / 共 3 页
字号:
         * protocol should be udp. this is a byte compare, test for         * endianess.         */        offset = ETHER_H_PREFIX + ((u_int8_t *)&(iphdr.ip_p) - (u_int8_t *)&iphdr);        pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHWORD + (offset / 2);        pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_AND;        pf.Pf_Filter [pf.Pf_FilterLen++] = htons (0x00FF);        pf.Pf_Filter [pf.Pf_FilterLen++] = ENF_PUSHLIT | ENF_CAND;      pf.Pf_Filter [pf.Pf_FilterLen++] = htons (IPPROTO_UDP);	/* Install the filter... */	if (strioctl (info -> rfdesc, PFIOCSETF, INFTIM,		      sizeof (pf), (char *)&pf) < 0) {	    log_fatal ("Can't set PFMOD receive filter on %s: %m", info -> name);	}#endif /* USE_DLPI_PFMOD */        if (!quiet_interface_discovery)		log_info ("Listening on DLPI/%s/%s%s%s",		      info -> name,		      print_hw_addr (info -> hw_address.hbuf [0],				     info -> hw_address.hlen - 1,				     &info -> hw_address.hbuf [1]),		      (info -> shared_network ? "/" : ""),		      (info -> shared_network ?		       info -> shared_network -> name : ""));#ifdef DLPI_FIRST_SEND_WAIT/* See the implementation notes at the beginning of this file */# ifdef USE_DLPI_SEND	sleep (DLPI_FIRST_SEND_WAIT / 2);# else	sleep (DLPI_FIRST_SEND_WAIT);# endif#endif}void if_deregister_receive (info)	struct interface_info *info;{	/* If we're using the DLPI API for sending and receiving,	   we don't need to register this interface twice. */#ifndef USE_DLPI_SEND	close (info -> rfdesc);#endif	info -> rfdesc = -1;        if (!quiet_interface_discovery)		log_info ("Disabling input on DLPI/%s/%s%s%s",		      info -> name,		      print_hw_addr (info -> hw_address.hbuf [0],				     info -> hw_address.hlen - 1,				     &info -> hw_address.hbuf [1]),		      (info -> shared_network ? "/" : ""),		      (info -> shared_network ?		       info -> shared_network -> name : ""));}#endif /* USE_DLPI_RECEIVE */#ifdef USE_DLPI_SENDssize_t send_packet (interface, packet, raw, len, from, to, hto)	struct interface_info *interface;	struct packet *packet;	struct dhcp_packet *raw;	size_t len;	struct in_addr from;	struct sockaddr_in *to;	struct hardware *hto;{	unsigned hbufp = 0;	double hh [32];	double ih [1536 / sizeof (double)];	unsigned char *dbuf = (unsigned char *)ih;	unsigned dbuflen;	unsigned char dstaddr [DLPI_MAXDLADDR];	unsigned addrlen;	int result;	int fudge;	if (!strcmp (interface -> name, "fallback"))		return send_fallback (interface, packet, raw,				      len, from, to, hto);	dbuflen = 0;	/* Assemble the headers... */#ifdef USE_DLPI_RAW	assemble_hw_header (interface, (unsigned char *)hh, &dbuflen, hto);      if (dbuflen > sizeof hh)              log_fatal ("send_packet: hh buffer too small.\n");	fudge = dbuflen % 4; /* IP header must be word-aligned. */	memcpy (dbuf + fudge, (unsigned char *)hh, dbuflen);	dbuflen += fudge;#else	fudge = 0;#endif	assemble_udp_ip_header (interface, dbuf, &dbuflen, from.s_addr,				to -> sin_addr.s_addr, to -> sin_port,				(unsigned char *)raw, len);	/* Copy the data into the buffer (yuk). */	memcpy (dbuf + dbuflen, raw, len);	dbuflen += len;#ifdef USE_DLPI_RAW	result = write (interface -> wfdesc, dbuf + fudge, dbuflen - fudge);#else	/*         * Setup the destination address (DLSAP) in dstaddr          *         * If sap_length < 0 we must deliver the DLSAP as phys+sap.          * If sap_length > 0 we must deliver the DLSAP as sap+phys.         *         * sap = Service Access Point == ETHERTYPE_IP         * sap + datalink address is called DLSAP in dlpi speak.         */        { /* ENCODE DLSAP */          unsigned char phys [DLPI_MAXDLADDR];          unsigned char sap [4];          int sap_len = interface -> dlpi_sap_length;          int phys_len = interface -> hw_address.hlen - 1;          /* sap = htons (ETHERTYPE_IP) kludge */          memset (sap, 0, sizeof (sap));# if (BYTE_ORDER == LITTLE_ENDIAN)          sap [0] = 0x00;          sap [1] = 0x08;# else          sap [0] = 0x08;          sap [1] = 0x00;# endif        if (hto && hto -> hlen == interface -> hw_address.hlen)             memcpy ( phys, (char *) &hto -> hbuf [1], phys_len);          else              memcpy ( phys, interface -> dlpi_broadcast_addr.hbuf,               interface -> dlpi_broadcast_addr.hlen);                     if (sap_len < 0) {              memcpy ( dstaddr, phys, phys_len);             memcpy ( (char *) &dstaddr [phys_len], sap, ABS (sap_len));          }          else {             memcpy ( dstaddr, (void *) sap, sap_len);             memcpy ( (char *) &dstaddr [sap_len], phys, phys_len);          }        addrlen = phys_len + ABS (sap_len);      } /* ENCODE DLSAP */	result = dlpiunitdatareq (interface -> wfdesc, dstaddr, addrlen,				  0, 0, dbuf, dbuflen);#endif /* USE_DLPI_RAW */	if (result < 0)		log_error ("send_packet: %m");	return result;}#endif /* USE_DLPI_SEND */#ifdef USE_DLPI_RECEIVEssize_t receive_packet (interface, buf, len, from, hfrom)	struct interface_info *interface;	unsigned char *buf;	size_t len;	struct sockaddr_in *from;	struct hardware *hfrom;{	unsigned char dbuf [1536];	unsigned char srcaddr [DLPI_MAXDLADDR];	unsigned long srcaddrlen;	int flags = 0;	int length = 0;	int offset = 0;	int rslt;	int bufix = 0;	#ifdef USE_DLPI_RAW	length = read (interface -> rfdesc, dbuf, sizeof (dbuf));#else		length = dlpiunitdataind (interface -> rfdesc, (unsigned char *)NULL,				  (unsigned long *)NULL, srcaddr, &srcaddrlen,				  (unsigned long *)NULL, dbuf, sizeof (dbuf));#endif	if (length <= 0) {	    return length;	}# if !defined (USE_DLPI_RAW)        /*         * Copy the sender's hw address into hfrom         * If sap_len < 0 the DLSAP is as phys+sap.         * If sap_len > 0 the DLSAP is as sap+phys.         *         * sap is discarded here.         */        { /* DECODE DLSAP */          int sap_len = interface -> dlpi_sap_length;          int phys_len = interface -> hw_address.hlen - 1;          if (hfrom && (srcaddrlen == ABS (sap_len) + phys_len )) {            hfrom -> hbuf [0] = interface -> hw_address.hbuf [0];            hfrom -> hlen = interface -> hw_address.hlen;                        if (sap_len < 0) {              memcpy ((char *) &hfrom -> hbuf [1], srcaddr, phys_len);            }            else {              memcpy ((char *) &hfrom -> hbuf [1], (char *) &srcaddr [phys_len],                phys_len);            }          }           else if (hfrom) {            memset (hfrom, '\0', sizeof *hfrom);          }        } /* DECODE_DLSAP */# endif /* !defined (USE_DLPI_RAW) */	/* Decode the IP and UDP headers... */	bufix = 0;#ifdef USE_DLPI_RAW	/* Decode the physical header... */	offset = decode_hw_header (interface, dbuf, bufix, hfrom);	/* If a physical layer checksum failed (dunno of any	   physical layer that supports this, but WTH), skip this	   packet. */	if (offset < 0) {		return 0;	}	bufix += offset;	length -= offset;#endif	offset = decode_udp_ip_header (interface, dbuf, bufix,				       from, (unsigned char *)0, length);	/* If the IP or UDP checksum was bad, skip the packet... */	if (offset < 0) {	    return 0;	}	bufix += offset;	length -= offset;	/* Copy out the data in the packet... */	memcpy (buf, &dbuf [bufix], length);	return length;}#endif/* Common DLPI routines ... * * Written by Eric James Negaard, <lmdejn@lmd.ericsson.se> * * Based largely in part to the example code contained in the document * "How to Use the STREAMS Data Link Provider Interface (DLPI)", written * by Neal Nuckolls of SunSoft Internet Engineering. *  * This code has been developed and tested on sparc-based machines running * SunOS 5.5.1, with le and hme network interfaces.  It should be pretty * generic, though. *  * The usual disclaimers apply.  This code works for me.  Don't blame me * if it makes your machine or network go down in flames.  That taken * into consideration, use this code as you wish.  If you make usefull * modifications I'd appreciate hearing about it. */#define DLPI_MAXWAIT		15	/* Max timeout *//* * Parse an interface name and extract the unit number */static int dlpiunit (ifname)	char *ifname;{	int fd;	char *cp, *dp, *ep;	int unit;		if (!ifname) {		return 0;	}		/* Advance to the end of the name */	cp = ifname;	while (*cp) cp++;	/* Back up to the start of the first digit */	while ((*(cp-1) >= '0' && *(cp-1) <= '9') || *(cp - 1) == ':') cp--;		/* Convert the unit number */	unit = 0;	while (*cp >= '0' && *cp <= '9') {		unit *= 10;		unit += (*cp++ - '0');	}		return unit;}/* * dlpiopen - open the DLPI device for a given interface name */static int dlpiopen (ifname)	char *ifname;{	char devname [50];	char *cp, *dp, *ep;		if (!ifname) {		return -1;	}		/* Open a DLPI device */	if (*ifname == '/') {		dp = devname;	} else {		/* Prepend the device directory */		memcpy (devname, DLPI_DEVDIR, strlen (DLPI_DEVDIR));		dp = &devname [strlen (DLPI_DEVDIR)];	}	/* Find the end of the interface name */	ep = cp = ifname;	while (*ep)		ep++;	/* And back up to the first digit (unit number) */	while ((*(ep - 1) >= '0' && *(ep - 1) <= '9') || *(ep - 1) == ':')		ep--;		/* Copy everything up to the unit number */	while (cp < ep) {		*dp++ = *cp++;	}	*dp = '\0';		return open (devname, O_RDWR, 0);}/* * dlpiinforeq - request information about the data link provider. */static int dlpiinforeq (fd)	int fd;{	dl_info_req_t info_req;	struct strbuf ctl;	int flags;		info_req.dl_primitive = DL_INFO_REQ;		ctl.maxlen = 0;	ctl.len = sizeof (info_req);	ctl.buf = (char *)&info_req;		flags = RS_HIPRI;		return putmsg (fd, &ctl, (struct strbuf *)NULL, flags);}/* * dlpiphysaddrreq - request the current physical address. */static int dlpiphysaddrreq (fd, addrtype)	int fd;	unsigned long addrtype;{	dl_phys_addr_req_t physaddr_req;	struct strbuf ctl;	int flags;		physaddr_req.dl_primitive = DL_PHYS_ADDR_REQ;	physaddr_req.dl_addr_type = addrtype;		ctl.maxlen = 0;	ctl.len = sizeof (physaddr_req);	ctl.buf = (char *)&physaddr_req;		flags = RS_HIPRI;		return putmsg (fd, &ctl, (struct strbuf *)NULL, flags);}/* * dlpiattachreq - send a request to attach to a specific unit. */static int dlpiattachreq (fd, ppa)	unsigned long ppa;	int fd;{	dl_attach_req_t	attach_req;	struct strbuf ctl;	int flags;		attach_req.dl_primitive = DL_ATTACH_REQ;	attach_req.dl_ppa = ppa;		ctl.maxlen = 0;	ctl.len = sizeof (attach_req);	ctl.buf = (char *)&attach_req;		flags = 0;		return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);}/* * dlpibindreq - send a request to bind to a specific SAP address. */static int dlpibindreq (fd, sap, max_conind, service_mode, conn_mgmt, xidtest)	unsigned long sap;	unsigned long max_conind;	unsigned long service_mode;	unsigned long conn_mgmt;	unsigned long xidtest;	int fd;{	dl_bind_req_t bind_req;	struct strbuf ctl;	int flags;		bind_req.dl_primitive = DL_BIND_REQ;	bind_req.dl_sap = sap;	bind_req.dl_max_conind = max_conind;	bind_req.dl_service_mode = service_mode;	bind_req.dl_conn_mgmt = conn_mgmt;	bind_req.dl_xidtest_flg = xidtest;		ctl.maxlen = 0;	ctl.len = sizeof (bind_req);	ctl.buf = (char *)&bind_req;		flags = 0;		return putmsg (fd, &ctl, (struct strbuf*)NULL, flags);}/* * dlpiunbindreq - send a request to unbind. */static int dlpiunbindreq (fd)	int fd;

⌨️ 快捷键说明

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