forked from Imagelibrary/rtems
Base files
This commit is contained in:
56
c/src/exec/libcsupport/include/sys/filio.h
Normal file
56
c/src/exec/libcsupport/include/sys/filio.h
Normal file
@@ -0,0 +1,56 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)filio.h 8.1 (Berkeley) 3/28/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_FILIO_H_
|
||||
#define _SYS_FILIO_H_
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/* Generic file-descriptor ioctl's. */
|
||||
#define FIOCLEX _IO('f', 1) /* set close on exec on fd */
|
||||
#define FIONCLEX _IO('f', 2) /* remove close on exec */
|
||||
#define FIONREAD _IOR('f', 127, int) /* get # bytes to read */
|
||||
#define FIONBIO _IOW('f', 126, int) /* set/clear non-blocking i/o */
|
||||
#define FIOASYNC _IOW('f', 125, int) /* set/clear async i/o */
|
||||
#define FIOSETOWN _IOW('f', 124, int) /* set owner */
|
||||
#define FIOGETOWN _IOR('f', 123, int) /* get owner */
|
||||
|
||||
#endif /* !_SYS_FILIO_H_ */
|
||||
77
c/src/exec/libcsupport/include/sys/ioctl.h
Normal file
77
c/src/exec/libcsupport/include/sys/ioctl.h
Normal file
@@ -0,0 +1,77 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ioctl.h 8.6 (Berkeley) 3/28/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_IOCTL_H_
|
||||
#define _SYS_IOCTL_H_
|
||||
|
||||
#include <sys/ttycom.h>
|
||||
|
||||
/*
|
||||
* Pun for SunOS prior to 3.2. SunOS 3.2 and later support TIOCGWINSZ
|
||||
* and TIOCSWINSZ (yes, even 3.2-3.5, the fact that it wasn't documented
|
||||
* notwithstanding).
|
||||
*/
|
||||
struct ttysize {
|
||||
unsigned short ts_lines;
|
||||
unsigned short ts_cols;
|
||||
unsigned short ts_xxx;
|
||||
unsigned short ts_yyy;
|
||||
};
|
||||
#define TIOCGSIZE TIOCGWINSZ
|
||||
#define TIOCSSIZE TIOCSWINSZ
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
#include <sys/filio.h>
|
||||
#include <sys/sockio.h>
|
||||
|
||||
#endif /* !_SYS_IOCTL_H_ */
|
||||
|
||||
/*
|
||||
* Keep outside _SYS_IOCTL_H_
|
||||
* Compatibility with old terminal driver
|
||||
*
|
||||
* Source level -> #define USE_OLD_TTY
|
||||
* Kernel level -> options COMPAT_43 or COMPAT_SUNOS
|
||||
*/
|
||||
#if defined(USE_OLD_TTY) || defined(COMPAT_43) || defined(COMPAT_SUNOS)
|
||||
#include <sys/ioctl_compat.h>
|
||||
#endif
|
||||
86
c/src/exec/libcsupport/include/sys/sockio.h
Normal file
86
c/src/exec/libcsupport/include/sys/sockio.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*-
|
||||
* Copyright (c) 1982, 1986, 1990, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)sockio.h 8.1 (Berkeley) 3/28/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _SYS_SOCKIO_H_
|
||||
#define _SYS_SOCKIO_H_
|
||||
|
||||
#include <sys/ioccom.h>
|
||||
|
||||
/* Socket ioctl's. */
|
||||
#define SIOCSHIWAT _IOW('s', 0, int) /* set high watermark */
|
||||
#define SIOCGHIWAT _IOR('s', 1, int) /* get high watermark */
|
||||
#define SIOCSLOWAT _IOW('s', 2, int) /* set low watermark */
|
||||
#define SIOCGLOWAT _IOR('s', 3, int) /* get low watermark */
|
||||
#define SIOCATMARK _IOR('s', 7, int) /* at oob mark? */
|
||||
#define SIOCSPGRP _IOW('s', 8, int) /* set process group */
|
||||
#define SIOCGPGRP _IOR('s', 9, int) /* get process group */
|
||||
|
||||
#define SIOCADDRT _IOW('r', 10, struct ortentry) /* add route */
|
||||
#define SIOCDELRT _IOW('r', 11, struct ortentry) /* delete route */
|
||||
#define SIOCGETVIFCNT _IOWR('r', 15, struct sioc_vif_req)/* get vif pkt cnt */
|
||||
#define SIOCGETSGCNT _IOWR('r', 16, struct sioc_sg_req) /* get s,g pkt cnt */
|
||||
|
||||
#define SIOCSIFADDR _IOW('i', 12, struct ifreq) /* set ifnet address */
|
||||
#define OSIOCGIFADDR _IOWR('i', 13, struct ifreq) /* get ifnet address */
|
||||
#define SIOCGIFADDR _IOWR('i', 33, struct ifreq) /* get ifnet address */
|
||||
#define SIOCSIFDSTADDR _IOW('i', 14, struct ifreq) /* set p-p address */
|
||||
#define OSIOCGIFDSTADDR _IOWR('i', 15, struct ifreq) /* get p-p address */
|
||||
#define SIOCGIFDSTADDR _IOWR('i', 34, struct ifreq) /* get p-p address */
|
||||
#define SIOCSIFFLAGS _IOW('i', 16, struct ifreq) /* set ifnet flags */
|
||||
#define SIOCGIFFLAGS _IOWR('i', 17, struct ifreq) /* get ifnet flags */
|
||||
#define OSIOCGIFBRDADDR _IOWR('i', 18, struct ifreq) /* get broadcast addr */
|
||||
#define SIOCGIFBRDADDR _IOWR('i', 35, struct ifreq) /* get broadcast addr */
|
||||
#define SIOCSIFBRDADDR _IOW('i', 19, struct ifreq) /* set broadcast addr */
|
||||
#define OSIOCGIFCONF _IOWR('i', 20, struct ifconf) /* get ifnet list */
|
||||
#define SIOCGIFCONF _IOWR('i', 36, struct ifconf) /* get ifnet list */
|
||||
#define OSIOCGIFNETMASK _IOWR('i', 21, struct ifreq) /* get net addr mask */
|
||||
#define SIOCGIFNETMASK _IOWR('i', 37, struct ifreq) /* get net addr mask */
|
||||
#define SIOCSIFNETMASK _IOW('i', 22, struct ifreq) /* set net addr mask */
|
||||
#define SIOCGIFMETRIC _IOWR('i', 23, struct ifreq) /* get IF metric */
|
||||
#define SIOCSIFMETRIC _IOW('i', 24, struct ifreq) /* set IF metric */
|
||||
#define SIOCDIFADDR _IOW('i', 25, struct ifreq) /* delete IF addr */
|
||||
#define SIOCAIFADDR _IOW('i', 26, struct ifaliasreq)/* add/chg IF alias */
|
||||
|
||||
#define SIOCADDMULTI _IOW('i', 49, struct ifreq) /* add m'cast addr */
|
||||
#define SIOCDELMULTI _IOW('i', 50, struct ifreq) /* del m'cast addr */
|
||||
#define SIOCGIFMTU _IOWR('i', 51, struct ifreq) /* get IF mtu */
|
||||
#define SIOCSIFMTU _IOW('i', 52, struct ifreq) /* set IF mtu */
|
||||
#define SIOCGIFPHYS _IOWR('i', 53, struct ifreq) /* get IF wire */
|
||||
#define SIOCSIFPHYS _IOW('i', 54, struct ifreq) /* set IF wire */
|
||||
#define SIOCSIFMEDIA _IOWR('i', 55, struct ifreq) /* set net media */
|
||||
#define SIOCGIFMEDIA _IOWR('i', 56, struct ifmediareq) /* get net media */
|
||||
|
||||
#endif /* !_SYS_SOCKIO_H_ */
|
||||
14
c/src/exec/libnetworking/README
Normal file
14
c/src/exec/libnetworking/README
Normal file
@@ -0,0 +1,14 @@
|
||||
This is a snapshot of my attempt to fit the FreeBSD networking code into
|
||||
RTEMS. Things seem to be working!
|
||||
|
||||
Things that need to be done:
|
||||
1) More documentation!
|
||||
2) Figure out what's still not working :-)
|
||||
3) Rationalize the include files. Right now I have a special
|
||||
hack in the Makefile to ensure that I pick up the FreeBSD versions
|
||||
of the include files that are duplicated between RTEMS
|
||||
and FreeBSD.
|
||||
The network device driver source should move to the BSP source tree.
|
||||
4) Have a look at all the FIXME comments.
|
||||
5) Go through and make sure that all the source files are
|
||||
free of undesired copyright restrictions.
|
||||
109
c/src/exec/libnetworking/arpa/ftp.h
Normal file
109
c/src/exec/libnetworking/arpa/ftp.h
Normal file
@@ -0,0 +1,109 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)ftp.h 8.1 (Berkeley) 6/2/93
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_FTP_H_
|
||||
#define _ARPA_FTP_H_
|
||||
|
||||
/* Definitions for FTP; see RFC-765. */
|
||||
|
||||
/*
|
||||
* Reply codes.
|
||||
*/
|
||||
#define PRELIM 1 /* positive preliminary */
|
||||
#define COMPLETE 2 /* positive completion */
|
||||
#define CONTINUE 3 /* positive intermediate */
|
||||
#define TRANSIENT 4 /* transient negative completion */
|
||||
#define ERROR 5 /* permanent negative completion */
|
||||
|
||||
/*
|
||||
* Type codes
|
||||
*/
|
||||
#define TYPE_A 1 /* ASCII */
|
||||
#define TYPE_E 2 /* EBCDIC */
|
||||
#define TYPE_I 3 /* image */
|
||||
#define TYPE_L 4 /* local byte size */
|
||||
|
||||
#ifdef FTP_NAMES
|
||||
char *typenames[] = {"0", "ASCII", "EBCDIC", "Image", "Local" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Form codes
|
||||
*/
|
||||
#define FORM_N 1 /* non-print */
|
||||
#define FORM_T 2 /* telnet format effectors */
|
||||
#define FORM_C 3 /* carriage control (ASA) */
|
||||
#ifdef FTP_NAMES
|
||||
char *formnames[] = {"0", "Nonprint", "Telnet", "Carriage-control" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure codes
|
||||
*/
|
||||
#define STRU_F 1 /* file (no record structure) */
|
||||
#define STRU_R 2 /* record structure */
|
||||
#define STRU_P 3 /* page structure */
|
||||
#ifdef FTP_NAMES
|
||||
char *strunames[] = {"0", "File", "Record", "Page" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Mode types
|
||||
*/
|
||||
#define MODE_S 1 /* stream */
|
||||
#define MODE_B 2 /* block */
|
||||
#define MODE_C 3 /* compressed */
|
||||
#ifdef FTP_NAMES
|
||||
char *modenames[] = {"0", "Stream", "Block", "Compressed" };
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Record Tokens
|
||||
*/
|
||||
#define REC_ESC '\377' /* Record-mode Escape */
|
||||
#define REC_EOR '\001' /* Record-mode End-of-Record */
|
||||
#define REC_EOF '\002' /* Record-mode End-of-File */
|
||||
|
||||
/*
|
||||
* Block Header
|
||||
*/
|
||||
#define BLK_EOR 0x80 /* Block is End-of-Record */
|
||||
#define BLK_EOF 0x40 /* Block is End-of-File */
|
||||
#define BLK_ERRORS 0x20 /* Block is suspected of containing errors */
|
||||
#define BLK_RESTART 0x10 /* Block is Restart Marker */
|
||||
|
||||
#define BLK_BYTECOUNT 2 /* Bytes in this block */
|
||||
|
||||
#endif /* !_FTP_H_ */
|
||||
103
c/src/exec/libnetworking/arpa/inet.h
Normal file
103
c/src/exec/libnetworking/arpa/inet.h
Normal file
@@ -0,0 +1,103 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @(#)inet.h 8.1 (Berkeley) 6/2/93
|
||||
* From: Id: inet.h,v 8.5 1997/01/29 08:48:09 vixie Exp $
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_INET_H_
|
||||
#define _ARPA_INET_H_
|
||||
|
||||
/* External definitions for functions in inet(3), addr2ascii(3) */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
struct in_addr;
|
||||
|
||||
/* XXX all new diversions!! argh!! */
|
||||
#define inet_addr __inet_addr
|
||||
#define inet_aton __inet_aton
|
||||
#define inet_lnaof __inet_lnaof
|
||||
#define inet_makeaddr __inet_makeaddr
|
||||
#define inet_neta __inet_neta
|
||||
#define inet_netof __inet_netof
|
||||
#define inet_network __inet_network
|
||||
#define inet_net_ntop __inet_net_ntop
|
||||
#define inet_net_pton __inet_net_pton
|
||||
#define inet_ntoa __inet_ntoa
|
||||
#define inet_pton __inet_pton
|
||||
#define inet_ntop __inet_ntop
|
||||
#define inet_nsap_addr __inet_nsap_addr
|
||||
#define inet_nsap_ntoa __inet_nsap_ntoa
|
||||
|
||||
__BEGIN_DECLS
|
||||
int ascii2addr __P((int, const char *, void *));
|
||||
char *addr2ascii __P((int, const void *, int, char *));
|
||||
unsigned long inet_addr __P((const char *));
|
||||
int inet_aton __P((const char *, struct in_addr *));
|
||||
unsigned long inet_lnaof __P((struct in_addr));
|
||||
struct in_addr inet_makeaddr __P((u_long , u_long));
|
||||
char * inet_neta __P((u_long, char *, size_t));
|
||||
unsigned long inet_netof __P((struct in_addr));
|
||||
unsigned long inet_network __P((const char *));
|
||||
char *inet_net_ntop __P((int, const void *, int, char *, size_t));
|
||||
int inet_net_pton __P((int, const char *, void *, size_t));
|
||||
char *inet_ntoa __P((struct in_addr));
|
||||
int inet_pton __P((int, const char *, void *));
|
||||
const char *inet_ntop __P((int, const void *, char *, size_t));
|
||||
u_int inet_nsap_addr __P((const char *, u_char *, int));
|
||||
char *inet_nsap_ntoa __P((int, const u_char *, char *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_INET_H_ */
|
||||
448
c/src/exec/libnetworking/arpa/nameser.h
Normal file
448
c/src/exec/libnetworking/arpa/nameser.h
Normal file
@@ -0,0 +1,448 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* From: Id: nameser.h,v 8.16 1998/02/06 00:35:58 halley Exp
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_H_
|
||||
#define _ARPA_NAMESER_H_
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
/*
|
||||
* revision information. this is the release date in YYYYMMDD format.
|
||||
* it can change every day so the right thing to do with it is use it
|
||||
* in preprocessor commands such as "#if (__NAMESER > 19931104)". do not
|
||||
* compare for equality; rather, use it to determine whether your libnameser.a
|
||||
* is new enough to contain a certain feature.
|
||||
*/
|
||||
|
||||
/* XXXRTH I made this bigger than __BIND in 4.9.5 T6B */
|
||||
#define __NAMESER 19961001 /* New interface version stamp. */
|
||||
|
||||
/*
|
||||
* Define constants based on RFC 883, RFC 1034, RFC 1035
|
||||
*/
|
||||
#define NS_PACKETSZ 512 /* maximum packet size */
|
||||
#define NS_MAXDNAME 1025 /* maximum domain name */
|
||||
#define NS_MAXCDNAME 255 /* maximum compressed domain name */
|
||||
#define NS_MAXLABEL 63 /* maximum length of domain label */
|
||||
#define NS_HFIXEDSZ 12 /* #/bytes of fixed data in header */
|
||||
#define NS_QFIXEDSZ 4 /* #/bytes of fixed data in query */
|
||||
#define NS_RRFIXEDSZ 10 /* #/bytes of fixed data in r record */
|
||||
#define NS_INT32SZ 4 /* #/bytes of data in a u_int32_t */
|
||||
#define NS_INT16SZ 2 /* #/bytes of data in a u_int16_t */
|
||||
#define NS_INT8SZ 1 /* #/bytes of data in a u_int8_t */
|
||||
#define NS_INADDRSZ 4 /* IPv4 T_A */
|
||||
#define NS_IN6ADDRSZ 16 /* IPv6 T_AAAA */
|
||||
#define NS_CMPRSFLGS 0xc0 /* Flag bits indicating name compression. */
|
||||
#define NS_DEFAULTPORT 53 /* For both TCP and UDP. */
|
||||
|
||||
/*
|
||||
* These can be expanded with synonyms, just keep ns_parse.c:ns_parserecord()
|
||||
* in synch with it.
|
||||
*/
|
||||
typedef enum __ns_sect {
|
||||
ns_s_qd = 0, /* Query: Question. */
|
||||
ns_s_zn = 0, /* Update: Zone. */
|
||||
ns_s_an = 1, /* Query: Answer. */
|
||||
ns_s_pr = 1, /* Update: Prerequisites. */
|
||||
ns_s_ns = 2, /* Query: Name servers. */
|
||||
ns_s_ud = 2, /* Update: Update. */
|
||||
ns_s_ar = 3, /* Query|Update: Additional records. */
|
||||
ns_s_max = 4
|
||||
} ns_sect;
|
||||
|
||||
/*
|
||||
* This is a message handle. It is caller allocated and has no dynamic data.
|
||||
* This structure is intended to be opaque to all but ns_parse.c, thus the
|
||||
* leading _'s on the member names. Use the accessor functions, not the _'s.
|
||||
*/
|
||||
typedef struct __ns_msg {
|
||||
const u_char *_msg, *_eom;
|
||||
u_int16_t _id, _flags, _counts[ns_s_max];
|
||||
const u_char *_sections[ns_s_max];
|
||||
ns_sect _sect;
|
||||
int _rrnum;
|
||||
const u_char *_ptr;
|
||||
} ns_msg;
|
||||
|
||||
/* Private data structure - do not use from outside library. */
|
||||
struct _ns_flagdata { int mask, shift; };
|
||||
extern struct _ns_flagdata _ns_flagdata[];
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
#define ns_msg_getflag(handle, flag) ( \
|
||||
((handle)._flags & _ns_flagdata[flag].mask) \
|
||||
>> _ns_flagdata[flag].shift \
|
||||
)
|
||||
#define ns_msg_id(handle) ((handle)._id + 0)
|
||||
#define ns_msg_base(handle) ((handle)._msg + 0)
|
||||
#define ns_msg_end(handle) ((handle)._eom + 0)
|
||||
#define ns_msg_size(handle) ((handle)._eom - (handle)._msg)
|
||||
#define ns_msg_count(handle, section) ((handle)._counts[section] + 0)
|
||||
|
||||
/*
|
||||
* This is a parsed record. It is caller allocated and has no dynamic data.
|
||||
*/
|
||||
typedef struct __ns_rr {
|
||||
char name[NS_MAXDNAME]; /* XXX need to malloc */
|
||||
u_int16_t type;
|
||||
u_int16_t class;
|
||||
u_int32_t ttl;
|
||||
u_int16_t rdlength;
|
||||
const u_char *rdata;
|
||||
} ns_rr;
|
||||
|
||||
/* Accessor macros - this is part of the public interface. */
|
||||
#define ns_rr_name(rr) (((rr).name[0] != '\0') ? (rr).name : ".")
|
||||
#define ns_rr_type(rr) ((rr).type + 0)
|
||||
#define ns_rr_class(rr) ((rr).class + 0)
|
||||
#define ns_rr_ttl(rr) ((rr).ttl + 0)
|
||||
#define ns_rr_rdlen(rr) ((rr).rdlength + 0)
|
||||
#define ns_rr_rdata(rr) ((rr).rdata + 0)
|
||||
|
||||
/*
|
||||
* These don't have to be in the same order as in the packet flags word,
|
||||
* and they can even overlap in some cases, but they will need to be kept
|
||||
* in synch with ns_parse.c:ns_flagdata[].
|
||||
*/
|
||||
typedef enum __ns_flag {
|
||||
ns_f_qr, /* Question/Response. */
|
||||
ns_f_opcode, /* Operation code. */
|
||||
ns_f_aa, /* Authoritative Answer. */
|
||||
ns_f_tc, /* Truncation occurred. */
|
||||
ns_f_rd, /* Recursion Desired. */
|
||||
ns_f_ra, /* Recursion Available. */
|
||||
ns_f_z, /* MBZ. */
|
||||
ns_f_ad, /* Authentic Data (DNSSEC). */
|
||||
ns_f_cd, /* Checking Disabled (DNSSEC). */
|
||||
ns_f_rcode, /* Response code. */
|
||||
ns_f_max
|
||||
} ns_flag;
|
||||
|
||||
/*
|
||||
* Currently defined opcodes.
|
||||
*/
|
||||
typedef enum __ns_opcode {
|
||||
ns_o_query = 0, /* Standard query. */
|
||||
ns_o_iquery = 1, /* Inverse query (deprecated/unsupported). */
|
||||
ns_o_status = 2, /* Name server status query (unsupported). */
|
||||
/* Opcode 3 is undefined/reserved. */
|
||||
ns_o_notify = 4, /* Zone change notification. */
|
||||
ns_o_update = 5, /* Zone update message. */
|
||||
ns_o_max = 6
|
||||
} ns_opcode;
|
||||
|
||||
/*
|
||||
* Currently defined response codes.
|
||||
*/
|
||||
typedef enum __ns_rcode {
|
||||
ns_r_noerror = 0, /* No error occurred. */
|
||||
ns_r_formerr = 1, /* Format error. */
|
||||
ns_r_servfail = 2, /* Server failure. */
|
||||
ns_r_nxdomain = 3, /* Name error. */
|
||||
ns_r_notimpl = 4, /* Unimplemented. */
|
||||
ns_r_refused = 5, /* Operation refused. */
|
||||
/* these are for BIND_UPDATE */
|
||||
ns_r_yxdomain = 6, /* Name exists */
|
||||
ns_r_yxrrset = 7, /* RRset exists */
|
||||
ns_r_nxrrset = 8, /* RRset does not exist */
|
||||
ns_r_notauth = 9, /* Not authoritative for zone */
|
||||
ns_r_notzone = 10, /* Zone of record different from zone section */
|
||||
ns_r_max = 11
|
||||
} ns_rcode;
|
||||
|
||||
/* BIND_UPDATE */
|
||||
typedef enum __ns_update_operation {
|
||||
ns_uop_delete = 0,
|
||||
ns_uop_add = 1,
|
||||
ns_uop_max = 2
|
||||
} ns_update_operation;
|
||||
|
||||
/*
|
||||
* This RR-like structure is particular to UPDATE.
|
||||
*/
|
||||
struct ns_updrec {
|
||||
struct ns_updrec *r_prev; /* prev record */
|
||||
struct ns_updrec *r_next; /* next record */
|
||||
u_int8_t r_section; /* ZONE/PREREQUISITE/UPDATE */
|
||||
char * r_dname; /* owner of the RR */
|
||||
u_int16_t r_class; /* class number */
|
||||
u_int16_t r_type; /* type number */
|
||||
u_int32_t r_ttl; /* time to live */
|
||||
u_char * r_data; /* rdata fields as text string */
|
||||
u_int16_t r_size; /* size of r_data field */
|
||||
int r_opcode; /* type of operation */
|
||||
/* following fields for private use by the resolver/server routines */
|
||||
struct ns_updrec *r_grpnext; /* next record when grouped */
|
||||
struct databuf *r_dp; /* databuf to process */
|
||||
struct databuf *r_deldp; /* databuf's deleted/overwritten */
|
||||
u_int16_t r_zone; /* zone number on server */
|
||||
};
|
||||
typedef struct ns_updrec ns_updrec;
|
||||
|
||||
/*
|
||||
* Currently defined type values for resources and queries.
|
||||
*/
|
||||
typedef enum __ns_type {
|
||||
ns_t_a = 1, /* Host address. */
|
||||
ns_t_ns = 2, /* Authoritative server. */
|
||||
ns_t_md = 3, /* Mail destination. */
|
||||
ns_t_mf = 4, /* Mail forwarder. */
|
||||
ns_t_cname = 5, /* Canonical name. */
|
||||
ns_t_soa = 6, /* Start of authority zone. */
|
||||
ns_t_mb = 7, /* Mailbox domain name. */
|
||||
ns_t_mg = 8, /* Mail group member. */
|
||||
ns_t_mr = 9, /* Mail rename name. */
|
||||
ns_t_null = 10, /* Null resource record. */
|
||||
ns_t_wks = 11, /* Well known service. */
|
||||
ns_t_ptr = 12, /* Domain name pointer. */
|
||||
ns_t_hinfo = 13, /* Host information. */
|
||||
ns_t_minfo = 14, /* Mailbox information. */
|
||||
ns_t_mx = 15, /* Mail routing information. */
|
||||
ns_t_txt = 16, /* Text strings. */
|
||||
ns_t_rp = 17, /* Responsible person. */
|
||||
ns_t_afsdb = 18, /* AFS cell database. */
|
||||
ns_t_x25 = 19, /* X_25 calling address. */
|
||||
ns_t_isdn = 20, /* ISDN calling address. */
|
||||
ns_t_rt = 21, /* Router. */
|
||||
ns_t_nsap = 22, /* NSAP address. */
|
||||
ns_t_nsap_ptr = 23, /* Reverse NSAP lookup (deprecated). */
|
||||
ns_t_sig = 24, /* Security signature. */
|
||||
ns_t_key = 25, /* Security key. */
|
||||
ns_t_px = 26, /* X.400 mail mapping. */
|
||||
ns_t_gpos = 27, /* Geographical position (withdrawn). */
|
||||
ns_t_aaaa = 28, /* Ip6 Address. */
|
||||
ns_t_loc = 29, /* Location Information. */
|
||||
ns_t_nxt = 30, /* Next domain (security). */
|
||||
ns_t_eid = 31, /* Endpoint identifier. */
|
||||
ns_t_nimloc = 32, /* Nimrod Locator. */
|
||||
ns_t_srv = 33, /* Server Selection. */
|
||||
ns_t_atma = 34, /* ATM Address */
|
||||
ns_t_naptr = 35, /* Naming Authority PoinTeR */
|
||||
/* Query type values which do not appear in resource records. */
|
||||
ns_t_ixfr = 251, /* Incremental zone transfer. */
|
||||
ns_t_axfr = 252, /* Transfer zone of authority. */
|
||||
ns_t_mailb = 253, /* Transfer mailbox records. */
|
||||
ns_t_maila = 254, /* Transfer mail agent records. */
|
||||
ns_t_any = 255, /* Wildcard match. */
|
||||
ns_t_max = 65536
|
||||
} ns_type;
|
||||
|
||||
/*
|
||||
* Values for class field
|
||||
*/
|
||||
typedef enum __ns_class {
|
||||
ns_c_in = 1, /* Internet. */
|
||||
/* Class 2 unallocated/unsupported. */
|
||||
ns_c_chaos = 3, /* MIT Chaos-net. */
|
||||
ns_c_hs = 4, /* MIT Hesiod. */
|
||||
/* Query class values which do not appear in resource records */
|
||||
ns_c_none = 254, /* for prereq. sections in update requests */
|
||||
ns_c_any = 255, /* Wildcard match. */
|
||||
ns_c_max = 65536
|
||||
} ns_class;
|
||||
|
||||
/*
|
||||
* Flags field of the KEY RR rdata
|
||||
*/
|
||||
#define NS_KEY_TYPEMASK 0xC000 /* Mask for "type" bits */
|
||||
#define NS_KEY_TYPE_AUTH_CONF 0x0000 /* Key usable for both */
|
||||
#define NS_KEY_TYPE_CONF_ONLY 0x8000 /* Key usable for confidentiality */
|
||||
#define NS_KEY_TYPE_AUTH_ONLY 0x4000 /* Key usable for authentication */
|
||||
#define NS_KEY_TYPE_NO_KEY 0xC000 /* No key usable for either; no key */
|
||||
/* The type bits can also be interpreted independently, as single bits: */
|
||||
#define NS_KEY_NO_AUTH 0x8000 /* Key unusable for authentication */
|
||||
#define NS_KEY_NO_CONF 0x4000 /* Key unusable for confidentiality */
|
||||
#define NS_KEY_EXPERIMENTAL 0x2000 /* Security is *mandatory* if bit=0 */
|
||||
#define NS_KEY_RESERVED3 0x1000 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED4 0x0800 /* reserved - must be zero */
|
||||
#define NS_KEY_USERACCOUNT 0x0400 /* key is assoc. with a user acct */
|
||||
#define NS_KEY_ENTITY 0x0200 /* key is assoc. with entity eg host */
|
||||
#define NS_KEY_ZONEKEY 0x0100 /* key is zone key */
|
||||
#define NS_KEY_IPSEC 0x0080 /* key is for IPSEC (host or user)*/
|
||||
#define NS_KEY_EMAIL 0x0040 /* key is for email (MIME security) */
|
||||
#define NS_KEY_RESERVED10 0x0020 /* reserved - must be zero */
|
||||
#define NS_KEY_RESERVED11 0x0010 /* reserved - must be zero */
|
||||
#define NS_KEY_SIGNATORYMASK 0x000F /* key can sign RR's of same name */
|
||||
|
||||
#define NS_KEY_RESERVED_BITMASK ( NS_KEY_RESERVED3 | \
|
||||
NS_KEY_RESERVED4 | \
|
||||
NS_KEY_RESERVED10 | \
|
||||
NS_KEY_RESERVED11 )
|
||||
|
||||
/* The Algorithm field of the KEY and SIG RR's is an integer, {1..254} */
|
||||
#define NS_ALG_MD5RSA 1 /* MD5 with RSA */
|
||||
#define NS_ALG_EXPIRE_ONLY 253 /* No alg, no security */
|
||||
#define NS_ALG_PRIVATE_OID 254 /* Key begins with OID giving alg */
|
||||
|
||||
/* Signatures */
|
||||
#define NS_MD5RSA_MIN_BITS 512 /* Size of a mod or exp in bits */
|
||||
#define NS_MD5RSA_MAX_BITS 2552
|
||||
/* Total of binary mod and exp */
|
||||
#define NS_MD5RSA_MAX_BYTES ((NS_MD5RSA_MAX_BITS+7/8)*2+3)
|
||||
/* Max length of text sig block */
|
||||
#define NS_MD5RSA_MAX_BASE64 (((NS_MD5RSA_MAX_BYTES+2)/3)*4)
|
||||
|
||||
/* Offsets into SIG record rdata to find various values */
|
||||
#define NS_SIG_TYPE 0 /* Type flags */
|
||||
#define NS_SIG_ALG 2 /* Algorithm */
|
||||
#define NS_SIG_LABELS 3 /* How many labels in name */
|
||||
#define NS_SIG_OTTL 4 /* Original TTL */
|
||||
#define NS_SIG_EXPIR 8 /* Expiration time */
|
||||
#define NS_SIG_SIGNED 12 /* Signature time */
|
||||
#define NS_SIG_FOOT 16 /* Key footprint */
|
||||
#define NS_SIG_SIGNER 18 /* Domain name of who signed it */
|
||||
|
||||
/* How RR types are represented as bit-flags in NXT records */
|
||||
#define NS_NXT_BITS 8
|
||||
#define NS_NXT_BIT_SET( n,p) (p[(n)/NS_NXT_BITS] |= (0x80>>((n)%NS_NXT_BITS)))
|
||||
#define NS_NXT_BIT_CLEAR(n,p) (p[(n)/NS_NXT_BITS] &= ~(0x80>>((n)%NS_NXT_BITS)))
|
||||
#define NS_NXT_BIT_ISSET(n,p) (p[(n)/NS_NXT_BITS] & (0x80>>((n)%NS_NXT_BITS)))
|
||||
|
||||
|
||||
/*
|
||||
* Inline versions of get/put short/long. Pointer is advanced.
|
||||
*/
|
||||
#define NS_GET16(s, cp) { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
(s) = ((u_int16_t)t_cp[0] << 8) \
|
||||
| ((u_int16_t)t_cp[1]) \
|
||||
; \
|
||||
(cp) += NS_INT16SZ; \
|
||||
}
|
||||
|
||||
#define NS_GET32(l, cp) { \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
(l) = ((u_int32_t)t_cp[0] << 24) \
|
||||
| ((u_int32_t)t_cp[1] << 16) \
|
||||
| ((u_int32_t)t_cp[2] << 8) \
|
||||
| ((u_int32_t)t_cp[3]) \
|
||||
; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
}
|
||||
|
||||
#define NS_PUT16(s, cp) { \
|
||||
register u_int16_t t_s = (u_int16_t)(s); \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
*t_cp++ = t_s >> 8; \
|
||||
*t_cp = t_s; \
|
||||
(cp) += NS_INT16SZ; \
|
||||
}
|
||||
|
||||
#define NS_PUT32(l, cp) { \
|
||||
register u_int32_t t_l = (u_int32_t)(l); \
|
||||
register u_char *t_cp = (u_char *)(cp); \
|
||||
*t_cp++ = t_l >> 24; \
|
||||
*t_cp++ = t_l >> 16; \
|
||||
*t_cp++ = t_l >> 8; \
|
||||
*t_cp = t_l; \
|
||||
(cp) += NS_INT32SZ; \
|
||||
}
|
||||
|
||||
/*
|
||||
* ANSI C identifier hiding.
|
||||
*/
|
||||
#define ns_get16 __ns_get16
|
||||
#define ns_get32 __ns_get32
|
||||
#define ns_put16 __ns_put16
|
||||
#define ns_put32 __ns_put32
|
||||
#define ns_initparse __ns_initparse
|
||||
#define ns_parserr __ns_parserr
|
||||
#define ns_sprintrr __ns_sprintrr
|
||||
#define ns_sprintrrf __ns_sprintrrf
|
||||
#define ns_format_ttl __ns_format_ttl
|
||||
#define ns_parse_ttl __ns_parse_ttl
|
||||
#define ns_name_ntop __ns_name_ntop
|
||||
#define ns_name_pton __ns_name_pton
|
||||
#define ns_name_unpack __ns_name_unpack
|
||||
#define ns_name_pack __ns_name_pack
|
||||
#define ns_name_compress __ns_name_compress
|
||||
#define ns_name_uncompress __ns_name_uncompress
|
||||
|
||||
__BEGIN_DECLS
|
||||
u_int ns_get16 __P((const u_char *));
|
||||
u_long ns_get32 __P((const u_char *));
|
||||
void ns_put16 __P((u_int, u_char *));
|
||||
void ns_put32 __P((u_long, u_char *));
|
||||
int ns_initparse __P((const u_char *, int, ns_msg *));
|
||||
int ns_parserr __P((ns_msg *, ns_sect, int, ns_rr *));
|
||||
int ns_sprintrr __P((const ns_msg *, const ns_rr *,
|
||||
const char *, const char *, char *, size_t));
|
||||
int ns_sprintrrf __P((const u_char *, size_t, const char *,
|
||||
ns_class, ns_type, u_long, const u_char *,
|
||||
size_t, const char *, const char *,
|
||||
char *, size_t));
|
||||
int ns_format_ttl __P((u_long, char *, size_t));
|
||||
int ns_parse_ttl __P((const char *, u_long *));
|
||||
int ns_name_ntop __P((const u_char *, char *, size_t));
|
||||
int ns_name_pton __P((const char *, u_char *, size_t));
|
||||
int ns_name_unpack __P((const u_char *, const u_char *,
|
||||
const u_char *, u_char *, size_t));
|
||||
int ns_name_pack __P((const u_char *, u_char *, int,
|
||||
const u_char **, const u_char **));
|
||||
int ns_name_uncompress __P((const u_char *, const u_char *,
|
||||
const u_char *, char *, size_t));
|
||||
int ns_name_compress __P((const char *, u_char *, size_t,
|
||||
const u_char **, const u_char **));
|
||||
int ns_name_skip __P((const u_char **, const u_char *));
|
||||
__END_DECLS
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
#include <arpa/nameser_compat.h>
|
||||
#endif
|
||||
|
||||
#endif /* !_ARPA_NAMESER_H_ */
|
||||
194
c/src/exec/libnetworking/arpa/nameser_compat.h
Normal file
194
c/src/exec/libnetworking/arpa/nameser_compat.h
Normal file
@@ -0,0 +1,194 @@
|
||||
/* Copyright (c) 1983, 1989
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* from nameser.h 8.1 (Berkeley) 6/2/93
|
||||
* From: Id: nameser_compat.h,v 8.9 1998/03/20 23:25:10 halley Exp
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_NAMESER_COMPAT_
|
||||
#define _ARPA_NAMESER_COMPAT_
|
||||
|
||||
#define __BIND 19950621 /* (DEAD) interface version stamp. */
|
||||
|
||||
#include <machine/endian.h>
|
||||
|
||||
#if !defined(BYTE_ORDER) || \
|
||||
(BYTE_ORDER != BIG_ENDIAN && BYTE_ORDER != LITTLE_ENDIAN && \
|
||||
BYTE_ORDER != PDP_ENDIAN)
|
||||
/* you must determine what the correct bit order is for
|
||||
* your compiler - the next line is an intentional error
|
||||
* which will force your compiles to bomb until you fix
|
||||
* the above macros.
|
||||
*/
|
||||
error "Undefined or invalid BYTE_ORDER";
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure for query header. The order of the fields is machine- and
|
||||
* compiler-dependent, depending on the byte/bit order and the layout
|
||||
* of bit fields. We use bit fields only in int variables, as this
|
||||
* is all ANSI requires. This requires a somewhat confusing rearrangement.
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
unsigned id :16; /* query identification number */
|
||||
#if BYTE_ORDER == BIG_ENDIAN
|
||||
/* fields in third byte */
|
||||
unsigned qr: 1; /* response flag */
|
||||
unsigned opcode: 4; /* purpose of message */
|
||||
unsigned aa: 1; /* authoritive answer */
|
||||
unsigned tc: 1; /* truncated message */
|
||||
unsigned rd: 1; /* recursion desired */
|
||||
/* fields in fourth byte */
|
||||
unsigned ra: 1; /* recursion available */
|
||||
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
|
||||
unsigned ad: 1; /* authentic data from named */
|
||||
unsigned cd: 1; /* checking disabled by resolver */
|
||||
unsigned rcode :4; /* response code */
|
||||
#endif
|
||||
#if BYTE_ORDER == LITTLE_ENDIAN || BYTE_ORDER == PDP_ENDIAN
|
||||
/* fields in third byte */
|
||||
unsigned rd :1; /* recursion desired */
|
||||
unsigned tc :1; /* truncated message */
|
||||
unsigned aa :1; /* authoritive answer */
|
||||
unsigned opcode :4; /* purpose of message */
|
||||
unsigned qr :1; /* response flag */
|
||||
/* fields in fourth byte */
|
||||
unsigned rcode :4; /* response code */
|
||||
unsigned cd: 1; /* checking disabled by resolver */
|
||||
unsigned ad: 1; /* authentic data from named */
|
||||
unsigned unused :1; /* unused bits (MBZ as of 4.9.3a3) */
|
||||
unsigned ra :1; /* recursion available */
|
||||
#endif
|
||||
/* remaining bytes */
|
||||
unsigned qdcount :16; /* number of question entries */
|
||||
unsigned ancount :16; /* number of answer entries */
|
||||
unsigned nscount :16; /* number of authority entries */
|
||||
unsigned arcount :16; /* number of resource entries */
|
||||
} HEADER;
|
||||
|
||||
#define PACKETSZ NS_PACKETSZ
|
||||
#define MAXDNAME NS_MAXDNAME
|
||||
#define MAXCDNAME NS_MAXCDNAME
|
||||
#define MAXLABEL NS_MAXLABEL
|
||||
#define HFIXEDSZ NS_HFIXEDSZ
|
||||
#define QFIXEDSZ NS_QFIXEDSZ
|
||||
#define RRFIXEDSZ NS_RRFIXEDSZ
|
||||
#define INT32SZ NS_INT32SZ
|
||||
#define INT16SZ NS_INT16SZ
|
||||
#define INADDRSZ NS_INADDRSZ
|
||||
#define IN6ADDRSZ NS_IN6ADDRSZ
|
||||
#define INDIR_MASK NS_CMPRSFLGS
|
||||
#define NAMESERVER_PORT NS_DEFAULTPORT
|
||||
|
||||
#define S_ZONE ns_s_zn
|
||||
#define S_PREREQ ns_s_pr
|
||||
#define S_UPDATE ns_s_ud
|
||||
#define S_ADDT ns_s_ar
|
||||
|
||||
#define QUERY ns_o_query
|
||||
#define IQUERY ns_o_iquery
|
||||
#define STATUS ns_o_status
|
||||
#define NS_NOTIFY_OP ns_o_notify
|
||||
#define NS_UPDATE_OP ns_o_update
|
||||
|
||||
#define NOERROR ns_r_noerror
|
||||
#define FORMERR ns_r_formerr
|
||||
#define SERVFAIL ns_r_servfail
|
||||
#define NXDOMAIN ns_r_nxdomain
|
||||
#define NOTIMP ns_r_notimpl
|
||||
#define REFUSED ns_r_refused
|
||||
#define YXDOMAIN ns_r_yxdomain
|
||||
#define YXRRSET ns_r_yxrrset
|
||||
#define NXRRSET ns_r_nxrrset
|
||||
#define NOTAUTH ns_r_notauth
|
||||
#define NOTZONE ns_r_notzone
|
||||
|
||||
#define DELETE ns_uop_delete
|
||||
#define ADD ns_uop_add
|
||||
|
||||
#define T_A ns_t_a
|
||||
#define T_NS ns_t_ns
|
||||
#define T_MD ns_t_md
|
||||
#define T_MF ns_t_mf
|
||||
#define T_CNAME ns_t_cname
|
||||
#define T_SOA ns_t_soa
|
||||
#define T_MB ns_t_mb
|
||||
#define T_MG ns_t_mg
|
||||
#define T_MR ns_t_mr
|
||||
#define T_NULL ns_t_null
|
||||
#define T_WKS ns_t_wks
|
||||
#define T_PTR ns_t_ptr
|
||||
#define T_HINFO ns_t_hinfo
|
||||
#define T_MINFO ns_t_minfo
|
||||
#define T_MX ns_t_mx
|
||||
#define T_TXT ns_t_txt
|
||||
#define T_RP ns_t_rp
|
||||
#define T_AFSDB ns_t_afsdb
|
||||
#define T_X25 ns_t_x25
|
||||
#define T_ISDN ns_t_isdn
|
||||
#define T_RT ns_t_rt
|
||||
#define T_NSAP ns_t_nsap
|
||||
#define T_NSAP_PTR ns_t_nsap_ptr
|
||||
#define T_SIG ns_t_sig
|
||||
#define T_KEY ns_t_key
|
||||
#define T_PX ns_t_px
|
||||
#define T_GPOS ns_t_gpos
|
||||
#define T_AAAA ns_t_aaaa
|
||||
#define T_LOC ns_t_loc
|
||||
#define T_NXT ns_t_nxt
|
||||
#define T_EID ns_t_eid
|
||||
#define T_NIMLOC ns_t_nimloc
|
||||
#define T_SRV ns_t_srv
|
||||
#define T_ATMA ns_t_atma
|
||||
#define T_NAPTR ns_t_naptr
|
||||
#define T_IXFR ns_t_ixfr
|
||||
#define T_AXFR ns_t_axfr
|
||||
#define T_MAILB ns_t_mailb
|
||||
#define T_MAILA ns_t_maila
|
||||
#define T_ANY ns_t_any
|
||||
|
||||
#define C_IN ns_c_in
|
||||
#define C_CHAOS ns_c_chaos
|
||||
#define C_HS ns_c_hs
|
||||
/* BIND_UPDATE */
|
||||
#define C_NONE ns_c_none
|
||||
#define C_ANY ns_c_any
|
||||
|
||||
#define GETSHORT NS_GET16
|
||||
#define GETLONG NS_GET32
|
||||
#define PUTSHORT NS_PUT16
|
||||
#define PUTLONG NS_PUT32
|
||||
|
||||
#endif /* _ARPA_NAMESER_COMPAT_ */
|
||||
340
c/src/exec/libnetworking/arpa/telnet.h
Normal file
340
c/src/exec/libnetworking/arpa/telnet.h
Normal file
@@ -0,0 +1,340 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)telnet.h 8.2 (Berkeley) 12/15/93
|
||||
*/
|
||||
|
||||
#ifndef _ARPA_TELNET_H_
|
||||
#define _ARPA_TELNET_H_
|
||||
|
||||
/*
|
||||
* Definitions for the TELNET protocol.
|
||||
*/
|
||||
#define IAC 255 /* interpret as command: */
|
||||
#define DONT 254 /* you are not to use option */
|
||||
#define DO 253 /* please, you use option */
|
||||
#define WONT 252 /* I won't use option */
|
||||
#define WILL 251 /* I will use option */
|
||||
#define SB 250 /* interpret as subnegotiation */
|
||||
#define GA 249 /* you may reverse the line */
|
||||
#define EL 248 /* erase the current line */
|
||||
#define EC 247 /* erase the current character */
|
||||
#define AYT 246 /* are you there */
|
||||
#define AO 245 /* abort output--but let prog finish */
|
||||
#define IP 244 /* interrupt process--permanently */
|
||||
#define BREAK 243 /* break */
|
||||
#define DM 242 /* data mark--for connect. cleaning */
|
||||
#define NOP 241 /* nop */
|
||||
#define SE 240 /* end sub negotiation */
|
||||
#define EOR 239 /* end of record (transparent mode) */
|
||||
#define ABORT 238 /* Abort process */
|
||||
#define SUSP 237 /* Suspend process */
|
||||
#define xEOF 236 /* End of file: EOF is already used... */
|
||||
|
||||
#define SYNCH 242 /* for telfunc calls */
|
||||
|
||||
#ifdef TELCMDS
|
||||
char *telcmds[] = {
|
||||
"EOF", "SUSP", "ABORT", "EOR",
|
||||
"SE", "NOP", "DMARK", "BRK", "IP", "AO", "AYT", "EC",
|
||||
"EL", "GA", "SB", "WILL", "WONT", "DO", "DONT", "IAC",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *telcmds[];
|
||||
#endif
|
||||
|
||||
#define TELCMD_FIRST xEOF
|
||||
#define TELCMD_LAST IAC
|
||||
#define TELCMD_OK(x) ((unsigned int)(x) <= TELCMD_LAST && \
|
||||
(unsigned int)(x) >= TELCMD_FIRST)
|
||||
#define TELCMD(x) telcmds[(x)-TELCMD_FIRST]
|
||||
|
||||
/* telnet options */
|
||||
#define TELOPT_BINARY 0 /* 8-bit data path */
|
||||
#define TELOPT_ECHO 1 /* echo */
|
||||
#define TELOPT_RCP 2 /* prepare to reconnect */
|
||||
#define TELOPT_SGA 3 /* suppress go ahead */
|
||||
#define TELOPT_NAMS 4 /* approximate message size */
|
||||
#define TELOPT_STATUS 5 /* give status */
|
||||
#define TELOPT_TM 6 /* timing mark */
|
||||
#define TELOPT_RCTE 7 /* remote controlled transmission and echo */
|
||||
#define TELOPT_NAOL 8 /* negotiate about output line width */
|
||||
#define TELOPT_NAOP 9 /* negotiate about output page size */
|
||||
#define TELOPT_NAOCRD 10 /* negotiate about CR disposition */
|
||||
#define TELOPT_NAOHTS 11 /* negotiate about horizontal tabstops */
|
||||
#define TELOPT_NAOHTD 12 /* negotiate about horizontal tab disposition */
|
||||
#define TELOPT_NAOFFD 13 /* negotiate about formfeed disposition */
|
||||
#define TELOPT_NAOVTS 14 /* negotiate about vertical tab stops */
|
||||
#define TELOPT_NAOVTD 15 /* negotiate about vertical tab disposition */
|
||||
#define TELOPT_NAOLFD 16 /* negotiate about output LF disposition */
|
||||
#define TELOPT_XASCII 17 /* extended ascic character set */
|
||||
#define TELOPT_LOGOUT 18 /* force logout */
|
||||
#define TELOPT_BM 19 /* byte macro */
|
||||
#define TELOPT_DET 20 /* data entry terminal */
|
||||
#define TELOPT_SUPDUP 21 /* supdup protocol */
|
||||
#define TELOPT_SUPDUPOUTPUT 22 /* supdup output */
|
||||
#define TELOPT_SNDLOC 23 /* send location */
|
||||
#define TELOPT_TTYPE 24 /* terminal type */
|
||||
#define TELOPT_EOR 25 /* end or record */
|
||||
#define TELOPT_TUID 26 /* TACACS user identification */
|
||||
#define TELOPT_OUTMRK 27 /* output marking */
|
||||
#define TELOPT_TTYLOC 28 /* terminal location number */
|
||||
#define TELOPT_3270REGIME 29 /* 3270 regime */
|
||||
#define TELOPT_X3PAD 30 /* X.3 PAD */
|
||||
#define TELOPT_NAWS 31 /* window size */
|
||||
#define TELOPT_TSPEED 32 /* terminal speed */
|
||||
#define TELOPT_LFLOW 33 /* remote flow control */
|
||||
#define TELOPT_LINEMODE 34 /* Linemode option */
|
||||
#define TELOPT_XDISPLOC 35 /* X Display Location */
|
||||
#define TELOPT_OLD_ENVIRON 36 /* Old - Environment variables */
|
||||
#define TELOPT_AUTHENTICATION 37/* Authenticate */
|
||||
#define TELOPT_ENCRYPT 38 /* Encryption option */
|
||||
#define TELOPT_NEW_ENVIRON 39 /* New - Environment variables */
|
||||
#define TELOPT_EXOPL 255 /* extended-options-list */
|
||||
|
||||
|
||||
#define NTELOPTS (1+TELOPT_NEW_ENVIRON)
|
||||
#ifdef TELOPTS
|
||||
char *telopts[NTELOPTS+1] = {
|
||||
"BINARY", "ECHO", "RCP", "SUPPRESS GO AHEAD", "NAME",
|
||||
"STATUS", "TIMING MARK", "RCTE", "NAOL", "NAOP",
|
||||
"NAOCRD", "NAOHTS", "NAOHTD", "NAOFFD", "NAOVTS",
|
||||
"NAOVTD", "NAOLFD", "EXTEND ASCII", "LOGOUT", "BYTE MACRO",
|
||||
"DATA ENTRY TERMINAL", "SUPDUP", "SUPDUP OUTPUT",
|
||||
"SEND LOCATION", "TERMINAL TYPE", "END OF RECORD",
|
||||
"TACACS UID", "OUTPUT MARKING", "TTYLOC",
|
||||
"3270 REGIME", "X.3 PAD", "NAWS", "TSPEED", "LFLOW",
|
||||
"LINEMODE", "XDISPLOC", "OLD-ENVIRON", "AUTHENTICATION",
|
||||
"ENCRYPT", "NEW-ENVIRON",
|
||||
0
|
||||
};
|
||||
#define TELOPT_FIRST TELOPT_BINARY
|
||||
#define TELOPT_LAST TELOPT_NEW_ENVIRON
|
||||
#define TELOPT_OK(x) ((unsigned int)(x) <= TELOPT_LAST)
|
||||
#define TELOPT(x) telopts[(x)-TELOPT_FIRST]
|
||||
#endif
|
||||
|
||||
/* sub-option qualifiers */
|
||||
#define TELQUAL_IS 0 /* option is... */
|
||||
#define TELQUAL_SEND 1 /* send option */
|
||||
#define TELQUAL_INFO 2 /* ENVIRON: informational version of IS */
|
||||
#define TELQUAL_REPLY 2 /* AUTHENTICATION: client version of IS */
|
||||
#define TELQUAL_NAME 3 /* AUTHENTICATION: client version of IS */
|
||||
|
||||
#define LFLOW_OFF 0 /* Disable remote flow control */
|
||||
#define LFLOW_ON 1 /* Enable remote flow control */
|
||||
#define LFLOW_RESTART_ANY 2 /* Restart output on any char */
|
||||
#define LFLOW_RESTART_XON 3 /* Restart output only on XON */
|
||||
|
||||
/*
|
||||
* LINEMODE suboptions
|
||||
*/
|
||||
|
||||
#define LM_MODE 1
|
||||
#define LM_FORWARDMASK 2
|
||||
#define LM_SLC 3
|
||||
|
||||
#define MODE_EDIT 0x01
|
||||
#define MODE_TRAPSIG 0x02
|
||||
#define MODE_ACK 0x04
|
||||
#define MODE_SOFT_TAB 0x08
|
||||
#define MODE_LIT_ECHO 0x10
|
||||
|
||||
#define MODE_MASK 0x1f
|
||||
|
||||
/* Not part of protocol, but needed to simplify things... */
|
||||
#define MODE_FLOW 0x0100
|
||||
#define MODE_ECHO 0x0200
|
||||
#define MODE_INBIN 0x0400
|
||||
#define MODE_OUTBIN 0x0800
|
||||
#define MODE_FORCE 0x1000
|
||||
|
||||
#define SLC_SYNCH 1
|
||||
#define SLC_BRK 2
|
||||
#define SLC_IP 3
|
||||
#define SLC_AO 4
|
||||
#define SLC_AYT 5
|
||||
#define SLC_EOR 6
|
||||
#define SLC_ABORT 7
|
||||
#define SLC_EOF 8
|
||||
#define SLC_SUSP 9
|
||||
#define SLC_EC 10
|
||||
#define SLC_EL 11
|
||||
#define SLC_EW 12
|
||||
#define SLC_RP 13
|
||||
#define SLC_LNEXT 14
|
||||
#define SLC_XON 15
|
||||
#define SLC_XOFF 16
|
||||
#define SLC_FORW1 17
|
||||
#define SLC_FORW2 18
|
||||
#define SLC_MCL 19
|
||||
#define SLC_MCR 20
|
||||
#define SLC_MCWL 21
|
||||
#define SLC_MCWR 22
|
||||
#define SLC_MCBOL 23
|
||||
#define SLC_MCEOL 24
|
||||
#define SLC_INSRT 25
|
||||
#define SLC_OVER 26
|
||||
#define SLC_ECR 27
|
||||
#define SLC_EWR 28
|
||||
#define SLC_EBOL 29
|
||||
#define SLC_EEOL 30
|
||||
|
||||
#define NSLC 30
|
||||
|
||||
/*
|
||||
* For backwards compatability, we define SLC_NAMES to be the
|
||||
* list of names if SLC_NAMES is not defined.
|
||||
*/
|
||||
#define SLC_NAMELIST "0", "SYNCH", "BRK", "IP", "AO", "AYT", "EOR", \
|
||||
"ABORT", "EOF", "SUSP", "EC", "EL", "EW", "RP", \
|
||||
"LNEXT", "XON", "XOFF", "FORW1", "FORW2", \
|
||||
"MCL", "MCR", "MCWL", "MCWR", "MCBOL", \
|
||||
"MCEOL", "INSRT", "OVER", "ECR", "EWR", \
|
||||
"EBOL", "EEOL", \
|
||||
0
|
||||
|
||||
#ifdef SLC_NAMES
|
||||
char *slc_names[] = {
|
||||
SLC_NAMELIST
|
||||
};
|
||||
#else
|
||||
extern char *slc_names[];
|
||||
#define SLC_NAMES SLC_NAMELIST
|
||||
#endif
|
||||
|
||||
#define SLC_NAME_OK(x) ((unsigned int)(x) <= NSLC)
|
||||
#define SLC_NAME(x) slc_names[x]
|
||||
|
||||
#define SLC_NOSUPPORT 0
|
||||
#define SLC_CANTCHANGE 1
|
||||
#define SLC_VARIABLE 2
|
||||
#define SLC_DEFAULT 3
|
||||
#define SLC_LEVELBITS 0x03
|
||||
|
||||
#define SLC_FUNC 0
|
||||
#define SLC_FLAGS 1
|
||||
#define SLC_VALUE 2
|
||||
|
||||
#define SLC_ACK 0x80
|
||||
#define SLC_FLUSHIN 0x40
|
||||
#define SLC_FLUSHOUT 0x20
|
||||
|
||||
#define OLD_ENV_VAR 1
|
||||
#define OLD_ENV_VALUE 0
|
||||
#define NEW_ENV_VAR 0
|
||||
#define NEW_ENV_VALUE 1
|
||||
#define ENV_ESC 2
|
||||
#define ENV_USERVAR 3
|
||||
|
||||
/*
|
||||
* AUTHENTICATION suboptions
|
||||
*/
|
||||
|
||||
/*
|
||||
* Who is authenticating who ...
|
||||
*/
|
||||
#define AUTH_WHO_CLIENT 0 /* Client authenticating server */
|
||||
#define AUTH_WHO_SERVER 1 /* Server authenticating client */
|
||||
#define AUTH_WHO_MASK 1
|
||||
|
||||
/*
|
||||
* amount of authentication done
|
||||
*/
|
||||
#define AUTH_HOW_ONE_WAY 0
|
||||
#define AUTH_HOW_MUTUAL 2
|
||||
#define AUTH_HOW_MASK 2
|
||||
|
||||
#define AUTHTYPE_NULL 0
|
||||
#define AUTHTYPE_KERBEROS_V4 1
|
||||
#define AUTHTYPE_KERBEROS_V5 2
|
||||
#define AUTHTYPE_SPX 3
|
||||
#define AUTHTYPE_MINK 4
|
||||
#define AUTHTYPE_CNT 5
|
||||
|
||||
#define AUTHTYPE_TEST 99
|
||||
|
||||
#ifdef AUTH_NAMES
|
||||
char *authtype_names[] = {
|
||||
"NULL", "KERBEROS_V4", "KERBEROS_V5", "SPX", "MINK",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *authtype_names[];
|
||||
#endif
|
||||
|
||||
#define AUTHTYPE_NAME_OK(x) ((unsigned int)(x) < AUTHTYPE_CNT)
|
||||
#define AUTHTYPE_NAME(x) authtype_names[x]
|
||||
|
||||
/*
|
||||
* ENCRYPTion suboptions
|
||||
*/
|
||||
#define ENCRYPT_IS 0 /* I pick encryption type ... */
|
||||
#define ENCRYPT_SUPPORT 1 /* I support encryption types ... */
|
||||
#define ENCRYPT_REPLY 2 /* Initial setup response */
|
||||
#define ENCRYPT_START 3 /* Am starting to send encrypted */
|
||||
#define ENCRYPT_END 4 /* Am ending encrypted */
|
||||
#define ENCRYPT_REQSTART 5 /* Request you start encrypting */
|
||||
#define ENCRYPT_REQEND 6 /* Request you end encrypting */
|
||||
#define ENCRYPT_ENC_KEYID 7
|
||||
#define ENCRYPT_DEC_KEYID 8
|
||||
#define ENCRYPT_CNT 9
|
||||
|
||||
#define ENCTYPE_ANY 0
|
||||
#define ENCTYPE_DES_CFB64 1
|
||||
#define ENCTYPE_DES_OFB64 2
|
||||
#define ENCTYPE_CNT 3
|
||||
|
||||
#ifdef ENCRYPT_NAMES
|
||||
char *encrypt_names[] = {
|
||||
"IS", "SUPPORT", "REPLY", "START", "END",
|
||||
"REQUEST-START", "REQUEST-END", "ENC-KEYID", "DEC-KEYID",
|
||||
0
|
||||
};
|
||||
char *enctype_names[] = {
|
||||
"ANY", "DES_CFB64", "DES_OFB64",
|
||||
0
|
||||
};
|
||||
#else
|
||||
extern char *encrypt_names[];
|
||||
extern char *enctype_names[];
|
||||
#endif
|
||||
|
||||
|
||||
#define ENCRYPT_NAME_OK(x) ((unsigned int)(x) < ENCRYPT_CNT)
|
||||
#define ENCRYPT_NAME(x) encrypt_names[x]
|
||||
|
||||
#define ENCTYPE_NAME_OK(x) ((unsigned int)(x) < ENCTYPE_CNT)
|
||||
#define ENCTYPE_NAME(x) enctype_names[x]
|
||||
|
||||
#endif /* !_TELNET_H_ */
|
||||
0
c/src/exec/libnetworking/bpfilter.h
Normal file
0
c/src/exec/libnetworking/bpfilter.h
Normal file
206
c/src/exec/libnetworking/kern/kern_subr.c
Normal file
206
c/src/exec/libnetworking/kern/kern_subr.c
Normal file
@@ -0,0 +1,206 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
* (c) UNIX System Laboratories, Inc.
|
||||
* All or some portions of this file are derived from material licensed
|
||||
* to the University of California by American Telephone and Telegraph
|
||||
* Co. or Unix System Laboratories, Inc. and are reproduced herein with
|
||||
* the permission of UNIX System Laboratories, Inc.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)kern_subr.c 8.3 (Berkeley) 1/21/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/queue.h>
|
||||
|
||||
int
|
||||
uiomove(cp, n, uio)
|
||||
register caddr_t cp;
|
||||
register int n;
|
||||
register struct uio *uio;
|
||||
{
|
||||
register struct iovec *iov;
|
||||
u_int cnt;
|
||||
int error;
|
||||
|
||||
#ifdef DIAGNOSTIC
|
||||
if (uio->uio_rw != UIO_READ && uio->uio_rw != UIO_WRITE)
|
||||
panic("uiomove: mode");
|
||||
#endif
|
||||
while (n > 0 && uio->uio_resid) {
|
||||
iov = uio->uio_iov;
|
||||
cnt = iov->iov_len;
|
||||
if (cnt == 0) {
|
||||
uio->uio_iov++;
|
||||
uio->uio_iovcnt--;
|
||||
continue;
|
||||
}
|
||||
if (cnt > n)
|
||||
cnt = n;
|
||||
|
||||
switch (uio->uio_segflg) {
|
||||
|
||||
case UIO_USERSPACE:
|
||||
case UIO_USERISPACE:
|
||||
if (uio->uio_rw == UIO_READ)
|
||||
error = copyout(cp, iov->iov_base, cnt);
|
||||
else
|
||||
error = copyin(iov->iov_base, cp, cnt);
|
||||
if (error)
|
||||
return (error);
|
||||
break;
|
||||
|
||||
case UIO_SYSSPACE:
|
||||
if (uio->uio_rw == UIO_READ)
|
||||
bcopy((caddr_t)cp, iov->iov_base, cnt);
|
||||
else
|
||||
bcopy(iov->iov_base, (caddr_t)cp, cnt);
|
||||
break;
|
||||
case UIO_NOCOPY:
|
||||
break;
|
||||
}
|
||||
iov->iov_base += cnt;
|
||||
iov->iov_len -= cnt;
|
||||
uio->uio_resid -= cnt;
|
||||
uio->uio_offset += cnt;
|
||||
cp += cnt;
|
||||
n -= cnt;
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
#ifdef vax /* unused except by ct.c, other oddities XXX */
|
||||
/*
|
||||
* Get next character written in by user from uio.
|
||||
*/
|
||||
int
|
||||
uwritec(uio)
|
||||
struct uio *uio;
|
||||
{
|
||||
register struct iovec *iov;
|
||||
register int c;
|
||||
|
||||
if (uio->uio_resid <= 0)
|
||||
return (-1);
|
||||
again:
|
||||
if (uio->uio_iovcnt <= 0)
|
||||
panic("uwritec");
|
||||
iov = uio->uio_iov;
|
||||
if (iov->iov_len == 0) {
|
||||
uio->uio_iov++;
|
||||
if (--uio->uio_iovcnt == 0)
|
||||
return (-1);
|
||||
goto again;
|
||||
}
|
||||
switch (uio->uio_segflg) {
|
||||
|
||||
case UIO_USERSPACE:
|
||||
c = fubyte(iov->iov_base);
|
||||
break;
|
||||
|
||||
case UIO_SYSSPACE:
|
||||
c = *(u_char *) iov->iov_base;
|
||||
break;
|
||||
|
||||
case UIO_USERISPACE:
|
||||
c = fuibyte(iov->iov_base);
|
||||
break;
|
||||
}
|
||||
if (c < 0)
|
||||
return (-1);
|
||||
iov->iov_base++;
|
||||
iov->iov_len--;
|
||||
uio->uio_resid--;
|
||||
uio->uio_offset++;
|
||||
return (c);
|
||||
}
|
||||
#endif /* vax */
|
||||
|
||||
/*
|
||||
* General routine to allocate a hash table.
|
||||
*/
|
||||
void *
|
||||
hashinit(elements, type, hashmask)
|
||||
int elements, type;
|
||||
u_long *hashmask;
|
||||
{
|
||||
long hashsize;
|
||||
LIST_HEAD(generic, generic) *hashtbl;
|
||||
int i;
|
||||
|
||||
if (elements <= 0)
|
||||
panic("hashinit: bad elements");
|
||||
for (hashsize = 1; hashsize <= elements; hashsize <<= 1)
|
||||
continue;
|
||||
hashsize >>= 1;
|
||||
hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
|
||||
for (i = 0; i < hashsize; i++)
|
||||
LIST_INIT(&hashtbl[i]);
|
||||
*hashmask = hashsize - 1;
|
||||
return (hashtbl);
|
||||
}
|
||||
|
||||
#define NPRIMES 27
|
||||
static int primes[] = { 1, 13, 31, 61, 127, 251, 509, 761, 1021, 1531, 2039,
|
||||
2557, 3067, 3583, 4093, 4603, 5119, 5623, 6143, 6653,
|
||||
7159, 7673, 8191, 12281, 16381, 24571, 32749 };
|
||||
|
||||
/*
|
||||
* General routine to allocate a prime number sized hash table.
|
||||
*/
|
||||
void *
|
||||
phashinit(elements, type, nentries)
|
||||
int elements, type;
|
||||
u_long *nentries;
|
||||
{
|
||||
long hashsize;
|
||||
LIST_HEAD(generic, generic) *hashtbl;
|
||||
int i;
|
||||
|
||||
if (elements <= 0)
|
||||
panic("phashinit: bad elements");
|
||||
for (i = 1, hashsize = primes[1]; hashsize <= elements;) {
|
||||
i++;
|
||||
if (i == NPRIMES)
|
||||
break;
|
||||
hashsize = primes[i];
|
||||
}
|
||||
hashsize = primes[i - 1];
|
||||
hashtbl = malloc((u_long)hashsize * sizeof(*hashtbl), type, M_WAITOK);
|
||||
for (i = 0; i < hashsize; i++)
|
||||
LIST_INIT(&hashtbl[i]);
|
||||
*nentries = hashsize;
|
||||
return (hashtbl);
|
||||
}
|
||||
226
c/src/exec/libnetworking/kern/uipc_domain.c
Normal file
226
c/src/exec/libnetworking/kern/uipc_domain.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_domain.c 8.2 (Berkeley) 10/18/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/systm.h>
|
||||
|
||||
/*
|
||||
* System initialization
|
||||
*
|
||||
* Note: domain initialization wants to take place on a per domain basis
|
||||
* as a result of traversing a linker set. Most likely, each domain
|
||||
* want to call a registration function rather than being handled here
|
||||
* in domaininit(). Probably this will look like:
|
||||
*
|
||||
* SYSINIT(unique, SI_SUB_PROTO_DOMAI, SI_ORDER_ANY, domain_add, xxx)
|
||||
*
|
||||
* Where 'xxx' is replaced by the address of a parameter struct to be
|
||||
* passed to the doamin_add() function.
|
||||
*/
|
||||
|
||||
static int x_save_spl; /* used by kludge*/
|
||||
static void kludge_splimp __P((void *));
|
||||
static void kludge_splx __P((void *));
|
||||
void domaininit __P((void *));
|
||||
SYSINIT(splimp, SI_SUB_PROTO_BEGIN, SI_ORDER_FIRST, kludge_splimp, &x_save_spl)
|
||||
SYSINIT(domain, SI_SUB_PROTO_DOMAIN, SI_ORDER_FIRST, domaininit, NULL)
|
||||
SYSINIT(splx, SI_SUB_PROTO_END, SI_ORDER_FIRST, kludge_splx, &x_save_spl)
|
||||
|
||||
static void pffasttimo __P((void *));
|
||||
static void pfslowtimo __P((void *));
|
||||
|
||||
struct domain *domains;
|
||||
|
||||
#define ADDDOMAIN(x) { \
|
||||
__CONCAT(x,domain.dom_next) = domains; \
|
||||
domains = &__CONCAT(x,domain); \
|
||||
}
|
||||
|
||||
extern struct linker_set domain_set;
|
||||
|
||||
/* ARGSUSED*/
|
||||
void
|
||||
domaininit(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
register struct domain *dp, **dpp;
|
||||
register struct protosw *pr;
|
||||
|
||||
/* - not in our sources
|
||||
#ifdef ISDN
|
||||
ADDDOMAIN(isdn);
|
||||
#endif
|
||||
*/
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next) {
|
||||
if (dp->dom_init)
|
||||
(*dp->dom_init)();
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++){
|
||||
#ifdef PRU_OLDSTYLE
|
||||
/* See comments in uipc_socket2.c. */
|
||||
if (pr->pr_usrreqs == 0 && pr->pr_ousrreq)
|
||||
pr->pr_usrreqs = &pru_oldstyle;
|
||||
#endif
|
||||
if (pr->pr_init)
|
||||
(*pr->pr_init)();
|
||||
}
|
||||
}
|
||||
|
||||
if (max_linkhdr < 16) /* XXX */
|
||||
max_linkhdr = 16;
|
||||
max_hdr = max_linkhdr + max_protohdr;
|
||||
max_datalen = MHLEN - max_hdr;
|
||||
timeout(pffasttimo, (void *)0, 1);
|
||||
timeout(pfslowtimo, (void *)0, 1);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* The following two operations are kludge code. Most likely, they should
|
||||
* be done as a "domainpreinit()" for the first function and then rolled
|
||||
* in as the last act of "domaininit()" for the second.
|
||||
*
|
||||
* In point of fact, it is questionable why other initialization prior
|
||||
* to this does not also take place at splimp by default.
|
||||
*/
|
||||
static void
|
||||
kludge_splimp(udata)
|
||||
void *udata;
|
||||
{
|
||||
int *savesplp = udata;
|
||||
|
||||
*savesplp = splimp();
|
||||
}
|
||||
|
||||
static void
|
||||
kludge_splx(udata)
|
||||
void *udata;
|
||||
{
|
||||
int *savesplp = udata;
|
||||
|
||||
splx( *savesplp);
|
||||
}
|
||||
|
||||
|
||||
|
||||
struct protosw *
|
||||
pffindtype(int family, int type)
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
if (dp->dom_family == family)
|
||||
goto found;
|
||||
return (0);
|
||||
found:
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
||||
if (pr->pr_type && pr->pr_type == type)
|
||||
return (pr);
|
||||
return (0);
|
||||
}
|
||||
|
||||
struct protosw *
|
||||
pffindproto(int family, int protocol, int type)
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
struct protosw *maybe = 0;
|
||||
|
||||
if (family == 0)
|
||||
return (0);
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
if (dp->dom_family == family)
|
||||
goto found;
|
||||
return (0);
|
||||
found:
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++) {
|
||||
if ((pr->pr_protocol == protocol) && (pr->pr_type == type))
|
||||
return (pr);
|
||||
|
||||
if (type == SOCK_RAW && pr->pr_type == SOCK_RAW &&
|
||||
pr->pr_protocol == 0 && maybe == (struct protosw *)0)
|
||||
maybe = pr;
|
||||
}
|
||||
return (maybe);
|
||||
}
|
||||
|
||||
void
|
||||
pfctlinput(cmd, sa)
|
||||
int cmd;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
||||
if (pr->pr_ctlinput)
|
||||
(*pr->pr_ctlinput)(cmd, sa, (void *)0);
|
||||
}
|
||||
|
||||
static void
|
||||
pfslowtimo(arg)
|
||||
void *arg;
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
||||
if (pr->pr_slowtimo)
|
||||
(*pr->pr_slowtimo)();
|
||||
timeout(pfslowtimo, (void *)0, hz/2);
|
||||
}
|
||||
|
||||
static void
|
||||
pffasttimo(arg)
|
||||
void *arg;
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
||||
if (pr->pr_fasttimo)
|
||||
(*pr->pr_fasttimo)();
|
||||
timeout(pffasttimo, (void *)0, hz/5);
|
||||
}
|
||||
851
c/src/exec/libnetworking/kern/uipc_mbuf.c
Normal file
851
c/src/exec/libnetworking/kern/uipc_mbuf.c
Normal file
@@ -0,0 +1,851 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_mbuf.c 8.2 (Berkeley) 1/4/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/malloc.h>
|
||||
#define MBTYPES
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/domain.h>
|
||||
#include <sys/protosw.h>
|
||||
|
||||
#include <vm/vm.h>
|
||||
#include <vm/vm_param.h>
|
||||
#include <vm/vm_kern.h>
|
||||
#include <vm/vm_extern.h>
|
||||
|
||||
static void mbinit __P((void *));
|
||||
SYSINIT(mbuf, SI_SUB_MBUF, SI_ORDER_FIRST, mbinit, NULL)
|
||||
|
||||
struct mbuf *mbutl;
|
||||
char *mclrefcnt;
|
||||
struct mbstat mbstat;
|
||||
struct mbuf *mmbfree;
|
||||
union mcluster *mclfree;
|
||||
int max_linkhdr;
|
||||
int max_protohdr;
|
||||
int max_hdr;
|
||||
int max_datalen;
|
||||
|
||||
static void m_reclaim __P((void));
|
||||
|
||||
/* "number of clusters of pages" */
|
||||
#define NCL_INIT 1
|
||||
|
||||
#define NMB_INIT 16
|
||||
|
||||
/* ARGSUSED*/
|
||||
static void
|
||||
mbinit(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
int s;
|
||||
|
||||
mmbfree = NULL; mclfree = NULL;
|
||||
s = splimp();
|
||||
if (m_mballoc(NMB_INIT, M_DONTWAIT) == 0)
|
||||
goto bad;
|
||||
if (m_clalloc(NCL_INIT, M_DONTWAIT) == 0)
|
||||
goto bad;
|
||||
splx(s);
|
||||
return;
|
||||
bad:
|
||||
panic("mbinit");
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate at least nmb mbufs and place on mbuf free list.
|
||||
* Must be called at splimp.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
m_mballoc(nmb, nowait)
|
||||
register int nmb;
|
||||
int nowait;
|
||||
{
|
||||
register caddr_t p;
|
||||
register int i;
|
||||
int nbytes;
|
||||
|
||||
/* Once we run out of map space, it will be impossible to get
|
||||
* any more (nothing is ever freed back to the map) (XXX which
|
||||
* is dumb). (however you are not dead as m_reclaim might
|
||||
* still be able to free a substantial amount of space).
|
||||
*/
|
||||
if (mb_map_full)
|
||||
return (0);
|
||||
|
||||
nbytes = round_page(nmb * MSIZE);
|
||||
p = (caddr_t)kmem_malloc(mb_map, nbytes, nowait ? M_NOWAIT : M_WAITOK);
|
||||
/*
|
||||
* Either the map is now full, or this is nowait and there
|
||||
* are no pages left.
|
||||
*/
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
|
||||
nmb = nbytes / MSIZE;
|
||||
for (i = 0; i < nmb; i++) {
|
||||
((struct mbuf *)p)->m_next = mmbfree;
|
||||
mmbfree = (struct mbuf *)p;
|
||||
p += MSIZE;
|
||||
}
|
||||
mbstat.m_mbufs += nmb;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate some number of mbuf clusters
|
||||
* and place on cluster free list.
|
||||
* Must be called at splimp.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
int
|
||||
m_clalloc(ncl, nowait)
|
||||
register int ncl;
|
||||
int nowait;
|
||||
{
|
||||
register caddr_t p;
|
||||
register int i;
|
||||
|
||||
/*
|
||||
* Once we run out of map space, it will be impossible
|
||||
* to get any more (nothing is ever freed back to the
|
||||
* map).
|
||||
*/
|
||||
if (mb_map_full)
|
||||
return (0);
|
||||
|
||||
p = (caddr_t)kmem_malloc(mb_map, ncl*MCLBYTES,
|
||||
nowait ? M_NOWAIT : M_WAITOK);
|
||||
/*
|
||||
* Either the map is now full, or this is nowait and there
|
||||
* are no pages left.
|
||||
*/
|
||||
if (p == NULL)
|
||||
return (0);
|
||||
|
||||
for (i = 0; i < ncl; i++) {
|
||||
((union mcluster *)p)->mcl_next = mclfree;
|
||||
mclfree = (union mcluster *)p;
|
||||
p += MCLBYTES;
|
||||
mbstat.m_clfree++;
|
||||
}
|
||||
mbstat.m_clusters += ncl;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* When MGET failes, ask protocols to free space when short of memory,
|
||||
* then re-attempt to allocate an mbuf.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_retry(i, t)
|
||||
int i, t;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
m_reclaim();
|
||||
#define m_retry(i, t) (struct mbuf *)0
|
||||
MGET(m, i, t);
|
||||
#undef m_retry
|
||||
if (m != NULL)
|
||||
mbstat.m_wait++;
|
||||
else
|
||||
mbstat.m_drops++;
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* As above; retry an MGETHDR.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_retryhdr(i, t)
|
||||
int i, t;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
m_reclaim();
|
||||
#define m_retryhdr(i, t) (struct mbuf *)0
|
||||
MGETHDR(m, i, t);
|
||||
#undef m_retryhdr
|
||||
if (m != NULL)
|
||||
mbstat.m_wait++;
|
||||
else
|
||||
mbstat.m_drops++;
|
||||
return (m);
|
||||
}
|
||||
|
||||
static void
|
||||
m_reclaim()
|
||||
{
|
||||
register struct domain *dp;
|
||||
register struct protosw *pr;
|
||||
int s = splimp();
|
||||
|
||||
for (dp = domains; dp; dp = dp->dom_next)
|
||||
for (pr = dp->dom_protosw; pr < dp->dom_protoswNPROTOSW; pr++)
|
||||
if (pr->pr_drain)
|
||||
(*pr->pr_drain)();
|
||||
splx(s);
|
||||
mbstat.m_drain++;
|
||||
}
|
||||
|
||||
/*
|
||||
* Space allocation routines.
|
||||
* These are also available as macros
|
||||
* for critical paths.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_get(nowait, type)
|
||||
int nowait, type;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
MGET(m, nowait, type);
|
||||
return (m);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
m_gethdr(nowait, type)
|
||||
int nowait, type;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
MGETHDR(m, nowait, type);
|
||||
return (m);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
m_getclr(nowait, type)
|
||||
int nowait, type;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
MGET(m, nowait, type);
|
||||
if (m == 0)
|
||||
return (0);
|
||||
bzero(mtod(m, caddr_t), MLEN);
|
||||
return (m);
|
||||
}
|
||||
|
||||
struct mbuf *
|
||||
m_free(m)
|
||||
struct mbuf *m;
|
||||
{
|
||||
register struct mbuf *n;
|
||||
|
||||
MFREE(m, n);
|
||||
return (n);
|
||||
}
|
||||
|
||||
void
|
||||
m_freem(m)
|
||||
register struct mbuf *m;
|
||||
{
|
||||
register struct mbuf *n;
|
||||
|
||||
if (m == NULL)
|
||||
return;
|
||||
do {
|
||||
MFREE(m, n);
|
||||
m = n;
|
||||
} while (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mbuffer utility routines.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Lesser-used path for M_PREPEND:
|
||||
* allocate new mbuf to prepend to chain,
|
||||
* copy junk along.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_prepend(m, len, how)
|
||||
register struct mbuf *m;
|
||||
int len, how;
|
||||
{
|
||||
struct mbuf *mn;
|
||||
|
||||
MGET(mn, how, m->m_type);
|
||||
if (mn == (struct mbuf *)NULL) {
|
||||
m_freem(m);
|
||||
return ((struct mbuf *)NULL);
|
||||
}
|
||||
if (m->m_flags & M_PKTHDR) {
|
||||
M_COPY_PKTHDR(mn, m);
|
||||
m->m_flags &= ~M_PKTHDR;
|
||||
}
|
||||
mn->m_next = m;
|
||||
m = mn;
|
||||
if (len < MHLEN)
|
||||
MH_ALIGN(m, len);
|
||||
m->m_len = len;
|
||||
return (m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Make a copy of an mbuf chain starting "off0" bytes from the beginning,
|
||||
* continuing for "len" bytes. If len is M_COPYALL, copy to end of mbuf.
|
||||
* The wait parameter is a choice of M_WAIT/M_DONTWAIT from caller.
|
||||
*/
|
||||
static int MCFail;
|
||||
|
||||
struct mbuf *
|
||||
m_copym(m, off0, len, wait)
|
||||
register struct mbuf *m;
|
||||
int off0, wait;
|
||||
register int len;
|
||||
{
|
||||
register struct mbuf *n, **np;
|
||||
register int off = off0;
|
||||
struct mbuf *top;
|
||||
int copyhdr = 0;
|
||||
|
||||
if (off < 0 || len < 0)
|
||||
panic("m_copym");
|
||||
if (off == 0 && m->m_flags & M_PKTHDR)
|
||||
copyhdr = 1;
|
||||
while (off > 0) {
|
||||
if (m == 0)
|
||||
panic("m_copym");
|
||||
if (off < m->m_len)
|
||||
break;
|
||||
off -= m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
np = ⊤
|
||||
top = 0;
|
||||
while (len > 0) {
|
||||
if (m == 0) {
|
||||
if (len != M_COPYALL)
|
||||
panic("m_copym");
|
||||
break;
|
||||
}
|
||||
MGET(n, wait, m->m_type);
|
||||
*np = n;
|
||||
if (n == 0)
|
||||
goto nospace;
|
||||
if (copyhdr) {
|
||||
M_COPY_PKTHDR(n, m);
|
||||
if (len == M_COPYALL)
|
||||
n->m_pkthdr.len -= off0;
|
||||
else
|
||||
n->m_pkthdr.len = len;
|
||||
copyhdr = 0;
|
||||
}
|
||||
n->m_len = min(len, m->m_len - off);
|
||||
if (m->m_flags & M_EXT) {
|
||||
n->m_data = m->m_data + off;
|
||||
if(!m->m_ext.ext_ref)
|
||||
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
|
||||
else
|
||||
(*(m->m_ext.ext_ref))(m->m_ext.ext_buf,
|
||||
m->m_ext.ext_size);
|
||||
n->m_ext = m->m_ext;
|
||||
n->m_flags |= M_EXT;
|
||||
} else
|
||||
bcopy(mtod(m, caddr_t)+off, mtod(n, caddr_t),
|
||||
(unsigned)n->m_len);
|
||||
if (len != M_COPYALL)
|
||||
len -= n->m_len;
|
||||
off = 0;
|
||||
m = m->m_next;
|
||||
np = &n->m_next;
|
||||
}
|
||||
if (top == 0)
|
||||
MCFail++;
|
||||
return (top);
|
||||
nospace:
|
||||
m_freem(top);
|
||||
MCFail++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy an entire packet, including header (which must be present).
|
||||
* An optimization of the common case `m_copym(m, 0, M_COPYALL, how)'.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_copypacket(m, how)
|
||||
struct mbuf *m;
|
||||
int how;
|
||||
{
|
||||
struct mbuf *top, *n, *o;
|
||||
|
||||
MGET(n, how, m->m_type);
|
||||
top = n;
|
||||
if (!n)
|
||||
goto nospace;
|
||||
|
||||
M_COPY_PKTHDR(n, m);
|
||||
n->m_len = m->m_len;
|
||||
if (m->m_flags & M_EXT) {
|
||||
n->m_data = m->m_data;
|
||||
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
|
||||
n->m_ext = m->m_ext;
|
||||
n->m_flags |= M_EXT;
|
||||
} else {
|
||||
bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
|
||||
}
|
||||
|
||||
m = m->m_next;
|
||||
while (m) {
|
||||
MGET(o, how, m->m_type);
|
||||
if (!o)
|
||||
goto nospace;
|
||||
|
||||
n->m_next = o;
|
||||
n = n->m_next;
|
||||
|
||||
n->m_len = m->m_len;
|
||||
if (m->m_flags & M_EXT) {
|
||||
n->m_data = m->m_data;
|
||||
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
|
||||
n->m_ext = m->m_ext;
|
||||
n->m_flags |= M_EXT;
|
||||
} else {
|
||||
bcopy(mtod(m, char *), mtod(n, char *), n->m_len);
|
||||
}
|
||||
|
||||
m = m->m_next;
|
||||
}
|
||||
return top;
|
||||
nospace:
|
||||
m_freem(top);
|
||||
MCFail++;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from an mbuf chain starting "off" bytes from the beginning,
|
||||
* continuing for "len" bytes, into the indicated buffer.
|
||||
*/
|
||||
void
|
||||
m_copydata(m, off, len, cp)
|
||||
register struct mbuf *m;
|
||||
register int off;
|
||||
register int len;
|
||||
caddr_t cp;
|
||||
{
|
||||
register unsigned count;
|
||||
|
||||
if (off < 0 || len < 0)
|
||||
panic("m_copydata");
|
||||
while (off > 0) {
|
||||
if (m == 0)
|
||||
panic("m_copydata");
|
||||
if (off < m->m_len)
|
||||
break;
|
||||
off -= m->m_len;
|
||||
m = m->m_next;
|
||||
}
|
||||
while (len > 0) {
|
||||
if (m == 0)
|
||||
panic("m_copydata");
|
||||
count = min(m->m_len - off, len);
|
||||
bcopy(mtod(m, caddr_t) + off, cp, count);
|
||||
len -= count;
|
||||
cp += count;
|
||||
off = 0;
|
||||
m = m->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Concatenate mbuf chain n to m.
|
||||
* Both chains must be of the same type (e.g. MT_DATA).
|
||||
* Any m_pkthdr is not updated.
|
||||
*/
|
||||
void
|
||||
m_cat(m, n)
|
||||
register struct mbuf *m, *n;
|
||||
{
|
||||
while (m->m_next)
|
||||
m = m->m_next;
|
||||
while (n) {
|
||||
if (m->m_flags & M_EXT ||
|
||||
m->m_data + m->m_len + n->m_len >= &m->m_dat[MLEN]) {
|
||||
/* just join the two chains */
|
||||
m->m_next = n;
|
||||
return;
|
||||
}
|
||||
/* splat the data from one into the other */
|
||||
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
|
||||
(u_int)n->m_len);
|
||||
m->m_len += n->m_len;
|
||||
n = m_free(n);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
m_adj(mp, req_len)
|
||||
struct mbuf *mp;
|
||||
int req_len;
|
||||
{
|
||||
register int len = req_len;
|
||||
register struct mbuf *m;
|
||||
register int count;
|
||||
|
||||
if ((m = mp) == NULL)
|
||||
return;
|
||||
if (len >= 0) {
|
||||
/*
|
||||
* Trim from head.
|
||||
*/
|
||||
while (m != NULL && len > 0) {
|
||||
if (m->m_len <= len) {
|
||||
len -= m->m_len;
|
||||
m->m_len = 0;
|
||||
m = m->m_next;
|
||||
} else {
|
||||
m->m_len -= len;
|
||||
m->m_data += len;
|
||||
len = 0;
|
||||
}
|
||||
}
|
||||
m = mp;
|
||||
if (mp->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len -= (req_len - len);
|
||||
} else {
|
||||
/*
|
||||
* Trim from tail. Scan the mbuf chain,
|
||||
* calculating its length and finding the last mbuf.
|
||||
* If the adjustment only affects this mbuf, then just
|
||||
* adjust and return. Otherwise, rescan and truncate
|
||||
* after the remaining size.
|
||||
*/
|
||||
len = -len;
|
||||
count = 0;
|
||||
for (;;) {
|
||||
count += m->m_len;
|
||||
if (m->m_next == (struct mbuf *)0)
|
||||
break;
|
||||
m = m->m_next;
|
||||
}
|
||||
if (m->m_len >= len) {
|
||||
m->m_len -= len;
|
||||
if (mp->m_flags & M_PKTHDR)
|
||||
mp->m_pkthdr.len -= len;
|
||||
return;
|
||||
}
|
||||
count -= len;
|
||||
if (count < 0)
|
||||
count = 0;
|
||||
/*
|
||||
* Correct length for chain is "count".
|
||||
* Find the mbuf with last data, adjust its length,
|
||||
* and toss data from remaining mbufs on chain.
|
||||
*/
|
||||
m = mp;
|
||||
if (m->m_flags & M_PKTHDR)
|
||||
m->m_pkthdr.len = count;
|
||||
for (; m; m = m->m_next) {
|
||||
if (m->m_len >= count) {
|
||||
m->m_len = count;
|
||||
break;
|
||||
}
|
||||
count -= m->m_len;
|
||||
}
|
||||
while (m->m_next)
|
||||
(m = m->m_next) ->m_len = 0;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Rearange an mbuf chain so that len bytes are contiguous
|
||||
* and in the data area of an mbuf (so that mtod and dtom
|
||||
* will work for a structure of size len). Returns the resulting
|
||||
* mbuf chain on success, frees it and returns null on failure.
|
||||
* If there is room, it will add up to max_protohdr-len extra bytes to the
|
||||
* contiguous region in an attempt to avoid being called next time.
|
||||
*/
|
||||
static int MPFail;
|
||||
|
||||
struct mbuf *
|
||||
m_pullup(n, len)
|
||||
register struct mbuf *n;
|
||||
int len;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
register int count;
|
||||
int space;
|
||||
|
||||
/*
|
||||
* If first mbuf has no cluster, and has room for len bytes
|
||||
* without shifting current data, pullup into it,
|
||||
* otherwise allocate a new mbuf to prepend to the chain.
|
||||
*/
|
||||
if ((n->m_flags & M_EXT) == 0 &&
|
||||
n->m_data + len < &n->m_dat[MLEN] && n->m_next) {
|
||||
if (n->m_len >= len)
|
||||
return (n);
|
||||
m = n;
|
||||
n = n->m_next;
|
||||
len -= m->m_len;
|
||||
} else {
|
||||
if (len > MHLEN)
|
||||
goto bad;
|
||||
MGET(m, M_DONTWAIT, n->m_type);
|
||||
if (m == 0)
|
||||
goto bad;
|
||||
m->m_len = 0;
|
||||
if (n->m_flags & M_PKTHDR) {
|
||||
M_COPY_PKTHDR(m, n);
|
||||
n->m_flags &= ~M_PKTHDR;
|
||||
}
|
||||
}
|
||||
space = &m->m_dat[MLEN] - (m->m_data + m->m_len);
|
||||
do {
|
||||
count = min(min(max(len, max_protohdr), space), n->m_len);
|
||||
bcopy(mtod(n, caddr_t), mtod(m, caddr_t) + m->m_len,
|
||||
(unsigned)count);
|
||||
len -= count;
|
||||
m->m_len += count;
|
||||
n->m_len -= count;
|
||||
space -= count;
|
||||
if (n->m_len)
|
||||
n->m_data += count;
|
||||
else
|
||||
n = m_free(n);
|
||||
} while (len > 0 && n);
|
||||
if (len > 0) {
|
||||
(void) m_free(m);
|
||||
goto bad;
|
||||
}
|
||||
m->m_next = n;
|
||||
return (m);
|
||||
bad:
|
||||
m_freem(n);
|
||||
MPFail++;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Partition an mbuf chain in two pieces, returning the tail --
|
||||
* all but the first len0 bytes. In case of failure, it returns NULL and
|
||||
* attempts to restore the chain to its original state.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_split(m0, len0, wait)
|
||||
register struct mbuf *m0;
|
||||
int len0, wait;
|
||||
{
|
||||
register struct mbuf *m, *n;
|
||||
unsigned len = len0, remain;
|
||||
|
||||
for (m = m0; m && len > m->m_len; m = m->m_next)
|
||||
len -= m->m_len;
|
||||
if (m == 0)
|
||||
return (0);
|
||||
remain = m->m_len - len;
|
||||
if (m0->m_flags & M_PKTHDR) {
|
||||
MGETHDR(n, wait, m0->m_type);
|
||||
if (n == 0)
|
||||
return (0);
|
||||
n->m_pkthdr.rcvif = m0->m_pkthdr.rcvif;
|
||||
n->m_pkthdr.len = m0->m_pkthdr.len - len0;
|
||||
m0->m_pkthdr.len = len0;
|
||||
if (m->m_flags & M_EXT)
|
||||
goto extpacket;
|
||||
if (remain > MHLEN) {
|
||||
/* m can't be the lead packet */
|
||||
MH_ALIGN(n, 0);
|
||||
n->m_next = m_split(m, len, wait);
|
||||
if (n->m_next == 0) {
|
||||
(void) m_free(n);
|
||||
return (0);
|
||||
} else
|
||||
return (n);
|
||||
} else
|
||||
MH_ALIGN(n, remain);
|
||||
} else if (remain == 0) {
|
||||
n = m->m_next;
|
||||
m->m_next = 0;
|
||||
return (n);
|
||||
} else {
|
||||
MGET(n, wait, m->m_type);
|
||||
if (n == 0)
|
||||
return (0);
|
||||
M_ALIGN(n, remain);
|
||||
}
|
||||
extpacket:
|
||||
if (m->m_flags & M_EXT) {
|
||||
n->m_flags |= M_EXT;
|
||||
n->m_ext = m->m_ext;
|
||||
if(!m->m_ext.ext_ref)
|
||||
mclrefcnt[mtocl(m->m_ext.ext_buf)]++;
|
||||
else
|
||||
(*(m->m_ext.ext_ref))(m->m_ext.ext_buf,
|
||||
m->m_ext.ext_size);
|
||||
m->m_ext.ext_size = 0; /* For Accounting XXXXXX danger */
|
||||
n->m_data = m->m_data + len;
|
||||
} else {
|
||||
bcopy(mtod(m, caddr_t) + len, mtod(n, caddr_t), remain);
|
||||
}
|
||||
n->m_len = remain;
|
||||
m->m_len = len;
|
||||
n->m_next = m->m_next;
|
||||
m->m_next = 0;
|
||||
return (n);
|
||||
}
|
||||
/*
|
||||
* Routine to copy from device local memory into mbufs.
|
||||
*/
|
||||
struct mbuf *
|
||||
m_devget(buf, totlen, off0, ifp, copy)
|
||||
char *buf;
|
||||
int totlen, off0;
|
||||
struct ifnet *ifp;
|
||||
void (*copy) __P((char *from, caddr_t to, u_int len));
|
||||
{
|
||||
register struct mbuf *m;
|
||||
struct mbuf *top = 0, **mp = ⊤
|
||||
register int off = off0, len;
|
||||
register char *cp;
|
||||
char *epkt;
|
||||
|
||||
cp = buf;
|
||||
epkt = cp + totlen;
|
||||
if (off) {
|
||||
cp += off + 2 * sizeof(u_short);
|
||||
totlen -= 2 * sizeof(u_short);
|
||||
}
|
||||
MGETHDR(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == 0)
|
||||
return (0);
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
m->m_pkthdr.len = totlen;
|
||||
m->m_len = MHLEN;
|
||||
|
||||
while (totlen > 0) {
|
||||
if (top) {
|
||||
MGET(m, M_DONTWAIT, MT_DATA);
|
||||
if (m == 0) {
|
||||
m_freem(top);
|
||||
return (0);
|
||||
}
|
||||
m->m_len = MLEN;
|
||||
}
|
||||
len = min(totlen, epkt - cp);
|
||||
if (len >= MINCLSIZE) {
|
||||
MCLGET(m, M_DONTWAIT);
|
||||
if (m->m_flags & M_EXT)
|
||||
m->m_len = len = min(len, MCLBYTES);
|
||||
else
|
||||
len = m->m_len;
|
||||
} else {
|
||||
/*
|
||||
* Place initial small packet/header at end of mbuf.
|
||||
*/
|
||||
if (len < m->m_len) {
|
||||
if (top == 0 && len + max_linkhdr <= m->m_len)
|
||||
m->m_data += max_linkhdr;
|
||||
m->m_len = len;
|
||||
} else
|
||||
len = m->m_len;
|
||||
}
|
||||
if (copy)
|
||||
copy(cp, mtod(m, caddr_t), (unsigned)len);
|
||||
else
|
||||
bcopy(cp, mtod(m, caddr_t), (unsigned)len);
|
||||
cp += len;
|
||||
*mp = m;
|
||||
mp = &m->m_next;
|
||||
totlen -= len;
|
||||
if (cp == epkt)
|
||||
cp = buf;
|
||||
}
|
||||
return (top);
|
||||
}
|
||||
|
||||
/*
|
||||
* Copy data from a buffer back into the indicated mbuf chain,
|
||||
* starting "off" bytes from the beginning, extending the mbuf
|
||||
* chain if necessary.
|
||||
*/
|
||||
void
|
||||
m_copyback(m0, off, len, cp)
|
||||
struct mbuf *m0;
|
||||
register int off;
|
||||
register int len;
|
||||
caddr_t cp;
|
||||
{
|
||||
register int mlen;
|
||||
register struct mbuf *m = m0, *n;
|
||||
int totlen = 0;
|
||||
|
||||
if (m0 == 0)
|
||||
return;
|
||||
while (off > (mlen = m->m_len)) {
|
||||
off -= mlen;
|
||||
totlen += mlen;
|
||||
if (m->m_next == 0) {
|
||||
n = m_getclr(M_DONTWAIT, m->m_type);
|
||||
if (n == 0)
|
||||
goto out;
|
||||
n->m_len = min(MLEN, len + off);
|
||||
m->m_next = n;
|
||||
}
|
||||
m = m->m_next;
|
||||
}
|
||||
while (len > 0) {
|
||||
mlen = min (m->m_len - off, len);
|
||||
bcopy(cp, off + mtod(m, caddr_t), (unsigned)mlen);
|
||||
cp += mlen;
|
||||
len -= mlen;
|
||||
mlen += off;
|
||||
off = 0;
|
||||
totlen += mlen;
|
||||
if (len == 0)
|
||||
break;
|
||||
if (m->m_next == 0) {
|
||||
n = m_get(M_DONTWAIT, m->m_type);
|
||||
if (n == 0)
|
||||
break;
|
||||
n->m_len = min(MLEN, len);
|
||||
m->m_next = n;
|
||||
}
|
||||
m = m->m_next;
|
||||
}
|
||||
out: if (((m = m0)->m_flags & M_PKTHDR) && (m->m_pkthdr.len < totlen))
|
||||
m->m_pkthdr.len = totlen;
|
||||
}
|
||||
1100
c/src/exec/libnetworking/kern/uipc_socket.c
Normal file
1100
c/src/exec/libnetworking/kern/uipc_socket.c
Normal file
File diff suppressed because it is too large
Load Diff
965
c/src/exec/libnetworking/kern/uipc_socket2.c
Normal file
965
c/src/exec/libnetworking/kern/uipc_socket2.c
Normal file
@@ -0,0 +1,965 @@
|
||||
/*
|
||||
* This file has undergone several changes to reflect the
|
||||
* differences between the RTEMS and FreeBSD kernels.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1988, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)uipc_socket2.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/file.h>
|
||||
#include <sys/buf.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/signalvar.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
/*
|
||||
* Primitive routines for operating on sockets and socket buffers
|
||||
*/
|
||||
|
||||
u_long sb_max = SB_MAX; /* XXX should be static */
|
||||
SYSCTL_INT(_kern, KERN_MAXSOCKBUF, maxsockbuf, CTLFLAG_RW, &sb_max, 0, "")
|
||||
|
||||
static u_long sb_efficiency = 8; /* parameter for sbreserve() */
|
||||
SYSCTL_INT(_kern, OID_AUTO, sockbuf_waste_factor, CTLFLAG_RW, &sb_efficiency,
|
||||
0, "");
|
||||
|
||||
/*
|
||||
* Procedures to manipulate state flags of socket
|
||||
* and do appropriate wakeups. Normal sequence from the
|
||||
* active (originating) side is that soisconnecting() is
|
||||
* called during processing of connect() call,
|
||||
* resulting in an eventual call to soisconnected() if/when the
|
||||
* connection is established. When the connection is torn down
|
||||
* soisdisconnecting() is called during processing of disconnect() call,
|
||||
* and soisdisconnected() is called when the connection to the peer
|
||||
* is totally severed. The semantics of these routines are such that
|
||||
* connectionless protocols can call soisconnected() and soisdisconnected()
|
||||
* only, bypassing the in-progress calls when setting up a ``connection''
|
||||
* takes no time.
|
||||
*
|
||||
* From the passive side, a socket is created with
|
||||
* two queues of sockets: so_q0 for connections in progress
|
||||
* and so_q for connections already made and awaiting user acceptance.
|
||||
* As a protocol is preparing incoming connections, it creates a socket
|
||||
* structure queued on so_q0 by calling sonewconn(). When the connection
|
||||
* is established, soisconnected() is called, and transfers the
|
||||
* socket structure to so_q, making it available to accept().
|
||||
*
|
||||
* If a socket is closed with sockets on either
|
||||
* so_q0 or so_q, these sockets are dropped.
|
||||
*
|
||||
* If higher level protocols are implemented in
|
||||
* the kernel, the wakeups done here will sometimes
|
||||
* cause software-interrupt process scheduling.
|
||||
*/
|
||||
|
||||
void
|
||||
soisconnecting(so)
|
||||
register struct socket *so;
|
||||
{
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= SS_ISCONNECTING;
|
||||
}
|
||||
|
||||
void
|
||||
soisconnected(so)
|
||||
register struct socket *so;
|
||||
{
|
||||
register struct socket *head = so->so_head;
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISDISCONNECTING|SS_ISCONFIRMING);
|
||||
so->so_state |= SS_ISCONNECTED;
|
||||
if (head && (so->so_state & SS_INCOMP)) {
|
||||
TAILQ_REMOVE(&head->so_incomp, so, so_list);
|
||||
head->so_incqlen--;
|
||||
so->so_state &= ~SS_INCOMP;
|
||||
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
|
||||
so->so_state |= SS_COMP;
|
||||
sorwakeup(head);
|
||||
soconnwakeup(head);
|
||||
} else {
|
||||
soconnwakeup(so);
|
||||
sorwakeup(so);
|
||||
sowwakeup(so);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
soisdisconnecting(so)
|
||||
register struct socket *so;
|
||||
{
|
||||
|
||||
so->so_state &= ~SS_ISCONNECTING;
|
||||
so->so_state |= (SS_ISDISCONNECTING|SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
soconnwakeup(so);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
void
|
||||
soisdisconnected(so)
|
||||
register struct socket *so;
|
||||
{
|
||||
|
||||
so->so_state &= ~(SS_ISCONNECTING|SS_ISCONNECTED|SS_ISDISCONNECTING);
|
||||
so->so_state |= (SS_CANTRCVMORE|SS_CANTSENDMORE);
|
||||
soconnwakeup(so);
|
||||
sowwakeup(so);
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a random connection that hasn't been serviced yet and
|
||||
* is eligible for discard. There is a one in qlen chance that
|
||||
* we will return a null, saying that there are no dropable
|
||||
* requests. In this case, the protocol specific code should drop
|
||||
* the new request. This insures fairness.
|
||||
*
|
||||
* This may be used in conjunction with protocol specific queue
|
||||
* congestion routines.
|
||||
*/
|
||||
struct socket *
|
||||
sodropablereq(head)
|
||||
register struct socket *head;
|
||||
{
|
||||
register struct socket *so;
|
||||
unsigned int i, j, qlen, m;
|
||||
|
||||
static int rnd;
|
||||
static long old_mono_secs;
|
||||
static unsigned int cur_cnt, old_cnt;
|
||||
|
||||
if ((i = (m = rtems_bsdnet_seconds_since_boot()) - old_mono_secs) != 0) {
|
||||
old_mono_secs = m;
|
||||
old_cnt = cur_cnt / i;
|
||||
cur_cnt = 0;
|
||||
}
|
||||
|
||||
so = TAILQ_FIRST(&head->so_incomp);
|
||||
if (!so)
|
||||
return (so);
|
||||
|
||||
qlen = head->so_incqlen;
|
||||
if (++cur_cnt > qlen || old_cnt > qlen) {
|
||||
rnd = (314159 * rnd + 66329) & 0xffff;
|
||||
j = ((qlen + 1) * rnd) >> 16;
|
||||
|
||||
while (j-- && so)
|
||||
so = TAILQ_NEXT(so, so_list);
|
||||
}
|
||||
|
||||
return (so);
|
||||
}
|
||||
|
||||
/*
|
||||
* When an attempt at a new connection is noted on a socket
|
||||
* which accepts connections, sonewconn is called. If the
|
||||
* connection is possible (subject to space constraints, etc.)
|
||||
* then we allocate a new structure, propoerly linked into the
|
||||
* data structure of the original socket, and return this.
|
||||
* Connstatus may be 0, or SO_ISCONFIRMING, or SO_ISCONNECTED.
|
||||
*
|
||||
* Currently, sonewconn() is defined as sonewconn1() in socketvar.h
|
||||
* to catch calls that are missing the (new) second parameter.
|
||||
*/
|
||||
struct socket *
|
||||
sonewconn1(head, connstatus)
|
||||
register struct socket *head;
|
||||
int connstatus;
|
||||
{
|
||||
register struct socket *so;
|
||||
|
||||
if (head->so_qlen > 3 * head->so_qlimit / 2)
|
||||
return ((struct socket *)0);
|
||||
MALLOC(so, struct socket *, sizeof(*so), M_SOCKET, M_DONTWAIT);
|
||||
if (so == NULL)
|
||||
return ((struct socket *)0);
|
||||
bzero((caddr_t)so, sizeof(*so));
|
||||
so->so_head = head;
|
||||
so->so_type = head->so_type;
|
||||
so->so_options = head->so_options &~ SO_ACCEPTCONN;
|
||||
so->so_linger = head->so_linger;
|
||||
so->so_state = head->so_state | SS_NOFDREF;
|
||||
so->so_proto = head->so_proto;
|
||||
so->so_timeo = head->so_timeo;
|
||||
so->so_pgid = head->so_pgid;
|
||||
so->so_uid = head->so_uid;
|
||||
(void) soreserve(so, head->so_snd.sb_hiwat, head->so_rcv.sb_hiwat);
|
||||
if (connstatus) {
|
||||
TAILQ_INSERT_TAIL(&head->so_comp, so, so_list);
|
||||
so->so_state |= SS_COMP;
|
||||
} else {
|
||||
TAILQ_INSERT_TAIL(&head->so_incomp, so, so_list);
|
||||
so->so_state |= SS_INCOMP;
|
||||
head->so_incqlen++;
|
||||
}
|
||||
head->so_qlen++;
|
||||
if ((*so->so_proto->pr_usrreqs->pru_attach)(so, 0)) {
|
||||
if (so->so_state & SS_COMP) {
|
||||
TAILQ_REMOVE(&head->so_comp, so, so_list);
|
||||
} else {
|
||||
TAILQ_REMOVE(&head->so_incomp, so, so_list);
|
||||
head->so_incqlen--;
|
||||
}
|
||||
head->so_qlen--;
|
||||
(void) free((caddr_t)so, M_SOCKET);
|
||||
return ((struct socket *)0);
|
||||
}
|
||||
if (connstatus) {
|
||||
sorwakeup(head);
|
||||
soconnwakeup(head);
|
||||
so->so_state |= connstatus;
|
||||
}
|
||||
return (so);
|
||||
}
|
||||
|
||||
/*
|
||||
* Socantsendmore indicates that no more data will be sent on the
|
||||
* socket; it would normally be applied to a socket when the user
|
||||
* informs the system that no more data is to be sent, by the protocol
|
||||
* code (in case PRU_SHUTDOWN). Socantrcvmore indicates that no more data
|
||||
* will be received, and will normally be applied to the socket by a
|
||||
* protocol when it detects that the peer will send no more data.
|
||||
* Data queued for reading in the socket may yet be read.
|
||||
*/
|
||||
|
||||
void
|
||||
socantsendmore(so)
|
||||
struct socket *so;
|
||||
{
|
||||
|
||||
so->so_state |= SS_CANTSENDMORE;
|
||||
sowwakeup(so);
|
||||
}
|
||||
|
||||
void
|
||||
socantrcvmore(so)
|
||||
struct socket *so;
|
||||
{
|
||||
|
||||
so->so_state |= SS_CANTRCVMORE;
|
||||
sorwakeup(so);
|
||||
}
|
||||
|
||||
/*
|
||||
* Socket buffer (struct sockbuf) utility routines.
|
||||
*
|
||||
* Each socket contains two socket buffers: one for sending data and
|
||||
* one for receiving data. Each buffer contains a queue of mbufs,
|
||||
* information about the number of mbufs and amount of data in the
|
||||
* queue, and other fields allowing select() statements and notification
|
||||
* on data availability to be implemented.
|
||||
*
|
||||
* Data stored in a socket buffer is maintained as a list of records.
|
||||
* Each record is a list of mbufs chained together with the m_next
|
||||
* field. Records are chained together with the m_nextpkt field. The upper
|
||||
* level routine soreceive() expects the following conventions to be
|
||||
* observed when placing information in the receive buffer:
|
||||
*
|
||||
* 1. If the protocol requires each message be preceded by the sender's
|
||||
* name, then a record containing that name must be present before
|
||||
* any associated data (mbuf's must be of type MT_SONAME).
|
||||
* 2. If the protocol supports the exchange of ``access rights'' (really
|
||||
* just additional data associated with the message), and there are
|
||||
* ``rights'' to be received, then a record containing this data
|
||||
* should be present (mbuf's must be of type MT_RIGHTS).
|
||||
* 3. If a name or rights record exists, then it must be followed by
|
||||
* a data record, perhaps of zero length.
|
||||
*
|
||||
* Before using a new socket structure it is first necessary to reserve
|
||||
* buffer space to the socket, by calling sbreserve(). This should commit
|
||||
* some of the available buffer space in the system buffer pool for the
|
||||
* socket (currently, it does nothing but enforce limits). The space
|
||||
* should be released by calling sbrelease() when the socket is destroyed.
|
||||
*/
|
||||
|
||||
int
|
||||
soreserve(so, sndcc, rcvcc)
|
||||
register struct socket *so;
|
||||
u_long sndcc, rcvcc;
|
||||
{
|
||||
|
||||
if (sbreserve(&so->so_snd, sndcc) == 0)
|
||||
goto bad;
|
||||
if (sbreserve(&so->so_rcv, rcvcc) == 0)
|
||||
goto bad2;
|
||||
if (so->so_rcv.sb_lowat == 0)
|
||||
so->so_rcv.sb_lowat = 1;
|
||||
if (so->so_snd.sb_lowat == 0)
|
||||
so->so_snd.sb_lowat = MCLBYTES;
|
||||
if (so->so_snd.sb_lowat > so->so_snd.sb_hiwat)
|
||||
so->so_snd.sb_lowat = so->so_snd.sb_hiwat;
|
||||
return (0);
|
||||
bad2:
|
||||
sbrelease(&so->so_snd);
|
||||
bad:
|
||||
return (ENOBUFS);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allot mbufs to a sockbuf.
|
||||
* Attempt to scale mbmax so that mbcnt doesn't become limiting
|
||||
* if buffering efficiency is near the normal case.
|
||||
*/
|
||||
int
|
||||
sbreserve(sb, cc)
|
||||
struct sockbuf *sb;
|
||||
u_long cc;
|
||||
{
|
||||
|
||||
if (cc > sb_max * MCLBYTES / (MSIZE + MCLBYTES))
|
||||
return (0);
|
||||
sb->sb_hiwat = cc;
|
||||
sb->sb_mbmax = min(cc * sb_efficiency, sb_max);
|
||||
if (sb->sb_lowat > sb->sb_hiwat)
|
||||
sb->sb_lowat = sb->sb_hiwat;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free mbufs held by a socket, and reserved mbuf space.
|
||||
*/
|
||||
void
|
||||
sbrelease(sb)
|
||||
struct sockbuf *sb;
|
||||
{
|
||||
|
||||
sbflush(sb);
|
||||
sb->sb_hiwat = sb->sb_mbmax = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Routines to add and remove
|
||||
* data from an mbuf queue.
|
||||
*
|
||||
* The routines sbappend() or sbappendrecord() are normally called to
|
||||
* append new mbufs to a socket buffer, after checking that adequate
|
||||
* space is available, comparing the function sbspace() with the amount
|
||||
* of data to be added. sbappendrecord() differs from sbappend() in
|
||||
* that data supplied is treated as the beginning of a new record.
|
||||
* To place a sender's address, optional access rights, and data in a
|
||||
* socket receive buffer, sbappendaddr() should be used. To place
|
||||
* access rights and data in a socket receive buffer, sbappendrights()
|
||||
* should be used. In either case, the new data begins a new record.
|
||||
* Note that unlike sbappend() and sbappendrecord(), these routines check
|
||||
* for the caller that there will be enough space to store the data.
|
||||
* Each fails if there is not enough space, or if it cannot find mbufs
|
||||
* to store additional information in.
|
||||
*
|
||||
* Reliable protocols may use the socket send buffer to hold data
|
||||
* awaiting acknowledgement. Data is normally copied from a socket
|
||||
* send buffer in a protocol with m_copy for output to a peer,
|
||||
* and then removing the data from the socket buffer with sbdrop()
|
||||
* or sbdroprecord() when the data is acknowledged by the peer.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Append mbuf chain m to the last record in the
|
||||
* socket buffer sb. The additional space associated
|
||||
* the mbuf chain is recorded in sb. Empty mbufs are
|
||||
* discarded and mbufs are compacted where possible.
|
||||
*/
|
||||
void
|
||||
sbappend(sb, m)
|
||||
struct sockbuf *sb;
|
||||
struct mbuf *m;
|
||||
{
|
||||
register struct mbuf *n;
|
||||
|
||||
if (m == 0)
|
||||
return;
|
||||
n = sb->sb_mb;
|
||||
if (n) {
|
||||
while (n->m_nextpkt)
|
||||
n = n->m_nextpkt;
|
||||
do {
|
||||
if (n->m_flags & M_EOR) {
|
||||
sbappendrecord(sb, m); /* XXXXXX!!!! */
|
||||
return;
|
||||
}
|
||||
} while (n->m_next && (n = n->m_next));
|
||||
}
|
||||
sbcompress(sb, m, n);
|
||||
}
|
||||
|
||||
#ifdef SOCKBUF_DEBUG
|
||||
void
|
||||
sbcheck(sb)
|
||||
register struct sockbuf *sb;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
register int len = 0, mbcnt = 0;
|
||||
|
||||
for (m = sb->sb_mb; m; m = m->m_next) {
|
||||
len += m->m_len;
|
||||
mbcnt += MSIZE;
|
||||
if (m->m_flags & M_EXT) /*XXX*/ /* pretty sure this is bogus */
|
||||
mbcnt += m->m_ext.ext_size;
|
||||
if (m->m_nextpkt)
|
||||
panic("sbcheck nextpkt");
|
||||
}
|
||||
if (len != sb->sb_cc || mbcnt != sb->sb_mbcnt) {
|
||||
printf("cc %d != %d || mbcnt %d != %d\n", len, sb->sb_cc,
|
||||
mbcnt, sb->sb_mbcnt);
|
||||
panic("sbcheck");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* As above, except the mbuf chain
|
||||
* begins a new record.
|
||||
*/
|
||||
void
|
||||
sbappendrecord(sb, m0)
|
||||
register struct sockbuf *sb;
|
||||
register struct mbuf *m0;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
|
||||
if (m0 == 0)
|
||||
return;
|
||||
m = sb->sb_mb;
|
||||
if (m)
|
||||
while (m->m_nextpkt)
|
||||
m = m->m_nextpkt;
|
||||
/*
|
||||
* Put the first mbuf on the queue.
|
||||
* Note this permits zero length records.
|
||||
*/
|
||||
sballoc(sb, m0);
|
||||
if (m)
|
||||
m->m_nextpkt = m0;
|
||||
else
|
||||
sb->sb_mb = m0;
|
||||
m = m0->m_next;
|
||||
m0->m_next = 0;
|
||||
if (m && (m0->m_flags & M_EOR)) {
|
||||
m0->m_flags &= ~M_EOR;
|
||||
m->m_flags |= M_EOR;
|
||||
}
|
||||
sbcompress(sb, m, m0);
|
||||
}
|
||||
|
||||
/*
|
||||
* As above except that OOB data
|
||||
* is inserted at the beginning of the sockbuf,
|
||||
* but after any other OOB data.
|
||||
*/
|
||||
void
|
||||
sbinsertoob(sb, m0)
|
||||
register struct sockbuf *sb;
|
||||
register struct mbuf *m0;
|
||||
{
|
||||
register struct mbuf *m;
|
||||
register struct mbuf **mp;
|
||||
|
||||
if (m0 == 0)
|
||||
return;
|
||||
for (mp = &sb->sb_mb; *mp ; mp = &((*mp)->m_nextpkt)) {
|
||||
m = *mp;
|
||||
again:
|
||||
switch (m->m_type) {
|
||||
|
||||
case MT_OOBDATA:
|
||||
continue; /* WANT next train */
|
||||
|
||||
case MT_CONTROL:
|
||||
m = m->m_next;
|
||||
if (m)
|
||||
goto again; /* inspect THIS train further */
|
||||
}
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Put the first mbuf on the queue.
|
||||
* Note this permits zero length records.
|
||||
*/
|
||||
sballoc(sb, m0);
|
||||
m0->m_nextpkt = *mp;
|
||||
*mp = m0;
|
||||
m = m0->m_next;
|
||||
m0->m_next = 0;
|
||||
if (m && (m0->m_flags & M_EOR)) {
|
||||
m0->m_flags &= ~M_EOR;
|
||||
m->m_flags |= M_EOR;
|
||||
}
|
||||
sbcompress(sb, m, m0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Append address and data, and optionally, control (ancillary) data
|
||||
* to the receive queue of a socket. If present,
|
||||
* m0 must include a packet header with total length.
|
||||
* Returns 0 if no space in sockbuf or insufficient mbufs.
|
||||
*/
|
||||
int
|
||||
sbappendaddr(sb, asa, m0, control)
|
||||
register struct sockbuf *sb;
|
||||
struct sockaddr *asa;
|
||||
struct mbuf *m0, *control;
|
||||
{
|
||||
register struct mbuf *m, *n;
|
||||
int space = asa->sa_len;
|
||||
|
||||
if (m0 && (m0->m_flags & M_PKTHDR) == 0)
|
||||
panic("sbappendaddr");
|
||||
if (m0)
|
||||
space += m0->m_pkthdr.len;
|
||||
for (n = control; n; n = n->m_next) {
|
||||
space += n->m_len;
|
||||
if (n->m_next == 0) /* keep pointer to last control buf */
|
||||
break;
|
||||
}
|
||||
if (space > sbspace(sb))
|
||||
return (0);
|
||||
if (asa->sa_len > MLEN)
|
||||
return (0);
|
||||
MGET(m, M_DONTWAIT, MT_SONAME);
|
||||
if (m == 0)
|
||||
return (0);
|
||||
m->m_len = asa->sa_len;
|
||||
bcopy((caddr_t)asa, mtod(m, caddr_t), asa->sa_len);
|
||||
if (n)
|
||||
n->m_next = m0; /* concatenate data to control */
|
||||
else
|
||||
control = m0;
|
||||
m->m_next = control;
|
||||
for (n = m; n; n = n->m_next)
|
||||
sballoc(sb, n);
|
||||
n = sb->sb_mb;
|
||||
if (n) {
|
||||
while (n->m_nextpkt)
|
||||
n = n->m_nextpkt;
|
||||
n->m_nextpkt = m;
|
||||
} else
|
||||
sb->sb_mb = m;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
sbappendcontrol(sb, m0, control)
|
||||
struct sockbuf *sb;
|
||||
struct mbuf *control, *m0;
|
||||
{
|
||||
register struct mbuf *m, *n;
|
||||
int space = 0;
|
||||
|
||||
if (control == 0)
|
||||
panic("sbappendcontrol");
|
||||
for (m = control; ; m = m->m_next) {
|
||||
space += m->m_len;
|
||||
if (m->m_next == 0)
|
||||
break;
|
||||
}
|
||||
n = m; /* save pointer to last control buffer */
|
||||
for (m = m0; m; m = m->m_next)
|
||||
space += m->m_len;
|
||||
if (space > sbspace(sb))
|
||||
return (0);
|
||||
n->m_next = m0; /* concatenate data to control */
|
||||
for (m = control; m; m = m->m_next)
|
||||
sballoc(sb, m);
|
||||
n = sb->sb_mb;
|
||||
if (n) {
|
||||
while (n->m_nextpkt)
|
||||
n = n->m_nextpkt;
|
||||
n->m_nextpkt = control;
|
||||
} else
|
||||
sb->sb_mb = control;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Compress mbuf chain m into the socket
|
||||
* buffer sb following mbuf n. If n
|
||||
* is null, the buffer is presumed empty.
|
||||
*/
|
||||
void
|
||||
sbcompress(sb, m, n)
|
||||
register struct sockbuf *sb;
|
||||
register struct mbuf *m, *n;
|
||||
{
|
||||
register int eor = 0;
|
||||
register struct mbuf *o;
|
||||
|
||||
while (m) {
|
||||
eor |= m->m_flags & M_EOR;
|
||||
if (m->m_len == 0 &&
|
||||
(eor == 0 ||
|
||||
(((o = m->m_next) || (o = n)) &&
|
||||
o->m_type == m->m_type))) {
|
||||
m = m_free(m);
|
||||
continue;
|
||||
}
|
||||
if (n && (n->m_flags & (M_EXT | M_EOR)) == 0 &&
|
||||
(n->m_data + n->m_len + m->m_len) < &n->m_dat[MLEN] &&
|
||||
n->m_type == m->m_type) {
|
||||
bcopy(mtod(m, caddr_t), mtod(n, caddr_t) + n->m_len,
|
||||
(unsigned)m->m_len);
|
||||
n->m_len += m->m_len;
|
||||
sb->sb_cc += m->m_len;
|
||||
m = m_free(m);
|
||||
continue;
|
||||
}
|
||||
if (n)
|
||||
n->m_next = m;
|
||||
else
|
||||
sb->sb_mb = m;
|
||||
sballoc(sb, m);
|
||||
n = m;
|
||||
m->m_flags &= ~M_EOR;
|
||||
m = m->m_next;
|
||||
n->m_next = 0;
|
||||
}
|
||||
if (eor) {
|
||||
if (n)
|
||||
n->m_flags |= eor;
|
||||
else
|
||||
printf("semi-panic: sbcompress\n");
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Free all mbufs in a sockbuf.
|
||||
* Check that all resources are reclaimed.
|
||||
*/
|
||||
void
|
||||
sbflush(sb)
|
||||
register struct sockbuf *sb;
|
||||
{
|
||||
|
||||
if (sb->sb_flags & SB_LOCK)
|
||||
panic("sbflush");
|
||||
while (sb->sb_mbcnt)
|
||||
sbdrop(sb, (int)sb->sb_cc);
|
||||
if (sb->sb_cc || sb->sb_mb)
|
||||
panic("sbflush 2");
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop data from (the front of) a sockbuf.
|
||||
*/
|
||||
void
|
||||
sbdrop(sb, len)
|
||||
register struct sockbuf *sb;
|
||||
register int len;
|
||||
{
|
||||
register struct mbuf *m, *mn;
|
||||
struct mbuf *next;
|
||||
|
||||
next = (m = sb->sb_mb) ? m->m_nextpkt : 0;
|
||||
while (len > 0) {
|
||||
if (m == 0) {
|
||||
if (next == 0)
|
||||
panic("sbdrop");
|
||||
m = next;
|
||||
next = m->m_nextpkt;
|
||||
continue;
|
||||
}
|
||||
if (m->m_len > len) {
|
||||
m->m_len -= len;
|
||||
m->m_data += len;
|
||||
sb->sb_cc -= len;
|
||||
break;
|
||||
}
|
||||
len -= m->m_len;
|
||||
sbfree(sb, m);
|
||||
MFREE(m, mn);
|
||||
m = mn;
|
||||
}
|
||||
while (m && m->m_len == 0) {
|
||||
sbfree(sb, m);
|
||||
MFREE(m, mn);
|
||||
m = mn;
|
||||
}
|
||||
if (m) {
|
||||
sb->sb_mb = m;
|
||||
m->m_nextpkt = next;
|
||||
} else
|
||||
sb->sb_mb = next;
|
||||
}
|
||||
|
||||
/*
|
||||
* Drop a record off the front of a sockbuf
|
||||
* and move the next record to the front.
|
||||
*/
|
||||
void
|
||||
sbdroprecord(sb)
|
||||
register struct sockbuf *sb;
|
||||
{
|
||||
register struct mbuf *m, *mn;
|
||||
|
||||
m = sb->sb_mb;
|
||||
if (m) {
|
||||
sb->sb_mb = m->m_nextpkt;
|
||||
do {
|
||||
sbfree(sb, m);
|
||||
MFREE(m, mn);
|
||||
m = mn;
|
||||
} while (m);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Create a "control" mbuf containing the specified data
|
||||
* with the specified type for presentation on a socket buffer.
|
||||
*/
|
||||
struct mbuf *
|
||||
sbcreatecontrol(p, size, type, level)
|
||||
caddr_t p;
|
||||
register int size;
|
||||
int type, level;
|
||||
{
|
||||
register struct cmsghdr *cp;
|
||||
struct mbuf *m;
|
||||
|
||||
if ((m = m_get(M_DONTWAIT, MT_CONTROL)) == NULL)
|
||||
return ((struct mbuf *) NULL);
|
||||
cp = mtod(m, struct cmsghdr *);
|
||||
/* XXX check size? */
|
||||
(void)memcpy(CMSG_DATA(cp), p, size);
|
||||
size += sizeof(*cp);
|
||||
m->m_len = size;
|
||||
cp->cmsg_len = size;
|
||||
cp->cmsg_level = level;
|
||||
cp->cmsg_type = type;
|
||||
return (m);
|
||||
}
|
||||
|
||||
#ifdef PRU_OLDSTYLE
|
||||
/*
|
||||
* The following routines mediate between the old-style `pr_usrreq'
|
||||
* protocol implementations and the new-style `struct pr_usrreqs'
|
||||
* calling convention.
|
||||
*/
|
||||
|
||||
/* syntactic sugar */
|
||||
#define nomb (struct mbuf *)0
|
||||
|
||||
static int
|
||||
old_abort(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ABORT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_accept(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ACCEPT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_attach(struct socket *so, int proto)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_ATTACH, nomb,
|
||||
(struct mbuf *)proto, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_bind(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_BIND, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONNECT, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_connect2(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
return so1->so_proto->pr_ousrreq(so1, PRU_CONNECT2, nomb,
|
||||
(struct mbuf *)so2, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_control(struct socket *so, int cmd, caddr_t data, struct ifnet *ifp)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_CONTROL, (struct mbuf *)cmd,
|
||||
(struct mbuf *)data,
|
||||
(struct mbuf *)ifp);
|
||||
}
|
||||
|
||||
static int
|
||||
old_detach(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DETACH, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_disconnect(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_DISCONNECT, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_listen(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_LISTEN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_peeraddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_PEERADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_rcvd(struct socket *so, int flags)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVD, nomb,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_rcvoob(struct socket *so, struct mbuf *m, int flags)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_RCVOOB, m,
|
||||
(struct mbuf *)flags, /* XXX */
|
||||
nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_send(struct socket *so, int flags, struct mbuf *m, struct mbuf *addr,
|
||||
struct mbuf *control)
|
||||
{
|
||||
int req;
|
||||
|
||||
if (flags & PRUS_OOB) {
|
||||
req = PRU_SENDOOB;
|
||||
} else if(flags & PRUS_EOF) {
|
||||
req = PRU_SEND_EOF;
|
||||
} else {
|
||||
req = PRU_SEND;
|
||||
}
|
||||
return so->so_proto->pr_ousrreq(so, req, m, addr, control);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sense(struct socket *so, struct stat *sb)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SENSE, (struct mbuf *)sb,
|
||||
nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_shutdown(struct socket *so)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SHUTDOWN, nomb, nomb, nomb);
|
||||
}
|
||||
|
||||
static int
|
||||
old_sockaddr(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return so->so_proto->pr_ousrreq(so, PRU_SOCKADDR, nomb, nam, nomb);
|
||||
}
|
||||
|
||||
struct pr_usrreqs pru_oldstyle = {
|
||||
old_abort, old_accept, old_attach, old_bind, old_connect,
|
||||
old_connect2, old_control, old_detach, old_disconnect,
|
||||
old_listen, old_peeraddr, old_rcvd, old_rcvoob, old_send,
|
||||
old_sense, old_shutdown, old_sockaddr
|
||||
};
|
||||
|
||||
#endif /* PRU_OLDSTYLE */
|
||||
|
||||
/*
|
||||
* Some routines that return EOPNOTSUPP for entry points that are not
|
||||
* supported by a protocol. Fill in as needed.
|
||||
*/
|
||||
int
|
||||
pru_accept_notsupp(struct socket *so, struct mbuf *nam)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
pru_connect2_notsupp(struct socket *so1, struct socket *so2)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
pru_control_notsupp(struct socket *so, int cmd, caddr_t data,
|
||||
struct ifnet *ifp)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
pru_listen_notsupp(struct socket *so)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
pru_rcvd_notsupp(struct socket *so, int flags)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
int
|
||||
pru_rcvoob_notsupp(struct socket *so, struct mbuf *m, int flags)
|
||||
{
|
||||
return EOPNOTSUPP;
|
||||
}
|
||||
|
||||
/*
|
||||
* This isn't really a ``null'' operation, but it's the default one
|
||||
* and doesn't do anything destructive.
|
||||
*/
|
||||
int
|
||||
pru_sense_null(struct socket *so, struct stat *sb)
|
||||
{
|
||||
sb->st_blksize = so->so_snd.sb_hiwat;
|
||||
return 0;
|
||||
}
|
||||
|
||||
1
c/src/exec/libnetworking/lib/README
Normal file
1
c/src/exec/libnetworking/lib/README
Normal file
@@ -0,0 +1 @@
|
||||
Sources from application-level (as opposed to kernel-level) libraries.
|
||||
42
c/src/exec/libnetworking/lib/getprotoby.c
Normal file
42
c/src/exec/libnetworking/lib/getprotoby.c
Normal file
@@ -0,0 +1,42 @@
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static const struct protoent prototab[] = {
|
||||
{ "ip", NULL, IPPROTO_IP },
|
||||
{ "icmp", NULL, IPPROTO_ICMP },
|
||||
{ "tcp", NULL, IPPROTO_TCP },
|
||||
{ "udp", NULL, IPPROTO_UDP },
|
||||
};
|
||||
|
||||
/*
|
||||
* Dummy version of BSD getprotobyname()
|
||||
*/
|
||||
struct protoent *
|
||||
getprotobyname (const char *name)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) {
|
||||
if (strcmp (name, prototab[i].p_name) == 0)
|
||||
return &prototab[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Dummy version of BSD getprotobynumber()
|
||||
*/
|
||||
struct protoent *
|
||||
getprotobynumber (int proto)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0 ; i < (sizeof prototab / sizeof prototab[0]) ; i++) {
|
||||
if (proto == prototab[i].p_proto)
|
||||
return &prototab[i];
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
187
c/src/exec/libnetworking/lib/syslog.c
Normal file
187
c/src/exec/libnetworking/lib/syslog.c
Normal file
@@ -0,0 +1,187 @@
|
||||
/*
|
||||
* RTEMS version of syslog and associated routines
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <rtems.h>
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
|
||||
static int LogStatus = LOG_CONS;
|
||||
static const char *LogTag = "syslog";
|
||||
static int LogFacility = LOG_USER;
|
||||
static int LogMask = 0xff;
|
||||
|
||||
static int LogFd = -1;
|
||||
static rtems_id LogSemaphore;
|
||||
extern struct in_addr rtems_bsdnet_log_host_address;
|
||||
|
||||
#define SYSLOG_PORT 514
|
||||
|
||||
void
|
||||
syslog (int pri, const char *fmt, ...)
|
||||
{
|
||||
va_list ap;
|
||||
|
||||
va_start (ap, fmt);
|
||||
vsyslog (pri, fmt, ap);
|
||||
va_end (ap);
|
||||
}
|
||||
|
||||
/*
|
||||
* FIXME: Should cbuf be static? It could be if we put the mutex
|
||||
* around the entire body of this routine. Then we wouldn't
|
||||
* have to worry about blowing stacks with a local variable
|
||||
* that large. Could make cbuf bigger, too.
|
||||
*/
|
||||
void
|
||||
vsyslog (int pri, const char *fmt, va_list ap)
|
||||
{
|
||||
int cnt;
|
||||
char *cp;
|
||||
char *msgp, cbuf[200];
|
||||
int sent;
|
||||
|
||||
if (pri & ~(LOG_PRIMASK|LOG_FACMASK)) {
|
||||
syslog (LOG_ERR|LOG_CONS|LOG_PERROR|LOG_PID,
|
||||
"syslog: unknown facility/priority: %#x", pri);
|
||||
pri &= LOG_PRIMASK|LOG_FACMASK;
|
||||
}
|
||||
|
||||
if (!LOG_MASK(LOG_PRI(pri)) & LogMask)
|
||||
return;
|
||||
|
||||
if ((pri & LOG_FACMASK) == 0)
|
||||
pri |= LogFacility;
|
||||
|
||||
cnt = sprintf (cbuf, "<%d>", pri);
|
||||
cp = msgp = cbuf + cnt;
|
||||
if (LogTag) {
|
||||
const char *lp = LogTag;
|
||||
while ((*cp = *lp++) != '\0')
|
||||
cp++;
|
||||
}
|
||||
if (LogStatus & LOG_PID) {
|
||||
rtems_id tid;
|
||||
rtems_task_ident (RTEMS_SELF, 0, &tid);
|
||||
cnt = sprintf (cp, "[%#lx]", (unsigned long)tid);
|
||||
cp += cnt;
|
||||
}
|
||||
if (LogTag) {
|
||||
*cp++ = ':';
|
||||
*cp++ = ' ';
|
||||
}
|
||||
cnt = vsprintf (cp, fmt, ap);
|
||||
cnt += cp - cbuf;
|
||||
if (cbuf[cnt-1] == '\n')
|
||||
cbuf[--cnt] = '\0';
|
||||
|
||||
if (LogStatus & LOG_PERROR)
|
||||
printf ("%s\n", cbuf);
|
||||
|
||||
/*
|
||||
* Grab the mutex
|
||||
*/
|
||||
sent = 0;
|
||||
if ((rtems_bsdnet_log_host_address.s_addr != INADDR_ANY)
|
||||
&& (LogFd >= 0)
|
||||
&& (rtems_semaphore_obtain (LogSemaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) == RTEMS_SUCCESSFUL)) {
|
||||
/*
|
||||
* Set the destination address/port
|
||||
*/
|
||||
struct sockaddr_in farAddress;
|
||||
farAddress.sin_family = AF_INET;
|
||||
farAddress.sin_port = htons (SYSLOG_PORT);
|
||||
farAddress.sin_addr = rtems_bsdnet_log_host_address;
|
||||
memset (farAddress.sin_zero, '\0', sizeof farAddress.sin_zero);
|
||||
|
||||
/*
|
||||
* Send the message
|
||||
*/
|
||||
if (sendto (LogFd, cbuf, cnt, 0, (struct sockaddr *)&farAddress, sizeof farAddress) >= 0)
|
||||
sent = 1;
|
||||
rtems_semaphore_release (LogSemaphore);
|
||||
}
|
||||
if (!sent && (LogStatus & LOG_CONS) && !(LogStatus & LOG_PERROR))
|
||||
printf ("%s\n", msgp);
|
||||
}
|
||||
|
||||
void
|
||||
openlog (const char *ident, int logstat, int logfac)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
struct sockaddr_in myAddress;
|
||||
|
||||
if (ident != NULL)
|
||||
LogTag = ident;
|
||||
LogStatus = logstat;
|
||||
if (logfac != 0 && (logfac & ~LOG_FACMASK) == 0)
|
||||
LogFacility = logfac;
|
||||
|
||||
/*
|
||||
* Create the socket
|
||||
*/
|
||||
if ((LogFd = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
printf ("Can't create syslog socket: %d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind socket to name
|
||||
*/
|
||||
myAddress.sin_family = AF_INET;
|
||||
myAddress.sin_addr.s_addr = INADDR_ANY;
|
||||
myAddress.sin_port = 0;
|
||||
memset (myAddress.sin_zero, '\0', sizeof myAddress.sin_zero);
|
||||
if (bind (LogFd, (struct sockaddr *)&myAddress, sizeof (myAddress)) < 0) {
|
||||
close (LogFd);
|
||||
LogFd = -1;
|
||||
printf ("Can't bind syslog socket: %d\n", errno);
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Create the mutex
|
||||
*/
|
||||
sc = rtems_semaphore_create (rtems_build_name('s', 'L', 'o', 'g'),
|
||||
1,
|
||||
RTEMS_PRIORITY |
|
||||
RTEMS_BINARY_SEMAPHORE |
|
||||
RTEMS_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL,
|
||||
0,
|
||||
&LogSemaphore);
|
||||
if (sc != RTEMS_SUCCESSFUL) {
|
||||
printf ("Can't create syslog seamphore: %d\n", sc);
|
||||
close (LogFd);
|
||||
LogFd = -1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
closelog(void)
|
||||
{
|
||||
if (LogFd >= 0) {
|
||||
close (LogFd);
|
||||
LogFd = -1;
|
||||
rtems_semaphore_delete (LogSemaphore);
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
setlogmask (int pmask)
|
||||
{
|
||||
int omask;
|
||||
|
||||
omask = LogMask;
|
||||
if (pmask != 0)
|
||||
LogMask = pmask;
|
||||
return (omask);
|
||||
}
|
||||
609
c/src/exec/libnetworking/lib/tftpDriver.c
Normal file
609
c/src/exec/libnetworking/lib/tftpDriver.c
Normal file
@@ -0,0 +1,609 @@
|
||||
/*
|
||||
* Trivial File Transfer Protocol (RFC 1350)
|
||||
*
|
||||
* Transfer file to/from remote host
|
||||
*
|
||||
* W. Eric Norum
|
||||
* Saskatchewan Accelerator Laboratory
|
||||
* University of Saskatchewan
|
||||
* Saskatoon, Saskatchewan, CANADA
|
||||
* eric@skatter.usask.ca
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <malloc.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <rtems.h>
|
||||
#include <rtems/libio.h>
|
||||
#include <rtems/rtems_bsdnet.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Range of UDP ports to try
|
||||
*/
|
||||
#define UDP_PORT_BASE 3180
|
||||
|
||||
/*
|
||||
* Pathname prefix
|
||||
*/
|
||||
#define TFTP_PATHNAME_PREFIX "/TFTP/"
|
||||
|
||||
/*
|
||||
* Default limits
|
||||
*/
|
||||
#define PACKET_REPLY_MILLISECONDS 6000
|
||||
#define OPEN_RETRY_LIMIT 10
|
||||
#define IO_RETRY_LIMIT 10
|
||||
|
||||
/*
|
||||
* TFTP opcodes
|
||||
*/
|
||||
#define TFTP_OPCODE_RRQ 1
|
||||
#define TFTP_OPCODE_WRQ 2
|
||||
#define TFTP_OPCODE_DATA 3
|
||||
#define TFTP_OPCODE_ACK 4
|
||||
#define TFTP_OPCODE_ERROR 5
|
||||
|
||||
/*
|
||||
* Largest data transfer
|
||||
*/
|
||||
#define TFTP_BUFSIZE 512
|
||||
|
||||
/*
|
||||
* Packets transferred between machines
|
||||
*/
|
||||
union tftpPacket {
|
||||
/*
|
||||
* RRQ/WRQ packet
|
||||
*/
|
||||
struct tftpRWRQ {
|
||||
rtems_unsigned16 opcode;
|
||||
char filename_mode[TFTP_BUFSIZE];
|
||||
} tftpRWRQ;
|
||||
|
||||
/*
|
||||
* DATA packet
|
||||
*/
|
||||
struct tftpDATA {
|
||||
rtems_unsigned16 opcode;
|
||||
rtems_unsigned16 blocknum;
|
||||
rtems_unsigned8 data[TFTP_BUFSIZE];
|
||||
} tftpDATA;
|
||||
|
||||
/*
|
||||
* ACK packet
|
||||
*/
|
||||
struct tftpACK {
|
||||
rtems_unsigned16 opcode;
|
||||
rtems_unsigned16 blocknum;
|
||||
} tftpACK;
|
||||
|
||||
/*
|
||||
* ERROR packet
|
||||
*/
|
||||
struct tftpERROR {
|
||||
rtems_unsigned16 opcode;
|
||||
rtems_unsigned16 errorCode;
|
||||
char errorMessage[TFTP_BUFSIZE];
|
||||
} tftpERROR;
|
||||
};
|
||||
|
||||
/*
|
||||
* State of each TFTP stream
|
||||
*/
|
||||
struct tftpStream {
|
||||
/*
|
||||
* Buffer for storing most recently-received packet
|
||||
*/
|
||||
union tftpPacket pkbuf;
|
||||
|
||||
/*
|
||||
* Last block number received
|
||||
*/
|
||||
rtems_unsigned16 blocknum;
|
||||
|
||||
/*
|
||||
* Data transfer socket
|
||||
*/
|
||||
int socket;
|
||||
struct sockaddr_in myAddress;
|
||||
struct sockaddr_in farAddress;
|
||||
|
||||
/*
|
||||
* Indices into buffer
|
||||
*/
|
||||
int nleft;
|
||||
int nused;
|
||||
|
||||
/*
|
||||
* Flags
|
||||
*/
|
||||
int firstReply;
|
||||
int eof;
|
||||
};
|
||||
|
||||
/*
|
||||
* Number of streams open at the same time
|
||||
*/
|
||||
static rtems_id tftp_mutex;
|
||||
static int nStreams;
|
||||
static struct tftpStream ** volatile tftpStreams;
|
||||
|
||||
/*
|
||||
* Initialize the TFTP driver
|
||||
*/
|
||||
rtems_device_driver rtems_tftp_initialize(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_status_code sc;
|
||||
|
||||
sc = rtems_semaphore_create (rtems_build_name('T', 'F', 'T', 'P'),
|
||||
1,
|
||||
RTEMS_FIFO |
|
||||
RTEMS_BINARY_SEMAPHORE |
|
||||
RTEMS_NO_INHERIT_PRIORITY |
|
||||
RTEMS_NO_PRIORITY_CEILING |
|
||||
RTEMS_LOCAL,
|
||||
0,
|
||||
&tftp_mutex);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
return sc;
|
||||
rtems_io_register_name (TFTP_PATHNAME_PREFIX, major, minor);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Set error message
|
||||
* This RTEMS/UNIX error mapping needs to be fixed!
|
||||
*/
|
||||
static void
|
||||
tftpSetErrno (struct tftpStream *tp)
|
||||
{
|
||||
unsigned int tftpError;
|
||||
static const int errorMap[] = {
|
||||
0,
|
||||
ENOENT,
|
||||
EPERM,
|
||||
ENOSPC,
|
||||
EINVAL,
|
||||
ENXIO,
|
||||
EEXIST,
|
||||
ESRCH,
|
||||
0,
|
||||
};
|
||||
|
||||
tftpError = ntohs (tp->pkbuf.tftpERROR.errorCode);
|
||||
if (tftpError < (sizeof errorMap / sizeof errorMap[0]))
|
||||
errno = errorMap[tftpError];
|
||||
else
|
||||
errno = 1000 + tftpError;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send a message to make the other end shut up
|
||||
*/
|
||||
static void
|
||||
sendStifle (struct tftpStream *tp, struct sockaddr_in *to)
|
||||
{
|
||||
int len;
|
||||
|
||||
/*
|
||||
* Create the error packet (Unknown transfer ID).
|
||||
*/
|
||||
tp->pkbuf.tftpERROR.opcode = htons (TFTP_OPCODE_ERROR);
|
||||
tp->pkbuf.tftpERROR.errorCode = htons (5);
|
||||
len = sizeof tp->pkbuf.tftpERROR.opcode +
|
||||
sizeof tp->pkbuf.tftpERROR.errorCode + 1;
|
||||
len += sprintf (tp->pkbuf.tftpERROR.errorMessage, "GO AWAY");
|
||||
|
||||
/*
|
||||
* Send it
|
||||
*/
|
||||
sendto (tp->socket, (char *)&tp->pkbuf, len, 0,
|
||||
(struct sockaddr *)to, sizeof *to);
|
||||
}
|
||||
|
||||
/*
|
||||
* Wait for a data packet
|
||||
*/
|
||||
static int
|
||||
getPacket (struct tftpStream *tp)
|
||||
{
|
||||
int len;
|
||||
struct timeval tv;
|
||||
|
||||
tv.tv_sec = 6;
|
||||
tv.tv_usec = 0;
|
||||
setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
|
||||
for (;;) {
|
||||
union {
|
||||
struct sockaddr s;
|
||||
struct sockaddr_in i;
|
||||
} from;
|
||||
int fromlen = sizeof from;
|
||||
len = recvfrom (tp->socket, (char *)&tp->pkbuf,
|
||||
sizeof tp->pkbuf, 0,
|
||||
&from.s, &fromlen);
|
||||
if (len < 0)
|
||||
break;
|
||||
if (from.i.sin_addr.s_addr == tp->farAddress.sin_addr.s_addr) {
|
||||
if (tp->firstReply) {
|
||||
tp->firstReply = 0;
|
||||
tp->farAddress.sin_port = from.i.sin_port;
|
||||
}
|
||||
if (tp->farAddress.sin_port == from.i.sin_port)
|
||||
break;
|
||||
}
|
||||
|
||||
/*
|
||||
* Packet is from someone with whom we are
|
||||
* not interested. Tell them to go away.
|
||||
*/
|
||||
sendStifle (tp, &from.i);
|
||||
}
|
||||
tv.tv_sec = 0;
|
||||
setsockopt (tp->socket, SOL_SOCKET, SO_RCVTIMEO, &tv, sizeof tv);
|
||||
return len;
|
||||
}
|
||||
|
||||
/*
|
||||
* Send an acknowledgement
|
||||
*/
|
||||
static int
|
||||
sendAck (struct tftpStream *tp)
|
||||
{
|
||||
/*
|
||||
* Create the acknowledgement
|
||||
*/
|
||||
tp->pkbuf.tftpACK.opcode = htons (TFTP_OPCODE_ACK);
|
||||
tp->pkbuf.tftpACK.blocknum = htons (tp->blocknum);
|
||||
|
||||
/*
|
||||
* Send it
|
||||
*/
|
||||
if (sendto (tp->socket, (char *)&tp->pkbuf, sizeof tp->pkbuf.tftpACK, 0,
|
||||
(struct sockaddr *)&tp->farAddress,
|
||||
sizeof tp->farAddress) < 0)
|
||||
return errno;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Release a stream and clear the pointer to it
|
||||
*/
|
||||
static void
|
||||
releaseStream (int s)
|
||||
{
|
||||
rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
free (tftpStreams[s]);
|
||||
tftpStreams[s] = NULL;
|
||||
rtems_semaphore_release (tftp_mutex);
|
||||
}
|
||||
|
||||
/*
|
||||
* Open a TFTP stream
|
||||
*/
|
||||
rtems_device_driver rtems_tftp_open(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_libio_open_close_args_t *ap = pargp;
|
||||
struct tftpStream *tp;
|
||||
int retryCount;
|
||||
rtems_unsigned32 farAddress;
|
||||
int s;
|
||||
int len;
|
||||
char *cp1, *cp2;
|
||||
char *remoteFilename;
|
||||
rtems_interval now;
|
||||
rtems_status_code sc;
|
||||
|
||||
/*
|
||||
* Read-only for now
|
||||
*/
|
||||
if (ap->flags & LIBIO_FLAGS_WRITE)
|
||||
return RTEMS_NOT_IMPLEMENTED;
|
||||
|
||||
/*
|
||||
* Pick apart the name into a host:pathname pair
|
||||
*/
|
||||
if (strlen (ap->iop->pathname) <= strlen (TFTP_PATHNAME_PREFIX))
|
||||
return RTEMS_INVALID_NAME;
|
||||
cp2 = ap->iop->pathname + strlen (TFTP_PATHNAME_PREFIX);
|
||||
if (*cp2 == '/') {
|
||||
farAddress = rtems_bsdnet_bootp_server_address.s_addr;
|
||||
}
|
||||
else {
|
||||
char *hostname;
|
||||
|
||||
cp1 = cp2;
|
||||
while (*cp2 != '/') {
|
||||
if (*cp2 == '\0')
|
||||
return RTEMS_INVALID_NAME;
|
||||
cp2++;
|
||||
}
|
||||
len = cp2 - cp1;
|
||||
hostname = malloc (len + 1);
|
||||
if (hostname == NULL)
|
||||
return RTEMS_NO_MEMORY;
|
||||
strncpy (hostname, cp1, len);
|
||||
hostname[len] = '\0';
|
||||
farAddress = inet_addr (hostname);
|
||||
free (hostname);
|
||||
}
|
||||
if ((farAddress == 0) || (farAddress == ~0))
|
||||
return RTEMS_INVALID_NAME;
|
||||
if (*++cp2 == '\0')
|
||||
return RTEMS_INVALID_NAME;
|
||||
remoteFilename = cp2;
|
||||
if (strlen (remoteFilename) > (TFTP_BUFSIZE - 10))
|
||||
return RTEMS_INVALID_NAME;
|
||||
|
||||
/*
|
||||
* Find a free stream
|
||||
*/
|
||||
sc = rtems_semaphore_obtain (tftp_mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
|
||||
if (sc != RTEMS_SUCCESSFUL)
|
||||
return sc;
|
||||
for (s = 0 ; s < nStreams ; s++) {
|
||||
if (tftpStreams[s] == NULL)
|
||||
break;
|
||||
}
|
||||
if (s == nStreams) {
|
||||
/*
|
||||
* Reallocate stream pointers
|
||||
* Guard against the case where realloc() returns NULL.
|
||||
*/
|
||||
struct tftpStream **np;
|
||||
|
||||
np = realloc (tftpStreams, ++nStreams * sizeof *tftpStreams);
|
||||
if (np == NULL) {
|
||||
rtems_semaphore_release (tftp_mutex);
|
||||
return RTEMS_NO_MEMORY;
|
||||
}
|
||||
tftpStreams = np;
|
||||
}
|
||||
tp = tftpStreams[s] = malloc (sizeof (struct tftpStream));
|
||||
rtems_semaphore_release (tftp_mutex);
|
||||
if (tp == NULL)
|
||||
return RTEMS_NO_MEMORY;
|
||||
ap->iop->data0 = s;
|
||||
ap->iop->data1 = tp;
|
||||
|
||||
/*
|
||||
* Create the socket
|
||||
*/
|
||||
if ((tp->socket = socket (AF_INET, SOCK_DGRAM, 0)) < 0) {
|
||||
releaseStream (s);
|
||||
return RTEMS_TOO_MANY;
|
||||
}
|
||||
|
||||
/*
|
||||
* Bind the socket to a local address
|
||||
*/
|
||||
retryCount = 0;
|
||||
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_SINCE_BOOT, &now);
|
||||
for (;;) {
|
||||
int try = (now + retryCount) % 10;
|
||||
|
||||
tp->myAddress.sin_family = AF_INET;
|
||||
tp->myAddress.sin_port = htons (UDP_PORT_BASE + nStreams * try + minor);
|
||||
tp->myAddress.sin_addr.s_addr = htonl (INADDR_ANY);
|
||||
if (bind (tp->socket, (struct sockaddr *)&tp->myAddress, sizeof tp->myAddress) >= 0)
|
||||
break;
|
||||
if (++retryCount == 10) {
|
||||
close (tp->socket);
|
||||
releaseStream (minor);
|
||||
return RTEMS_RESOURCE_IN_USE;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Set the UDP destination to the TFTP server
|
||||
* port on the remote machine.
|
||||
*/
|
||||
tp->farAddress.sin_family = AF_INET;
|
||||
tp->farAddress.sin_addr.s_addr = farAddress;
|
||||
tp->farAddress.sin_port = htons (69);
|
||||
|
||||
/*
|
||||
* Start the transfer
|
||||
*/
|
||||
tp->firstReply = 1;
|
||||
for (;;) {
|
||||
/*
|
||||
* Create the request
|
||||
*/
|
||||
tp->pkbuf.tftpRWRQ.opcode = htons (TFTP_OPCODE_RRQ);
|
||||
cp1 = tp->pkbuf.tftpRWRQ.filename_mode;
|
||||
cp2 = remoteFilename;
|
||||
while ((*cp1++ = *cp2++) != '\0')
|
||||
continue;
|
||||
cp2 = "octet";
|
||||
while ((*cp1++ = *cp2++) != '\0')
|
||||
continue;
|
||||
len = cp1 - (char *)&tp->pkbuf.tftpRWRQ;
|
||||
|
||||
/*
|
||||
* Send the request
|
||||
*/
|
||||
if (sendto (tp->socket, (char *)&tp->pkbuf, len, 0,
|
||||
(struct sockaddr *)&tp->farAddress,
|
||||
sizeof tp->farAddress) < 0) {
|
||||
close (tp->socket);
|
||||
releaseStream (minor);
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
|
||||
/*
|
||||
* Get reply
|
||||
*/
|
||||
len = getPacket (tp);
|
||||
if (len >= (int) sizeof tp->pkbuf.tftpACK) {
|
||||
int opcode = ntohs (tp->pkbuf.tftpDATA.opcode);
|
||||
if ((opcode == TFTP_OPCODE_DATA)
|
||||
&& (ntohs (tp->pkbuf.tftpDATA.blocknum) == 1)) {
|
||||
tp->nused = 0;
|
||||
tp->blocknum = 1;
|
||||
tp->nleft = len - 2 * sizeof (rtems_unsigned16);
|
||||
tp->eof = (tp->nleft < TFTP_BUFSIZE);
|
||||
if (sendAck (tp) != 0) {
|
||||
close (tp->socket);
|
||||
releaseStream (minor);
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (opcode == TFTP_OPCODE_ERROR) {
|
||||
tftpSetErrno (tp);
|
||||
close (tp->socket);
|
||||
releaseStream (ap->iop->data0);
|
||||
return RTEMS_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep trying
|
||||
*/
|
||||
if (++retryCount >= OPEN_RETRY_LIMIT) {
|
||||
close (tp->socket);
|
||||
releaseStream (minor);
|
||||
return RTEMS_UNSATISFIED;
|
||||
}
|
||||
}
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Read from a TFTP stream
|
||||
*/
|
||||
rtems_device_driver rtems_tftp_read(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_libio_rw_args_t *ap = pargp;
|
||||
char *bp;
|
||||
struct tftpStream *tp;
|
||||
int retryCount;
|
||||
int nwant;
|
||||
|
||||
tp = ap->iop->data1;
|
||||
|
||||
/*
|
||||
* Read till user request is satisfied or EOF is reached
|
||||
*/
|
||||
bp = ap->buffer;
|
||||
nwant = ap->count;
|
||||
while (nwant) {
|
||||
if (tp->nleft) {
|
||||
int count;
|
||||
if (nwant < tp->nleft)
|
||||
count = nwant;
|
||||
else
|
||||
count = tp->nleft;
|
||||
memcpy (bp, &tp->pkbuf.tftpDATA.data[tp->nused], count);
|
||||
tp->nused += count;
|
||||
tp->nleft -= count;
|
||||
bp += count;
|
||||
nwant -= count;
|
||||
if (nwant == 0)
|
||||
break;
|
||||
}
|
||||
if (tp->eof)
|
||||
break;
|
||||
|
||||
/*
|
||||
* Wait for the next packet
|
||||
*/
|
||||
retryCount = 0;
|
||||
for (;;) {
|
||||
int len = getPacket (tp);
|
||||
if (len >= (int)sizeof tp->pkbuf.tftpACK) {
|
||||
int opcode = ntohs (tp->pkbuf.tftpDATA.opcode);
|
||||
rtems_unsigned16 nextBlock = tp->blocknum + 1;
|
||||
if ((opcode == TFTP_OPCODE_DATA)
|
||||
&& (ntohs (tp->pkbuf.tftpDATA.blocknum) == nextBlock)) {
|
||||
tp->nused = 0;
|
||||
tp->nleft = len - 2 * sizeof (rtems_unsigned16);
|
||||
tp->eof = (tp->nleft < TFTP_BUFSIZE);
|
||||
tp->blocknum++;
|
||||
if (sendAck (tp) != 0)
|
||||
return RTEMS_IO_ERROR;
|
||||
break;
|
||||
}
|
||||
if (opcode == TFTP_OPCODE_ERROR) {
|
||||
tftpSetErrno (tp);
|
||||
return RTEMS_INTERNAL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Keep trying?
|
||||
*/
|
||||
if (++retryCount == IO_RETRY_LIMIT)
|
||||
return RTEMS_IO_ERROR;
|
||||
if (sendAck (tp) != 0)
|
||||
return RTEMS_IO_ERROR;
|
||||
}
|
||||
}
|
||||
ap->bytes_moved = ap->count - nwant;
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
/*
|
||||
* Close a TFTP stream
|
||||
*/
|
||||
rtems_device_driver rtems_tftp_close(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
rtems_libio_open_close_args_t *ap = pargp;
|
||||
struct tftpStream *tp = ap->iop->data1;;
|
||||
|
||||
if (!tp->eof && !tp->firstReply) {
|
||||
/*
|
||||
* Tell the other end to stop
|
||||
*/
|
||||
rtems_interval ticksPerSecond;
|
||||
sendStifle (tp, &tp->farAddress);
|
||||
rtems_clock_get (RTEMS_CLOCK_GET_TICKS_PER_SECOND, &ticksPerSecond);
|
||||
rtems_task_wake_after (1 + ticksPerSecond / 10);
|
||||
}
|
||||
close (tp->socket);
|
||||
releaseStream (ap->iop->data0);
|
||||
return RTEMS_SUCCESSFUL;
|
||||
}
|
||||
|
||||
rtems_device_driver rtems_tftp_write(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
return RTEMS_NOT_CONFIGURED;
|
||||
}
|
||||
|
||||
rtems_device_driver rtems_tftp_control(
|
||||
rtems_device_major_number major,
|
||||
rtems_device_minor_number minor,
|
||||
void *pargp
|
||||
)
|
||||
{
|
||||
return RTEMS_NOT_CONFIGURED;
|
||||
}
|
||||
216
c/src/exec/libnetworking/libc/addr2ascii.3
Normal file
216
c/src/exec/libnetworking/libc/addr2ascii.3
Normal file
@@ -0,0 +1,216 @@
|
||||
.\"
|
||||
.\" Copyright 1996 Massachusetts Institute of Technology
|
||||
.\"
|
||||
.\" Permission to use, copy, modify, and distribute this software and
|
||||
.\" its documentation for any purpose and without fee is hereby
|
||||
.\" granted, provided that both the above copyright notice and this
|
||||
.\" permission notice appear in all copies, that both the above
|
||||
.\" copyright notice and this permission notice appear in all
|
||||
.\" supporting documentation, and that the name of M.I.T. not be used
|
||||
.\" in advertising or publicity pertaining to distribution of the
|
||||
.\" software without specific, written prior permission. M.I.T. makes
|
||||
.\" no representations about the suitability of this software for any
|
||||
.\" purpose. It is provided "as is" without express or implied
|
||||
.\" warranty.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
.\" ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
.\" INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
.\" MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
.\" SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
.\" SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
.\" LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
.\" USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
.\" ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
.\" OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
.\" OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $ANA: addr2ascii.3,v 1.1 1996/06/13 18:41:46 wollman Exp $
|
||||
.\"
|
||||
.Dd June 13, 1996
|
||||
.Dt ADDR2ASCII 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm addr2ascii ,
|
||||
.Nm ascii2addr
|
||||
.Nd Generic address formatting routines
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <netinet/in.h>
|
||||
.Fd #include <arpa/inet.h>
|
||||
.Ft "char *"
|
||||
.Fn addr2ascii "int af" "const void *addrp" "int len" "char *buf"
|
||||
.Ft int
|
||||
.Fn ascii2addr "int af" "const char *ascii" "void *result"
|
||||
.Sh DESCRIPTION
|
||||
The routines
|
||||
.Fn addr2ascii
|
||||
and
|
||||
.Fn ascii2addr
|
||||
are used to convert network addresses between binary form and a
|
||||
printable form appropriate to the address family. Both functions take
|
||||
an
|
||||
.Fa af
|
||||
argument, specifying the address family to be used in the conversion
|
||||
process.
|
||||
(Currently, only the
|
||||
.Dv AF_INET
|
||||
and
|
||||
.Dv AF_LINK
|
||||
address families are supported.)
|
||||
.Pp
|
||||
The
|
||||
.Fn addr2ascii
|
||||
function
|
||||
is used to convert binary, network-format addresses into printable
|
||||
form. In addition to
|
||||
.Fa af ,
|
||||
there are three other arguments. The
|
||||
.Fa addrp
|
||||
argument is a pointer to the network address to be converted.
|
||||
The
|
||||
.Fa len
|
||||
argument is the length of the address. The
|
||||
.Fa buf
|
||||
argument is an optional pointer to a caller-allocated buffer to hold
|
||||
the result; if a null pointer is passed,
|
||||
.Fn addr2ascii
|
||||
uses a statically-allocated buffer.
|
||||
.Pp
|
||||
The
|
||||
.Fn ascii2addr
|
||||
function performs the inverse operation to
|
||||
.Fn addr2ascii .
|
||||
In addition to
|
||||
.Fa af ,
|
||||
it takes two parameters,
|
||||
.Fa ascii
|
||||
and
|
||||
.Fa result .
|
||||
The
|
||||
.Fa ascii
|
||||
parameter is a pointer to the string which is to be converted into
|
||||
binary. The
|
||||
.Fa result
|
||||
parameter is a pointer to an appropriate network address structure for
|
||||
the specified family.
|
||||
.Pp
|
||||
The following gives the appropriate structure to use for binary
|
||||
addresses in the specified family:
|
||||
.Pp
|
||||
.Bl -tag -width AF_INETxxxx -compact
|
||||
.It Dv AF_INET
|
||||
.Li struct in_addr
|
||||
.Pq in Aq Pa netinet/in.h
|
||||
.It Dv AF_LINK
|
||||
.Li struct sockaddr_dl
|
||||
.Pq in Aq Pa net/if_dl.h
|
||||
.\" .It Dv AF_INET6
|
||||
.\" .Li struct in6_addr
|
||||
.\" .Pq in Aq Pa netinet6/in6.h
|
||||
.El
|
||||
.Sh RETURN VALUES
|
||||
The
|
||||
.Fn addr2ascii
|
||||
function returns the address of the buffer it was passed, or a static
|
||||
buffer if the a null pointer was passed; on failure, it returns a null
|
||||
pointer.
|
||||
The
|
||||
.Fn ascii2addr
|
||||
function returns the length of the binary address in bytes, or -1 on
|
||||
failure.
|
||||
.Sh EXAMPLES
|
||||
The
|
||||
.Xr inet 3
|
||||
functions
|
||||
.Fn inet_ntoa
|
||||
and
|
||||
.Fn inet_aton
|
||||
could be implemented thusly:
|
||||
.Bd -literal -offset indent
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
char *
|
||||
inet_ntoa(struct in_addr addr)
|
||||
{
|
||||
return addr2ascii(AF_INET, &addr, sizeof addr, 0);
|
||||
}
|
||||
|
||||
int
|
||||
inet_aton(const char *ascii, struct in_addr *addr)
|
||||
{
|
||||
return (ascii2addr(AF_INET, ascii, addr)
|
||||
== sizeof(*addr));
|
||||
}
|
||||
.Ed
|
||||
.Pp
|
||||
In actuality, this cannot be done because
|
||||
.Fn addr2ascii
|
||||
and
|
||||
.Fn ascii2addr
|
||||
are implemented in terms of the
|
||||
.Xr inet 3
|
||||
functions, rather than the other way around.
|
||||
.Sh ERRORS
|
||||
When a failure is returned,
|
||||
.Li errno
|
||||
is set to one of the following values:
|
||||
.Bl -tag -width [EPROTONOSUPPORT]
|
||||
.It Bq Er ENAMETOOLONG
|
||||
The
|
||||
.Fn addr2ascii
|
||||
routine was passed a
|
||||
.Fa len
|
||||
parameter which was inappropriate for the address family given by
|
||||
.Fa af .
|
||||
.It Bq Er EPROTONOSUPPORT
|
||||
Either routine was passed an
|
||||
.Fa af
|
||||
parameter other than
|
||||
.Dv AF_INET
|
||||
or
|
||||
.Dv AF_LINK .
|
||||
.It Bq Er EINVAL
|
||||
The string passed to
|
||||
.Fn ascii2addr
|
||||
was improperly formatted for address family
|
||||
.Fa af .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr inet 3 ,
|
||||
.Xr linkaddr 3 ,
|
||||
.Xr inet 4
|
||||
.Sh HISTORY
|
||||
An interface close to this one was originally suggested by Craig
|
||||
Partridge. This particular interface originally appeared in the
|
||||
.Tn INRIA
|
||||
.Tn IPv6
|
||||
implementation.
|
||||
.Sh AUTHORS
|
||||
Code and documentation by
|
||||
.An Garrett A. Wollman ,
|
||||
MIT Laboratory for Computer Science.
|
||||
.Sh BUGS
|
||||
The original implementations supported IPv6. This support should
|
||||
eventually be resurrected. The
|
||||
.Tn NRL
|
||||
implementation also included support for the
|
||||
.Dv AF_ISO
|
||||
and
|
||||
.Dv AF_NS
|
||||
address families.
|
||||
.Pp
|
||||
The genericity of this interface is somewhat questionable. A truly
|
||||
generic interface would provide a means for determining the length of
|
||||
the buffer to be used so that it could be dynamically allocated, and
|
||||
would always require a
|
||||
.Dq Li "struct sockaddr"
|
||||
to hold the binary address. Unfortunately, this is incompatible with existing
|
||||
practice. This limitation means that a routine for printing network
|
||||
addresses from arbitrary address families must still have internal
|
||||
knowledge of the maximum buffer length needed and the appropriate part
|
||||
of the address to use as the binary address.
|
||||
92
c/src/exec/libnetworking/libc/addr2ascii.c
Normal file
92
c/src/exec/libnetworking/libc/addr2ascii.c
Normal file
@@ -0,0 +1,92 @@
|
||||
/*
|
||||
* Copyright 1996 Massachusetts Institute of Technology
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that both the above copyright notice and this
|
||||
* permission notice appear in all copies, that both the above
|
||||
* copyright notice and this permission notice appear in all
|
||||
* supporting documentation, and that the name of M.I.T. not be used
|
||||
* in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. M.I.T. makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $ANA: addr2ascii.c,v 1.1 1996/06/13 18:41:46 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*-
|
||||
* Convert a network address from binary to printable numeric format.
|
||||
* This API is copied from INRIA's IPv6 implementation, but it is a
|
||||
* bit bogus in two ways:
|
||||
*
|
||||
* 1) There is no value in passing both an address family and
|
||||
* an address length; either one should imply the other,
|
||||
* or we should be passing sockaddrs instead.
|
||||
* 2) There should by contrast be /added/ a length for the buffer
|
||||
* that we pass in, so that programmers are spared the need to
|
||||
* manually calculate (read: ``guess'') the maximum length.
|
||||
*
|
||||
* Flash: the API is also the same in the NRL implementation, and seems to
|
||||
* be some sort of standard, so we appear to be stuck with both the bad
|
||||
* naming and the poor choice of arguments.
|
||||
*/
|
||||
char *
|
||||
addr2ascii(af, addrp, len, buf)
|
||||
int af;
|
||||
const void *addrp;
|
||||
int len; /* should be size_t XXX */
|
||||
char *buf; /* XXX should pass length of buffer */
|
||||
{
|
||||
static char staticbuf[64]; /* 64 for AF_LINK > 16 for AF_INET */
|
||||
|
||||
if (!buf)
|
||||
buf = staticbuf;
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
if (len != sizeof(struct in_addr)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return 0;
|
||||
}
|
||||
strcpy(buf, inet_ntoa(*(const struct in_addr *)addrp));
|
||||
break;
|
||||
|
||||
case AF_LINK:
|
||||
if (len != sizeof(struct sockaddr_dl)) {
|
||||
errno = ENAMETOOLONG;
|
||||
return 0;
|
||||
}
|
||||
strcpy(buf, link_ntoa((const struct sockaddr_dl *)addrp));
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EPROTONOSUPPORT;
|
||||
return 0;
|
||||
}
|
||||
return buf;
|
||||
}
|
||||
72
c/src/exec/libnetworking/libc/ascii2addr.c
Normal file
72
c/src/exec/libnetworking/libc/ascii2addr.c
Normal file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright 1996 Massachusetts Institute of Technology
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software and
|
||||
* its documentation for any purpose and without fee is hereby
|
||||
* granted, provided that both the above copyright notice and this
|
||||
* permission notice appear in all copies, that both the above
|
||||
* copyright notice and this permission notice appear in all
|
||||
* supporting documentation, and that the name of M.I.T. not be used
|
||||
* in advertising or publicity pertaining to distribution of the
|
||||
* software without specific, written prior permission. M.I.T. makes
|
||||
* no representations about the suitability of this software for any
|
||||
* purpose. It is provided "as is" without express or implied
|
||||
* warranty.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY M.I.T. ``AS IS''. M.I.T. DISCLAIMS
|
||||
* ALL EXPRESS OR IMPLIED WARRANTIES WITH REGARD TO THIS SOFTWARE,
|
||||
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT
|
||||
* SHALL M.I.T. BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
|
||||
* USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
|
||||
* ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
|
||||
* OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
|
||||
* OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $ANA: ascii2addr.c,v 1.2 1996/06/13 18:46:02 wollman Exp $
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <net/if_dl.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
int
|
||||
ascii2addr(af, ascii, result)
|
||||
int af;
|
||||
const char *ascii;
|
||||
void *result;
|
||||
{
|
||||
struct in_addr *ina;
|
||||
char strbuf[4*sizeof("123")]; /* long enough for V4 only */
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
ina = result;
|
||||
strbuf[0] = '\0';
|
||||
strncat(strbuf, ascii, (sizeof strbuf)-1);
|
||||
if (inet_aton(strbuf, ina))
|
||||
return sizeof(struct in_addr);
|
||||
errno = EINVAL;
|
||||
break;
|
||||
|
||||
case AF_LINK:
|
||||
link_addr(ascii, result);
|
||||
/* oops... no way to detect failure */
|
||||
return sizeof(struct sockaddr_dl);
|
||||
|
||||
default:
|
||||
errno = EPROTONOSUPPORT;
|
||||
break;
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
316
c/src/exec/libnetworking/libc/base64.c
Normal file
316
c/src/exec/libnetworking/libc/base64.c
Normal file
@@ -0,0 +1,316 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
#if !defined(LINT) && !defined(CODECENTER)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define Assert(Cond) if (!(Cond)) abort()
|
||||
|
||||
static const char Base64[] =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
static const char Pad64 = '=';
|
||||
|
||||
/* (From RFC1521 and draft-ietf-dnssec-secext-03.txt)
|
||||
The following encoding technique is taken from RFC 1521 by Borenstein
|
||||
and Freed. It is reproduced here in a slightly edited form for
|
||||
convenience.
|
||||
|
||||
A 65-character subset of US-ASCII is used, enabling 6 bits to be
|
||||
represented per printable character. (The extra 65th character, "=",
|
||||
is used to signify a special processing function.)
|
||||
|
||||
The encoding process represents 24-bit groups of input bits as output
|
||||
strings of 4 encoded characters. Proceeding from left to right, a
|
||||
24-bit input group is formed by concatenating 3 8-bit input groups.
|
||||
These 24 bits are then treated as 4 concatenated 6-bit groups, each
|
||||
of which is translated into a single digit in the base64 alphabet.
|
||||
|
||||
Each 6-bit group is used as an index into an array of 64 printable
|
||||
characters. The character referenced by the index is placed in the
|
||||
output string.
|
||||
|
||||
Table 1: The Base64 Alphabet
|
||||
|
||||
Value Encoding Value Encoding Value Encoding Value Encoding
|
||||
0 A 17 R 34 i 51 z
|
||||
1 B 18 S 35 j 52 0
|
||||
2 C 19 T 36 k 53 1
|
||||
3 D 20 U 37 l 54 2
|
||||
4 E 21 V 38 m 55 3
|
||||
5 F 22 W 39 n 56 4
|
||||
6 G 23 X 40 o 57 5
|
||||
7 H 24 Y 41 p 58 6
|
||||
8 I 25 Z 42 q 59 7
|
||||
9 J 26 a 43 r 60 8
|
||||
10 K 27 b 44 s 61 9
|
||||
11 L 28 c 45 t 62 +
|
||||
12 M 29 d 46 u 63 /
|
||||
13 N 30 e 47 v
|
||||
14 O 31 f 48 w (pad) =
|
||||
15 P 32 g 49 x
|
||||
16 Q 33 h 50 y
|
||||
|
||||
Special processing is performed if fewer than 24 bits are available
|
||||
at the end of the data being encoded. A full encoding quantum is
|
||||
always completed at the end of a quantity. When fewer than 24 input
|
||||
bits are available in an input group, zero bits are added (on the
|
||||
right) to form an integral number of 6-bit groups. Padding at the
|
||||
end of the data is performed using the '=' character.
|
||||
|
||||
Since all base64 input is an integral number of octets, only the
|
||||
-------------------------------------------------
|
||||
following cases can arise:
|
||||
|
||||
(1) the final quantum of encoding input is an integral
|
||||
multiple of 24 bits; here, the final unit of encoded
|
||||
output will be an integral multiple of 4 characters
|
||||
with no "=" padding,
|
||||
(2) the final quantum of encoding input is exactly 8 bits;
|
||||
here, the final unit of encoded output will be two
|
||||
characters followed by two "=" padding characters, or
|
||||
(3) the final quantum of encoding input is exactly 16 bits;
|
||||
here, the final unit of encoded output will be three
|
||||
characters followed by one "=" padding character.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_ntop(u_char const *src, size_t srclength, char *target, size_t targsize) {
|
||||
size_t datalength = 0;
|
||||
u_char input[3];
|
||||
u_char output[4];
|
||||
size_t i;
|
||||
|
||||
while (2 < srclength) {
|
||||
input[0] = *src++;
|
||||
input[1] = *src++;
|
||||
input[2] = *src++;
|
||||
srclength -= 3;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
output[3] = input[2] & 0x3f;
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
Assert(output[3] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Base64[output[3]];
|
||||
}
|
||||
|
||||
/* Now we worry about padding. */
|
||||
if (0 != srclength) {
|
||||
/* Get what's left. */
|
||||
input[0] = input[1] = input[2] = '\0';
|
||||
for (i = 0; i < srclength; i++)
|
||||
input[i] = *src++;
|
||||
|
||||
output[0] = input[0] >> 2;
|
||||
output[1] = ((input[0] & 0x03) << 4) + (input[1] >> 4);
|
||||
output[2] = ((input[1] & 0x0f) << 2) + (input[2] >> 6);
|
||||
Assert(output[0] < 64);
|
||||
Assert(output[1] < 64);
|
||||
Assert(output[2] < 64);
|
||||
|
||||
if (datalength + 4 > targsize)
|
||||
return (-1);
|
||||
target[datalength++] = Base64[output[0]];
|
||||
target[datalength++] = Base64[output[1]];
|
||||
if (srclength == 1)
|
||||
target[datalength++] = Pad64;
|
||||
else
|
||||
target[datalength++] = Base64[output[2]];
|
||||
target[datalength++] = Pad64;
|
||||
}
|
||||
if (datalength >= targsize)
|
||||
return (-1);
|
||||
target[datalength] = '\0'; /* Returned value doesn't count \0. */
|
||||
return (datalength);
|
||||
}
|
||||
|
||||
/* skips all whitespace anywhere.
|
||||
converts characters, four at a time, starting at (or after)
|
||||
src from base - 64 numbers into three 8 bit bytes in the target area.
|
||||
it returns the number of data bytes stored at the target, or -1 on error.
|
||||
*/
|
||||
|
||||
int
|
||||
b64_pton(src, target, targsize)
|
||||
char const *src;
|
||||
u_char *target;
|
||||
size_t targsize;
|
||||
{
|
||||
int tarindex, state, ch;
|
||||
char *pos;
|
||||
|
||||
state = 0;
|
||||
tarindex = 0;
|
||||
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (isspace(ch)) /* Skip whitespace anywhere. */
|
||||
continue;
|
||||
|
||||
if (ch == Pad64)
|
||||
break;
|
||||
|
||||
pos = strchr(Base64, ch);
|
||||
if (pos == 0) /* A non-base64 character. */
|
||||
return (-1);
|
||||
|
||||
switch (state) {
|
||||
case 0:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] = (pos - Base64) << 2;
|
||||
}
|
||||
state = 1;
|
||||
break;
|
||||
case 1:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 4;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x0f)
|
||||
<< 4 ;
|
||||
}
|
||||
tarindex++;
|
||||
state = 2;
|
||||
break;
|
||||
case 2:
|
||||
if (target) {
|
||||
if ((size_t)tarindex + 1 >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64) >> 2;
|
||||
target[tarindex+1] = ((pos - Base64) & 0x03)
|
||||
<< 6;
|
||||
}
|
||||
tarindex++;
|
||||
state = 3;
|
||||
break;
|
||||
case 3:
|
||||
if (target) {
|
||||
if ((size_t)tarindex >= targsize)
|
||||
return (-1);
|
||||
target[tarindex] |= (pos - Base64);
|
||||
}
|
||||
tarindex++;
|
||||
state = 0;
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* We are done decoding Base-64 chars. Let's see if we ended
|
||||
* on a byte boundary, and/or with erroneous trailing characters.
|
||||
*/
|
||||
|
||||
if (ch == Pad64) { /* We got a pad char. */
|
||||
ch = *src++; /* Skip it, get next. */
|
||||
switch (state) {
|
||||
case 0: /* Invalid = in first position */
|
||||
case 1: /* Invalid = in second position */
|
||||
return (-1);
|
||||
|
||||
case 2: /* Valid, means one byte of info */
|
||||
/* Skip any number of spaces. */
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
break;
|
||||
/* Make sure there is another trailing = sign. */
|
||||
if (ch != Pad64)
|
||||
return (-1);
|
||||
ch = *src++; /* Skip the = */
|
||||
/* Fall through to "single trailing =" case. */
|
||||
/* FALLTHROUGH */
|
||||
|
||||
case 3: /* Valid, means two bytes of info */
|
||||
/*
|
||||
* We know this char is an =. Is there anything but
|
||||
* whitespace after it?
|
||||
*/
|
||||
for ((void)NULL; ch != '\0'; ch = *src++)
|
||||
if (!isspace(ch))
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Now make sure for cases 2 and 3 that the "extra"
|
||||
* bits that slopped past the last full byte were
|
||||
* zeros. If we don't check them, they become a
|
||||
* subliminal channel.
|
||||
*/
|
||||
if (target && target[tarindex] != 0)
|
||||
return (-1);
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* We ended by seeing the end of the string. Make sure we
|
||||
* have no partial bytes lying around.
|
||||
*/
|
||||
if (state != 0)
|
||||
return (-1);
|
||||
}
|
||||
|
||||
return (tarindex);
|
||||
}
|
||||
76
c/src/exec/libnetworking/libc/byteorder.3
Normal file
76
c/src/exec/libnetworking/libc/byteorder.3
Normal file
@@ -0,0 +1,76 @@
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)byteorder.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt BYTEORDER 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm htonl ,
|
||||
.Nm htons ,
|
||||
.Nm ntohl ,
|
||||
.Nm ntohs
|
||||
.Nd convert values between host and network byte order
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/param.h>
|
||||
.Ft u_long
|
||||
.Fn htonl "u_long hostlong"
|
||||
.Ft u_short
|
||||
.Fn htons "u_short hostshort"
|
||||
.Ft u_long
|
||||
.Fn ntohl "u_long netlong"
|
||||
.Ft u_short
|
||||
.Fn ntohs "u_short netshort"
|
||||
.Sh DESCRIPTION
|
||||
These routines convert 16 and 32 bit quantities between network
|
||||
byte order and host byte order.
|
||||
On machines which have a byte order which is the same as the network
|
||||
order, routines are defined as null macros.
|
||||
.Pp
|
||||
These routines are most often used in conjunction with Internet
|
||||
addresses and ports as returned by
|
||||
.Xr gethostbyname 3
|
||||
and
|
||||
.Xr getservent 3 .
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr getservent 3
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm byteorder
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
On the
|
||||
.Tn VAX
|
||||
bytes are handled backwards from most everyone else in
|
||||
the world. This is not expected to be fixed in the near future.
|
||||
226
c/src/exec/libnetworking/libc/ether_addr.c
Normal file
226
c/src/exec/libnetworking/libc/ether_addr.c
Normal file
@@ -0,0 +1,226 @@
|
||||
/*
|
||||
* Copyright (c) 1995
|
||||
* Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by Bill Paul.
|
||||
* 4. Neither the name of the author nor the names of any co-contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* ethernet address conversion and lookup routines
|
||||
*
|
||||
* Written by Bill Paul <wpaul@ctr.columbia.edu>
|
||||
* Center for Telecommunications Research
|
||||
* Columbia University, New York City
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <paths.h>
|
||||
#include <sys/types.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/ethernet.h>
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#ifndef _PATH_ETHERS
|
||||
#define _PATH_ETHERS "/etc/ethers"
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Parse a string of text containing an ethernet address and hostname
|
||||
* and separate it into its component parts.
|
||||
*/
|
||||
int ether_line(l, e, hostname)
|
||||
char *l;
|
||||
struct ether_addr *e;
|
||||
char *hostname;
|
||||
{
|
||||
int i, o[6];
|
||||
|
||||
i = sscanf(l, "%x:%x:%x:%x:%x:%x %s", &o[0], &o[1], &o[2],
|
||||
&o[3], &o[4], &o[5],
|
||||
hostname);
|
||||
if (i != 7)
|
||||
return (i);
|
||||
|
||||
for (i=0; i<6; i++)
|
||||
e->octet[i] = o[i];
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert an ASCII representation of an ethernet address to
|
||||
* binary form.
|
||||
*/
|
||||
struct ether_addr *ether_aton(a)
|
||||
char *a;
|
||||
{
|
||||
int i;
|
||||
static struct ether_addr o;
|
||||
unsigned int o0, o1, o2, o3, o4, o5;
|
||||
|
||||
i = sscanf(a, "%x:%x:%x:%x:%x:%x", &o0, &o1, &o2, &o3, &o4, &o5);
|
||||
|
||||
if (i != 6)
|
||||
return (NULL);
|
||||
|
||||
o.octet[0]=o0;
|
||||
o.octet[1]=o1;
|
||||
o.octet[2]=o2;
|
||||
o.octet[3]=o3;
|
||||
o.octet[4]=o4;
|
||||
o.octet[5]=o5;
|
||||
|
||||
return ((struct ether_addr *)&o);
|
||||
}
|
||||
|
||||
/*
|
||||
* Convert a binary representation of an ethernet address to
|
||||
* an ASCII string.
|
||||
*/
|
||||
char *ether_ntoa(n)
|
||||
struct ether_addr *n;
|
||||
{
|
||||
int i;
|
||||
static char a[18];
|
||||
|
||||
i = sprintf(a,"%x:%x:%x:%x:%x:%x",n->octet[0],n->octet[1],n->octet[2],
|
||||
n->octet[3],n->octet[4],n->octet[5]);
|
||||
if (i < 11)
|
||||
return (NULL);
|
||||
return ((char *)&a);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map an ethernet address to a hostname. Use either /etc/ethers or
|
||||
* NIS/YP.
|
||||
*/
|
||||
|
||||
int ether_ntohost(hostname, e)
|
||||
char *hostname;
|
||||
struct ether_addr *e;
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ + 2];
|
||||
struct ether_addr local_ether;
|
||||
char local_host[MAXHOSTNAMELEN];
|
||||
#ifdef YP
|
||||
char *result;
|
||||
int resultlen;
|
||||
char *ether_a;
|
||||
char *yp_domain;
|
||||
#endif
|
||||
if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
|
||||
return (1);
|
||||
|
||||
while (fgets(buf,BUFSIZ,fp)) {
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
#ifdef YP
|
||||
if (buf[0] == '+') {
|
||||
if (yp_get_default_domain(&yp_domain))
|
||||
continue;
|
||||
ether_a = ether_ntoa(e);
|
||||
if (yp_match(yp_domain, "ethers.byaddr", ether_a,
|
||||
strlen(ether_a), &result, &resultlen)) {
|
||||
continue;
|
||||
}
|
||||
strncpy(buf, result, resultlen);
|
||||
buf[resultlen] = '\0';
|
||||
free(result);
|
||||
}
|
||||
#endif
|
||||
if (!ether_line(buf, &local_ether, local_host)) {
|
||||
if (!bcmp((char *)&local_ether.octet[0],
|
||||
(char *)&e->octet[0], 6)) {
|
||||
/* We have a match */
|
||||
strcpy(hostname, local_host);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map a hostname to an ethernet address using /etc/ethers or
|
||||
* NIS/YP.
|
||||
*/
|
||||
int ether_hostton(hostname, e)
|
||||
char *hostname;
|
||||
struct ether_addr *e;
|
||||
{
|
||||
FILE *fp;
|
||||
char buf[BUFSIZ + 2];
|
||||
struct ether_addr local_ether;
|
||||
char local_host[MAXHOSTNAMELEN];
|
||||
#ifdef YP
|
||||
char *result;
|
||||
int resultlen;
|
||||
char *yp_domain;
|
||||
#endif
|
||||
if ((fp = fopen(_PATH_ETHERS, "r")) == NULL)
|
||||
return (1);
|
||||
|
||||
while (fgets(buf,BUFSIZ,fp)) {
|
||||
if (buf[0] == '#')
|
||||
continue;
|
||||
#ifdef YP
|
||||
if (buf[0] == '+') {
|
||||
if (yp_get_default_domain(&yp_domain))
|
||||
continue;
|
||||
if (yp_match(yp_domain, "ethers.byname", hostname,
|
||||
strlen(hostname), &result, &resultlen)) {
|
||||
continue;
|
||||
}
|
||||
strncpy(buf, result, resultlen);
|
||||
buf[resultlen] = '\0';
|
||||
free(result);
|
||||
}
|
||||
#endif
|
||||
if (!ether_line(buf, &local_ether, local_host)) {
|
||||
if (!strcmp(hostname, local_host)) {
|
||||
/* We have a match */
|
||||
bcopy((char *)&local_ether.octet[0],
|
||||
(char *)&e->octet[0], 6);
|
||||
fclose(fp);
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return (1);
|
||||
}
|
||||
193
c/src/exec/libnetworking/libc/ethers.3
Normal file
193
c/src/exec/libnetworking/libc/ethers.3
Normal file
@@ -0,0 +1,193 @@
|
||||
.\" Copyright (c) 1995
|
||||
.\" Bill Paul <wpaul@ctr.columbia.edu>. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by Bill Paul.
|
||||
.\" 4. Neither the name of the author nor the names of any co-contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY Bill Paul AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd April 12, 1995
|
||||
.Dt ETHERS 3
|
||||
.Os FreeBSD 2.1
|
||||
.Sh NAME
|
||||
.Nm ethers ,
|
||||
.Nm ether_line ,
|
||||
.Nm ether_aton ,
|
||||
.Nm ether_ntoa ,
|
||||
.Nm ether_ntohost ,
|
||||
.Nm ether_hostton
|
||||
.Nd Ethernet address conversion and lookup routines
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <net/ethernet.h>
|
||||
.Ft int
|
||||
.Fn ether_line "char *l" "struct ether_addr *e" "char *hostname"
|
||||
.Ft struct ether_addr *
|
||||
.Fn ether_aton "char *a"
|
||||
.Ft char *
|
||||
.Fn ether_ntoa "struct ether_addr *n"
|
||||
.Ft int
|
||||
.Fn ether_ntohost "char *hostname" "struct ether_addr *e"
|
||||
.Ft int
|
||||
.Fn ether_hostton "char *hostname" "struct ether_addr *e"
|
||||
.Sh DESCRIPTION
|
||||
These functions operate on ethernet addresses using an
|
||||
.Ar ether_addr
|
||||
structure, which is defined in the header file
|
||||
.Aq Pa netinet/if_ether.h :
|
||||
.Bd -literal -offset indent
|
||||
/*
|
||||
* The number of bytes in an ethernet (MAC) address.
|
||||
*/
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/*
|
||||
* Structure of a 48-bit Ethernet address.
|
||||
*/
|
||||
struct ether_addr {
|
||||
u_char octet[ETHER_ADDR_LEN];
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The function
|
||||
.Fn ether_line
|
||||
scans
|
||||
.Ar l ,
|
||||
an
|
||||
.Tn ASCII
|
||||
string in
|
||||
.Xr ethers 5
|
||||
format and sets
|
||||
.Ar e
|
||||
to the ethernet address specified in the string and
|
||||
.Ar h
|
||||
to the hostname. This function is used to parse lines from
|
||||
.Pa /etc/ethers
|
||||
into their component parts.
|
||||
.Pp
|
||||
The
|
||||
.Fn ether_aton
|
||||
function converts an
|
||||
.Tn ASCII
|
||||
representation of an ethernet address into an
|
||||
.Ar ether_addr
|
||||
structure. Likewise,
|
||||
.Fn ether_ntoa
|
||||
converts an ethernet address specified as an
|
||||
.Ar ether_addr
|
||||
structure into an
|
||||
.Tn ASCII
|
||||
string.
|
||||
.Pp
|
||||
The
|
||||
.Fn ether_ntohost
|
||||
and
|
||||
.Fn ether_hostton
|
||||
functions map ethernet addresses to their corresponding hostnames
|
||||
as specified in the
|
||||
.Pa /etc/ethers
|
||||
database.
|
||||
.Fn ether_ntohost
|
||||
converts from ethernet address to hostname, and
|
||||
.Fn ether_hostton
|
||||
converts from hostname to ethernet address.
|
||||
.Sh RETURN VALUES
|
||||
.Fn ether_line
|
||||
returns zero on success and non-zero if it was unable to parse
|
||||
any part of the supplied line
|
||||
.Ar l .
|
||||
It returns the extracted ethernet address in the supplied
|
||||
.Ar ether_addr
|
||||
structure
|
||||
.Ar e
|
||||
and the hostname in the supplied string
|
||||
.Ar h .
|
||||
.Pp
|
||||
On success,
|
||||
.Fn ether_ntoa
|
||||
returns a pointer to a string containing an
|
||||
.Tn ASCII
|
||||
representation of an ethernet address. If it is unable to convert
|
||||
the supplied
|
||||
.Ar ether_addr
|
||||
structure, it returns a
|
||||
.Dv NULL
|
||||
pointer. Likewise,
|
||||
.Fn ether_aton
|
||||
returns a pointer to an
|
||||
.Ar ether_addr
|
||||
structure on success and a
|
||||
.Dv NULL
|
||||
pointer on failure.
|
||||
.Pp
|
||||
The
|
||||
.Fn ether_ntohost
|
||||
and
|
||||
.Fn ether_hostton
|
||||
functions both return zero on success or non-zero if they were
|
||||
unable to find a match in the
|
||||
.Pa /etc/ethers
|
||||
database.
|
||||
.Sh NOTES
|
||||
The user must insure that the hostname strings passed to the
|
||||
the
|
||||
.Fn ether_line ,
|
||||
.Fn ether_ntohost
|
||||
and
|
||||
.Fn ether_hostton
|
||||
functions are large enough to contain the returned hostnames.
|
||||
.Sh NIS INTERACTION
|
||||
If the
|
||||
.Pa /etc/ethers
|
||||
contains a line with a single + in it, the
|
||||
.Fn ether_ntohost
|
||||
and
|
||||
.Fn ether_hostton
|
||||
functions will attempt to consult the NIS
|
||||
.Pa ethers.byname
|
||||
and
|
||||
.Pa ethers.byaddr
|
||||
maps in addition to the data in the
|
||||
.Pa /etc/ethers
|
||||
file.
|
||||
.Sh SEE ALSO
|
||||
.Xr yp 4 ,
|
||||
.Xr ethers 5
|
||||
.Sh BUGS
|
||||
.Pp
|
||||
The
|
||||
.Fn ether_aton
|
||||
and
|
||||
.Fn ether_ntoa
|
||||
functions returns values that are stored in static memory areas
|
||||
which may be overwritten the next time they are called.
|
||||
.Sh HISTORY
|
||||
This particular implementation of the
|
||||
.Nm ethers
|
||||
library functions were written for and first appeared in
|
||||
.Fx 2.1 .
|
||||
773
c/src/exec/libnetworking/libc/gethostbydns.c
Normal file
773
c/src/exec/libnetworking/libc/gethostbydns.c
Normal file
@@ -0,0 +1,773 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
|
||||
static char fromrcsid[] = "From: Id: gethnamaddr.c,v 8.23 1998/04/07 04:59:46 vixie Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
static const char AskedForGot[] =
|
||||
"gethostby*.gethostanswer: asked for \"%s\", got \"%s\"";
|
||||
|
||||
static char *h_addr_ptrs[MAXADDRS + 1];
|
||||
|
||||
static struct hostent host;
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static char hostbuf[8*1024];
|
||||
static u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static void addrsort __P((char **, int));
|
||||
#endif
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
typedef union {
|
||||
int32_t al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
extern int h_errno;
|
||||
int _dns_ttl_;
|
||||
|
||||
#ifdef DEBUG
|
||||
static void
|
||||
dprintf(msg, num)
|
||||
char *msg;
|
||||
int num;
|
||||
{
|
||||
if (_res.options & RES_DEBUG) {
|
||||
int save = errno;
|
||||
|
||||
printf(msg, num);
|
||||
errno = save;
|
||||
}
|
||||
}
|
||||
#else
|
||||
# define dprintf(msg, num) /*nada*/
|
||||
#endif
|
||||
|
||||
#define BOUNDED_INCR(x) \
|
||||
do { \
|
||||
cp += x; \
|
||||
if (cp > eom) { \
|
||||
h_errno = NO_RECOVERY; \
|
||||
return (NULL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define BOUNDS_CHECK(ptr, count) \
|
||||
do { \
|
||||
if ((ptr) + (count) > eom) { \
|
||||
h_errno = NO_RECOVERY; \
|
||||
return (NULL); \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
static struct hostent *
|
||||
gethostanswer(answer, anslen, qname, qtype)
|
||||
const querybuf *answer;
|
||||
int anslen;
|
||||
const char *qname;
|
||||
int qtype;
|
||||
{
|
||||
register const HEADER *hp;
|
||||
register const u_char *cp;
|
||||
register int n;
|
||||
const u_char *eom, *erdata;
|
||||
char *bp, **ap, **hap;
|
||||
int type, class, buflen, ancount, qdcount;
|
||||
int haveanswer, had_error;
|
||||
int toobig = 0;
|
||||
char tbuf[MAXDNAME];
|
||||
const char *tname;
|
||||
int (*name_ok) __P((const char *));
|
||||
|
||||
tname = qname;
|
||||
host.h_name = NULL;
|
||||
eom = answer->buf + anslen;
|
||||
switch (qtype) {
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
name_ok = res_hnok;
|
||||
break;
|
||||
case T_PTR:
|
||||
name_ok = res_dnok;
|
||||
break;
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL); /* XXX should be abort(); */
|
||||
}
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*/
|
||||
hp = &answer->hdr;
|
||||
ancount = ntohs(hp->ancount);
|
||||
qdcount = ntohs(hp->qdcount);
|
||||
bp = hostbuf;
|
||||
buflen = sizeof hostbuf;
|
||||
cp = answer->buf;
|
||||
BOUNDED_INCR(HFIXEDSZ);
|
||||
if (qdcount != 1) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
BOUNDED_INCR(n + QFIXEDSZ);
|
||||
if (qtype == T_A || qtype == T_AAAA) {
|
||||
/* res_send() has already verified that the query name is the
|
||||
* same as the one we sent; this just gets the expanded name
|
||||
* (i.e., with the succeeding search-domain tacked on).
|
||||
*/
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* The qname can be abbreviated, but h_name is now absolute. */
|
||||
qname = host.h_name;
|
||||
}
|
||||
ap = host_aliases;
|
||||
*ap = NULL;
|
||||
host.h_aliases = host_aliases;
|
||||
hap = h_addr_ptrs;
|
||||
*hap = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
haveanswer = 0;
|
||||
had_error = 0;
|
||||
_dns_ttl_ = -1;
|
||||
while (ancount-- > 0 && cp < eom && !had_error) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
if ((n < 0) || !(*name_ok)(bp)) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
cp += n; /* name */
|
||||
BOUNDS_CHECK(cp, 3 * INT16SZ + INT32SZ);
|
||||
type = _getshort(cp);
|
||||
cp += INT16SZ; /* type */
|
||||
class = _getshort(cp);
|
||||
cp += INT16SZ; /* class */
|
||||
if (qtype == T_A && type == T_A)
|
||||
_dns_ttl_ = _getlong(cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
n = _getshort(cp);
|
||||
cp += INT16SZ; /* len */
|
||||
BOUNDS_CHECK(cp, n);
|
||||
erdata = cp + n;
|
||||
if (class != C_IN) {
|
||||
/* XXX - debug? syslog? */
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
if ((qtype == T_A || qtype == T_AAAA) && type == T_CNAME) {
|
||||
if (ap >= &host_aliases[MAXALIASES-1])
|
||||
continue;
|
||||
n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
|
||||
if ((n < 0) || !(*name_ok)(tbuf)) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
/* Store alias. */
|
||||
*ap++ = bp;
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (qtype == T_PTR && type == T_CNAME) {
|
||||
n = dn_expand(answer->buf, eom, cp, tbuf, sizeof tbuf);
|
||||
if (n < 0 || !res_dnok(tbuf)) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
/* Get canonical name. */
|
||||
n = strlen(tbuf) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
strcpy(bp, tbuf);
|
||||
tname = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
continue;
|
||||
}
|
||||
if (type != qtype) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostby*.gethostanswer: asked for \"%s %s %s\", got type \"%s\"",
|
||||
qname, p_class(C_IN), p_type(qtype),
|
||||
p_type(type));
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
switch (type) {
|
||||
case T_PTR:
|
||||
if (strcasecmp(tname, bp) != 0) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
AskedForGot, qname, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
had_error++;
|
||||
break;
|
||||
}
|
||||
#if MULTI_PTRS_ARE_ALIASES
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
if (!haveanswer)
|
||||
host.h_name = bp;
|
||||
else if (ap < &host_aliases[MAXALIASES-1])
|
||||
*ap++ = bp;
|
||||
else
|
||||
n = -1;
|
||||
if (n != -1) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
break;
|
||||
#else
|
||||
host.h_name = bp;
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
n = strlen(bp) + 1; /* for the \0 */
|
||||
if (n >= MAXHOSTNAMELEN) {
|
||||
had_error++;
|
||||
break;
|
||||
}
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
_map_v4v6_hostent(&host, &bp, &buflen);
|
||||
}
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
#endif
|
||||
case T_A:
|
||||
case T_AAAA:
|
||||
if (strcasecmp(host.h_name, bp) != 0) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
AskedForGot, host.h_name, bp);
|
||||
cp += n;
|
||||
continue; /* XXX - had_error++ ? */
|
||||
}
|
||||
if (n != host.h_length) {
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
if (!haveanswer) {
|
||||
register int nn;
|
||||
|
||||
host.h_name = bp;
|
||||
nn = strlen(bp) + 1; /* for the \0 */
|
||||
bp += nn;
|
||||
buflen -= nn;
|
||||
}
|
||||
|
||||
bp += sizeof(align) - ((u_long)bp % sizeof(align));
|
||||
|
||||
if (bp + n >= &hostbuf[sizeof hostbuf]) {
|
||||
dprintf("size (%d) too big\n", n);
|
||||
had_error++;
|
||||
continue;
|
||||
}
|
||||
if (hap >= &h_addr_ptrs[MAXADDRS-1]) {
|
||||
if (!toobig++)
|
||||
dprintf("Too many addresses (%d)\n",
|
||||
MAXADDRS);
|
||||
cp += n;
|
||||
continue;
|
||||
}
|
||||
bcopy(cp, *hap++ = bp, n);
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
cp += n;
|
||||
if (cp != erdata) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
break;
|
||||
default:
|
||||
dprintf("Impossible condition (type=%d)\n", type);
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
/* BIND has abort() here, too risky on bad data */
|
||||
}
|
||||
if (!had_error)
|
||||
haveanswer++;
|
||||
}
|
||||
if (haveanswer) {
|
||||
*ap = NULL;
|
||||
*hap = NULL;
|
||||
# if defined(RESOLVSORT)
|
||||
/*
|
||||
* Note: we sort even if host can take only one address
|
||||
* in its return structures - should give it the "best"
|
||||
* address in that case, not some random one
|
||||
*/
|
||||
if (_res.nsort && haveanswer > 1 && qtype == T_A)
|
||||
addrsort(h_addr_ptrs, haveanswer);
|
||||
# endif /*RESOLVSORT*/
|
||||
if (!host.h_name) {
|
||||
n = strlen(qname) + 1; /* for the \0 */
|
||||
if (n > buflen || n >= MAXHOSTNAMELEN)
|
||||
goto no_recovery;
|
||||
strcpy(bp, qname);
|
||||
host.h_name = bp;
|
||||
bp += n;
|
||||
buflen -= n;
|
||||
}
|
||||
if (_res.options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(&host, &bp, &buflen);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
}
|
||||
no_recovery:
|
||||
h_errno = NO_RECOVERY;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
__dns_getanswer(answer, anslen, qname, qtype)
|
||||
const char *answer;
|
||||
int anslen;
|
||||
const char *qname;
|
||||
int qtype;
|
||||
{
|
||||
switch(qtype) {
|
||||
case T_AAAA:
|
||||
host.h_addrtype = AF_INET6;
|
||||
host.h_length = IN6ADDRSZ;
|
||||
break;
|
||||
case T_A:
|
||||
default:
|
||||
host.h_addrtype = AF_INET;
|
||||
host.h_length = INADDRSZ;
|
||||
break;
|
||||
}
|
||||
|
||||
return(gethostanswer((const querybuf *)answer, anslen, qname, qtype));
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbydnsname(name, af)
|
||||
const char *name;
|
||||
int af;
|
||||
{
|
||||
querybuf buf;
|
||||
register const char *cp;
|
||||
char *bp;
|
||||
int n, size, type, len;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
type = T_A;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
type = T_AAAA;
|
||||
break;
|
||||
default:
|
||||
h_errno = NETDB_INTERNAL;
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
host.h_addrtype = af;
|
||||
host.h_length = size;
|
||||
|
||||
/*
|
||||
* if there aren't any dots, it could be a user-level alias.
|
||||
* this is also done in res_query() since we are not the only
|
||||
* function that looks up host names.
|
||||
*/
|
||||
if (!strchr(name, '.') && (cp = __hostalias(name)))
|
||||
name = cp;
|
||||
|
||||
/*
|
||||
* disallow names consisting only of digits/dots, unless
|
||||
* they end in a dot.
|
||||
*/
|
||||
if (isdigit(name[0]))
|
||||
for (cp = name;; ++cp) {
|
||||
if (!*cp) {
|
||||
if (*--cp == '.')
|
||||
break;
|
||||
/*
|
||||
* All-numeric, no dot at the end.
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
}
|
||||
strncpy(hostbuf, name, MAXDNAME);
|
||||
hostbuf[MAXDNAME] = '\0';
|
||||
bp = hostbuf + MAXDNAME;
|
||||
len = sizeof hostbuf - MAXDNAME;
|
||||
host.h_name = hostbuf;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
if (_res.options & RES_USE_INET6)
|
||||
_map_v4v6_hostent(&host, &bp, &len);
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
}
|
||||
if (!isdigit(*cp) && *cp != '.')
|
||||
break;
|
||||
}
|
||||
if ((isxdigit(name[0]) && strchr(name, ':') != NULL) ||
|
||||
name[0] == ':')
|
||||
for (cp = name;; ++cp) {
|
||||
if (!*cp) {
|
||||
if (*--cp == '.')
|
||||
break;
|
||||
/*
|
||||
* All-IPv6-legal, no dot at the end.
|
||||
* Fake up a hostent as if we'd actually
|
||||
* done a lookup.
|
||||
*/
|
||||
if (inet_pton(af, name, host_addr) <= 0) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
}
|
||||
strncpy(hostbuf, name, MAXDNAME);
|
||||
hostbuf[MAXDNAME] = '\0';
|
||||
bp = hostbuf + MAXDNAME;
|
||||
len = sizeof hostbuf - MAXDNAME;
|
||||
host.h_name = hostbuf;
|
||||
host.h_aliases = host_aliases;
|
||||
host_aliases[0] = NULL;
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
}
|
||||
if (!isxdigit(*cp) && *cp != ':' && *cp != '.')
|
||||
break;
|
||||
}
|
||||
|
||||
if ((n = res_search(name, C_IN, type, buf.buf, sizeof(buf))) < 0) {
|
||||
dprintf("res_search failed (%d)\n", n);
|
||||
return (NULL);
|
||||
}
|
||||
return (gethostanswer(&buf, n, name, type));
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbydnsaddr(addr, len, af)
|
||||
const char *addr; /* XXX should have been def'd as u_char! */
|
||||
int len, af;
|
||||
{
|
||||
const u_char *uaddr = (const u_char *)addr;
|
||||
static const u_char mapped[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0xff,0xff };
|
||||
static const u_char tunnelled[] = { 0,0, 0,0, 0,0, 0,0, 0,0, 0,0 };
|
||||
int n, size;
|
||||
querybuf buf;
|
||||
register struct hostent *hp;
|
||||
char qbuf[MAXDNAME+1], *qp;
|
||||
#ifdef SUNSECURITY
|
||||
register struct hostent *rhp;
|
||||
char **haddr;
|
||||
u_long old_options;
|
||||
char hname2[MAXDNAME+1];
|
||||
#endif /*SUNSECURITY*/
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (af == AF_INET6 && len == IN6ADDRSZ &&
|
||||
(!bcmp(uaddr, mapped, sizeof mapped) ||
|
||||
!bcmp(uaddr, tunnelled, sizeof tunnelled))) {
|
||||
/* Unmap. */
|
||||
addr += sizeof mapped;
|
||||
uaddr += sizeof mapped;
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
size = INADDRSZ;
|
||||
break;
|
||||
case AF_INET6:
|
||||
size = IN6ADDRSZ;
|
||||
break;
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (size != len) {
|
||||
errno = EINVAL;
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
(void) sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa",
|
||||
(uaddr[3] & 0xff),
|
||||
(uaddr[2] & 0xff),
|
||||
(uaddr[1] & 0xff),
|
||||
(uaddr[0] & 0xff));
|
||||
break;
|
||||
case AF_INET6:
|
||||
qp = qbuf;
|
||||
for (n = IN6ADDRSZ - 1; n >= 0; n--) {
|
||||
qp += SPRINTF((qp, "%x.%x.",
|
||||
uaddr[n] & 0xf,
|
||||
(uaddr[n] >> 4) & 0xf));
|
||||
}
|
||||
strcpy(qp, "ip6.int");
|
||||
break;
|
||||
default:
|
||||
abort();
|
||||
}
|
||||
n = res_query(qbuf, C_IN, T_PTR, (u_char *)buf.buf, sizeof buf.buf);
|
||||
if (n < 0) {
|
||||
dprintf("res_query failed (%d)\n", n);
|
||||
return (NULL);
|
||||
}
|
||||
if (!(hp = gethostanswer(&buf, n, qbuf, T_PTR)))
|
||||
return (NULL); /* h_errno was set by gethostanswer() */
|
||||
#ifdef SUNSECURITY
|
||||
if (af == AF_INET) {
|
||||
/*
|
||||
* turn off search as the name should be absolute,
|
||||
* 'localhost' should be matched by defnames
|
||||
*/
|
||||
strncpy(hname2, hp->h_name, MAXDNAME);
|
||||
hname2[MAXDNAME] = '\0';
|
||||
old_options = _res.options;
|
||||
_res.options &= ~RES_DNSRCH;
|
||||
_res.options |= RES_DEFNAMES;
|
||||
if (!(rhp = gethostbyname(hname2))) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: No A record for %s (verifying [%s])",
|
||||
hname2, inet_ntoa(*((struct in_addr *)addr)));
|
||||
_res.options = old_options;
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
}
|
||||
_res.options = old_options;
|
||||
for (haddr = rhp->h_addr_list; *haddr; haddr++)
|
||||
if (!memcmp(*haddr, addr, INADDRSZ))
|
||||
break;
|
||||
if (!*haddr) {
|
||||
syslog(LOG_NOTICE|LOG_AUTH,
|
||||
"gethostbyaddr: A record of %s != PTR record [%s]",
|
||||
hname2, inet_ntoa(*((struct in_addr *)addr)));
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
#endif /*SUNSECURITY*/
|
||||
hp->h_addrtype = af;
|
||||
hp->h_length = len;
|
||||
bcopy(addr, host_addr, len);
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
if (af == AF_INET && (_res.options & RES_USE_INET6)) {
|
||||
_map_v4v6_address((char*)host_addr, (char*)host_addr);
|
||||
hp->h_addrtype = AF_INET6;
|
||||
hp->h_length = IN6ADDRSZ;
|
||||
}
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (hp);
|
||||
}
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static void
|
||||
addrsort(ap, num)
|
||||
char **ap;
|
||||
int num;
|
||||
{
|
||||
int i, j;
|
||||
char **p;
|
||||
short aval[MAXADDRS];
|
||||
int needsort = 0;
|
||||
|
||||
p = ap;
|
||||
for (i = 0; i < num; i++, p++) {
|
||||
for (j = 0 ; (unsigned)j < _res.nsort; j++)
|
||||
if (_res.sort_list[j].addr.s_addr ==
|
||||
(((struct in_addr *)(*p))->s_addr & _res.sort_list[j].mask))
|
||||
break;
|
||||
aval[i] = j;
|
||||
if (needsort == 0 && i > 0 && j < aval[i-1])
|
||||
needsort = i;
|
||||
}
|
||||
if (!needsort)
|
||||
return;
|
||||
|
||||
while (needsort < num) {
|
||||
for (j = needsort - 1; j >= 0; j--) {
|
||||
if (aval[j] > aval[j+1]) {
|
||||
char *hp;
|
||||
|
||||
i = aval[j];
|
||||
aval[j] = aval[j+1];
|
||||
aval[j+1] = i;
|
||||
|
||||
hp = ap[j];
|
||||
ap[j] = ap[j+1];
|
||||
ap[j+1] = hp;
|
||||
|
||||
} else
|
||||
break;
|
||||
}
|
||||
needsort++;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
void
|
||||
_sethostdnsent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return;
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
void
|
||||
_endhostdnsent()
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_close();
|
||||
}
|
||||
202
c/src/exec/libnetworking/libc/gethostbyht.c
Normal file
202
c/src/exec/libnetworking/libc/gethostbyht.c
Normal file
@@ -0,0 +1,202 @@
|
||||
/*-
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/nameser.h> /* XXX */
|
||||
#include <resolv.h> /* XXX */
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static struct hostent host;
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static char hostbuf[BUFSIZ+1];
|
||||
static FILE *hostf = NULL;
|
||||
static u_char host_addr[16]; /* IPv4 or IPv6 */
|
||||
static char *h_addr_ptrs[2];
|
||||
static int stayopen = 0;
|
||||
|
||||
void
|
||||
_sethosthtent(f)
|
||||
int f;
|
||||
{
|
||||
if (!hostf)
|
||||
hostf = fopen(_PATH_HOSTS, "r" );
|
||||
else
|
||||
rewind(hostf);
|
||||
stayopen = f;
|
||||
}
|
||||
|
||||
void
|
||||
_endhosthtent()
|
||||
{
|
||||
if (hostf && !stayopen) {
|
||||
(void) fclose(hostf);
|
||||
hostf = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
int af, len;
|
||||
|
||||
if (!hostf && !(hostf = fopen(_PATH_HOSTS, "r" ))) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
again:
|
||||
if (!(p = fgets(hostbuf, sizeof hostbuf, hostf))) {
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
return (NULL);
|
||||
}
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
if (!(cp = strpbrk(p, "#\n")))
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
if (!(cp = strpbrk(p, " \t")))
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
if (inet_pton(AF_INET6, p, host_addr) > 0) {
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else if (inet_pton(AF_INET, p, host_addr) > 0) {
|
||||
if (_res.options & RES_USE_INET6) {
|
||||
_map_v4v6_address((char*)host_addr, (char*)host_addr);
|
||||
af = AF_INET6;
|
||||
len = IN6ADDRSZ;
|
||||
} else {
|
||||
af = AF_INET;
|
||||
len = INADDRSZ;
|
||||
}
|
||||
} else {
|
||||
goto again;
|
||||
}
|
||||
h_addr_ptrs[0] = (char *)host_addr;
|
||||
h_addr_ptrs[1] = NULL;
|
||||
host.h_addr_list = h_addr_ptrs;
|
||||
host.h_length = len;
|
||||
host.h_addrtype = af;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
host.h_name = cp;
|
||||
q = host.h_aliases = host_aliases;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
if ((cp = strpbrk(cp, " \t")) != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
h_errno = NETDB_SUCCESS;
|
||||
return (&host);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbyhtname(name, af)
|
||||
const char *name;
|
||||
int af;
|
||||
{
|
||||
register struct hostent *p;
|
||||
register char **cp;
|
||||
|
||||
sethostent(0);
|
||||
while ((p = gethostent()) != NULL) {
|
||||
if (p->h_addrtype != af)
|
||||
continue;
|
||||
if (strcasecmp(p->h_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->h_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
endhostent();
|
||||
return (p);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbyhtaddr(addr, len, af)
|
||||
const char *addr;
|
||||
int len, af;
|
||||
{
|
||||
register struct hostent *p;
|
||||
|
||||
sethostent(0);
|
||||
while ((p = gethostent()) != NULL)
|
||||
if (p->h_addrtype == af && !bcmp(p->h_addr, addr, len))
|
||||
break;
|
||||
endhostent();
|
||||
return (p);
|
||||
}
|
||||
305
c/src/exec/libnetworking/libc/gethostbyname.3
Normal file
305
c/src/exec/libnetworking/libc/gethostbyname.3
Normal file
@@ -0,0 +1,305 @@
|
||||
.\" Copyright (c) 1983, 1987, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" From: @(#)gethostbyname.3 8.4 (Berkeley) 5/25/95
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd May 25, 1995
|
||||
.Dt GETHOSTBYNAME 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm gethostbyname ,
|
||||
.Nm gethostbyname2 ,
|
||||
.Nm gethostbyaddr ,
|
||||
.Nm gethostent ,
|
||||
.Nm sethostent ,
|
||||
.Nm endhostent ,
|
||||
.Nm herror ,
|
||||
.Nm hstrerror
|
||||
.Nd get network host entry
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netdb.h>
|
||||
.Vt extern int h_errno;
|
||||
.Ft struct hostent *
|
||||
.Fn gethostbyname "const char *name"
|
||||
.Ft struct hostent *
|
||||
.Fn gethostbyname2 "const char *name" "int af"
|
||||
.Ft struct hostent *
|
||||
.Fn gethostbyaddr "const char *addr" "int len" "int type"
|
||||
.Ft struct hostent *
|
||||
.Fn gethostent void
|
||||
.Ft void
|
||||
.Fn sethostent "int stayopen"
|
||||
.Ft void
|
||||
.Fn endhostent void
|
||||
.Ft void
|
||||
.Fn herror "const char *string"
|
||||
.Ft const char *
|
||||
.Fn hstrerror "int err"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostbyname2
|
||||
and
|
||||
.Fn gethostbyaddr
|
||||
functions
|
||||
each return a pointer to an object with the
|
||||
following structure describing an internet host
|
||||
referenced by name or by address, respectively.
|
||||
This structure contains either the information obtained from the name server,
|
||||
.Xr named 8 ,
|
||||
or broken-out fields from a line in
|
||||
.Pa /etc/hosts .
|
||||
If the local name server is not running these routines do a lookup in
|
||||
.Pa /etc/hosts .
|
||||
.Bd -literal
|
||||
struct hostent {
|
||||
char *h_name; /* official name of host */
|
||||
char **h_aliases; /* alias list */
|
||||
int h_addrtype; /* host address type */
|
||||
int h_length; /* length of address */
|
||||
char **h_addr_list; /* list of addresses from name server */
|
||||
};
|
||||
#define h_addr h_addr_list[0] /* address, for backward compatibility */
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width h_addr_list
|
||||
.It Fa h_name
|
||||
Official name of the host.
|
||||
.It Fa h_aliases
|
||||
A NULL-terminated array of alternate names for the host.
|
||||
.It Fa h_addrtype
|
||||
The type of address being returned; usually
|
||||
.Dv AF_INET .
|
||||
.It Fa h_length
|
||||
The length, in bytes, of the address.
|
||||
.It Fa h_addr_list
|
||||
A NULL-terminated array of network addresses for the host.
|
||||
Host addresses are returned in network byte order.
|
||||
.It Fa h_addr
|
||||
The first address in
|
||||
.Fa h_addr_list ;
|
||||
this is for backward compatibility.
|
||||
.El
|
||||
.Pp
|
||||
When using the nameserver,
|
||||
.Fn gethostbyname
|
||||
and
|
||||
.Fn gethostbyname
|
||||
will search for the named host in the current domain and its parents
|
||||
unless the name ends in a dot.
|
||||
If the name contains no dot, and if the environment variable
|
||||
.Dq Ev HOSTALIASES
|
||||
contains the name of an alias file, the alias file will first be searched
|
||||
for an alias matching the input name.
|
||||
See
|
||||
.Xr hostname 7
|
||||
for the domain search procedure and the alias file format.
|
||||
.Pp
|
||||
The
|
||||
.Fn gethostbyname2
|
||||
function is an evolution of
|
||||
.Fn gethostbyname
|
||||
which is intended to allow lookups in address families other than
|
||||
.Dv AF_INET ,
|
||||
for example
|
||||
.Dv AF_INET6 .
|
||||
Currently the
|
||||
.Fa af
|
||||
argument must be specified as
|
||||
.Dv AF_INET
|
||||
else the function will return
|
||||
.Dv NULL
|
||||
after having set
|
||||
.Va h_errno
|
||||
to
|
||||
.Dv NETDB_INTERNAL
|
||||
.Pp
|
||||
The
|
||||
.Fn sethostent
|
||||
function
|
||||
may be used to request the use of a connected
|
||||
.Tn TCP
|
||||
socket for queries.
|
||||
If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
this sets the option to send all queries to the name server using
|
||||
.Tn TCP
|
||||
and to retain the connection after each call to
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostbyname2
|
||||
or
|
||||
.Fn gethostbyaddr .
|
||||
Otherwise, queries are performed using
|
||||
.Tn UDP
|
||||
datagrams.
|
||||
.Pp
|
||||
The
|
||||
.Fn endhostent
|
||||
function
|
||||
closes the
|
||||
.Tn TCP
|
||||
connection.
|
||||
.Pp
|
||||
The
|
||||
.Fn herror
|
||||
function writes a message to the diagnostic output consisting of the
|
||||
string parameter
|
||||
.Fa s ,
|
||||
the constant string ": ", and a message corresponding to the value of
|
||||
.Va h_errno .
|
||||
.Pp
|
||||
The
|
||||
.Fn hstrerror
|
||||
function returns a string which is the message text corresponding to the
|
||||
value of the
|
||||
.Fa err
|
||||
parameter.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/resolv.conf -compact
|
||||
.It Pa /etc/hosts
|
||||
.It Pa /etc/host.conf
|
||||
.It Pa /etc/resolv.conf
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Error return status from
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostbyname2
|
||||
and
|
||||
.Fn gethostbyaddr
|
||||
is indicated by return of a null pointer.
|
||||
The external integer
|
||||
.Va h_errno
|
||||
may then be checked to see whether this is a temporary failure
|
||||
or an invalid or unknown host.
|
||||
The routine
|
||||
.Fn herror
|
||||
can be used to print an error message describing the failure.
|
||||
If its argument
|
||||
.Fa string
|
||||
is
|
||||
.Pf non Dv -NULL ,
|
||||
it is printed, followed by a colon and a space.
|
||||
The error message is printed with a trailing newline.
|
||||
.Pp
|
||||
The variable
|
||||
.Va h_errno
|
||||
can have the following values:
|
||||
.Bl -tag -width HOST_NOT_FOUND
|
||||
.It Dv HOST_NOT_FOUND
|
||||
No such host is known.
|
||||
.It Dv TRY_AGAIN
|
||||
This is usually a temporary error
|
||||
and means that the local server did not receive
|
||||
a response from an authoritative server.
|
||||
A retry at some later time may succeed.
|
||||
.It Dv NO_RECOVERY
|
||||
Some unexpected server failure was encountered.
|
||||
This is a non-recoverable error.
|
||||
.It Dv NO_DATA
|
||||
The requested name is valid but does not have an IP address;
|
||||
this is not a temporary error.
|
||||
This means that the name is known to the name server but there is no address
|
||||
associated with this name.
|
||||
Another type of request to the name server using this domain name
|
||||
will result in an answer;
|
||||
for example, a mail-forwarder may be registered for this domain.
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr resolver 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr hostname 7 ,
|
||||
.Xr named 8
|
||||
.Sh CAVEAT
|
||||
The
|
||||
.Fn gethostent
|
||||
function
|
||||
is defined, and
|
||||
.Fn sethostent
|
||||
and
|
||||
.Fn endhostent
|
||||
are redefined,
|
||||
when
|
||||
.Xr libc 3
|
||||
is built to use only the routines to lookup in
|
||||
.Pa /etc/hosts
|
||||
and not the name server.
|
||||
.Pp
|
||||
The
|
||||
.Fn gethostent
|
||||
function
|
||||
reads the next line of
|
||||
.Pa /etc/hosts ,
|
||||
opening the file if necessary.
|
||||
.Pp
|
||||
The
|
||||
.Fn sethostent
|
||||
function
|
||||
opens and/or rewinds the file
|
||||
.Pa /etc/hosts .
|
||||
If the
|
||||
.Fa stayopen
|
||||
argument is non-zero,
|
||||
the file will not be closed after each call to
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostbyname2
|
||||
or
|
||||
.Fn gethostbyaddr .
|
||||
.Pp
|
||||
The
|
||||
.Fn endhostent
|
||||
function
|
||||
closes the file.
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn herror
|
||||
function appeared in
|
||||
.Bx 4.3 .
|
||||
The
|
||||
.Fn endhostent ,
|
||||
.Fn gethostbyaddr ,
|
||||
.Fn gethostbyname ,
|
||||
.Fn gethostent ,
|
||||
and
|
||||
.Fn sethostent
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
The
|
||||
.Fn gethostbyname2
|
||||
function first appeared in bind-4.9.4.
|
||||
.Sh BUGS
|
||||
These functions use static data storage;
|
||||
if the data is needed for future use, it should be
|
||||
copied before any subsequent calls overwrite it.
|
||||
Only the Internet
|
||||
address format is currently understood.
|
||||
142
c/src/exec/libnetworking/libc/gethostbynis.c
Normal file
142
c/src/exec/libnetworking/libc/gethostbynis.c
Normal file
@@ -0,0 +1,142 @@
|
||||
/*-
|
||||
* Copyright (c) 1994, Garrett Wollman
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)$Id$";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
#ifdef YP
|
||||
static char *host_aliases[MAXALIASES];
|
||||
static char hostaddr[MAXADDRS];
|
||||
static char *host_addrs[2];
|
||||
#endif /* YP */
|
||||
|
||||
static struct hostent *
|
||||
_gethostbynis(name, map, af)
|
||||
const char *name;
|
||||
char *map;
|
||||
int af;
|
||||
{
|
||||
#ifdef YP
|
||||
register char *cp, **q;
|
||||
char *result;
|
||||
int resultlen;
|
||||
static struct hostent h;
|
||||
static char *domain = (char *)NULL;
|
||||
static char ypbuf[YPMAXRECORD + 2];
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
break;
|
||||
default:
|
||||
case AF_INET6:
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&domain))
|
||||
return ((struct hostent *)NULL);
|
||||
|
||||
if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
|
||||
return ((struct hostent *)NULL);
|
||||
|
||||
/* avoid potential memory leak */
|
||||
bcopy((char *)result, (char *)&ypbuf, resultlen);
|
||||
ypbuf[resultlen] = '\0';
|
||||
free(result);
|
||||
result = (char *)&ypbuf;
|
||||
|
||||
if ((cp = index(result, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
cp = strpbrk(result, " \t");
|
||||
*cp++ = '\0';
|
||||
h.h_addr_list = host_addrs;
|
||||
h.h_addr = hostaddr;
|
||||
*((u_long *)h.h_addr) = inet_addr(result);
|
||||
h.h_length = sizeof(u_long);
|
||||
h.h_addrtype = AF_INET;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
h.h_name = cp;
|
||||
q = h.h_aliases = host_aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&h);
|
||||
#else
|
||||
return (NULL);
|
||||
#endif /* YP */
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbynisname(name, af)
|
||||
const char *name;
|
||||
int af;
|
||||
{
|
||||
return _gethostbynis(name, "hosts.byname", af);
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
_gethostbynisaddr(addr, len, af)
|
||||
const char *addr;
|
||||
int len;
|
||||
int af;
|
||||
{
|
||||
return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af);
|
||||
}
|
||||
224
c/src/exec/libnetworking/libc/gethostnamadr.c
Normal file
224
c/src/exec/libnetworking/libc/gethostnamadr.c
Normal file
@@ -0,0 +1,224 @@
|
||||
/*-
|
||||
* Copyright (c) 1994, Garrett Wollman
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)$Id$";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/nameser.h> /* XXX hack for _res */
|
||||
#include <resolv.h> /* XXX hack for _res */
|
||||
|
||||
#define _PATH_HOSTCONF "/etc/host.conf"
|
||||
|
||||
enum service_type {
|
||||
SERVICE_NONE = 0,
|
||||
SERVICE_BIND,
|
||||
SERVICE_HOSTS,
|
||||
SERVICE_NIS };
|
||||
#define SERVICE_MAX SERVICE_NIS
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
enum service_type type;
|
||||
} service_names[] = {
|
||||
{ "hosts", SERVICE_HOSTS },
|
||||
{ "/etc/hosts", SERVICE_HOSTS },
|
||||
{ "hosttable", SERVICE_HOSTS },
|
||||
{ "htable", SERVICE_HOSTS },
|
||||
{ "bind", SERVICE_BIND },
|
||||
{ "dns", SERVICE_BIND },
|
||||
{ "domain", SERVICE_BIND },
|
||||
{ "yp", SERVICE_NIS },
|
||||
{ "yellowpages", SERVICE_NIS },
|
||||
{ "nis", SERVICE_NIS },
|
||||
{ 0, SERVICE_NONE }
|
||||
};
|
||||
|
||||
static enum service_type service_order[SERVICE_MAX + 1];
|
||||
static int service_done = 0;
|
||||
|
||||
static enum service_type
|
||||
get_service_name(const char *name) {
|
||||
int i;
|
||||
for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
|
||||
if(!strcasecmp(name, service_names[i].name)) {
|
||||
return service_names[i].type;
|
||||
}
|
||||
}
|
||||
return SERVICE_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_services()
|
||||
{
|
||||
char *cp, *p, buf[BUFSIZ];
|
||||
register int cc = 0;
|
||||
FILE *fd;
|
||||
|
||||
if ((fd = (FILE *)fopen(_PATH_HOSTCONF, "r")) == NULL) {
|
||||
/* make some assumptions */
|
||||
service_order[0] = SERVICE_BIND;
|
||||
service_order[1] = SERVICE_HOSTS;
|
||||
service_order[2] = SERVICE_NONE;
|
||||
} else {
|
||||
while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
|
||||
if(buf[0] == '#')
|
||||
continue;
|
||||
|
||||
p = buf;
|
||||
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
|
||||
;
|
||||
if (cp == NULL)
|
||||
continue;
|
||||
do {
|
||||
if (isalpha(cp[0])) {
|
||||
service_order[cc] = get_service_name(cp);
|
||||
if(service_order[cc] != SERVICE_NONE)
|
||||
cc++;
|
||||
}
|
||||
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
|
||||
;
|
||||
} while(cp != NULL && cc < SERVICE_MAX);
|
||||
}
|
||||
service_order[cc] = SERVICE_NONE;
|
||||
fclose(fd);
|
||||
}
|
||||
service_done = 1;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname(const char *name)
|
||||
{
|
||||
struct hostent *hp;
|
||||
|
||||
if (_res.options & RES_USE_INET6) { /* XXX */
|
||||
hp = gethostbyname2(name, AF_INET6); /* XXX */
|
||||
if (hp) /* XXX */
|
||||
return (hp); /* XXX */
|
||||
} /* XXX */
|
||||
return (gethostbyname2(name, AF_INET));
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyname2(const char *name, int type)
|
||||
{
|
||||
struct hostent *hp = 0;
|
||||
int nserv = 0;
|
||||
|
||||
if (!service_done)
|
||||
init_services();
|
||||
|
||||
while (!hp) {
|
||||
switch (service_order[nserv]) {
|
||||
case SERVICE_NONE:
|
||||
return NULL;
|
||||
case SERVICE_HOSTS:
|
||||
hp = _gethostbyhtname(name, type);
|
||||
break;
|
||||
case SERVICE_BIND:
|
||||
hp = _gethostbydnsname(name, type);
|
||||
break;
|
||||
case SERVICE_NIS:
|
||||
hp = _gethostbynisname(name, type);
|
||||
break;
|
||||
}
|
||||
nserv++;
|
||||
}
|
||||
return hp;
|
||||
}
|
||||
|
||||
struct hostent *
|
||||
gethostbyaddr(const char *addr, int len, int type)
|
||||
{
|
||||
struct hostent *hp = 0;
|
||||
int nserv = 0;
|
||||
|
||||
if (!service_done)
|
||||
init_services();
|
||||
|
||||
while (!hp) {
|
||||
switch (service_order[nserv]) {
|
||||
case SERVICE_NONE:
|
||||
return 0;
|
||||
case SERVICE_HOSTS:
|
||||
hp = _gethostbyhtaddr(addr, len, type);
|
||||
break;
|
||||
case SERVICE_BIND:
|
||||
hp = _gethostbydnsaddr(addr, len, type);
|
||||
break;
|
||||
case SERVICE_NIS:
|
||||
hp = _gethostbynisaddr(addr, len, type);
|
||||
break;
|
||||
}
|
||||
nserv++;
|
||||
}
|
||||
return hp;
|
||||
}
|
||||
|
||||
#ifdef _THREAD_SAFE
|
||||
struct hostent_data;
|
||||
|
||||
/*
|
||||
* Temporary function (not thread safe)
|
||||
*/
|
||||
int gethostbyaddr_r(const char *addr, int len, int type,
|
||||
struct hostent *result, struct hostent_data *buffer)
|
||||
{
|
||||
struct hostent *hp;
|
||||
int ret;
|
||||
if ((hp = gethostbyaddr(addr, len, type)) == NULL) {
|
||||
ret = -1;
|
||||
} else {
|
||||
memcpy(result, hp, sizeof(struct hostent));
|
||||
ret = 0;
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
sethostent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
_sethosthtent(stayopen);
|
||||
_sethostdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endhostent()
|
||||
{
|
||||
_endhosthtent();
|
||||
_endhostdnsent();
|
||||
}
|
||||
22
c/src/exec/libnetworking/libc/gethostname.c
Normal file
22
c/src/exec/libnetworking/libc/gethostname.c
Normal file
@@ -0,0 +1,22 @@
|
||||
#include "config.h"
|
||||
|
||||
/*
|
||||
* Solaris doesn't include the gethostname call by default.
|
||||
*/
|
||||
#include <sys/utsname.h>
|
||||
#include <sys/systeminfo.h>
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
/*
|
||||
* PUBLIC: #ifndef HAVE_GETHOSTNAME
|
||||
* PUBLIC: int gethostname __P((char *, int));
|
||||
* PUBLIC: #endif
|
||||
*/
|
||||
int
|
||||
gethostname(host, len)
|
||||
char *host;
|
||||
int len;
|
||||
{
|
||||
return (sysinfo(SI_HOSTNAME, host, len) == -1 ? -1 : 0);
|
||||
}
|
||||
313
c/src/exec/libnetworking/libc/getnetbydns.c
Normal file
313
c/src/exec/libnetworking/libc/getnetbydns.c
Normal file
@@ -0,0 +1,313 @@
|
||||
/*-
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <syslog.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
extern int h_errno;
|
||||
|
||||
#define BYADDR 0
|
||||
#define BYNAME 1
|
||||
#define MAXALIASES 35
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
typedef union {
|
||||
HEADER hdr;
|
||||
u_char buf[MAXPACKET];
|
||||
} querybuf;
|
||||
|
||||
typedef union {
|
||||
long al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
static struct netent *
|
||||
getnetanswer(answer, anslen, net_i)
|
||||
querybuf *answer;
|
||||
int anslen;
|
||||
int net_i;
|
||||
{
|
||||
|
||||
register HEADER *hp;
|
||||
register u_char *cp;
|
||||
register int n;
|
||||
u_char *eom;
|
||||
int type, class, buflen, ancount, qdcount, haveanswer, i, nchar;
|
||||
char aux1[MAXHOSTNAMELEN], aux2[MAXHOSTNAMELEN], ans[MAXHOSTNAMELEN];
|
||||
char *in, *st, *pauxt, *bp, **ap;
|
||||
char *paux1 = &aux1[0], *paux2 = &aux2[0], flag = 0;
|
||||
static struct netent net_entry;
|
||||
static char *net_aliases[MAXALIASES], netbuf[PACKETSZ];
|
||||
|
||||
/*
|
||||
* find first satisfactory answer
|
||||
*
|
||||
* answer --> +------------+ ( MESSAGE )
|
||||
* | Header |
|
||||
* +------------+
|
||||
* | Question | the question for the name server
|
||||
* +------------+
|
||||
* | Answer | RRs answering the question
|
||||
* +------------+
|
||||
* | Authority | RRs pointing toward an authority
|
||||
* | Additional | RRs holding additional information
|
||||
* +------------+
|
||||
*/
|
||||
eom = answer->buf + anslen;
|
||||
hp = &answer->hdr;
|
||||
ancount = ntohs(hp->ancount); /* #/records in the answer section */
|
||||
qdcount = ntohs(hp->qdcount); /* #/entries in the question section */
|
||||
bp = netbuf;
|
||||
buflen = sizeof(netbuf);
|
||||
cp = answer->buf + HFIXEDSZ;
|
||||
if (!qdcount) {
|
||||
if (hp->aa)
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
else
|
||||
h_errno = TRY_AGAIN;
|
||||
return (NULL);
|
||||
}
|
||||
while (qdcount-- > 0)
|
||||
cp += __dn_skipname(cp, eom) + QFIXEDSZ;
|
||||
ap = net_aliases;
|
||||
*ap = NULL;
|
||||
net_entry.n_aliases = net_aliases;
|
||||
haveanswer = 0;
|
||||
while (--ancount >= 0 && cp < eom) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
if ((n < 0) || !res_dnok(bp))
|
||||
break;
|
||||
cp += n;
|
||||
ans[0] = '\0';
|
||||
(void)strncpy(&ans[0], bp, sizeof(ans) - 1);
|
||||
ans[sizeof(ans) - 1] = '\0';
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
cp += INT32SZ; /* TTL */
|
||||
GETSHORT(n, cp);
|
||||
if (class == C_IN && type == T_PTR) {
|
||||
n = dn_expand(answer->buf, eom, cp, bp, buflen);
|
||||
if ((n < 0) || !res_hnok(bp)) {
|
||||
cp += n;
|
||||
return (NULL);
|
||||
}
|
||||
cp += n;
|
||||
*ap++ = bp;
|
||||
bp += strlen(bp) + 1;
|
||||
net_entry.n_addrtype =
|
||||
(class == C_IN) ? AF_INET : AF_UNSPEC;
|
||||
haveanswer++;
|
||||
}
|
||||
}
|
||||
if (haveanswer) {
|
||||
*ap = NULL;
|
||||
switch (net_i) {
|
||||
case BYADDR:
|
||||
net_entry.n_name = *net_entry.n_aliases;
|
||||
net_entry.n_net = 0L;
|
||||
break;
|
||||
case BYNAME:
|
||||
in = *net_entry.n_aliases;
|
||||
net_entry.n_name = &ans[0];
|
||||
aux2[0] = '\0';
|
||||
for (i = 0; i < 4; i++) {
|
||||
for (st = in, nchar = 0;
|
||||
*st != '.';
|
||||
st++, nchar++)
|
||||
;
|
||||
if (nchar != 1 || *in != '0' || flag) {
|
||||
flag = 1;
|
||||
(void)strncpy(paux1,
|
||||
(i==0) ? in : in-1,
|
||||
(i==0) ?nchar : nchar+1);
|
||||
paux1[(i==0) ? nchar : nchar+1] = '\0';
|
||||
pauxt = paux2;
|
||||
paux2 = strcat(paux1, paux2);
|
||||
paux1 = pauxt;
|
||||
}
|
||||
in = ++st;
|
||||
}
|
||||
net_entry.n_net = inet_network(paux2);
|
||||
break;
|
||||
}
|
||||
net_entry.n_aliases++;
|
||||
return (&net_entry);
|
||||
}
|
||||
h_errno = TRY_AGAIN;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbydnsaddr(net, net_type)
|
||||
register unsigned long net;
|
||||
register int net_type;
|
||||
{
|
||||
unsigned int netbr[4];
|
||||
int nn, anslen;
|
||||
querybuf buf;
|
||||
char qbuf[MAXDNAME];
|
||||
unsigned long net2;
|
||||
struct netent *net_entry;
|
||||
|
||||
if (net_type != AF_INET)
|
||||
return (NULL);
|
||||
|
||||
for (nn = 4, net2 = net; net2; net2 >>= 8)
|
||||
netbr[--nn] = net2 & 0xff;
|
||||
switch (nn) {
|
||||
case 3: /* Class A */
|
||||
sprintf(qbuf, "0.0.0.%u.in-addr.arpa", netbr[3]);
|
||||
break;
|
||||
case 2: /* Class B */
|
||||
sprintf(qbuf, "0.0.%u.%u.in-addr.arpa", netbr[3], netbr[2]);
|
||||
break;
|
||||
case 1: /* Class C */
|
||||
sprintf(qbuf, "0.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
|
||||
netbr[1]);
|
||||
break;
|
||||
case 0: /* Class D - E */
|
||||
sprintf(qbuf, "%u.%u.%u.%u.in-addr.arpa", netbr[3], netbr[2],
|
||||
netbr[1], netbr[0]);
|
||||
break;
|
||||
}
|
||||
anslen = res_query(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
|
||||
if (anslen < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query failed\n");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
net_entry = getnetanswer(&buf, anslen, BYADDR);
|
||||
if (net_entry) {
|
||||
unsigned u_net = net; /* maybe net should be unsigned ? */
|
||||
|
||||
/* Strip trailing zeros */
|
||||
while ((u_net & 0xff) == 0 && u_net != 0)
|
||||
u_net >>= 8;
|
||||
net_entry->n_net = u_net;
|
||||
return (net_entry);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbydnsname(net)
|
||||
register const char *net;
|
||||
{
|
||||
int anslen;
|
||||
querybuf buf;
|
||||
char qbuf[MAXDNAME];
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (NULL);
|
||||
}
|
||||
strncpy(qbuf, net, sizeof(qbuf) - 1);
|
||||
qbuf[sizeof(qbuf) - 1] = '\0';
|
||||
anslen = res_search(qbuf, C_IN, T_PTR, (u_char *)&buf, sizeof(buf));
|
||||
if (anslen < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf("res_query failed\n");
|
||||
#endif
|
||||
return (NULL);
|
||||
}
|
||||
return getnetanswer(&buf, anslen, BYNAME);
|
||||
}
|
||||
|
||||
void
|
||||
_setnetdnsent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
if (stayopen)
|
||||
_res.options |= RES_STAYOPEN | RES_USEVC;
|
||||
}
|
||||
|
||||
void
|
||||
_endnetdnsent()
|
||||
{
|
||||
_res.options &= ~(RES_STAYOPEN | RES_USEVC);
|
||||
res_close();
|
||||
}
|
||||
173
c/src/exec/libnetworking/libc/getnetbyht.c
Normal file
173
c/src/exec/libnetworking/libc/getnetbyht.c
Normal file
@@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* Portions Copyright (c) 1993 Carlos Leandro and Rui Salgueiro
|
||||
* Dep. Matematica Universidade de Coimbra, Portugal, Europe
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* from getnetent.c 1.1 (Coimbra) 93/06/02
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getnetent.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: getnetent.c,v 8.4 1997/06/01 20:34:37 vixie Exp";
|
||||
static chat rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *netf;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct netent net;
|
||||
static char *net_aliases[MAXALIASES];
|
||||
static int _net_stayopen;
|
||||
|
||||
void
|
||||
_setnethtent(f)
|
||||
int f;
|
||||
{
|
||||
|
||||
if (netf == NULL)
|
||||
netf = fopen(_PATH_NETWORKS, "r" );
|
||||
else
|
||||
rewind(netf);
|
||||
_net_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
_endnethtent()
|
||||
{
|
||||
|
||||
if (netf) {
|
||||
fclose(netf);
|
||||
netf = NULL;
|
||||
}
|
||||
_net_stayopen = 0;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (netf == NULL && (netf = fopen(_PATH_NETWORKS, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
p = fgets(line, sizeof line, netf);
|
||||
if (p == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
net.n_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
net.n_net = inet_network(cp);
|
||||
net.n_addrtype = AF_INET;
|
||||
q = net.n_aliases = net_aliases;
|
||||
if (p != NULL)
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &net_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&net);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbyhtname(name)
|
||||
register const char *name;
|
||||
{
|
||||
register struct netent *p;
|
||||
register char **cp;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ( (p = getnetent()) ) {
|
||||
if (strcasecmp(p->n_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->n_aliases; *cp != 0; cp++)
|
||||
if (strcasecmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
return (p);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbyhtaddr(net, type)
|
||||
register unsigned long net;
|
||||
register int type;
|
||||
{
|
||||
register struct netent *p;
|
||||
|
||||
setnetent(_net_stayopen);
|
||||
while ( (p = getnetent()) )
|
||||
if (p->n_addrtype == type && p->n_net == net)
|
||||
break;
|
||||
if (!_net_stayopen)
|
||||
endnetent();
|
||||
return (p);
|
||||
}
|
||||
177
c/src/exec/libnetworking/libc/getnetbynis.c
Normal file
177
c/src/exec/libnetworking/libc/getnetbynis.c
Normal file
@@ -0,0 +1,177 @@
|
||||
/*-
|
||||
* Copyright (c) 1994, Garrett Wollman
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)$Id$";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include <arpa/nameser.h>
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
#define MAXALIASES 35
|
||||
#define MAXADDRS 35
|
||||
|
||||
#ifdef YP
|
||||
static char *host_aliases[MAXALIASES];
|
||||
#endif /* YP */
|
||||
|
||||
static struct netent *
|
||||
_getnetbynis(name, map, af)
|
||||
const char *name;
|
||||
char *map;
|
||||
int af;
|
||||
{
|
||||
#ifdef YP
|
||||
register char *cp, **q;
|
||||
static char *result;
|
||||
int resultlen;
|
||||
static struct netent h;
|
||||
static char *domain = (char *)NULL;
|
||||
static char ypbuf[YPMAXRECORD + 2];
|
||||
|
||||
switch(af) {
|
||||
case AF_INET:
|
||||
break;
|
||||
default:
|
||||
case AF_INET6:
|
||||
errno = EAFNOSUPPORT;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (domain == (char *)NULL)
|
||||
if (yp_get_default_domain (&domain))
|
||||
return (NULL);
|
||||
|
||||
if (yp_match(domain, map, name, strlen(name), &result, &resultlen))
|
||||
return (NULL);
|
||||
|
||||
bcopy((char *)result, (char *)&ypbuf, resultlen);
|
||||
ypbuf[resultlen] = '\0';
|
||||
free(result);
|
||||
result = (char *)&ypbuf;
|
||||
|
||||
if ((cp = index(result, '\n')))
|
||||
*cp = '\0';
|
||||
|
||||
cp = strpbrk(result, " \t");
|
||||
*cp++ = '\0';
|
||||
h.n_name = result;
|
||||
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
|
||||
h.n_net = inet_network(cp);
|
||||
h.n_addrtype = AF_INET;
|
||||
|
||||
q = h.n_aliases = host_aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &host_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&h);
|
||||
#else
|
||||
return (NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbynisname(name)
|
||||
const char *name;
|
||||
{
|
||||
return _getnetbynis(name, "networks.byname", AF_INET);
|
||||
}
|
||||
|
||||
struct netent *
|
||||
_getnetbynisaddr(addr, af)
|
||||
unsigned long addr;
|
||||
int af;
|
||||
{
|
||||
char *str, *cp;
|
||||
unsigned long net2;
|
||||
int nn;
|
||||
unsigned int netbr[4];
|
||||
char buf[MAXDNAME];
|
||||
|
||||
if (af != AF_INET) {
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
for (nn = 4, net2 = addr; net2; net2 >>= 8) {
|
||||
netbr[--nn] = net2 & 0xff;
|
||||
}
|
||||
|
||||
switch (nn) {
|
||||
case 3: /* Class A */
|
||||
sprintf(buf, "%u", netbr[3]);
|
||||
break;
|
||||
case 2: /* Class B */
|
||||
sprintf(buf, "%u.%u", netbr[2], netbr[3]);
|
||||
break;
|
||||
case 1: /* Class C */
|
||||
sprintf(buf, "%u.%u.%u", netbr[1], netbr[2], netbr[3]);
|
||||
break;
|
||||
case 0: /* Class D - E */
|
||||
sprintf(buf, "%u.%u.%u.%u", netbr[0], netbr[1],
|
||||
netbr[2], netbr[3]);
|
||||
break;
|
||||
}
|
||||
|
||||
str = (char *)&buf;
|
||||
cp = str + (strlen(str) - 2);
|
||||
|
||||
while(!strcmp(cp, ".0")) {
|
||||
*cp = '\0';
|
||||
cp = str + (strlen(str) - 2);
|
||||
}
|
||||
|
||||
return _getnetbynis(str, "networks.byaddr", af);
|
||||
}
|
||||
158
c/src/exec/libnetworking/libc/getnetent.3
Normal file
158
c/src/exec/libnetworking/libc/getnetent.3
Normal file
@@ -0,0 +1,158 @@
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)getnetent.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt GETNETENT 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm getnetent ,
|
||||
.Nm getnetbyaddr ,
|
||||
.Nm getnetbyname ,
|
||||
.Nm setnetent ,
|
||||
.Nm endnetent
|
||||
.Nd get network entry
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netdb.h>
|
||||
.Ft struct netent *
|
||||
.Fn getnetent void
|
||||
.Ft struct netent *
|
||||
.Fn getnetbyname "const char *name"
|
||||
.Ft struct netent *
|
||||
.Fn getnetbyaddr "unsigned long net" "int type"
|
||||
.Ft void
|
||||
.Fn setnetent "int stayopen"
|
||||
.Ft void
|
||||
.Fn endnetent void
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getnetent ,
|
||||
.Fn getnetbyname ,
|
||||
and
|
||||
.Fn getnetbyaddr
|
||||
functions
|
||||
each return a pointer to an object with the
|
||||
following structure
|
||||
containing the broken-out
|
||||
fields of a line in the network data base,
|
||||
.Pa /etc/networks .
|
||||
.Bd -literal -offset indent
|
||||
struct netent {
|
||||
char *n_name; /* official name of net */
|
||||
char **n_aliases; /* alias list */
|
||||
int n_addrtype; /* net number type */
|
||||
unsigned long n_net; /* net number */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width n_addrtype
|
||||
.It Fa n_name
|
||||
The official name of the network.
|
||||
.It Fa n_aliases
|
||||
A zero terminated list of alternate names for the network.
|
||||
.It Fa n_addrtype
|
||||
The type of the network number returned; currently only AF_INET.
|
||||
.It Fa n_net
|
||||
The network number. Network numbers are returned in machine byte
|
||||
order.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn getnetent
|
||||
function
|
||||
reads the next line of the file, opening the file if necessary.
|
||||
.Pp
|
||||
The
|
||||
.Fn setnetent
|
||||
function
|
||||
opens and rewinds the file. If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
the net data base will not be closed after each call to
|
||||
.Fn getnetbyname
|
||||
or
|
||||
.Fn getnetbyaddr .
|
||||
.Pp
|
||||
The
|
||||
.Fn endnetent
|
||||
function
|
||||
closes the file.
|
||||
.Pp
|
||||
The
|
||||
.Fn getnetbyname
|
||||
function
|
||||
and
|
||||
.Fn getnetbyaddr
|
||||
sequentially search from the beginning
|
||||
of the file until a matching
|
||||
net name or
|
||||
net address and type is found,
|
||||
or until
|
||||
.Dv EOF
|
||||
is encountered. The
|
||||
.Fa type
|
||||
must be
|
||||
.Dv AF_INET .
|
||||
Network numbers are supplied in host order.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/networks -compact
|
||||
.It Pa /etc/networks
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Null pointer
|
||||
(0) returned on
|
||||
.Dv EOF
|
||||
or error.
|
||||
.Sh SEE ALSO
|
||||
.Xr networks 5
|
||||
.Pp
|
||||
.%T RFC 1101
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getnetent ,
|
||||
.Fn getnetbyaddr ,
|
||||
.Fn getnetbyname ,
|
||||
.Fn setnetent ,
|
||||
and
|
||||
.Fn endnetent
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
The data space used by
|
||||
these functions is static; if future use requires the data, it should be
|
||||
copied before any subsequent calls to these functions overwrite it.
|
||||
Only Internet network
|
||||
numbers are currently understood.
|
||||
Expecting network numbers to fit
|
||||
in no more than 32 bits is probably
|
||||
naive.
|
||||
190
c/src/exec/libnetworking/libc/getnetnamadr.c
Normal file
190
c/src/exec/libnetworking/libc/getnetnamadr.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*-
|
||||
* Copyright (c) 1994, Garrett Wollman
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifndef _PATH_NETCONF
|
||||
#define _PATH_NETCONF "/etc/host.conf"
|
||||
#endif
|
||||
|
||||
enum service_type {
|
||||
SERVICE_NONE = 0,
|
||||
SERVICE_BIND,
|
||||
SERVICE_TABLE,
|
||||
SERVICE_NIS };
|
||||
#define SERVICE_MAX SERVICE_NIS
|
||||
|
||||
static struct {
|
||||
const char *name;
|
||||
enum service_type type;
|
||||
} service_names[] = {
|
||||
{ "hosts", SERVICE_TABLE },
|
||||
{ "/etc/hosts", SERVICE_TABLE },
|
||||
{ "hosttable", SERVICE_TABLE },
|
||||
{ "htable", SERVICE_TABLE },
|
||||
{ "bind", SERVICE_BIND },
|
||||
{ "dns", SERVICE_BIND },
|
||||
{ "domain", SERVICE_BIND },
|
||||
{ "yp", SERVICE_NIS },
|
||||
{ "yellowpages", SERVICE_NIS },
|
||||
{ "nis", SERVICE_NIS },
|
||||
{ 0, SERVICE_NONE }
|
||||
};
|
||||
|
||||
static enum service_type service_order[SERVICE_MAX + 1];
|
||||
static int service_done = 0;
|
||||
|
||||
static enum service_type
|
||||
get_service_name(const char *name) {
|
||||
int i;
|
||||
for(i = 0; service_names[i].type != SERVICE_NONE; i++) {
|
||||
if(!strcasecmp(name, service_names[i].name)) {
|
||||
return service_names[i].type;
|
||||
}
|
||||
}
|
||||
return SERVICE_NONE;
|
||||
}
|
||||
|
||||
static void
|
||||
init_services()
|
||||
{
|
||||
char *cp, *p, buf[BUFSIZ];
|
||||
register int cc = 0;
|
||||
FILE *fd;
|
||||
|
||||
if ((fd = (FILE *)fopen(_PATH_NETCONF, "r")) == NULL) {
|
||||
/* make some assumptions */
|
||||
service_order[0] = SERVICE_TABLE;
|
||||
service_order[1] = SERVICE_NONE;
|
||||
} else {
|
||||
while (fgets(buf, BUFSIZ, fd) != NULL && cc < SERVICE_MAX) {
|
||||
if(buf[0] == '#')
|
||||
continue;
|
||||
|
||||
p = buf;
|
||||
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
|
||||
;
|
||||
if (cp == NULL)
|
||||
continue;
|
||||
do {
|
||||
if (isalpha(cp[0])) {
|
||||
service_order[cc] = get_service_name(cp);
|
||||
if(service_order[cc] != SERVICE_NONE)
|
||||
cc++;
|
||||
}
|
||||
while ((cp = strsep(&p, "\n \t,:;")) != NULL && *cp == '\0')
|
||||
;
|
||||
} while(cp != NULL && cc < SERVICE_MAX);
|
||||
}
|
||||
service_order[cc] = SERVICE_NONE;
|
||||
fclose(fd);
|
||||
}
|
||||
service_done = 1;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyname(const char *name)
|
||||
{
|
||||
struct netent *hp = 0;
|
||||
int nserv = 0;
|
||||
|
||||
if (!service_done)
|
||||
init_services();
|
||||
|
||||
while (!hp) {
|
||||
switch (service_order[nserv]) {
|
||||
case SERVICE_NONE:
|
||||
return NULL;
|
||||
case SERVICE_TABLE:
|
||||
hp = _getnetbyhtname(name);
|
||||
break;
|
||||
case SERVICE_BIND:
|
||||
hp = _getnetbydnsname(name);
|
||||
break;
|
||||
case SERVICE_NIS:
|
||||
hp = _getnetbynisname(name);
|
||||
break;
|
||||
}
|
||||
nserv++;
|
||||
}
|
||||
return hp;
|
||||
}
|
||||
|
||||
struct netent *
|
||||
getnetbyaddr(addr, af)
|
||||
u_long addr;
|
||||
int af;
|
||||
{
|
||||
struct netent *hp = 0;
|
||||
int nserv = 0;
|
||||
|
||||
if (!service_done)
|
||||
init_services();
|
||||
|
||||
while (!hp) {
|
||||
switch (service_order[nserv]) {
|
||||
case SERVICE_NONE:
|
||||
return 0;
|
||||
case SERVICE_TABLE:
|
||||
hp = _getnetbyhtaddr(addr, af);
|
||||
break;
|
||||
case SERVICE_BIND:
|
||||
hp = _getnetbydnsaddr(addr, af);
|
||||
break;
|
||||
case SERVICE_NIS:
|
||||
hp = _getnetbynisaddr(addr, af);
|
||||
break;
|
||||
}
|
||||
nserv++;
|
||||
}
|
||||
return hp;
|
||||
}
|
||||
|
||||
void
|
||||
setnetent(stayopen)
|
||||
int stayopen;
|
||||
{
|
||||
_setnethtent(stayopen);
|
||||
_setnetdnsent(stayopen);
|
||||
}
|
||||
|
||||
void
|
||||
endnetent()
|
||||
{
|
||||
_endnethtent();
|
||||
_endnetdnsent();
|
||||
}
|
||||
55
c/src/exec/libnetworking/libc/getproto.c
Normal file
55
c/src/exec/libnetworking/libc/getproto.c
Normal file
@@ -0,0 +1,55 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getproto.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
extern int _proto_stayopen;
|
||||
|
||||
struct protoent *
|
||||
getprotobynumber(proto)
|
||||
register int proto;
|
||||
{
|
||||
register struct protoent *p;
|
||||
|
||||
setprotoent(_proto_stayopen);
|
||||
while ( (p = getprotoent()) )
|
||||
if (p->p_proto == proto)
|
||||
break;
|
||||
if (!_proto_stayopen)
|
||||
endprotoent();
|
||||
return (p);
|
||||
}
|
||||
146
c/src/exec/libnetworking/libc/getprotoent.3
Normal file
146
c/src/exec/libnetworking/libc/getprotoent.3
Normal file
@@ -0,0 +1,146 @@
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)getprotoent.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt GETPROTOENT 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm getprotoent ,
|
||||
.Nm getprotobynumber ,
|
||||
.Nm getprotobyname ,
|
||||
.Nm setprotoent ,
|
||||
.Nm endprotoent
|
||||
.Nd get protocol entry
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netdb.h>
|
||||
.Ft struct protoent *
|
||||
.Fn getprotoent void
|
||||
.Ft struct protoent *
|
||||
.Fn getprotobyname "const char *name"
|
||||
.Ft struct protoent *
|
||||
.Fn getprotobynumber "int proto"
|
||||
.Ft void
|
||||
.Fn setprotoent "int stayopen"
|
||||
.Ft void
|
||||
.Fn endprotoent void
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getprotoent ,
|
||||
.Fn getprotobyname ,
|
||||
and
|
||||
.Fn getprotobynumber
|
||||
functions
|
||||
each return a pointer to an object with the
|
||||
following structure
|
||||
containing the broken-out
|
||||
fields of a line in the network protocol data base,
|
||||
.Pa /etc/protocols .
|
||||
.Bd -literal -offset indent
|
||||
.Pp
|
||||
struct protoent {
|
||||
char *p_name; /* official name of protocol */
|
||||
char **p_aliases; /* alias list */
|
||||
int p_proto; /* protocol number */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width p_aliases
|
||||
.It Fa p_name
|
||||
The official name of the protocol.
|
||||
.It Fa p_aliases
|
||||
A zero terminated list of alternate names for the protocol.
|
||||
.It Fa p_proto
|
||||
The protocol number.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn getprotoent
|
||||
function
|
||||
reads the next line of the file, opening the file if necessary.
|
||||
.Pp
|
||||
The
|
||||
.Fn setprotoent
|
||||
function
|
||||
opens and rewinds the file. If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
the net data base will not be closed after each call to
|
||||
.Fn getprotobyname
|
||||
or
|
||||
.Fn getprotobynumber .
|
||||
.Pp
|
||||
The
|
||||
.Fn endprotoent
|
||||
function
|
||||
closes the file.
|
||||
.Pp
|
||||
The
|
||||
.Fn getprotobyname
|
||||
function
|
||||
and
|
||||
.Fn getprotobynumber
|
||||
sequentially search from the beginning
|
||||
of the file until a matching
|
||||
protocol name or
|
||||
protocol number is found,
|
||||
or until
|
||||
.Dv EOF
|
||||
is encountered.
|
||||
.Sh RETURN VALUES
|
||||
Null pointer
|
||||
(0) returned on
|
||||
.Dv EOF
|
||||
or error.
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/protocols -compact
|
||||
.It Pa /etc/protocols
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr protocols 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getprotoent ,
|
||||
.Fn getprotobynumber ,
|
||||
.Fn getprotobyname ,
|
||||
.Fn setprotoent ,
|
||||
and
|
||||
.Fn endprotoent
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
These functions use a static data space;
|
||||
if the data is needed for future use, it should be
|
||||
copied before any subsequent calls overwrite it.
|
||||
Only the Internet
|
||||
protocols are currently understood.
|
||||
119
c/src/exec/libnetworking/libc/getprotoent.c
Normal file
119
c/src/exec/libnetworking/libc/getprotoent.c
Normal file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getprotoent.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *protof = NULL;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct protoent proto;
|
||||
static char *proto_aliases[MAXALIASES];
|
||||
int _proto_stayopen;
|
||||
|
||||
void
|
||||
setprotoent(f)
|
||||
int f;
|
||||
{
|
||||
if (protof == NULL)
|
||||
protof = fopen(_PATH_PROTOCOLS, "r" );
|
||||
else
|
||||
rewind(protof);
|
||||
_proto_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
endprotoent()
|
||||
{
|
||||
if (protof) {
|
||||
fclose(protof);
|
||||
protof = NULL;
|
||||
}
|
||||
_proto_stayopen = 0;
|
||||
}
|
||||
|
||||
struct protoent *
|
||||
getprotoent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
if (protof == NULL && (protof = fopen(_PATH_PROTOCOLS, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
if ((p = fgets(line, BUFSIZ, protof)) == NULL)
|
||||
return (NULL);
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
proto.p_name = p;
|
||||
cp = strpbrk(p, " \t");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
p = strpbrk(cp, " \t");
|
||||
if (p != NULL)
|
||||
*p++ = '\0';
|
||||
proto.p_proto = atoi(cp);
|
||||
q = proto.p_aliases = proto_aliases;
|
||||
if (p != NULL) {
|
||||
cp = p;
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &proto_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
}
|
||||
*q = NULL;
|
||||
return (&proto);
|
||||
}
|
||||
62
c/src/exec/libnetworking/libc/getprotoname.c
Normal file
62
c/src/exec/libnetworking/libc/getprotoname.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getprotoname.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int _proto_stayopen;
|
||||
|
||||
struct protoent *
|
||||
getprotobyname(name)
|
||||
register const char *name;
|
||||
{
|
||||
register struct protoent *p;
|
||||
register char **cp;
|
||||
|
||||
setprotoent(_proto_stayopen);
|
||||
while ( (p = getprotoent()) ) {
|
||||
if (strcmp(p->p_name, name) == 0)
|
||||
break;
|
||||
for (cp = p->p_aliases; *cp != 0; cp++)
|
||||
if (strcmp(*cp, name) == 0)
|
||||
goto found;
|
||||
}
|
||||
found:
|
||||
if (!_proto_stayopen)
|
||||
endprotoent();
|
||||
return (p);
|
||||
}
|
||||
79
c/src/exec/libnetworking/libc/getservbyname.c
Normal file
79
c/src/exec/libnetworking/libc/getservbyname.c
Normal file
@@ -0,0 +1,79 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservbyname.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int _serv_stayopen;
|
||||
|
||||
struct servent *
|
||||
getservbyname(name, proto)
|
||||
const char *name, *proto;
|
||||
{
|
||||
register struct servent *p;
|
||||
register char **cp;
|
||||
|
||||
#ifdef YP
|
||||
extern char *___getservbyname_yp;
|
||||
extern char *___getservbyproto_yp;
|
||||
|
||||
___getservbyname_yp = (char *)name;
|
||||
___getservbyproto_yp = (char *)proto;
|
||||
#endif
|
||||
|
||||
setservent(_serv_stayopen);
|
||||
while ( (p = getservent()) ) {
|
||||
if (strcmp(name, p->s_name) == 0)
|
||||
goto gotname;
|
||||
for (cp = p->s_aliases; *cp; cp++)
|
||||
if (strcmp(name, *cp) == 0)
|
||||
goto gotname;
|
||||
continue;
|
||||
gotname:
|
||||
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!_serv_stayopen)
|
||||
endservent();
|
||||
|
||||
#ifdef YP
|
||||
___getservbyname_yp = NULL;
|
||||
___getservbyproto_yp = NULL;
|
||||
#endif
|
||||
|
||||
return (p);
|
||||
}
|
||||
74
c/src/exec/libnetworking/libc/getservbyport.c
Normal file
74
c/src/exec/libnetworking/libc/getservbyport.c
Normal file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservbyport.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
|
||||
extern int _serv_stayopen;
|
||||
|
||||
struct servent *
|
||||
getservbyport(port, proto)
|
||||
int port;
|
||||
const char *proto;
|
||||
{
|
||||
register struct servent *p;
|
||||
|
||||
#ifdef YP
|
||||
extern int ___getservbyport_yp;
|
||||
extern char *___getservbyproto_yp;
|
||||
|
||||
___getservbyport_yp = port;
|
||||
___getservbyproto_yp = (char *)proto;
|
||||
#endif
|
||||
|
||||
setservent(_serv_stayopen);
|
||||
while ( (p = getservent()) ) {
|
||||
if (p->s_port != port)
|
||||
continue;
|
||||
if (proto == 0 || strcmp(p->s_proto, proto) == 0)
|
||||
break;
|
||||
}
|
||||
if (!_serv_stayopen)
|
||||
endservent();
|
||||
|
||||
#ifdef YP
|
||||
___getservbyport_yp = 0;
|
||||
___getservbyproto_yp = NULL;
|
||||
#endif
|
||||
|
||||
return (p);
|
||||
}
|
||||
156
c/src/exec/libnetworking/libc/getservent.3
Normal file
156
c/src/exec/libnetworking/libc/getservent.3
Normal file
@@ -0,0 +1,156 @@
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" From: @(#)getservent.3 8.3 (Berkeley) 1/12/94
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd July 9, 1995
|
||||
.Dt GETSERVENT 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm getservent ,
|
||||
.Nm getservbyport ,
|
||||
.Nm getservbyname ,
|
||||
.Nm setservent ,
|
||||
.Nm endservent
|
||||
.Nd get service entry
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <netdb.h>
|
||||
.Ft struct servent *
|
||||
.Fn getservent
|
||||
.Ft struct servent *
|
||||
.Fn getservbyname "const char *name" "const char *proto"
|
||||
.Ft struct servent *
|
||||
.Fn getservbyport "int port" "const char *proto"
|
||||
.Ft void
|
||||
.Fn setservent "int stayopen"
|
||||
.Ft void
|
||||
.Fn endservent void
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn getservent ,
|
||||
.Fn getservbyname ,
|
||||
and
|
||||
.Fn getservbyport
|
||||
functions
|
||||
each return a pointer to an object with the
|
||||
following structure
|
||||
containing the broken-out
|
||||
fields of a line in the network services data base,
|
||||
.Pa /etc/services .
|
||||
.Bd -literal -offset indent
|
||||
struct servent {
|
||||
char *s_name; /* official name of service */
|
||||
char **s_aliases; /* alias list */
|
||||
int s_port; /* port service resides at */
|
||||
char *s_proto; /* protocol to use */
|
||||
};
|
||||
.Ed
|
||||
.Pp
|
||||
The members of this structure are:
|
||||
.Bl -tag -width s_aliases
|
||||
.It Fa s_name
|
||||
The official name of the service.
|
||||
.It Fa s_aliases
|
||||
A zero terminated list of alternate names for the service.
|
||||
.It Fa s_port
|
||||
The port number at which the service resides.
|
||||
Port numbers are returned in network byte order.
|
||||
.It Fa s_proto
|
||||
The name of the protocol to use when contacting the
|
||||
service.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn getservent
|
||||
function
|
||||
reads the next line of the file, opening the file if necessary.
|
||||
.Pp
|
||||
The
|
||||
.Fn setservent
|
||||
function
|
||||
opens and rewinds the file. If the
|
||||
.Fa stayopen
|
||||
flag is non-zero,
|
||||
the net data base will not be closed after each call to
|
||||
.Fn getservbyname
|
||||
or
|
||||
.Fn getservbyport .
|
||||
.Pp
|
||||
The
|
||||
.Fn endservent
|
||||
function
|
||||
closes the file.
|
||||
.Pp
|
||||
The
|
||||
.Fn getservbyname
|
||||
and
|
||||
.Fn getservbyport
|
||||
functions
|
||||
sequentially search from the beginning
|
||||
of the file until a matching
|
||||
protocol name or
|
||||
port number is found,
|
||||
or until
|
||||
.Dv EOF
|
||||
is encountered.
|
||||
If a protocol name is also supplied (non-
|
||||
.Dv NULL ) ,
|
||||
searches must also match the protocol.
|
||||
.ne 1i
|
||||
.Sh FILES
|
||||
.Bl -tag -width /etc/services -compact
|
||||
.It Pa /etc/services
|
||||
.El
|
||||
.Sh DIAGNOSTICS
|
||||
Null pointer
|
||||
(0) returned on
|
||||
.Dv EOF
|
||||
or error.
|
||||
.Sh SEE ALSO
|
||||
.Xr getprotoent 3 ,
|
||||
.Xr services 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn getservent ,
|
||||
.Fn getservbyport ,
|
||||
.Fn getservbyname ,
|
||||
.Fn setservent ,
|
||||
and
|
||||
.Fn endservent
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
These functions use static data storage;
|
||||
if the data is needed for future use, it should be
|
||||
copied before any subsequent calls overwrite it.
|
||||
Expecting port numbers to fit in a 32 bit
|
||||
quantity is probably naive.
|
||||
278
c/src/exec/libnetworking/libc/getservent.c
Normal file
278
c/src/exec/libnetworking/libc/getservent.c
Normal file
@@ -0,0 +1,278 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)getservent.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netdb.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
static int serv_stepping_yp = 0;
|
||||
extern int _yp_check __P(( char ** ));
|
||||
#endif
|
||||
|
||||
|
||||
#define MAXALIASES 35
|
||||
|
||||
static FILE *servf = NULL;
|
||||
static char line[BUFSIZ+1];
|
||||
static struct servent serv;
|
||||
static char *serv_aliases[MAXALIASES];
|
||||
int _serv_stayopen;
|
||||
|
||||
#ifdef YP
|
||||
char *___getservbyname_yp = NULL;
|
||||
char *___getservbyproto_yp = NULL;
|
||||
int ___getservbyport_yp = 0;
|
||||
static char *yp_domain = NULL;
|
||||
|
||||
static int
|
||||
_getservbyport_yp(line)
|
||||
char *line;
|
||||
{
|
||||
char *result;
|
||||
int resultlen;
|
||||
char buf[YPMAXRECORD + 2];
|
||||
int rv;
|
||||
|
||||
snprintf(buf, sizeof(buf), "%d/%s", ntohs(___getservbyport_yp),
|
||||
___getservbyproto_yp);
|
||||
|
||||
___getservbyport_yp = 0;
|
||||
___getservbyproto_yp = NULL;
|
||||
|
||||
if(!yp_domain) {
|
||||
if(yp_get_default_domain(&yp_domain))
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* We have to be a little flexible here. Ideally you're supposed
|
||||
* to have both a services.byname and a services.byport map, but
|
||||
* some systems have only services.byname. FreeBSD cheats a little
|
||||
* by putting the services.byport information in the same map as
|
||||
* services.byname so that either case will work. We allow for both
|
||||
* possibilities here: if there is no services.byport map, we try
|
||||
* services.byname instead.
|
||||
*/
|
||||
if ((rv = yp_match(yp_domain, "services.byport", buf, strlen(buf),
|
||||
&result, &resultlen))) {
|
||||
if (rv == YPERR_MAP) {
|
||||
if (yp_match(yp_domain, "services.byname", buf,
|
||||
strlen(buf), &result, &resultlen))
|
||||
return(0);
|
||||
} else
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
_getservbyname_yp(line)
|
||||
char *line;
|
||||
{
|
||||
char *result;
|
||||
int resultlen;
|
||||
char buf[YPMAXRECORD + 2];
|
||||
|
||||
if(!yp_domain) {
|
||||
if(yp_get_default_domain(&yp_domain))
|
||||
return (0);
|
||||
}
|
||||
|
||||
snprintf(buf, sizeof(buf), "%s/%s", ___getservbyname_yp,
|
||||
___getservbyproto_yp);
|
||||
|
||||
___getservbyname_yp = 0;
|
||||
___getservbyproto_yp = NULL;
|
||||
|
||||
if (yp_match(yp_domain, "services.byname", buf, strlen(buf),
|
||||
&result, &resultlen)) {
|
||||
return(0);
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
return(1);
|
||||
}
|
||||
|
||||
static int
|
||||
_getservent_yp(line)
|
||||
char *line;
|
||||
{
|
||||
static char *key = NULL;
|
||||
static int keylen;
|
||||
char *lastkey, *result;
|
||||
int resultlen;
|
||||
int rv;
|
||||
|
||||
if(!yp_domain) {
|
||||
if(yp_get_default_domain(&yp_domain))
|
||||
return (0);
|
||||
}
|
||||
|
||||
if (!serv_stepping_yp) {
|
||||
if (key)
|
||||
free(key);
|
||||
if ((rv = yp_first(yp_domain, "services.byname", &key, &keylen,
|
||||
&result, &resultlen))) {
|
||||
serv_stepping_yp = 0;
|
||||
return(0);
|
||||
}
|
||||
serv_stepping_yp = 1;
|
||||
} else {
|
||||
lastkey = key;
|
||||
rv = yp_next(yp_domain, "services.byname", key, keylen, &key,
|
||||
&keylen, &result, &resultlen);
|
||||
free(lastkey);
|
||||
if (rv) {
|
||||
serv_stepping_yp = 0;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/* getservent() expects lines terminated with \n -- make it happy */
|
||||
snprintf(line, BUFSIZ, "%.*s\n", resultlen, result);
|
||||
|
||||
free(result);
|
||||
|
||||
return(1);
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
setservent(f)
|
||||
int f;
|
||||
{
|
||||
if (servf == NULL)
|
||||
servf = fopen(_PATH_SERVICES, "r" );
|
||||
else
|
||||
rewind(servf);
|
||||
_serv_stayopen |= f;
|
||||
}
|
||||
|
||||
void
|
||||
endservent()
|
||||
{
|
||||
if (servf) {
|
||||
fclose(servf);
|
||||
servf = NULL;
|
||||
}
|
||||
_serv_stayopen = 0;
|
||||
}
|
||||
|
||||
struct servent *
|
||||
getservent()
|
||||
{
|
||||
char *p;
|
||||
register char *cp, **q;
|
||||
|
||||
#ifdef YP
|
||||
if (serv_stepping_yp && _getservent_yp(line)) {
|
||||
p = (char *)&line;
|
||||
goto unpack;
|
||||
}
|
||||
tryagain:
|
||||
#endif
|
||||
if (servf == NULL && (servf = fopen(_PATH_SERVICES, "r" )) == NULL)
|
||||
return (NULL);
|
||||
again:
|
||||
if ((p = fgets(line, BUFSIZ, servf)) == NULL)
|
||||
return (NULL);
|
||||
#ifdef YP
|
||||
if (*p == '+' && _yp_check(NULL)) {
|
||||
if (___getservbyname_yp != NULL) {
|
||||
if (!_getservbyname_yp(line))
|
||||
goto tryagain;
|
||||
}
|
||||
else if (___getservbyport_yp != 0) {
|
||||
if (!_getservbyport_yp(line))
|
||||
goto tryagain;
|
||||
}
|
||||
else if (!_getservent_yp(line))
|
||||
goto tryagain;
|
||||
}
|
||||
unpack:
|
||||
#endif
|
||||
if (*p == '#')
|
||||
goto again;
|
||||
cp = strpbrk(p, "#\n");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp = '\0';
|
||||
serv.s_name = p;
|
||||
p = strpbrk(p, " \t");
|
||||
if (p == NULL)
|
||||
goto again;
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
cp = strpbrk(p, ",/");
|
||||
if (cp == NULL)
|
||||
goto again;
|
||||
*cp++ = '\0';
|
||||
serv.s_port = htons((u_short)atoi(p));
|
||||
serv.s_proto = cp;
|
||||
q = serv.s_aliases = serv_aliases;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
while (cp && *cp) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (q < &serv_aliases[MAXALIASES - 1])
|
||||
*q++ = cp;
|
||||
cp = strpbrk(cp, " \t");
|
||||
if (cp != NULL)
|
||||
*cp++ = '\0';
|
||||
}
|
||||
*q = NULL;
|
||||
return (&serv);
|
||||
}
|
||||
122
c/src/exec/libnetworking/libc/herror.c
Normal file
122
c/src/exec/libnetworking/libc/herror.c
Normal file
@@ -0,0 +1,122 @@
|
||||
/*
|
||||
* Copyright (c) 1987, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)herror.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/uio.h>
|
||||
#include <netdb.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
const char *h_errlist[] = {
|
||||
"Resolver Error 0 (no error)",
|
||||
"Unknown host", /* 1 HOST_NOT_FOUND */
|
||||
"Host name lookup failure", /* 2 TRY_AGAIN */
|
||||
"Unknown server error", /* 3 NO_RECOVERY */
|
||||
"No address associated with name", /* 4 NO_ADDRESS */
|
||||
};
|
||||
int h_nerr = { sizeof h_errlist / sizeof h_errlist[0] };
|
||||
|
||||
int h_errno;
|
||||
|
||||
/*
|
||||
* herror --
|
||||
* print the error indicated by the h_errno value.
|
||||
*/
|
||||
void
|
||||
herror(s)
|
||||
const char *s;
|
||||
{
|
||||
#if 0
|
||||
struct iovec iov[4];
|
||||
register struct iovec *v = iov;
|
||||
|
||||
if (s && *s) {
|
||||
v->iov_base = (char *)s;
|
||||
v->iov_len = strlen(s);
|
||||
v++;
|
||||
v->iov_base = ": ";
|
||||
v->iov_len = 2;
|
||||
v++;
|
||||
}
|
||||
v->iov_base = (char *)hstrerror(h_errno);
|
||||
v->iov_len = strlen(v->iov_base);
|
||||
v++;
|
||||
v->iov_base = "\n";
|
||||
v->iov_len = 1;
|
||||
writev(STDERR_FILENO, iov, (v - iov) + 1);
|
||||
#else
|
||||
/*
|
||||
* RTEMS: no writev yet
|
||||
*/
|
||||
if (s && *s) {
|
||||
write (2, s, strlen (s));
|
||||
write (2, ": ", 2);
|
||||
}
|
||||
s = (char *)hstrerror(h_errno);
|
||||
write (2, s, strlen (s));
|
||||
write (2, "\n", 1);
|
||||
#endif
|
||||
}
|
||||
|
||||
const char *
|
||||
hstrerror(err)
|
||||
int err;
|
||||
{
|
||||
if (err < 0)
|
||||
return ("Resolver internal error");
|
||||
else if (err < h_nerr)
|
||||
return (h_errlist[err]);
|
||||
return ("Unknown resolver error");
|
||||
}
|
||||
210
c/src/exec/libnetworking/libc/inet.3
Normal file
210
c/src/exec/libnetworking/libc/inet.3
Normal file
@@ -0,0 +1,210 @@
|
||||
.\" Copyright (c) 1983, 1990, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" From: @(#)inet.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd June 17, 1996
|
||||
.Dt INET 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm inet_aton ,
|
||||
.Nm inet_addr ,
|
||||
.Nm inet_network ,
|
||||
.Nm inet_ntoa ,
|
||||
.Nm inet_makeaddr ,
|
||||
.Nm inet_lnaof ,
|
||||
.Nm inet_netof
|
||||
.Nd Internet address manipulation routines
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <netinet/in.h>
|
||||
.Fd #include <arpa/inet.h>
|
||||
.Ft int
|
||||
.Fn inet_aton "const char *cp" "struct in_addr *pin"
|
||||
.Ft unsigned long
|
||||
.Fn inet_addr "const char *cp"
|
||||
.Ft unsigned long
|
||||
.Fn inet_network "const char *cp"
|
||||
.Ft char *
|
||||
.Fn inet_ntoa "struct in_addr in"
|
||||
.Ft struct in_addr
|
||||
.Fn inet_makeaddr "unsigned long net" "unsigned long lna"
|
||||
.Ft unsigned long
|
||||
.Fn inet_lnaof "struct in_addr in"
|
||||
.Ft unsigned long
|
||||
.Fn inet_netof "struct in_addr in"
|
||||
.Sh DESCRIPTION
|
||||
The routines
|
||||
.Fn inet_aton ,
|
||||
.Fn inet_addr
|
||||
and
|
||||
.Fn inet_network
|
||||
interpret character strings representing
|
||||
numbers expressed in the Internet standard
|
||||
.Ql \&.
|
||||
notation.
|
||||
The
|
||||
.Fn inet_aton
|
||||
routine interprets the specified character string as an Internet address,
|
||||
placing the address into the structure provided.
|
||||
It returns 1 if the string was successfully interpreted,
|
||||
or 0 if the string is invalid.
|
||||
The
|
||||
.Fn inet_addr
|
||||
and
|
||||
.Fn inet_network
|
||||
functions return numbers suitable for use
|
||||
as Internet addresses and Internet network
|
||||
numbers, respectively.
|
||||
The routine
|
||||
.Fn inet_ntoa
|
||||
takes an Internet address and returns an
|
||||
.Tn ASCII
|
||||
string representing the address in
|
||||
.Ql \&.
|
||||
notation. The routine
|
||||
.Fn inet_makeaddr
|
||||
takes an Internet network number and a local
|
||||
network address and constructs an Internet address
|
||||
from it. The routines
|
||||
.Fn inet_netof
|
||||
and
|
||||
.Fn inet_lnaof
|
||||
break apart Internet host addresses, returning
|
||||
the network number and local network address part,
|
||||
respectively.
|
||||
.Pp
|
||||
All Internet addresses are returned in network
|
||||
order (bytes ordered from left to right).
|
||||
All network numbers and local address parts are
|
||||
returned as machine format integer values.
|
||||
.Sh INTERNET ADDRESSES
|
||||
Values specified using the
|
||||
.Ql \&.
|
||||
notation take one
|
||||
of the following forms:
|
||||
.Bd -literal -offset indent
|
||||
a.b.c.d
|
||||
a.b.c
|
||||
a.b
|
||||
a
|
||||
.Ed
|
||||
.Pp
|
||||
When four parts are specified, each is interpreted
|
||||
as a byte of data and assigned, from left to right,
|
||||
to the four bytes of an Internet address. Note
|
||||
that when an Internet address is viewed as a 32-bit
|
||||
integer quantity on the
|
||||
.Tn VAX
|
||||
the bytes referred to
|
||||
above appear as
|
||||
.Dq Li d.c.b.a .
|
||||
That is,
|
||||
.Tn VAX
|
||||
bytes are
|
||||
ordered from right to left.
|
||||
.Pp
|
||||
When a three part address is specified, the last
|
||||
part is interpreted as a 16-bit quantity and placed
|
||||
in the right-most two bytes of the network address.
|
||||
This makes the three part address format convenient
|
||||
for specifying Class B network addresses as
|
||||
.Dq Li 128.net.host .
|
||||
.Pp
|
||||
When a two part address is supplied, the last part
|
||||
is interpreted as a 24-bit quantity and placed in
|
||||
the right most three bytes of the network address.
|
||||
This makes the two part address format convenient
|
||||
for specifying Class A network addresses as
|
||||
.Dq Li net.host .
|
||||
.Pp
|
||||
When only one part is given, the value is stored
|
||||
directly in the network address without any byte
|
||||
rearrangement.
|
||||
.Pp
|
||||
All numbers supplied as
|
||||
.Dq parts
|
||||
in a
|
||||
.Ql \&.
|
||||
notation
|
||||
may be decimal, octal, or hexadecimal, as specified
|
||||
in the C language (i.e., a leading 0x or 0X implies
|
||||
hexadecimal; otherwise, a leading 0 implies octal;
|
||||
otherwise, the number is interpreted as decimal).
|
||||
.Pp
|
||||
The
|
||||
.Fn inet_aton
|
||||
and
|
||||
.Fn inet_ntoa
|
||||
functions are semi-deprecated in favor of the
|
||||
.Xr addr2ascii 3
|
||||
family. However, since those functions are not yet widely implemented,
|
||||
portable programs cannot rely on their presence and will continue
|
||||
to use the
|
||||
.Xr inet 3
|
||||
functions for some time.
|
||||
.Sh DIAGNOSTICS
|
||||
The constant
|
||||
.Dv INADDR_NONE
|
||||
is returned by
|
||||
.Fn inet_addr
|
||||
and
|
||||
.Fn inet_network
|
||||
for malformed requests.
|
||||
.Sh SEE ALSO
|
||||
.Xr addr2ascii 3 ,
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr getnetent 3 ,
|
||||
.Xr hosts 5 ,
|
||||
.Xr networks 5
|
||||
.Sh HISTORY
|
||||
These
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
.Sh BUGS
|
||||
The value
|
||||
.Dv INADDR_NONE
|
||||
(0xffffffff) is a valid broadcast address, but
|
||||
.Fn inet_addr
|
||||
cannot return that value without indicating failure.
|
||||
The newer
|
||||
.Fn inet_aton
|
||||
function does not share this problem.
|
||||
The problem of host byte ordering versus network byte ordering is
|
||||
confusing.
|
||||
The string returned by
|
||||
.Fn inet_ntoa
|
||||
resides in a static memory area.
|
||||
.Pp
|
||||
Inet_addr should return a
|
||||
.Fa struct in_addr .
|
||||
180
c/src/exec/libnetworking/libc/inet_addr.c
Normal file
180
c/src/exec/libnetworking/libc/inet_addr.c
Normal file
@@ -0,0 +1,180 @@
|
||||
/*
|
||||
* ++Copyright++ 1983, 1990, 1993
|
||||
* -
|
||||
* Copyright (c) 1983, 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_addr.c 8.1 (Berkeley) 6/17/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Ascii internet address interpretation routine.
|
||||
* The value returned is in network order.
|
||||
*/
|
||||
u_long
|
||||
inet_addr(cp)
|
||||
register const char *cp;
|
||||
{
|
||||
struct in_addr val;
|
||||
|
||||
if (inet_aton(cp, &val))
|
||||
return (val.s_addr);
|
||||
return (INADDR_NONE);
|
||||
}
|
||||
|
||||
/*
|
||||
* Check whether "cp" is a valid ascii representation
|
||||
* of an Internet address and convert to a binary address.
|
||||
* Returns 1 if the address is valid, 0 if not.
|
||||
* This replaces inet_addr, the return value from which
|
||||
* cannot distinguish between failure and a local broadcast address.
|
||||
*/
|
||||
int
|
||||
inet_aton(cp, addr)
|
||||
register const char *cp;
|
||||
struct in_addr *addr;
|
||||
{
|
||||
register u_long val;
|
||||
register int base, n;
|
||||
register char c;
|
||||
u_int parts[4];
|
||||
register u_int *pp = parts;
|
||||
|
||||
c = *cp;
|
||||
for (;;) {
|
||||
/*
|
||||
* Collect number up to ``.''.
|
||||
* Values are specified as for C:
|
||||
* 0x=hex, 0=octal, isdigit=decimal.
|
||||
*/
|
||||
if (!isdigit(c))
|
||||
return (0);
|
||||
val = 0; base = 10;
|
||||
if (c == '0') {
|
||||
c = *++cp;
|
||||
if (c == 'x' || c == 'X')
|
||||
base = 16, c = *++cp;
|
||||
else
|
||||
base = 8;
|
||||
}
|
||||
for (;;) {
|
||||
if (isascii(c) && isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
c = *++cp;
|
||||
} else if (base == 16 && isascii(c) && isxdigit(c)) {
|
||||
val = (val << 4) |
|
||||
(c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
if (c == '.') {
|
||||
/*
|
||||
* Internet format:
|
||||
* a.b.c.d
|
||||
* a.b.c (with c treated as 16 bits)
|
||||
* a.b (with b treated as 24 bits)
|
||||
*/
|
||||
if (pp >= parts + 3)
|
||||
return (0);
|
||||
*pp++ = val;
|
||||
c = *++cp;
|
||||
} else
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Check for trailing characters.
|
||||
*/
|
||||
if (c != '\0' && (!isascii(c) || !isspace(c)))
|
||||
return (0);
|
||||
/*
|
||||
* Concoct the address according to
|
||||
* the number of parts specified.
|
||||
*/
|
||||
n = pp - parts + 1;
|
||||
switch (n) {
|
||||
|
||||
case 0:
|
||||
return (0); /* initial nondigit */
|
||||
|
||||
case 1: /* a -- 32 bits */
|
||||
break;
|
||||
|
||||
case 2: /* a.b -- 8.24 bits */
|
||||
if (val > 0xffffff)
|
||||
return (0);
|
||||
val |= parts[0] << 24;
|
||||
break;
|
||||
|
||||
case 3: /* a.b.c -- 8.8.16 bits */
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16);
|
||||
break;
|
||||
|
||||
case 4: /* a.b.c.d -- 8.8.8.8 bits */
|
||||
if (val > 0xff)
|
||||
return (0);
|
||||
val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
|
||||
break;
|
||||
}
|
||||
if (addr)
|
||||
addr->s_addr = htonl(val);
|
||||
return (1);
|
||||
}
|
||||
59
c/src/exec/libnetworking/libc/inet_lnaof.c
Normal file
59
c/src/exec/libnetworking/libc/inet_lnaof.c
Normal file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_lnaof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Return the local network address portion of an
|
||||
* internet address; handles class a/b/c network
|
||||
* number formats.
|
||||
*/
|
||||
u_long
|
||||
inet_lnaof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return ((i)&IN_CLASSA_HOST);
|
||||
else if (IN_CLASSB(i))
|
||||
return ((i)&IN_CLASSB_HOST);
|
||||
else
|
||||
return ((i)&IN_CLASSC_HOST);
|
||||
}
|
||||
62
c/src/exec/libnetworking/libc/inet_makeaddr.c
Normal file
62
c/src/exec/libnetworking/libc/inet_makeaddr.c
Normal file
@@ -0,0 +1,62 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_makeaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Formulate an Internet address from network + host. Used in
|
||||
* building addresses stored in the ifnet structure.
|
||||
*/
|
||||
struct in_addr
|
||||
inet_makeaddr(net, host)
|
||||
u_long net, host;
|
||||
{
|
||||
u_long addr;
|
||||
|
||||
if (net < 128)
|
||||
addr = (net << IN_CLASSA_NSHIFT) | (host & IN_CLASSA_HOST);
|
||||
else if (net < 65536)
|
||||
addr = (net << IN_CLASSB_NSHIFT) | (host & IN_CLASSB_HOST);
|
||||
else if (net < 16777216L)
|
||||
addr = (net << IN_CLASSC_NSHIFT) | (host & IN_CLASSC_HOST);
|
||||
else
|
||||
addr = net | host;
|
||||
addr = htonl(addr);
|
||||
return (*(struct in_addr *)&addr);
|
||||
}
|
||||
140
c/src/exec/libnetworking/libc/inet_net_ntop.c
Normal file
140
c/src/exec/libnetworking/libc/inet_net_ntop.c
Normal file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char orig_rcsid[] = "From Id: inet_net_ntop.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
|
||||
static const char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static char * inet_net_ntop_ipv4 __P((const u_char *src, int bits,
|
||||
char *dst, size_t size));
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_net_ntop(af, src, bits, dst, size)
|
||||
* convert network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_net_ntop(af, src, bits, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_ntop_ipv4(src, bits, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* static char *
|
||||
* inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
* convert IPv4 network number from network to presentation format.
|
||||
* generates CIDR style result always.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
static char *
|
||||
inet_net_ntop_ipv4(src, bits, dst, size)
|
||||
const u_char *src;
|
||||
int bits;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *t;
|
||||
u_int m;
|
||||
int b;
|
||||
|
||||
if (bits < 0 || bits > 32) {
|
||||
errno = EINVAL;
|
||||
return (NULL);
|
||||
}
|
||||
if (bits == 0) {
|
||||
if (size < sizeof "0")
|
||||
goto emsgsize;
|
||||
*dst++ = '0';
|
||||
*dst = '\0';
|
||||
}
|
||||
|
||||
/* Format whole octets. */
|
||||
for (b = bits / 8; b > 0; b--) {
|
||||
if (size < sizeof "255.")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
dst += SPRINTF((dst, "%u", *src++));
|
||||
if (b > 1) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format partial octet. */
|
||||
b = bits % 8;
|
||||
if (b > 0) {
|
||||
if (size < sizeof ".255")
|
||||
goto emsgsize;
|
||||
t = dst;
|
||||
if (dst != odst)
|
||||
*dst++ = '.';
|
||||
m = ((1 << b) - 1) << (8 - b);
|
||||
dst += SPRINTF((dst, "%u", *src & m));
|
||||
size -= (size_t)(dst - t);
|
||||
}
|
||||
|
||||
/* Format CIDR /width. */
|
||||
if (size < sizeof "/32")
|
||||
goto emsgsize;
|
||||
dst += SPRINTF((dst, "/%u", bits));
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
207
c/src/exec/libnetworking/libc/inet_net_pton.c
Normal file
207
c/src/exec/libnetworking/libc/inet_net_pton.c
Normal file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char orig_rcsid[] = "From Id: inet_net_pton.c,v 1.8 1996/11/21 10:28:12 vixie Exp $";
|
||||
static const char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
static int inet_net_pton_ipv4 __P((const char *src, u_char *dst,
|
||||
size_t size));
|
||||
|
||||
/*
|
||||
* static int
|
||||
* inet_net_pton(af, src, dst, size)
|
||||
* convert network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not a valid network specification.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
int
|
||||
inet_net_pton(af, src, dst, size)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_net_pton_ipv4(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* static int
|
||||
* inet_net_pton_ipv4(src, dst, size)
|
||||
* convert IPv4 network number from presentation to network format.
|
||||
* accepts hex octets, hex strings, decimal octets, and /CIDR.
|
||||
* "size" is in bytes and describes "dst".
|
||||
* return:
|
||||
* number of bits, either imputed classfully or specified with /CIDR,
|
||||
* or -1 if some failure occurred (check errno). ENOENT means it was
|
||||
* not an IPv4 network specification.
|
||||
* note:
|
||||
* network byte order assumed. this means 192.5.5.240/28 has
|
||||
* 0x11110000 in its fourth octet.
|
||||
* author:
|
||||
* Paul Vixie (ISC), June 1996
|
||||
*/
|
||||
static int
|
||||
inet_net_pton_ipv4(src, dst, size)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
size_t size;
|
||||
{
|
||||
static const char
|
||||
xdigits[] = "0123456789abcdef",
|
||||
digits[] = "0123456789";
|
||||
int n, ch, tmp, dirty, bits;
|
||||
const u_char *odst = dst;
|
||||
|
||||
ch = *src++;
|
||||
if (ch == '0' && (src[0] == 'x' || src[0] == 'X')
|
||||
&& isascii(src[1]) && isxdigit(src[1])) {
|
||||
/* Hexadecimal: Eat nybble string. */
|
||||
if (size <= 0)
|
||||
goto emsgsize;
|
||||
*dst = 0, dirty = 0;
|
||||
src++; /* skip x or X. */
|
||||
while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isxdigit(ch)) {
|
||||
if (isupper(ch))
|
||||
ch = tolower(ch);
|
||||
n = strchr(xdigits, ch) - xdigits;
|
||||
assert(n >= 0 && n <= 15);
|
||||
*dst |= n;
|
||||
if (!dirty++)
|
||||
*dst <<= 4;
|
||||
else if (size-- > 0)
|
||||
*++dst = 0, dirty = 0;
|
||||
else
|
||||
goto emsgsize;
|
||||
}
|
||||
if (dirty)
|
||||
size--;
|
||||
} else if (isascii(ch) && isdigit(ch)) {
|
||||
/* Decimal: eat dotted digit string. */
|
||||
for (;;) {
|
||||
tmp = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
assert(n >= 0 && n <= 9);
|
||||
tmp *= 10;
|
||||
tmp += n;
|
||||
if (tmp > 255)
|
||||
goto enoent;
|
||||
} while ((ch = *src++) != '\0' &&
|
||||
isascii(ch) && isdigit(ch));
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = (u_char) tmp;
|
||||
if (ch == '\0' || ch == '/')
|
||||
break;
|
||||
if (ch != '.')
|
||||
goto enoent;
|
||||
ch = *src++;
|
||||
if (!isascii(ch) || !isdigit(ch))
|
||||
goto enoent;
|
||||
}
|
||||
} else
|
||||
goto enoent;
|
||||
|
||||
bits = -1;
|
||||
if (ch == '/' && isascii(src[0]) && isdigit(src[0]) && dst > odst) {
|
||||
/* CIDR width specifier. Nothing can follow it. */
|
||||
ch = *src++; /* Skip over the /. */
|
||||
bits = 0;
|
||||
do {
|
||||
n = strchr(digits, ch) - digits;
|
||||
assert(n >= 0 && n <= 9);
|
||||
bits *= 10;
|
||||
bits += n;
|
||||
} while ((ch = *src++) != '\0' && isascii(ch) && isdigit(ch));
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
if (bits > 32)
|
||||
goto emsgsize;
|
||||
}
|
||||
|
||||
/* Firey death and destruction unless we prefetched EOS. */
|
||||
if (ch != '\0')
|
||||
goto enoent;
|
||||
|
||||
/* If nothing was written to the destination, we found no address. */
|
||||
if (dst == odst)
|
||||
goto enoent;
|
||||
/* If no CIDR spec was given, infer width from net class. */
|
||||
if (bits == -1) {
|
||||
if (*odst >= 240) /* Class E */
|
||||
bits = 32;
|
||||
else if (*odst >= 224) /* Class D */
|
||||
bits = 4;
|
||||
else if (*odst >= 192) /* Class C */
|
||||
bits = 24;
|
||||
else if (*odst >= 128) /* Class B */
|
||||
bits = 16;
|
||||
else /* Class A */
|
||||
bits = 8;
|
||||
/* If imputed mask is narrower than specified octets, widen. */
|
||||
if (bits >= 8 && bits < ((dst - odst) * 8))
|
||||
bits = (dst - odst) * 8;
|
||||
}
|
||||
/* Extend network to cover the actual mask. */
|
||||
while (bits > ((dst - odst) * 8)) {
|
||||
if (size-- <= 0)
|
||||
goto emsgsize;
|
||||
*dst++ = '\0';
|
||||
}
|
||||
return (bits);
|
||||
|
||||
enoent:
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
84
c/src/exec/libnetworking/libc/inet_neta.c
Normal file
84
c/src/exec/libnetworking/libc/inet_neta.c
Normal file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char orig_rcsid[] = "From Id: inet_neta.c,v 8.2 1996/08/08 06:54:44 vixie Exp";
|
||||
static const char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#ifdef SPRINTF_CHAR
|
||||
# define SPRINTF(x) strlen(sprintf/**/x)
|
||||
#else
|
||||
# define SPRINTF(x) ((size_t)sprintf x)
|
||||
#endif
|
||||
|
||||
/*
|
||||
* char *
|
||||
* inet_neta(src, dst, size)
|
||||
* format a u_long network number into presentation format.
|
||||
* return:
|
||||
* pointer to dst, or NULL if an error occurred (check errno).
|
||||
* note:
|
||||
* format of ``src'' is as for inet_network().
|
||||
* author:
|
||||
* Paul Vixie (ISC), July 1996
|
||||
*/
|
||||
char *
|
||||
inet_neta(src, dst, size)
|
||||
u_long src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
char *odst = dst;
|
||||
char *tp;
|
||||
|
||||
while (src & 0xffffffff) {
|
||||
u_char b = (src & 0xff000000) >> 24;
|
||||
|
||||
src <<= 8;
|
||||
if (b) {
|
||||
if (size < sizeof "255.")
|
||||
goto emsgsize;
|
||||
tp = dst;
|
||||
dst += SPRINTF((dst, "%u", b));
|
||||
if (src != 0L) {
|
||||
*dst++ = '.';
|
||||
*dst = '\0';
|
||||
}
|
||||
size -= (size_t)(dst - tp);
|
||||
}
|
||||
}
|
||||
if (dst == odst) {
|
||||
if (size < sizeof "0.0.0.0")
|
||||
goto emsgsize;
|
||||
strcpy(dst, "0.0.0.0");
|
||||
}
|
||||
return (odst);
|
||||
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (NULL);
|
||||
}
|
||||
58
c/src/exec/libnetworking/libc/inet_netof.c
Normal file
58
c/src/exec/libnetworking/libc/inet_netof.c
Normal file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_netof.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
/*
|
||||
* Return the network number from an internet
|
||||
* address; handles class a/b/c network #'s.
|
||||
*/
|
||||
u_long
|
||||
inet_netof(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
register u_long i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (((i)&IN_CLASSA_NET) >> IN_CLASSA_NSHIFT);
|
||||
else if (IN_CLASSB(i))
|
||||
return (((i)&IN_CLASSB_NET) >> IN_CLASSB_NSHIFT);
|
||||
else
|
||||
return (((i)&IN_CLASSC_NET) >> IN_CLASSC_NSHIFT);
|
||||
}
|
||||
90
c/src/exec/libnetworking/libc/inet_network.c
Normal file
90
c/src/exec/libnetworking/libc/inet_network.c
Normal file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_network.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <ctype.h>
|
||||
|
||||
/*
|
||||
* Internet network address interpretation routine.
|
||||
* The library routines call this routine to interpret
|
||||
* network numbers.
|
||||
*/
|
||||
u_long
|
||||
inet_network(cp)
|
||||
register const char *cp;
|
||||
{
|
||||
register u_long val, base, n, i;
|
||||
register char c;
|
||||
u_long parts[4], *pp = parts;
|
||||
|
||||
again:
|
||||
val = 0; base = 10;
|
||||
if (*cp == '0')
|
||||
base = 8, cp++;
|
||||
if (*cp == 'x' || *cp == 'X')
|
||||
base = 16, cp++;
|
||||
while ((c = *cp) != 0) {
|
||||
if (isdigit(c)) {
|
||||
val = (val * base) + (c - '0');
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
if (base == 16 && isxdigit(c)) {
|
||||
val = (val << 4) + (c + 10 - (islower(c) ? 'a' : 'A'));
|
||||
cp++;
|
||||
continue;
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (*cp == '.') {
|
||||
if (pp >= parts + 3)
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val, cp++;
|
||||
goto again;
|
||||
}
|
||||
if (*cp && !isspace(*cp))
|
||||
return (INADDR_NONE);
|
||||
*pp++ = val;
|
||||
n = pp - parts;
|
||||
for (val = 0, i = 0; i < n; i++) {
|
||||
val <<= 8;
|
||||
val |= parts[i] & 0xff;
|
||||
}
|
||||
return (val);
|
||||
}
|
||||
57
c/src/exec/libnetworking/libc/inet_ntoa.c
Normal file
57
c/src/exec/libnetworking/libc/inet_ntoa.c
Normal file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)inet_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Convert network-format internet address
|
||||
* to base 256 d.d.d.d representation.
|
||||
*/
|
||||
char *
|
||||
inet_ntoa(in)
|
||||
struct in_addr in;
|
||||
{
|
||||
static char ret[18];
|
||||
|
||||
strcpy(ret, "[inet_ntoa error]");
|
||||
(void) inet_ntop(AF_INET, &in, ret, sizeof ret);
|
||||
return (ret);
|
||||
}
|
||||
191
c/src/exec/libnetworking/libc/inet_ntop.c
Normal file
191
c/src/exec/libnetworking/libc/inet_ntop.c
Normal file
@@ -0,0 +1,191 @@
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static const char *inet_ntop4 __P((const u_char *src, char *dst, size_t size));
|
||||
static const char *inet_ntop6 __P((const u_char *src, char *dst, size_t size));
|
||||
|
||||
/* char *
|
||||
* inet_ntop(af, src, dst, size)
|
||||
* convert a network format address to presentation format.
|
||||
* return:
|
||||
* pointer to presentation format address (`dst'), or NULL (see errno).
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
const char *
|
||||
inet_ntop(af, src, dst, size)
|
||||
int af;
|
||||
const void *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_ntop4(src, dst, size));
|
||||
case AF_INET6:
|
||||
return (inet_ntop6(src, dst, size));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (NULL);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop4(src, dst, size)
|
||||
* format an IPv4 address, more or less like inet_ntoa()
|
||||
* return:
|
||||
* `dst' (as a const)
|
||||
* notes:
|
||||
* (1) uses no statics
|
||||
* (2) takes a u_char* not an in_addr as input
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop4(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
static const char fmt[] = "%u.%u.%u.%u";
|
||||
char tmp[sizeof "255.255.255.255"];
|
||||
|
||||
if (SPRINTF((tmp, fmt, src[0], src[1], src[2], src[3])) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
/* const char *
|
||||
* inet_ntop6(src, dst, size)
|
||||
* convert IPv6 binary address into presentation (printable) format
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static const char *
|
||||
inet_ntop6(src, dst, size)
|
||||
const u_char *src;
|
||||
char *dst;
|
||||
size_t size;
|
||||
{
|
||||
/*
|
||||
* Note that int32_t and int16_t need only be "at least" large enough
|
||||
* to contain a value of the specified size. On some systems, like
|
||||
* Crays, there is no such thing as an integer variable with 16 bits.
|
||||
* Keep this in mind if you think this function should have been coded
|
||||
* to use pointer overlays. All the world's not a VAX.
|
||||
*/
|
||||
char tmp[sizeof "ffff:ffff:ffff:ffff:ffff:ffff:255.255.255.255"], *tp;
|
||||
struct { int base, len; } best, cur;
|
||||
u_int words[NS_IN6ADDRSZ / NS_INT16SZ];
|
||||
int i;
|
||||
|
||||
/*
|
||||
* Preprocess:
|
||||
* Copy the input (bytewise) array into a wordwise array.
|
||||
* Find the longest run of 0x00's in src[] for :: shorthanding.
|
||||
*/
|
||||
memset(words, '\0', sizeof words);
|
||||
for (i = 0; i < NS_IN6ADDRSZ; i++)
|
||||
words[i / 2] |= (src[i] << ((1 - (i % 2)) << 3));
|
||||
best.base = -1;
|
||||
cur.base = -1;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
if (words[i] == 0) {
|
||||
if (cur.base == -1)
|
||||
cur.base = i, cur.len = 1;
|
||||
else
|
||||
cur.len++;
|
||||
} else {
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
cur.base = -1;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (cur.base != -1) {
|
||||
if (best.base == -1 || cur.len > best.len)
|
||||
best = cur;
|
||||
}
|
||||
if (best.base != -1 && best.len < 2)
|
||||
best.base = -1;
|
||||
|
||||
/*
|
||||
* Format the result.
|
||||
*/
|
||||
tp = tmp;
|
||||
for (i = 0; i < (NS_IN6ADDRSZ / NS_INT16SZ); i++) {
|
||||
/* Are we inside the best run of 0x00's? */
|
||||
if (best.base != -1 && i >= best.base &&
|
||||
i < (best.base + best.len)) {
|
||||
if (i == best.base)
|
||||
*tp++ = ':';
|
||||
continue;
|
||||
}
|
||||
/* Are we following an initial run of 0x00s or any real hex? */
|
||||
if (i != 0)
|
||||
*tp++ = ':';
|
||||
/* Is this address an encapsulated IPv4? */
|
||||
if (i == 6 && best.base == 0 &&
|
||||
(best.len == 6 || (best.len == 5 && words[5] == 0xffff))) {
|
||||
if (!inet_ntop4(src+12, tp, sizeof tmp - (tp - tmp)))
|
||||
return (NULL);
|
||||
tp += strlen(tp);
|
||||
break;
|
||||
}
|
||||
tp += SPRINTF((tp, "%x", words[i]));
|
||||
}
|
||||
/* Was it a trailing run of 0x00's? */
|
||||
if (best.base != -1 && (best.base + best.len) ==
|
||||
(NS_IN6ADDRSZ / NS_INT16SZ))
|
||||
*tp++ = ':';
|
||||
*tp++ = '\0';
|
||||
|
||||
/*
|
||||
* Check for overflow, copy, and we're done.
|
||||
*/
|
||||
if ((size_t)(tp - tmp) > size) {
|
||||
errno = ENOSPC;
|
||||
return (NULL);
|
||||
}
|
||||
strcpy(dst, tmp);
|
||||
return (dst);
|
||||
}
|
||||
214
c/src/exec/libnetworking/libc/inet_pton.c
Normal file
214
c/src/exec/libnetworking/libc/inet_pton.c
Normal file
@@ -0,0 +1,214 @@
|
||||
/* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
|
||||
/*
|
||||
* WARNING: Don't even consider trying to compile this on a system where
|
||||
* sizeof(int) < 4. sizeof(int) > 4 is fine; all the world's not a VAX.
|
||||
*/
|
||||
|
||||
static int inet_pton4 __P((const char *src, u_char *dst));
|
||||
static int inet_pton6 __P((const char *src, u_char *dst));
|
||||
|
||||
/* int
|
||||
* inet_pton(af, src, dst)
|
||||
* convert from presentation format (which usually means ASCII printable)
|
||||
* to network format (which is usually some kind of binary format).
|
||||
* return:
|
||||
* 1 if the address was valid for the specified address family
|
||||
* 0 if the address wasn't valid (`dst' is untouched in this case)
|
||||
* -1 if some other error occurred (`dst' is untouched in this case, too)
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
int
|
||||
inet_pton(af, src, dst)
|
||||
int af;
|
||||
const char *src;
|
||||
void *dst;
|
||||
{
|
||||
switch (af) {
|
||||
case AF_INET:
|
||||
return (inet_pton4(src, dst));
|
||||
case AF_INET6:
|
||||
return (inet_pton6(src, dst));
|
||||
default:
|
||||
errno = EAFNOSUPPORT;
|
||||
return (-1);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton4(src, dst)
|
||||
* like inet_aton() but without all the hexadecimal and shorthand.
|
||||
* return:
|
||||
* 1 if `src' is a valid dotted quad, else 0.
|
||||
* notice:
|
||||
* does not touch `dst' unless it's returning 1.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton4(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char digits[] = "0123456789";
|
||||
int saw_digit, octets, ch;
|
||||
u_char tmp[NS_INADDRSZ], *tp;
|
||||
|
||||
saw_digit = 0;
|
||||
octets = 0;
|
||||
*(tp = tmp) = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr(digits, ch)) != NULL) {
|
||||
u_int new = *tp * 10 + (pch - digits);
|
||||
|
||||
if (new > 255)
|
||||
return (0);
|
||||
*tp = new;
|
||||
if (! saw_digit) {
|
||||
if (++octets > 4)
|
||||
return (0);
|
||||
saw_digit = 1;
|
||||
}
|
||||
} else if (ch == '.' && saw_digit) {
|
||||
if (octets == 4)
|
||||
return (0);
|
||||
*++tp = 0;
|
||||
saw_digit = 0;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
if (octets < 4)
|
||||
return (0);
|
||||
|
||||
memcpy(dst, tmp, NS_INADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int
|
||||
* inet_pton6(src, dst)
|
||||
* convert presentation level address to network order binary form.
|
||||
* return:
|
||||
* 1 if `src' is a valid [RFC1884 2.2] address, else 0.
|
||||
* notice:
|
||||
* (1) does not touch `dst' unless it's returning 1.
|
||||
* (2) :: in a full address is silently ignored.
|
||||
* credit:
|
||||
* inspired by Mark Andrews.
|
||||
* author:
|
||||
* Paul Vixie, 1996.
|
||||
*/
|
||||
static int
|
||||
inet_pton6(src, dst)
|
||||
const char *src;
|
||||
u_char *dst;
|
||||
{
|
||||
static const char xdigits_l[] = "0123456789abcdef",
|
||||
xdigits_u[] = "0123456789ABCDEF";
|
||||
u_char tmp[NS_IN6ADDRSZ], *tp, *endp, *colonp;
|
||||
const char *xdigits, *curtok;
|
||||
int ch, saw_xdigit;
|
||||
u_int val;
|
||||
|
||||
memset((tp = tmp), '\0', NS_IN6ADDRSZ);
|
||||
endp = tp + NS_IN6ADDRSZ;
|
||||
colonp = NULL;
|
||||
/* Leading :: requires some special handling. */
|
||||
if (*src == ':')
|
||||
if (*++src != ':')
|
||||
return (0);
|
||||
curtok = src;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
const char *pch;
|
||||
|
||||
if ((pch = strchr((xdigits = xdigits_l), ch)) == NULL)
|
||||
pch = strchr((xdigits = xdigits_u), ch);
|
||||
if (pch != NULL) {
|
||||
val <<= 4;
|
||||
val |= (pch - xdigits);
|
||||
if (val > 0xffff)
|
||||
return (0);
|
||||
saw_xdigit = 1;
|
||||
continue;
|
||||
}
|
||||
if (ch == ':') {
|
||||
curtok = src;
|
||||
if (!saw_xdigit) {
|
||||
if (colonp)
|
||||
return (0);
|
||||
colonp = tp;
|
||||
continue;
|
||||
}
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
saw_xdigit = 0;
|
||||
val = 0;
|
||||
continue;
|
||||
}
|
||||
if (ch == '.' && ((tp + NS_INADDRSZ) <= endp) &&
|
||||
inet_pton4(curtok, tp) > 0) {
|
||||
tp += NS_INADDRSZ;
|
||||
saw_xdigit = 0;
|
||||
break; /* '\0' was seen by inet_pton4(). */
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
if (saw_xdigit) {
|
||||
if (tp + NS_INT16SZ > endp)
|
||||
return (0);
|
||||
*tp++ = (u_char) (val >> 8) & 0xff;
|
||||
*tp++ = (u_char) val & 0xff;
|
||||
}
|
||||
if (colonp != NULL) {
|
||||
/*
|
||||
* Since some memmove()'s erroneously fail to handle
|
||||
* overlapping regions, we'll do the shift by hand.
|
||||
*/
|
||||
const int n = tp - colonp;
|
||||
int i;
|
||||
|
||||
for (i = 1; i <= n; i++) {
|
||||
endp[- i] = colonp[n - i];
|
||||
colonp[n - i] = 0;
|
||||
}
|
||||
tp = endp;
|
||||
}
|
||||
if (tp != endp)
|
||||
return (0);
|
||||
memcpy(dst, tmp, NS_IN6ADDRSZ);
|
||||
return (1);
|
||||
}
|
||||
110
c/src/exec/libnetworking/libc/iso_addr.3
Normal file
110
c/src/exec/libnetworking/libc/iso_addr.3
Normal file
@@ -0,0 +1,110 @@
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)iso_addr.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt ISO_ADDR 3
|
||||
.Os
|
||||
.Sh NAME
|
||||
.Nm iso_addr ,
|
||||
.Nm iso_ntoa
|
||||
.Nd "elementary network address conversion routines for Open System Interconnection
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <netiso/iso.h>
|
||||
.Ft struct iso_addr *
|
||||
.Fn iso_addr "char *cp"
|
||||
.Ft char *
|
||||
.Fn iso_ntoa "struct iso_addr *isoa"
|
||||
.Sh DESCRIPTION
|
||||
The routine
|
||||
.Fn iso_addr
|
||||
interprets character strings representing
|
||||
.Tn OSI
|
||||
addresses, returning binary information suitable
|
||||
for use in system calls.
|
||||
The routine
|
||||
.Fn iso_ntoa
|
||||
takes
|
||||
.Tn OSI
|
||||
addresses and returns
|
||||
.Tn ASCII
|
||||
strings representing NSAPs (network service
|
||||
access points) in a
|
||||
notation inverse to that accepted by
|
||||
.Fn iso_addr .
|
||||
.Pp
|
||||
Unfortunately, no universal standard exists for representing
|
||||
.Tn OSI
|
||||
network addresses.
|
||||
.Pp
|
||||
The format employed by
|
||||
.Fn iso_addr
|
||||
is a sequence of hexadecimal
|
||||
.Dq digits
|
||||
(optionally separated by periods),
|
||||
of the form:
|
||||
.Bd -filled -offset indent
|
||||
<hex digits>.<hex digits>.<hex digits>
|
||||
.Ed
|
||||
.Pp
|
||||
Each pair of hexadecimal digits represents a byte
|
||||
with the leading digit indicating the higher-ordered bits.
|
||||
A period following an even number of bytes has no
|
||||
effect (but may be used to increase legibility).
|
||||
A period following an odd number of bytes has the
|
||||
effect of causing the byte of address being translated
|
||||
to have its higher order bits filled with zeros.
|
||||
.Sh RETURN VALUES
|
||||
.Fn iso_ntoa
|
||||
always returns a null terminated string.
|
||||
.Fn iso_addr
|
||||
always returns a pointer to a struct iso_addr.
|
||||
(See
|
||||
.Sx BUGS . )
|
||||
.Sh SEE ALSO
|
||||
.Xr iso 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn iso_addr
|
||||
and
|
||||
.Fn iso_ntoa
|
||||
functions appeared in
|
||||
.Bx 4.3 Reno .
|
||||
.Sh BUGS
|
||||
The returned values
|
||||
reside in a static memory area.
|
||||
.Pp
|
||||
The function
|
||||
.Fn iso_addr
|
||||
should diagnose improperly formed input, and there should be an unambiguous
|
||||
way to recognize this.
|
||||
117
c/src/exec/libnetworking/libc/iso_addr.c
Normal file
117
c/src/exec/libnetworking/libc/iso_addr.c
Normal file
@@ -0,0 +1,117 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)iso_addr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <string.h>
|
||||
|
||||
/* States*/
|
||||
#define VIRGIN 0
|
||||
#define GOTONE 1
|
||||
#define GOTTWO 2
|
||||
/* Inputs */
|
||||
#define DIGIT (4*0)
|
||||
#define END (4*1)
|
||||
#define DELIM (4*2)
|
||||
|
||||
struct iso_addr *
|
||||
iso_addr(addr)
|
||||
register const char *addr;
|
||||
{
|
||||
static struct iso_addr out_addr;
|
||||
register char *cp = out_addr.isoa_genaddr;
|
||||
char *cplim = cp + sizeof(out_addr.isoa_genaddr);
|
||||
register int byte = 0, state = VIRGIN, new;
|
||||
|
||||
bzero((char *)&out_addr, sizeof(out_addr));
|
||||
do {
|
||||
if ((*addr >= '0') && (*addr <= '9')) {
|
||||
new = *addr - '0';
|
||||
} else if ((*addr >= 'a') && (*addr <= 'f')) {
|
||||
new = *addr - 'a' + 10;
|
||||
} else if ((*addr >= 'A') && (*addr <= 'F')) {
|
||||
new = *addr - 'A' + 10;
|
||||
} else if (*addr == 0)
|
||||
state |= END;
|
||||
else
|
||||
state |= DELIM;
|
||||
addr++;
|
||||
switch (state /* | INPUT */) {
|
||||
case GOTTWO | DIGIT:
|
||||
*cp++ = byte; /*FALLTHROUGH*/
|
||||
case VIRGIN | DIGIT:
|
||||
state = GOTONE; byte = new; continue;
|
||||
case GOTONE | DIGIT:
|
||||
state = GOTTWO; byte = new + (byte << 4); continue;
|
||||
default: /* | DELIM */
|
||||
state = VIRGIN; *cp++ = byte; byte = 0; continue;
|
||||
case GOTONE | END:
|
||||
case GOTTWO | END:
|
||||
*cp++ = byte; /* FALLTHROUGH */
|
||||
case VIRGIN | END:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} while (cp < cplim);
|
||||
out_addr.isoa_len = cp - out_addr.isoa_genaddr;
|
||||
return (&out_addr);
|
||||
}
|
||||
|
||||
static char hexlist[] = "0123456789abcdef";
|
||||
|
||||
char *
|
||||
iso_ntoa(isoa)
|
||||
const struct iso_addr *isoa;
|
||||
{
|
||||
static char tmpbuf[sizeof(isoa->isoa_genaddr)*3];
|
||||
const u_char *binary;
|
||||
char *cp;
|
||||
int i;
|
||||
|
||||
binary = isoa->isoa_genaddr;
|
||||
cp = tmpbuf;
|
||||
|
||||
for (i = 0; i < isoa->isoa_len; i++) {
|
||||
*cp++ = hexlist[*binary >> 4];
|
||||
*cp++ = hexlist[*binary++ & 0xf];
|
||||
|
||||
if ((((i % 2) == 0) && ((i + 1) < isoa->isoa_len)))
|
||||
*cp++ = '.';
|
||||
}
|
||||
*cp = '\0';
|
||||
return tmpbuf;
|
||||
}
|
||||
138
c/src/exec/libnetworking/libc/linkaddr.3
Normal file
138
c/src/exec/libnetworking/libc/linkaddr.3
Normal file
@@ -0,0 +1,138 @@
|
||||
.\" Copyright (c) 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" This code is derived from software contributed to Berkeley by
|
||||
.\" Donn Seeley at BSDI.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" From: @(#)linkaddr.3 8.1 (Berkeley) 7/28/93
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd June 17, 1996
|
||||
.Dt LINK_ADDR 3
|
||||
.Os BSD 4.4
|
||||
.Sh NAME
|
||||
.Nm link_addr ,
|
||||
.Nm link_ntoa
|
||||
.Nd elementary address specification routines for link level access
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <sys/socket.h>
|
||||
.Fd #include <net/if_dl.h>
|
||||
.Ft void
|
||||
.Fn link_addr "const char *addr" "struct sockaddr_dl *sdl"
|
||||
.Ft char *
|
||||
.Fn link_ntoa "const struct sockaddr_dl *sdl"
|
||||
.Sh DESCRIPTION
|
||||
The routine
|
||||
.Fn link_addr
|
||||
interprets character strings representing
|
||||
link-level addresses, returning binary information suitable
|
||||
for use in system calls.
|
||||
The routine
|
||||
.Fn link_ntoa
|
||||
takes
|
||||
a link-level
|
||||
address and returns an
|
||||
.Tn ASCII
|
||||
string representing some of the information present,
|
||||
including the link level address itself, and the interface name
|
||||
or number, if present.
|
||||
This facility is experimental and is
|
||||
still subject to change.
|
||||
.Pp
|
||||
For
|
||||
.Fn link_addr ,
|
||||
the string
|
||||
.Fa addr
|
||||
may contain
|
||||
an optional network interface identifier of the form
|
||||
.Dq "name unit-number" ,
|
||||
suitable for the first argument to
|
||||
.Xr ifconfig 8 ,
|
||||
followed in all cases by a colon and
|
||||
an interface address in the form of
|
||||
groups of hexadecimal digits
|
||||
separated by periods.
|
||||
Each group represents a byte of address;
|
||||
address bytes are filled left to right from
|
||||
low order bytes through high order bytes.
|
||||
.Pp
|
||||
.\" A regular expression may make this format clearer:
|
||||
.\" .Bd -literal -offset indent
|
||||
.\" ([a-z]+[0-9]+:)?[0-9a-f]+(\e.[0-9a-f]+)*
|
||||
.\" .Ed
|
||||
.\" .Pp
|
||||
Thus
|
||||
.Li le0:8.0.9.13.d.30
|
||||
represents an ethernet address
|
||||
to be transmitted on the first Lance ethernet interface.
|
||||
.Pp
|
||||
The direct use of these functions is deprecated in favor of the
|
||||
.Xr addr2ascii 3
|
||||
interface; however, portable programs cannot rely on the latter as it is
|
||||
not yet widely implemented.
|
||||
.Sh RETURN VALUES
|
||||
.Fn link_ntoa
|
||||
always returns a null terminated string.
|
||||
.Fn link_addr
|
||||
has no return value.
|
||||
(See
|
||||
.Sx BUGS . )
|
||||
.Sh SEE ALSO
|
||||
.Xr addr2ascii 3
|
||||
.\" .Xr iso 4
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn link_addr
|
||||
and
|
||||
.Fn link_ntoa
|
||||
functions appeared in
|
||||
.Bx 4.3 Reno .
|
||||
.Sh BUGS
|
||||
The returned values for link_ntoa
|
||||
reside in a static memory area.
|
||||
.Pp
|
||||
The function
|
||||
.Fn link_addr
|
||||
should diagnose improperly formed input, and there should be an unambiguous
|
||||
way to recognize this.
|
||||
.Pp
|
||||
If the
|
||||
.Va sdl_len
|
||||
field of the link socket address
|
||||
.Fa sdl
|
||||
is 0,
|
||||
.Fn link_ntoa
|
||||
will not insert a colon before the interface address bytes.
|
||||
If this translated address is given to
|
||||
.Fn link_addr
|
||||
without inserting an initial colon,
|
||||
the latter will not interpret it correctly.
|
||||
158
c/src/exec/libnetworking/libc/linkaddr.c
Normal file
158
c/src/exec/libnetworking/libc/linkaddr.c
Normal file
@@ -0,0 +1,158 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)linkaddr.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <string.h>
|
||||
|
||||
/* States*/
|
||||
#define NAMING 0
|
||||
#define GOTONE 1
|
||||
#define GOTTWO 2
|
||||
#define RESET 3
|
||||
/* Inputs */
|
||||
#define DIGIT (4*0)
|
||||
#define END (4*1)
|
||||
#define DELIM (4*2)
|
||||
#define LETTER (4*3)
|
||||
|
||||
void
|
||||
link_addr(addr, sdl)
|
||||
register const char *addr;
|
||||
register struct sockaddr_dl *sdl;
|
||||
{
|
||||
register char *cp = sdl->sdl_data;
|
||||
char *cplim = sdl->sdl_len + (char *)sdl;
|
||||
register int byte = 0, state = NAMING, new;
|
||||
|
||||
bzero((char *)&sdl->sdl_family, sdl->sdl_len - 1);
|
||||
sdl->sdl_family = AF_LINK;
|
||||
do {
|
||||
state &= ~LETTER;
|
||||
if ((*addr >= '0') && (*addr <= '9')) {
|
||||
new = *addr - '0';
|
||||
} else if ((*addr >= 'a') && (*addr <= 'f')) {
|
||||
new = *addr - 'a' + 10;
|
||||
} else if ((*addr >= 'A') && (*addr <= 'F')) {
|
||||
new = *addr - 'A' + 10;
|
||||
} else if (*addr == 0) {
|
||||
state |= END;
|
||||
} else if (state == NAMING &&
|
||||
(((*addr >= 'A') && (*addr <= 'Z')) ||
|
||||
((*addr >= 'a') && (*addr <= 'z'))))
|
||||
state |= LETTER;
|
||||
else
|
||||
state |= DELIM;
|
||||
addr++;
|
||||
switch (state /* | INPUT */) {
|
||||
case NAMING | DIGIT:
|
||||
case NAMING | LETTER:
|
||||
*cp++ = addr[-1];
|
||||
continue;
|
||||
case NAMING | DELIM:
|
||||
state = RESET;
|
||||
sdl->sdl_nlen = cp - sdl->sdl_data;
|
||||
continue;
|
||||
case GOTTWO | DIGIT:
|
||||
*cp++ = byte;
|
||||
/* FALLTHROUGH */
|
||||
case RESET | DIGIT:
|
||||
state = GOTONE;
|
||||
byte = new;
|
||||
continue;
|
||||
case GOTONE | DIGIT:
|
||||
state = GOTTWO;
|
||||
byte = new + (byte << 4);
|
||||
continue;
|
||||
default: /* | DELIM */
|
||||
state = RESET;
|
||||
*cp++ = byte;
|
||||
byte = 0;
|
||||
continue;
|
||||
case GOTONE | END:
|
||||
case GOTTWO | END:
|
||||
*cp++ = byte;
|
||||
/* FALLTHROUGH */
|
||||
case RESET | END:
|
||||
break;
|
||||
}
|
||||
break;
|
||||
} while (cp < cplim);
|
||||
sdl->sdl_alen = cp - LLADDR(sdl);
|
||||
new = cp - (char *)sdl;
|
||||
if (new > sizeof(*sdl))
|
||||
sdl->sdl_len = new;
|
||||
return;
|
||||
}
|
||||
|
||||
static char hexlist[] = "0123456789abcdef";
|
||||
|
||||
char *
|
||||
link_ntoa(sdl)
|
||||
register const struct sockaddr_dl *sdl;
|
||||
{
|
||||
static char obuf[64];
|
||||
register char *out = obuf;
|
||||
register int i;
|
||||
register u_char *in = (u_char *)LLADDR(sdl);
|
||||
u_char *inlim = in + sdl->sdl_alen;
|
||||
int firsttime = 1;
|
||||
|
||||
if (sdl->sdl_nlen) {
|
||||
bcopy(sdl->sdl_data, obuf, sdl->sdl_nlen);
|
||||
out += sdl->sdl_nlen;
|
||||
if (sdl->sdl_alen)
|
||||
*out++ = ':';
|
||||
}
|
||||
while (in < inlim) {
|
||||
if (firsttime)
|
||||
firsttime = 0;
|
||||
else
|
||||
*out++ = '.';
|
||||
i = *in++;
|
||||
if (i > 0xf) {
|
||||
out[1] = hexlist[i & 0xf];
|
||||
i >>= 4;
|
||||
out[0] = hexlist[i];
|
||||
out += 2;
|
||||
} else
|
||||
*out++ = hexlist[i];
|
||||
}
|
||||
*out = 0;
|
||||
return (obuf);
|
||||
}
|
||||
128
c/src/exec/libnetworking/libc/map_v4v6.c
Normal file
128
c/src/exec/libnetworking/libc/map_v4v6.c
Normal file
@@ -0,0 +1,128 @@
|
||||
/*
|
||||
* ++Copyright++ 1985, 1988, 1993
|
||||
* -
|
||||
* Copyright (c) 1985, 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
* -
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
* -
|
||||
* --Copyright--
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)gethostnamadr.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <syslog.h>
|
||||
|
||||
typedef union {
|
||||
int32_t al;
|
||||
char ac;
|
||||
} align;
|
||||
|
||||
void
|
||||
_map_v4v6_address(src, dst)
|
||||
const char *src;
|
||||
char *dst;
|
||||
{
|
||||
u_char *p = (u_char *)dst;
|
||||
char tmp[INADDRSZ];
|
||||
int i;
|
||||
|
||||
/* Stash a temporary copy so our caller can update in place. */
|
||||
bcopy(src, tmp, INADDRSZ);
|
||||
/* Mark this ipv6 addr as a mapped ipv4. */
|
||||
for (i = 0; i < 10; i++)
|
||||
*p++ = 0x00;
|
||||
*p++ = 0xff;
|
||||
*p++ = 0xff;
|
||||
/* Retrieve the saved copy and we're done. */
|
||||
bcopy(tmp, (void*)p, INADDRSZ);
|
||||
}
|
||||
|
||||
void
|
||||
_map_v4v6_hostent(hp, bpp, lenp)
|
||||
struct hostent *hp;
|
||||
char **bpp;
|
||||
int *lenp;
|
||||
{
|
||||
char **ap;
|
||||
|
||||
if (hp->h_addrtype != AF_INET || hp->h_length != INADDRSZ)
|
||||
return;
|
||||
hp->h_addrtype = AF_INET6;
|
||||
hp->h_length = IN6ADDRSZ;
|
||||
for (ap = hp->h_addr_list; *ap; ap++) {
|
||||
int i = sizeof(align) - ((u_long)*bpp % sizeof(align));
|
||||
|
||||
if (*lenp < (i + IN6ADDRSZ)) {
|
||||
/* Out of memory. Truncate address list here. XXX */
|
||||
*ap = NULL;
|
||||
return;
|
||||
}
|
||||
*bpp += i;
|
||||
*lenp -= i;
|
||||
_map_v4v6_address(*ap, *bpp);
|
||||
*ap = *bpp;
|
||||
*bpp += IN6ADDRSZ;
|
||||
*lenp -= IN6ADDRSZ;
|
||||
}
|
||||
}
|
||||
131
c/src/exec/libnetworking/libc/ns.3
Normal file
131
c/src/exec/libnetworking/libc/ns.3
Normal file
@@ -0,0 +1,131 @@
|
||||
.\" Copyright (c) 1986, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)ns.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt NS 3
|
||||
.Os BSD 4.3
|
||||
.Sh NAME
|
||||
.Nm ns_addr ,
|
||||
.Nm ns_ntoa
|
||||
.Nd Xerox
|
||||
.Tn NS Ns (tm)
|
||||
address conversion routines
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <netns/ns.h>
|
||||
.Ft struct ns_addr
|
||||
.Fn ns_addr "char *cp"
|
||||
.Ft char *
|
||||
.Fn ns_ntoa "struct ns_addr ns"
|
||||
.Sh DESCRIPTION
|
||||
The routine
|
||||
.Fn ns_addr
|
||||
interprets character strings representing
|
||||
.Tn XNS
|
||||
addresses, returning binary information suitable
|
||||
for use in system calls.
|
||||
The routine
|
||||
.Fn ns_ntoa
|
||||
takes
|
||||
.Tn XNS
|
||||
addresses and returns
|
||||
.Tn ASCII
|
||||
strings representing the address in a
|
||||
notation in common use in the Xerox Development Environment:
|
||||
.Bd -filled -offset indent
|
||||
<network number>.<host number>.<port number>
|
||||
.Ed
|
||||
.Pp
|
||||
Trailing zero fields are suppressed, and each number is printed in hexadecimal,
|
||||
in a format suitable for input to
|
||||
.Fn ns_addr .
|
||||
Any fields lacking super-decimal digits will have a
|
||||
trailing
|
||||
.Ql H
|
||||
appended.
|
||||
.Pp
|
||||
Unfortunately, no universal standard exists for representing
|
||||
.Tn XNS
|
||||
addresses.
|
||||
An effort has been made to insure that
|
||||
.Fn ns_addr
|
||||
be compatible with most formats in common use.
|
||||
It will first separate an address into 1 to 3 fields using a single delimiter
|
||||
chosen from
|
||||
period
|
||||
.Ql \&. ,
|
||||
colon
|
||||
.Ql \&:
|
||||
or pound-sign
|
||||
.Ql \&# .
|
||||
Each field is then examined for byte separators (colon or period).
|
||||
If there are byte separators, each subfield separated is taken to be
|
||||
a small hexadecimal number, and the entirety is taken as a network-byte-ordered
|
||||
quantity to be zero extended in the high-network-order bytes.
|
||||
Next, the field is inspected for hyphens, in which case
|
||||
the field is assumed to be a number in decimal notation
|
||||
with hyphens separating the millenia.
|
||||
Next, the field is assumed to be a number:
|
||||
It is interpreted
|
||||
as hexadecimal if there is a leading
|
||||
.Ql 0x
|
||||
(as in C),
|
||||
a trailing
|
||||
.Ql H
|
||||
(as in Mesa), or there are any super-decimal digits present.
|
||||
It is interpreted as octal is there is a leading
|
||||
.Ql 0
|
||||
and there are no super-octal digits.
|
||||
Otherwise, it is converted as a decimal number.
|
||||
.Sh RETURN VALUES
|
||||
None. (See
|
||||
.Sx BUGS . )
|
||||
.Sh SEE ALSO
|
||||
.Xr hosts 5 ,
|
||||
.Xr networks 5
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Fn ns_addr
|
||||
and
|
||||
.Fn ns_toa
|
||||
functions appeared in
|
||||
.Bx 4.3 .
|
||||
.Sh BUGS
|
||||
The string returned by
|
||||
.Fn ns_ntoa
|
||||
resides in a static memory area.
|
||||
The function
|
||||
.Fn ns_addr
|
||||
should diagnose improperly formed input, and there should be an unambiguous
|
||||
way to recognize this.
|
||||
227
c/src/exec/libnetworking/libc/ns_addr.c
Normal file
227
c/src/exec/libnetworking/libc/ns_addr.c
Normal file
@@ -0,0 +1,227 @@
|
||||
/*
|
||||
* Copyright (c) 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from software contributed to Berkeley by
|
||||
* J.Q. Johnson.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)ns_addr.c 8.1 (Berkeley) 6/7/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netns/ns.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
static struct ns_addr addr, zero_addr;
|
||||
|
||||
static void Field(), cvtbase();
|
||||
|
||||
struct ns_addr
|
||||
ns_addr(name)
|
||||
const char *name;
|
||||
{
|
||||
char separator;
|
||||
char *hostname, *socketname, *cp;
|
||||
char buf[50];
|
||||
|
||||
(void)strncpy(buf, name, sizeof(buf) - 1);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
|
||||
/*
|
||||
* First, figure out what he intends as a field separtor.
|
||||
* Despite the way this routine is written, the prefered
|
||||
* form 2-272.AA001234H.01777, i.e. XDE standard.
|
||||
* Great efforts are made to insure backward compatability.
|
||||
*/
|
||||
if ((hostname = strchr(buf, '#')) != NULL)
|
||||
separator = '#';
|
||||
else {
|
||||
hostname = strchr(buf, '.');
|
||||
if ((cp = strchr(buf, ':')) &&
|
||||
((hostname && cp < hostname) || (hostname == 0))) {
|
||||
hostname = cp;
|
||||
separator = ':';
|
||||
} else
|
||||
separator = '.';
|
||||
}
|
||||
if (hostname)
|
||||
*hostname++ = 0;
|
||||
|
||||
addr = zero_addr;
|
||||
Field(buf, addr.x_net.c_net, 4);
|
||||
if (hostname == 0)
|
||||
return (addr); /* No separator means net only */
|
||||
|
||||
socketname = strchr(hostname, separator);
|
||||
if (socketname) {
|
||||
*socketname++ = 0;
|
||||
Field(socketname, (u_char *)&addr.x_port, 2);
|
||||
}
|
||||
|
||||
Field(hostname, addr.x_host.c_host, 6);
|
||||
|
||||
return (addr);
|
||||
}
|
||||
|
||||
static void
|
||||
Field(buf, out, len)
|
||||
char *buf;
|
||||
u_char *out;
|
||||
int len;
|
||||
{
|
||||
register char *bp = buf;
|
||||
int i, ibase, base16 = 0, base10 = 0, clen = 0;
|
||||
int hb[6], *hp;
|
||||
char *fmt;
|
||||
|
||||
/*
|
||||
* first try 2-273#2-852-151-014#socket
|
||||
*/
|
||||
if ((*buf != '-') &&
|
||||
(1 < (i = sscanf(buf, "%d-%d-%d-%d-%d",
|
||||
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4])))) {
|
||||
cvtbase(1000L, 256, hb, i, out, len);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* try form 8E1#0.0.AA.0.5E.E6#socket
|
||||
*/
|
||||
if (1 < (i = sscanf(buf,"%x.%x.%x.%x.%x.%x",
|
||||
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
|
||||
cvtbase(256L, 256, hb, i, out, len);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* try form 8E1#0:0:AA:0:5E:E6#socket
|
||||
*/
|
||||
if (1 < (i = sscanf(buf,"%x:%x:%x:%x:%x:%x",
|
||||
&hb[0], &hb[1], &hb[2], &hb[3], &hb[4], &hb[5]))) {
|
||||
cvtbase(256L, 256, hb, i, out, len);
|
||||
return;
|
||||
}
|
||||
/*
|
||||
* This is REALLY stretching it but there was a
|
||||
* comma notation separting shorts -- definitely non standard
|
||||
*/
|
||||
if (1 < (i = sscanf(buf,"%x,%x,%x",
|
||||
&hb[0], &hb[1], &hb[2]))) {
|
||||
hb[0] = htons(hb[0]); hb[1] = htons(hb[1]);
|
||||
hb[2] = htons(hb[2]);
|
||||
cvtbase(65536L, 256, hb, i, out, len);
|
||||
return;
|
||||
}
|
||||
|
||||
/* Need to decide if base 10, 16 or 8 */
|
||||
while (*bp) switch (*bp++) {
|
||||
|
||||
case '0': case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '-':
|
||||
break;
|
||||
|
||||
case '8': case '9':
|
||||
base10 = 1;
|
||||
break;
|
||||
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
base16 = 1;
|
||||
break;
|
||||
|
||||
case 'x': case 'X':
|
||||
*--bp = '0';
|
||||
base16 = 1;
|
||||
break;
|
||||
|
||||
case 'h': case 'H':
|
||||
base16 = 1;
|
||||
/* fall into */
|
||||
|
||||
default:
|
||||
*--bp = 0; /* Ends Loop */
|
||||
}
|
||||
if (base16) {
|
||||
fmt = "%3x";
|
||||
ibase = 4096;
|
||||
} else if (base10 == 0 && *buf == '0') {
|
||||
fmt = "%3o";
|
||||
ibase = 512;
|
||||
} else {
|
||||
fmt = "%3d";
|
||||
ibase = 1000;
|
||||
}
|
||||
|
||||
for (bp = buf; *bp++; ) clen++;
|
||||
if (clen == 0) clen++;
|
||||
if (clen > 18) clen = 18;
|
||||
i = ((clen - 1) / 3) + 1;
|
||||
bp = clen + buf - 3;
|
||||
hp = hb + i - 1;
|
||||
|
||||
while (hp > hb) {
|
||||
(void)sscanf(bp, fmt, hp);
|
||||
bp[0] = 0;
|
||||
hp--;
|
||||
bp -= 3;
|
||||
}
|
||||
(void)sscanf(buf, fmt, hp);
|
||||
cvtbase((long)ibase, 256, hb, i, out, len);
|
||||
}
|
||||
|
||||
static void
|
||||
cvtbase(oldbase,newbase,input,inlen,result,reslen)
|
||||
long oldbase;
|
||||
int newbase;
|
||||
int input[];
|
||||
int inlen;
|
||||
unsigned char result[];
|
||||
int reslen;
|
||||
{
|
||||
int d, e;
|
||||
long sum;
|
||||
|
||||
e = 1;
|
||||
while (e > 0 && reslen > 0) {
|
||||
d = 0; e = 0; sum = 0;
|
||||
/* long division: input=input/newbase */
|
||||
while (d < inlen) {
|
||||
sum = sum*oldbase + (long) input[d];
|
||||
e += (sum > 0);
|
||||
input[d++] = sum / newbase;
|
||||
sum %= newbase;
|
||||
}
|
||||
result[--reslen] = sum; /* accumulate remainder */
|
||||
}
|
||||
for (d=0; d < reslen; d++)
|
||||
result[d] = 0;
|
||||
}
|
||||
593
c/src/exec/libnetworking/libc/ns_name.c
Normal file
593
c/src/exec/libnetworking/libc/ns_name.c
Normal file
@@ -0,0 +1,593 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Data. */
|
||||
|
||||
static char digits[] = "0123456789";
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static int special(int);
|
||||
static int printable(int);
|
||||
static int dn_find(const u_char *, const u_char *,
|
||||
const u_char * const *,
|
||||
const u_char * const *);
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*
|
||||
* ns_name_ntop(src, dst, dstsiz)
|
||||
* Convert an encoded domain name to printable ascii as per RFC1035.
|
||||
* return:
|
||||
* Number of bytes written to buffer, or -1 (with errno set)
|
||||
* notes:
|
||||
* The root is returned as "."
|
||||
* All other domains are returned in non absolute form
|
||||
*/
|
||||
int
|
||||
ns_name_ntop(const u_char *src, char *dst, size_t dstsiz) {
|
||||
const u_char *cp;
|
||||
char *dn, *eom;
|
||||
u_char c;
|
||||
u_int n;
|
||||
|
||||
cp = src;
|
||||
dn = dst;
|
||||
eom = dst + dstsiz;
|
||||
|
||||
while ((n = *cp++) != 0) {
|
||||
if ((n & NS_CMPRSFLGS) != 0) {
|
||||
/* Some kind of compression pointer. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (dn != dst) {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '.';
|
||||
}
|
||||
if (dn + n >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
for ((void)NULL; n > 0; n--) {
|
||||
c = *cp++;
|
||||
if (special(c)) {
|
||||
if (dn + 1 >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\\';
|
||||
*dn++ = (char)c;
|
||||
} else if (!printable(c)) {
|
||||
if (dn + 3 >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\\';
|
||||
*dn++ = digits[c / 100];
|
||||
*dn++ = digits[(c % 100) / 10];
|
||||
*dn++ = digits[c % 10];
|
||||
} else {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = (char)c;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (dn == dst) {
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '.';
|
||||
}
|
||||
if (dn >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dn++ = '\0';
|
||||
return (dn - dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_pton(src, dst, dstsiz)
|
||||
* Convert a ascii string into an encoded domain name as per RFC1035.
|
||||
* return:
|
||||
* -1 if it fails
|
||||
* 1 if string was fully qualified
|
||||
* 0 is string was not fully qualified
|
||||
* notes:
|
||||
* Enforces label and domain length limits.
|
||||
*/
|
||||
|
||||
int
|
||||
ns_name_pton(const char *src, u_char *dst, size_t dstsiz) {
|
||||
u_char *label, *bp, *eom;
|
||||
int c, n, escaped;
|
||||
char *cp;
|
||||
|
||||
escaped = 0;
|
||||
bp = dst;
|
||||
eom = dst + dstsiz;
|
||||
label = bp++;
|
||||
|
||||
while ((c = *src++) != 0) {
|
||||
if (escaped) {
|
||||
if ((cp = strchr(digits, c)) != NULL) {
|
||||
n = (cp - digits) * 100;
|
||||
if ((c = *src++) == 0 ||
|
||||
(cp = strchr(digits, c)) == NULL) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
n += (cp - digits) * 10;
|
||||
if ((c = *src++) == 0 ||
|
||||
(cp = strchr(digits, c)) == NULL) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
n += (cp - digits);
|
||||
if (n > 255) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
c = n;
|
||||
}
|
||||
escaped = 0;
|
||||
} else if (c == '\\') {
|
||||
escaped = 1;
|
||||
continue;
|
||||
} else if (c == '.') {
|
||||
c = (bp - label - 1);
|
||||
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (label >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*label = c;
|
||||
/* Fully qualified ? */
|
||||
if (*src == '\0') {
|
||||
if (c != 0) {
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = '\0';
|
||||
}
|
||||
if ((bp - dst) > MAXCDNAME) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
if (c == 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
label = bp++;
|
||||
continue;
|
||||
}
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = (u_char)c;
|
||||
}
|
||||
c = (bp - label - 1);
|
||||
if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (label >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*label = c;
|
||||
if (c != 0) {
|
||||
if (bp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*bp++ = 0;
|
||||
}
|
||||
if ((bp - dst) > MAXCDNAME) { /* src too big */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_unpack(msg, eom, src, dst, dstsiz)
|
||||
* Unpack a domain name from a message, source may be compressed.
|
||||
* return:
|
||||
* -1 if it fails, or consumed octets if it succeeds.
|
||||
*/
|
||||
int
|
||||
ns_name_unpack(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
u_char *dst, size_t dstsiz)
|
||||
{
|
||||
const u_char *srcp, *dstlim;
|
||||
u_char *dstp;
|
||||
int n, c, len, checked;
|
||||
|
||||
len = -1;
|
||||
checked = 0;
|
||||
dstp = dst;
|
||||
srcp = src;
|
||||
dstlim = dst + dstsiz;
|
||||
if (srcp < msg || srcp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
/* Fetch next label in domain name. */
|
||||
while ((n = *srcp++) != 0) {
|
||||
/* Check for indirection. */
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0:
|
||||
/* Limit checks. */
|
||||
if (dstp + n + 1 >= dstlim || srcp + n >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
checked += n + 1;
|
||||
*dstp++ = n;
|
||||
memcpy(dstp, srcp, n);
|
||||
dstp += n;
|
||||
srcp += n;
|
||||
break;
|
||||
|
||||
case NS_CMPRSFLGS:
|
||||
if (srcp >= eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (len < 0)
|
||||
len = srcp - src + 1;
|
||||
srcp = msg + (((n & 0x3f) << 8) | (*srcp & 0xff));
|
||||
if (srcp < msg || srcp >= eom) { /* Out of range. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
checked += 2;
|
||||
/*
|
||||
* Check for loops in the compressed name;
|
||||
* if we've looked at the whole message,
|
||||
* there must be a loop.
|
||||
*/
|
||||
if (checked >= eom - msg) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
errno = EMSGSIZE;
|
||||
return (-1); /* flag error */
|
||||
}
|
||||
}
|
||||
*dstp = '\0';
|
||||
if (len < 0)
|
||||
len = srcp - src;
|
||||
return (len);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_pack(src, dst, dstsiz, dnptrs, lastdnptr)
|
||||
* Pack domain name 'domain' into 'comp_dn'.
|
||||
* return:
|
||||
* Size of the compressed name, or -1.
|
||||
* notes:
|
||||
* 'dnptrs' is an array of pointers to previous compressed names.
|
||||
* dnptrs[0] is a pointer to the beginning of the message. The array
|
||||
* ends with NULL.
|
||||
* 'lastdnptr' is a pointer to the end of the array pointed to
|
||||
* by 'dnptrs'.
|
||||
* Side effects:
|
||||
* The list of pointers in dnptrs is updated for labels inserted into
|
||||
* the message as we compress the name. If 'dnptr' is NULL, we don't
|
||||
* try to compress names. If 'lastdnptr' is NULL, we don't update the
|
||||
* list.
|
||||
*/
|
||||
int
|
||||
ns_name_pack(const u_char *src, u_char *dst, int dstsiz,
|
||||
const u_char **dnptrs, const u_char **lastdnptr)
|
||||
{
|
||||
u_char *dstp;
|
||||
const u_char **cpp, **lpp, *eob, *msg;
|
||||
const u_char *srcp;
|
||||
int n, l;
|
||||
|
||||
srcp = src;
|
||||
dstp = dst;
|
||||
eob = dstp + dstsiz;
|
||||
lpp = cpp = NULL;
|
||||
if (dnptrs != NULL) {
|
||||
if ((msg = *dnptrs++) != NULL) {
|
||||
for (cpp = dnptrs; *cpp != NULL; cpp++)
|
||||
(void)NULL;
|
||||
lpp = cpp; /* end of list to search */
|
||||
}
|
||||
} else
|
||||
msg = NULL;
|
||||
|
||||
/* make sure the domain we are about to add is legal */
|
||||
l = 0;
|
||||
do {
|
||||
n = *srcp;
|
||||
if ((n & NS_CMPRSFLGS) != 0) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
l += n + 1;
|
||||
if (l > MAXCDNAME) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
srcp += n + 1;
|
||||
} while (n != 0);
|
||||
|
||||
srcp = src;
|
||||
do {
|
||||
/* Look to see if we can use pointers. */
|
||||
n = *srcp;
|
||||
if (n != 0 && msg != NULL) {
|
||||
l = dn_find(srcp, msg, (const u_char * const *)dnptrs,
|
||||
(const u_char * const *)lpp);
|
||||
if (l >= 0) {
|
||||
if (dstp + 1 >= eob) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*dstp++ = (l >> 8) | NS_CMPRSFLGS;
|
||||
*dstp++ = l % 256;
|
||||
return (dstp - dst);
|
||||
}
|
||||
/* Not found, save it. */
|
||||
if (lastdnptr != NULL && cpp < lastdnptr - 1 &&
|
||||
(dstp - msg) < 0x4000) {
|
||||
*cpp++ = dstp;
|
||||
*cpp = NULL;
|
||||
}
|
||||
}
|
||||
/* copy label to buffer */
|
||||
if (n & NS_CMPRSFLGS) { /* Should not happen. */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
if (dstp + 1 + n >= eob) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
memcpy(dstp, srcp, n + 1);
|
||||
srcp += n + 1;
|
||||
dstp += n + 1;
|
||||
} while (n != 0);
|
||||
|
||||
if (dstp > eob) {
|
||||
if (msg != NULL)
|
||||
*lpp = NULL;
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
return (dstp - dst);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_uncompress(msg, eom, src, dst, dstsiz)
|
||||
* Expand compressed domain name to presentation format.
|
||||
* return:
|
||||
* Number of bytes read out of `src', or -1 (with errno set).
|
||||
* note:
|
||||
* Root domain returns as "." not "".
|
||||
*/
|
||||
int
|
||||
ns_name_uncompress(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
char *dst, size_t dstsiz)
|
||||
{
|
||||
u_char tmp[NS_MAXCDNAME];
|
||||
int n;
|
||||
|
||||
if ((n = ns_name_unpack(msg, eom, src, tmp, sizeof tmp)) == -1)
|
||||
return (-1);
|
||||
if (ns_name_ntop(tmp, dst, dstsiz) == -1)
|
||||
return (-1);
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_compress(src, dst, dstsiz, dnptrs, lastdnptr)
|
||||
* Compress a domain name into wire format, using compression pointers.
|
||||
* return:
|
||||
* Number of bytes consumed in `dst' or -1 (with errno set).
|
||||
* notes:
|
||||
* 'dnptrs' is an array of pointers to previous compressed names.
|
||||
* dnptrs[0] is a pointer to the beginning of the message.
|
||||
* The list ends with NULL. 'lastdnptr' is a pointer to the end of the
|
||||
* array pointed to by 'dnptrs'. Side effect is to update the list of
|
||||
* pointers for labels inserted into the message as we compress the name.
|
||||
* If 'dnptr' is NULL, we don't try to compress names. If 'lastdnptr'
|
||||
* is NULL, we don't update the list.
|
||||
*/
|
||||
int
|
||||
ns_name_compress(const char *src, u_char *dst, size_t dstsiz,
|
||||
const u_char **dnptrs, const u_char **lastdnptr)
|
||||
{
|
||||
u_char tmp[NS_MAXCDNAME];
|
||||
|
||||
if (ns_name_pton(src, tmp, sizeof tmp) == -1)
|
||||
return (-1);
|
||||
return (ns_name_pack(tmp, dst, dstsiz, dnptrs, lastdnptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* ns_name_skip(ptrptr, eom)
|
||||
* Advance *ptrptr to skip over the compressed name it points at.
|
||||
* return:
|
||||
* 0 on success, -1 (with errno set) on failure.
|
||||
*/
|
||||
int
|
||||
ns_name_skip(const u_char **ptrptr, const u_char *eom) {
|
||||
const u_char *cp;
|
||||
u_int n;
|
||||
|
||||
cp = *ptrptr;
|
||||
while (cp < eom && (n = *cp++) != 0) {
|
||||
/* Check for indirection. */
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0: /* normal case, n == len */
|
||||
cp += n;
|
||||
continue;
|
||||
case NS_CMPRSFLGS: /* indirection */
|
||||
cp++;
|
||||
break;
|
||||
default: /* illegal type */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
break;
|
||||
}
|
||||
if (cp > eom) {
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
*ptrptr = cp;
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*
|
||||
* special(ch)
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* is this characted special ("in need of quoting") ?
|
||||
* return:
|
||||
* boolean.
|
||||
*/
|
||||
static int
|
||||
special(int ch) {
|
||||
switch (ch) {
|
||||
case 0x22: /* '"' */
|
||||
case 0x2E: /* '.' */
|
||||
case 0x3B: /* ';' */
|
||||
case 0x5C: /* '\\' */
|
||||
/* Special modifiers in zone files. */
|
||||
case 0x40: /* '@' */
|
||||
case 0x24: /* '$' */
|
||||
return (1);
|
||||
default:
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* printable(ch)
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* is this character visible and not a space when printed ?
|
||||
* return:
|
||||
* boolean.
|
||||
*/
|
||||
static int
|
||||
printable(int ch) {
|
||||
return (ch > 0x20 && ch < 0x7f);
|
||||
}
|
||||
|
||||
/*
|
||||
* Thinking in noninternationalized USASCII (per the DNS spec),
|
||||
* convert this character to lower case if it's upper case.
|
||||
*/
|
||||
static int
|
||||
mklower(int ch) {
|
||||
if (ch >= 0x41 && ch <= 0x5A)
|
||||
return (ch + 0x20);
|
||||
return (ch);
|
||||
}
|
||||
|
||||
/*
|
||||
* dn_find(domain, msg, dnptrs, lastdnptr)
|
||||
* Search for the counted-label name in an array of compressed names.
|
||||
* return:
|
||||
* offset from msg if found, or -1.
|
||||
* notes:
|
||||
* dnptrs is the pointer to the first name on the list,
|
||||
* not the pointer to the start of the message.
|
||||
*/
|
||||
static int
|
||||
dn_find(const u_char *domain, const u_char *msg,
|
||||
const u_char * const *dnptrs,
|
||||
const u_char * const *lastdnptr)
|
||||
{
|
||||
const u_char *dn, *cp, *sp;
|
||||
const u_char * const *cpp;
|
||||
u_int n;
|
||||
|
||||
for (cpp = dnptrs; cpp < lastdnptr; cpp++) {
|
||||
dn = domain;
|
||||
sp = cp = *cpp;
|
||||
while ((n = *cp++) != 0) {
|
||||
/*
|
||||
* check for indirection
|
||||
*/
|
||||
switch (n & NS_CMPRSFLGS) {
|
||||
case 0: /* normal case, n == len */
|
||||
if (n != *dn++)
|
||||
goto next;
|
||||
for ((void)NULL; n > 0; n--)
|
||||
if (mklower(*dn++) != mklower(*cp++))
|
||||
goto next;
|
||||
/* Is next root for both ? */
|
||||
if (*dn == '\0' && *cp == '\0')
|
||||
return (sp - msg);
|
||||
if (*dn)
|
||||
continue;
|
||||
goto next;
|
||||
|
||||
case NS_CMPRSFLGS: /* indirection */
|
||||
cp = msg + (((n & 0x3f) << 8) | *cp);
|
||||
break;
|
||||
|
||||
default: /* illegal type */
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
next: ;
|
||||
}
|
||||
errno = ENOENT;
|
||||
return (-1);
|
||||
}
|
||||
54
c/src/exec/libnetworking/libc/ns_netint.c
Normal file
54
c/src/exec/libnetworking/libc/ns_netint.c
Normal file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
u_int
|
||||
ns_get16(const u_char *src) {
|
||||
u_int dst;
|
||||
|
||||
NS_GET16(dst, src);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
u_long
|
||||
ns_get32(const u_char *src) {
|
||||
u_long dst;
|
||||
|
||||
NS_GET32(dst, src);
|
||||
return (dst);
|
||||
}
|
||||
|
||||
void
|
||||
ns_put16(u_int src, u_char *dst) {
|
||||
NS_PUT16(src, dst);
|
||||
}
|
||||
|
||||
void
|
||||
ns_put32(u_long src, u_char *dst) {
|
||||
NS_PUT32(src, dst);
|
||||
}
|
||||
100
c/src/exec/libnetworking/libc/ns_ntoa.c
Normal file
100
c/src/exec/libnetworking/libc/ns_ntoa.c
Normal file
@@ -0,0 +1,100 @@
|
||||
/*
|
||||
* Copyright (c) 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)ns_ntoa.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <netns/ns.h>
|
||||
#include <stdio.h>
|
||||
|
||||
char *
|
||||
ns_ntoa(addr)
|
||||
struct ns_addr addr;
|
||||
{
|
||||
static char obuf[40];
|
||||
union { union ns_net net_e; u_long long_e; } net;
|
||||
u_short port = htons(addr.x_port);
|
||||
register char *cp;
|
||||
char *cp2;
|
||||
register u_char *up = addr.x_host.c_host;
|
||||
u_char *uplim = up + 6;
|
||||
static char *spectHex();
|
||||
|
||||
net.net_e = addr.x_net;
|
||||
sprintf(obuf, "%lx", (u_long)ntohl(net.long_e));
|
||||
cp = spectHex(obuf);
|
||||
cp2 = cp + 1;
|
||||
while (*up==0 && up < uplim) up++;
|
||||
if (up == uplim) {
|
||||
if (port) {
|
||||
sprintf(cp, ".0");
|
||||
cp += 2;
|
||||
}
|
||||
} else {
|
||||
sprintf(cp, ".%x", *up++);
|
||||
while (up < uplim) {
|
||||
while (*cp) cp++;
|
||||
sprintf(cp, "%02x", *up++);
|
||||
}
|
||||
cp = spectHex(cp2);
|
||||
}
|
||||
if (port) {
|
||||
sprintf(cp, ".%x", port);
|
||||
spectHex(cp + 1);
|
||||
}
|
||||
return (obuf);
|
||||
}
|
||||
|
||||
static char *
|
||||
spectHex(p0)
|
||||
char *p0;
|
||||
{
|
||||
int ok = 0;
|
||||
int nonzero = 0;
|
||||
register char *p = p0;
|
||||
for (; *p; p++) switch (*p) {
|
||||
|
||||
case 'a': case 'b': case 'c': case 'd': case 'e': case 'f':
|
||||
*p += ('A' - 'a');
|
||||
/* fall into . . . */
|
||||
case 'A': case 'B': case 'C': case 'D': case 'E': case 'F':
|
||||
ok = 1;
|
||||
case '1': case '2': case '3': case '4': case '5':
|
||||
case '6': case '7': case '8': case '9':
|
||||
nonzero = 1;
|
||||
}
|
||||
if (nonzero && !ok) { *p++ = 'H'; *p = 0; }
|
||||
return (p);
|
||||
}
|
||||
190
c/src/exec/libnetworking/libc/ns_parse.c
Normal file
190
c/src/exec/libnetworking/libc/ns_parse.c
Normal file
@@ -0,0 +1,190 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
#include <sys/types.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
|
||||
/* These need to be in the same order as the nres.h:ns_flag enum. */
|
||||
struct _ns_flagdata _ns_flagdata[16] = {
|
||||
{ 0x8000, 15 }, /* qr. */
|
||||
{ 0x7800, 11 }, /* opcode. */
|
||||
{ 0x0400, 10 }, /* aa. */
|
||||
{ 0x0200, 9 }, /* tc. */
|
||||
{ 0x0100, 8 }, /* rd. */
|
||||
{ 0x0080, 7 }, /* ra. */
|
||||
{ 0x0040, 6 }, /* z. */
|
||||
{ 0x0020, 5 }, /* ad. */
|
||||
{ 0x0010, 4 }, /* cd. */
|
||||
{ 0x000f, 0 }, /* rcode. */
|
||||
{ 0x0000, 0 }, /* expansion (1/6). */
|
||||
{ 0x0000, 0 }, /* expansion (2/6). */
|
||||
{ 0x0000, 0 }, /* expansion (3/6). */
|
||||
{ 0x0000, 0 }, /* expansion (4/6). */
|
||||
{ 0x0000, 0 }, /* expansion (5/6). */
|
||||
{ 0x0000, 0 }, /* expansion (6/6). */
|
||||
};
|
||||
|
||||
static int
|
||||
skiprr(const u_char *ptr, const u_char *eom, ns_sect section, int count) {
|
||||
const u_char *optr = ptr;
|
||||
|
||||
for ((void)NULL; count > 0; count--) {
|
||||
int b, rdlength;
|
||||
|
||||
b = dn_skipname(ptr, eom);
|
||||
if (b < 0)
|
||||
goto emsgsize;
|
||||
ptr += b/*Name*/ + NS_INT16SZ/*Type*/ + NS_INT16SZ/*Class*/;
|
||||
if (section != ns_s_qd) {
|
||||
if (ptr + NS_INT32SZ > eom)
|
||||
goto emsgsize;
|
||||
ptr += NS_INT32SZ/*TTL*/;
|
||||
if (ptr + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rdlength, ptr);
|
||||
ptr += rdlength/*RData*/;
|
||||
}
|
||||
}
|
||||
if (ptr > eom)
|
||||
goto emsgsize;
|
||||
return (ptr - optr);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
ns_initparse(const u_char *msg, int msglen, ns_msg *handle) {
|
||||
const u_char *eom = msg + msglen;
|
||||
int i;
|
||||
|
||||
memset(handle, 0x5e, sizeof *handle);
|
||||
handle->_msg = msg;
|
||||
handle->_eom = eom;
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_id, msg);
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_flags, msg);
|
||||
for (i = 0; i < ns_s_max; i++) {
|
||||
if (msg + NS_INT16SZ > eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(handle->_counts[i], msg);
|
||||
}
|
||||
for (i = 0; i < ns_s_max; i++)
|
||||
if (handle->_counts[i] == 0)
|
||||
handle->_sections[i] = NULL;
|
||||
else {
|
||||
int b = skiprr(msg, eom, (ns_sect)i,
|
||||
handle->_counts[i]);
|
||||
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_sections[i] = msg;
|
||||
msg += b;
|
||||
}
|
||||
if (msg != eom)
|
||||
goto emsgsize;
|
||||
handle->_sect = ns_s_max;
|
||||
handle->_rrnum = -1;
|
||||
handle->_ptr = NULL;
|
||||
return (0);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
ns_parserr(ns_msg *handle, ns_sect section, int rrnum, ns_rr *rr) {
|
||||
int b;
|
||||
|
||||
/* Make section right. */
|
||||
if (section < 0 || section >= ns_s_max)
|
||||
goto enodev;
|
||||
if ((int)section != (int)handle->_sect) {
|
||||
handle->_sect = section;
|
||||
handle->_rrnum = 0;
|
||||
handle->_ptr = handle->_sections[(int)section];
|
||||
}
|
||||
|
||||
/* Make rrnum right. */
|
||||
if (rrnum == -1)
|
||||
rrnum = handle->_rrnum;
|
||||
if (rrnum < 0 || rrnum >= handle->_counts[(int)section])
|
||||
goto enodev;
|
||||
if (rrnum < handle->_rrnum) {
|
||||
handle->_rrnum = 0;
|
||||
handle->_ptr = handle->_sections[(int)section];
|
||||
}
|
||||
|
||||
b = skiprr(handle->_msg, handle->_eom, section,
|
||||
rrnum - handle->_rrnum);
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_ptr += b;
|
||||
handle->_rrnum = rrnum;
|
||||
|
||||
/* Do the parse. */
|
||||
b = dn_expand(handle->_msg, handle->_eom,
|
||||
handle->_ptr, rr->name, NS_MAXDNAME);
|
||||
if (b < 0)
|
||||
return (-1);
|
||||
handle->_ptr += b;
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->type, handle->_ptr);
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->class, handle->_ptr);
|
||||
if (section == ns_s_qd) {
|
||||
rr->ttl = 0;
|
||||
rr->rdlength = 0;
|
||||
rr->rdata = NULL;
|
||||
} else {
|
||||
if (handle->_ptr + NS_INT32SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET32(rr->ttl, handle->_ptr);
|
||||
if (handle->_ptr + NS_INT16SZ > handle->_eom)
|
||||
goto emsgsize;
|
||||
NS_GET16(rr->rdlength, handle->_ptr);
|
||||
if (handle->_ptr + rr->rdlength > handle->_eom)
|
||||
goto emsgsize;
|
||||
rr->rdata = handle->_ptr;
|
||||
handle->_ptr += rr->rdlength;
|
||||
}
|
||||
handle->_rrnum++;
|
||||
|
||||
/* All done. */
|
||||
return (0);
|
||||
enodev:
|
||||
errno = ENODEV;
|
||||
return (-1);
|
||||
emsgsize:
|
||||
errno = EMSGSIZE;
|
||||
return (-1);
|
||||
}
|
||||
743
c/src/exec/libnetworking/libc/ns_print.c
Normal file
743
c/src/exec/libnetworking/libc/ns_print.c
Normal file
@@ -0,0 +1,743 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
#include <resolv.h>
|
||||
#include <string.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static size_t prune_origin(const char *name, const char *origin);
|
||||
static int charstr(const u_char *rdata, const u_char *edata,
|
||||
char **buf, size_t *buflen);
|
||||
static int addname(const u_char *msg, size_t msglen,
|
||||
const u_char **p, const char *origin,
|
||||
char **buf, size_t *buflen);
|
||||
static void addlen(size_t len, char **buf, size_t *buflen);
|
||||
static int addstr(const char *src, size_t len,
|
||||
char **buf, size_t *buflen);
|
||||
static int addtab(size_t len, size_t target, int spaced,
|
||||
char **buf, size_t *buflen);
|
||||
|
||||
/* Macros. */
|
||||
|
||||
#define T(x) \
|
||||
do { \
|
||||
if ((x) < 0) \
|
||||
return (-1); \
|
||||
} while (0)
|
||||
|
||||
/* Public. */
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_sprintrr(handle, rr, name_ctx, origin, buf, buflen)
|
||||
* Convert an RR to presentation format.
|
||||
* return:
|
||||
* Number of characters written to buf, or -1 (check errno).
|
||||
*/
|
||||
int
|
||||
ns_sprintrr(const ns_msg *handle, const ns_rr *rr,
|
||||
const char *name_ctx, const char *origin,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
int n;
|
||||
|
||||
n = ns_sprintrrf(ns_msg_base(*handle), ns_msg_size(*handle),
|
||||
ns_rr_name(*rr), ns_rr_class(*rr), ns_rr_type(*rr),
|
||||
ns_rr_ttl(*rr), ns_rr_rdata(*rr), ns_rr_rdlen(*rr),
|
||||
name_ctx, origin, buf, buflen);
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* ns_sprintrrf(msg, msglen, name, class, type, ttl, rdata, rdlen,
|
||||
* name_ctx, origin, buf, buflen)
|
||||
* Convert the fields of an RR into presentation format.
|
||||
* return:
|
||||
* Number of characters written to buf, or -1 (check errno).
|
||||
*/
|
||||
int
|
||||
ns_sprintrrf(const u_char *msg, size_t msglen,
|
||||
const char *name, ns_class class, ns_type type,
|
||||
u_long ttl, const u_char *rdata, size_t rdlen,
|
||||
const char *name_ctx, const char *origin,
|
||||
char *buf, size_t buflen)
|
||||
{
|
||||
const char *obuf = buf;
|
||||
const u_char *edata = rdata + rdlen;
|
||||
int spaced = 0;
|
||||
|
||||
const char *comment;
|
||||
char tmp[100];
|
||||
int len, x;
|
||||
|
||||
/*
|
||||
* Owner.
|
||||
*/
|
||||
if (name_ctx != NULL && strcasecmp(name_ctx, name) == 0) {
|
||||
T(addstr("\t\t\t", 3, &buf, &buflen));
|
||||
} else {
|
||||
len = prune_origin(name, origin);
|
||||
if (len == 0) {
|
||||
T(addstr("@\t\t\t", 4, &buf, &buflen));
|
||||
} else {
|
||||
T(addstr(name, len, &buf, &buflen));
|
||||
/* Origin not used and no trailing dot? */
|
||||
if ((!origin || !origin[0] || name[len] == '\0') &&
|
||||
name[len - 1] != '.') {
|
||||
T(addstr(".", 1, &buf, &buflen));
|
||||
len++;
|
||||
}
|
||||
T(spaced = addtab(len, 24, spaced, &buf, &buflen));
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* TTL, Class, Type.
|
||||
*/
|
||||
T(x = ns_format_ttl(ttl, buf, buflen));
|
||||
addlen(x, &buf, &buflen);
|
||||
len = SPRINTF((tmp, " %s %s", p_class(class), p_type(type)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
T(spaced = addtab(x + len, 16, spaced, &buf, &buflen));
|
||||
|
||||
/*
|
||||
* RData.
|
||||
*/
|
||||
switch (type) {
|
||||
case ns_t_a:
|
||||
if (rdlen != NS_INADDRSZ)
|
||||
goto formerr;
|
||||
(void) inet_ntop(AF_INET, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
break;
|
||||
|
||||
case ns_t_cname:
|
||||
case ns_t_mb:
|
||||
case ns_t_mg:
|
||||
case ns_t_mr:
|
||||
case ns_t_ns:
|
||||
case ns_t_ptr:
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
|
||||
case ns_t_hinfo:
|
||||
case ns_t_isdn:
|
||||
/* First word. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Second word. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
break;
|
||||
|
||||
case ns_t_soa: {
|
||||
u_long t;
|
||||
|
||||
/* Server name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Administrator name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" (\n", 3, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
if ((edata - rdata) != 5*NS_INT32SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Serial number. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
len = SPRINTF((tmp, "%lu", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; serial\n", 9, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Refresh interval. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; refresh\n", 10, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Retry interval. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; retry\n", 8, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Expiry. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; expiry\n", 9, &buf, &buflen));
|
||||
spaced = 0;
|
||||
|
||||
/* Minimum TTL. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
T(addstr("\t\t\t\t\t", 5, &buf, &buflen));
|
||||
T(len = ns_format_ttl(t, buf, buflen));
|
||||
addlen(len, &buf, &buflen);
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
T(spaced = addtab(len, 16, spaced, &buf, &buflen));
|
||||
T(addstr("; minimum\n", 10, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_mx:
|
||||
case ns_t_afsdb:
|
||||
case ns_t_rt: {
|
||||
u_int t;
|
||||
|
||||
if (rdlen < NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Target. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_px: {
|
||||
u_int t;
|
||||
|
||||
if (rdlen < NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Priority. */
|
||||
t = ns_get16(rdata);
|
||||
rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Name1. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Name2. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_x25:
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
break;
|
||||
|
||||
case ns_t_txt:
|
||||
while (rdata < edata) {
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
if (rdata < edata)
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
}
|
||||
break;
|
||||
|
||||
case ns_t_nsap: {
|
||||
char t[255*3];
|
||||
|
||||
(void) inet_nsap_ntoa(rdlen, rdata, t);
|
||||
T(addstr(t, strlen(t), &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_aaaa:
|
||||
if (rdlen != NS_IN6ADDRSZ)
|
||||
goto formerr;
|
||||
(void) inet_ntop(AF_INET6, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
break;
|
||||
|
||||
case ns_t_loc: {
|
||||
char t[255];
|
||||
|
||||
/* XXX protocol format checking? */
|
||||
(void) loc_ntoa(rdata, t);
|
||||
T(addstr(t, strlen(t), &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_naptr: {
|
||||
u_int order, preference;
|
||||
char t[50];
|
||||
|
||||
if (rdlen < 2*NS_INT16SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Order, Precedence. */
|
||||
order = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
preference = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u ", order, preference));
|
||||
T(addstr(t, len, &buf, &buflen));
|
||||
|
||||
/* Flags. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Service. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Regexp. */
|
||||
T(len = charstr(rdata, edata, &buf, &buflen));
|
||||
if (len < 0)
|
||||
return (-1);
|
||||
if (len == 0)
|
||||
goto formerr;
|
||||
rdata += len;
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Server. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_srv: {
|
||||
u_int priority, weight, port;
|
||||
char t[50];
|
||||
|
||||
if (rdlen < NS_INT16SZ*3)
|
||||
goto formerr;
|
||||
|
||||
/* Priority, Weight, Port. */
|
||||
priority = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
weight = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
port = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((t, "%u %u %u ", priority, weight, port));
|
||||
T(addstr(t, len, &buf, &buflen));
|
||||
|
||||
/* Server. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_minfo:
|
||||
case ns_t_rp:
|
||||
/* Name1. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
T(addstr(" ", 1, &buf, &buflen));
|
||||
|
||||
/* Name2. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
break;
|
||||
|
||||
case ns_t_wks: {
|
||||
int n, lcnt;
|
||||
|
||||
if (rdlen < NS_INT32SZ + 1)
|
||||
goto formerr;
|
||||
|
||||
/* Address. */
|
||||
(void) inet_ntop(AF_INET, rdata, buf, buflen);
|
||||
addlen(strlen(buf), &buf, &buflen);
|
||||
rdata += NS_INADDRSZ;
|
||||
|
||||
/* Protocol. */
|
||||
len = SPRINTF((tmp, " %u ( ", *rdata));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
rdata += NS_INT8SZ;
|
||||
|
||||
/* Bit map. */
|
||||
n = 0;
|
||||
lcnt = 0;
|
||||
while (rdata < edata) {
|
||||
u_int c = *rdata++;
|
||||
do {
|
||||
if (c & 0200) {
|
||||
if (lcnt == 0) {
|
||||
T(addstr("\n\t\t\t\t", 5,
|
||||
&buf, &buflen));
|
||||
lcnt = 10;
|
||||
spaced = 0;
|
||||
}
|
||||
len = SPRINTF((tmp, "%d ", n));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
lcnt--;
|
||||
}
|
||||
c <<= 1;
|
||||
} while (++n & 07);
|
||||
}
|
||||
T(addstr(")", 1, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_key: {
|
||||
char base64_key[NS_MD5RSA_MAX_BASE64];
|
||||
u_int keyflags, protocol, algorithm;
|
||||
const char *leader;
|
||||
int n;
|
||||
|
||||
if (rdlen < NS_INT16SZ + NS_INT8SZ + NS_INT8SZ)
|
||||
goto formerr;
|
||||
|
||||
/* Key flags, Protocol, Algorithm. */
|
||||
keyflags = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
protocol = *rdata++;
|
||||
algorithm = *rdata++;
|
||||
len = SPRINTF((tmp, "0x%04x %u %u",
|
||||
keyflags, protocol, algorithm));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Public key data. */
|
||||
len = b64_ntop(rdata, edata - rdata,
|
||||
base64_key, sizeof base64_key);
|
||||
if (len < 0)
|
||||
goto formerr;
|
||||
if (len > 15) {
|
||||
T(addstr(" (", 2, &buf, &buflen));
|
||||
leader = "\n\t\t";
|
||||
spaced = 0;
|
||||
} else
|
||||
leader = " ";
|
||||
for (n = 0; n < len; n += 48) {
|
||||
T(addstr(leader, strlen(leader), &buf, &buflen));
|
||||
T(addstr(base64_key + n, MIN(len - n, 48),
|
||||
&buf, &buflen));
|
||||
}
|
||||
if (len > 15)
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_sig: {
|
||||
char base64_key[NS_MD5RSA_MAX_BASE64];
|
||||
u_int type, algorithm, labels, footprint;
|
||||
const char *leader;
|
||||
u_long t;
|
||||
int n;
|
||||
|
||||
if (rdlen < 22)
|
||||
goto formerr;
|
||||
|
||||
/* Type covered, Algorithm, Label count, Original TTL. */
|
||||
type = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
algorithm = *rdata++;
|
||||
labels = *rdata++;
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, " %s %d %lu ",
|
||||
p_type(type), algorithm, t));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
if (labels != (u_int)dn_count_labels(name))
|
||||
goto formerr;
|
||||
|
||||
/* Signature expiry. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Time signed. */
|
||||
t = ns_get32(rdata); rdata += NS_INT32SZ;
|
||||
len = SPRINTF((tmp, "%s ", p_secstodate(t)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Signature Footprint. */
|
||||
footprint = ns_get16(rdata); rdata += NS_INT16SZ;
|
||||
len = SPRINTF((tmp, "%u ", footprint));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
|
||||
/* Signer's name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
/* Signature. */
|
||||
len = b64_ntop(rdata, edata - rdata,
|
||||
base64_key, sizeof base64_key);
|
||||
if (len > 15) {
|
||||
T(addstr(" (", 2, &buf, &buflen));
|
||||
leader = "\n\t\t";
|
||||
spaced = 0;
|
||||
} else
|
||||
leader = " ";
|
||||
if (len < 0)
|
||||
goto formerr;
|
||||
for (n = 0; n < len; n += 48) {
|
||||
T(addstr(leader, strlen(leader), &buf, &buflen));
|
||||
T(addstr(base64_key + n, MIN(len - n, 48),
|
||||
&buf, &buflen));
|
||||
}
|
||||
if (len > 15)
|
||||
T(addstr(" )", 2, &buf, &buflen));
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case ns_t_nxt: {
|
||||
int n, c;
|
||||
|
||||
/* Next domain name. */
|
||||
T(addname(msg, msglen, &rdata, origin, &buf, &buflen));
|
||||
|
||||
/* Type bit map. */
|
||||
n = edata - rdata;
|
||||
for (c = 0; c < n*8; c++)
|
||||
if (NS_NXT_BIT_ISSET(c, rdata)) {
|
||||
len = SPRINTF((tmp, " %s", p_type(c)));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
comment = "unknown RR type";
|
||||
goto hexify;
|
||||
}
|
||||
return (buf - obuf);
|
||||
formerr:
|
||||
comment = "RR format error";
|
||||
hexify: {
|
||||
int n, m;
|
||||
char *p;
|
||||
|
||||
len = SPRINTF((tmp, "\\#(\t\t; %s", comment));
|
||||
T(addstr(tmp, len, &buf, &buflen));
|
||||
while (rdata < edata) {
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "\n\t"));
|
||||
spaced = 0;
|
||||
n = MIN(16, edata - rdata);
|
||||
for (m = 0; m < n; m++)
|
||||
p += SPRINTF((p, "%02x ", rdata[m]));
|
||||
T(addstr(tmp, p - tmp, &buf, &buflen));
|
||||
if (n < 16) {
|
||||
T(addstr(")", 1, &buf, &buflen));
|
||||
T(addtab(p - tmp + 1, 48, spaced, &buf, &buflen));
|
||||
}
|
||||
p = tmp;
|
||||
p += SPRINTF((p, "; "));
|
||||
for (m = 0; m < n; m++)
|
||||
*p++ = (isascii(rdata[m]) && isprint(rdata[m]))
|
||||
? rdata[m]
|
||||
: '.';
|
||||
T(addstr(tmp, p - tmp, &buf, &buflen));
|
||||
rdata += n;
|
||||
}
|
||||
return (buf - obuf);
|
||||
}
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
/*
|
||||
* size_t
|
||||
* prune_origin(name, origin)
|
||||
* Find out if the name is at or under the current origin.
|
||||
* return:
|
||||
* Number of characters in name before start of origin,
|
||||
* or length of name if origin does not match.
|
||||
* notes:
|
||||
* This function should share code with samedomain().
|
||||
*/
|
||||
static size_t
|
||||
prune_origin(const char *name, const char *origin) {
|
||||
const char *oname = name;
|
||||
|
||||
while (*name != '\0') {
|
||||
if (origin != NULL && strcasecmp(name, origin) == 0)
|
||||
return (name - oname - (name > oname));
|
||||
while (*name != '\0') {
|
||||
if (*name == '\\') {
|
||||
name++;
|
||||
/* XXX need to handle \nnn form. */
|
||||
if (*name == '\0')
|
||||
break;
|
||||
} else if (*name == '.') {
|
||||
name++;
|
||||
break;
|
||||
}
|
||||
name++;
|
||||
}
|
||||
}
|
||||
return (name - oname);
|
||||
}
|
||||
|
||||
/*
|
||||
* int
|
||||
* charstr(rdata, edata, buf, buflen)
|
||||
* Format a <character-string> into the presentation buffer.
|
||||
* return:
|
||||
* Number of rdata octets consumed
|
||||
* 0 for protocol format error
|
||||
* -1 for output buffer error
|
||||
* side effects:
|
||||
* buffer is advanced on success.
|
||||
*/
|
||||
static int
|
||||
charstr(const u_char *rdata, const u_char *edata, char **buf, size_t *buflen) {
|
||||
const u_char *odata = rdata;
|
||||
size_t save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
|
||||
if (addstr("\"", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
if (rdata < edata) {
|
||||
int n = *rdata;
|
||||
|
||||
if (rdata + 1 + n <= edata) {
|
||||
rdata++;
|
||||
while (n-- > 0) {
|
||||
if (strchr("\n\"\\", *rdata) != NULL)
|
||||
if (addstr("\\", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
if (addstr((const char *)rdata, 1,
|
||||
buf, buflen) < 0)
|
||||
goto enospc;
|
||||
rdata++;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (addstr("\"", 1, buf, buflen) < 0)
|
||||
goto enospc;
|
||||
return (rdata - odata);
|
||||
enospc:
|
||||
errno = ENOSPC;
|
||||
*buf = save_buf;
|
||||
*buflen = save_buflen;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static int
|
||||
addname(const u_char *msg, size_t msglen,
|
||||
const u_char **pp, const char *origin,
|
||||
char **buf, size_t *buflen)
|
||||
{
|
||||
size_t newlen, save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
int n;
|
||||
|
||||
n = dn_expand(msg, msg + msglen, *pp, *buf, *buflen);
|
||||
if (n < 0)
|
||||
goto enospc; /* Guess. */
|
||||
newlen = prune_origin(*buf, origin);
|
||||
if ((origin == NULL || origin[0] == '\0' || (*buf)[newlen] == '\0') &&
|
||||
(newlen == 0 || (*buf)[newlen - 1] != '.')) {
|
||||
/* No trailing dot. */
|
||||
if (newlen + 2 > *buflen)
|
||||
goto enospc; /* No room for ".\0". */
|
||||
(*buf)[newlen++] = '.';
|
||||
(*buf)[newlen] = '\0';
|
||||
}
|
||||
if (newlen == 0) {
|
||||
/* Use "@" instead of name. */
|
||||
if (newlen + 2 > *buflen)
|
||||
goto enospc; /* No room for "@\0". */
|
||||
(*buf)[newlen++] = '@';
|
||||
(*buf)[newlen] = '\0';
|
||||
}
|
||||
*pp += n;
|
||||
addlen(newlen, buf, buflen);
|
||||
**buf = '\0';
|
||||
return (newlen);
|
||||
enospc:
|
||||
errno = ENOSPC;
|
||||
*buf = save_buf;
|
||||
*buflen = save_buflen;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
static void
|
||||
addlen(size_t len, char **buf, size_t *buflen) {
|
||||
assert(len <= *buflen);
|
||||
*buf += len;
|
||||
*buflen -= len;
|
||||
}
|
||||
|
||||
static int
|
||||
addstr(const char *src, size_t len, char **buf, size_t *buflen) {
|
||||
if (len > *buflen) {
|
||||
errno = ENOSPC;
|
||||
return (-1);
|
||||
}
|
||||
memcpy(*buf, src, len);
|
||||
addlen(len, buf, buflen);
|
||||
**buf = '\0';
|
||||
return (0);
|
||||
}
|
||||
|
||||
static int
|
||||
addtab(size_t len, size_t target, int spaced, char **buf, size_t *buflen) {
|
||||
size_t save_buflen = *buflen;
|
||||
char *save_buf = *buf;
|
||||
int t;
|
||||
|
||||
if (spaced || len >= target - 1) {
|
||||
T(addstr(" ", 2, buf, buflen));
|
||||
spaced = 1;
|
||||
} else {
|
||||
for (t = (target - len - 1) / 8; t >= 0; t--)
|
||||
if (addstr("\t", 1, buf, buflen) < 0) {
|
||||
*buflen = save_buflen;
|
||||
*buf = save_buf;
|
||||
return (-1);
|
||||
}
|
||||
spaced = 0;
|
||||
}
|
||||
return (spaced);
|
||||
}
|
||||
151
c/src/exec/libnetworking/libc/ns_ttl.c
Normal file
151
c/src/exec/libnetworking/libc/ns_ttl.c
Normal file
@@ -0,0 +1,151 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#ifndef lint
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif
|
||||
|
||||
/* Import. */
|
||||
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define SPRINTF(x) ((size_t)sprintf x)
|
||||
|
||||
/* Forward. */
|
||||
|
||||
static int fmt1(int t, char s, char **buf, size_t *buflen);
|
||||
|
||||
/* Macros. */
|
||||
|
||||
#define T(x) if ((x) < 0) return (-1); else (void)NULL
|
||||
|
||||
/* Public. */
|
||||
|
||||
int
|
||||
ns_format_ttl(u_long src, char *dst, size_t dstlen) {
|
||||
char *odst = dst;
|
||||
int secs, mins, hours, days, weeks, x;
|
||||
char tmp[50], *p;
|
||||
|
||||
secs = src % 60; src /= 60;
|
||||
mins = src % 60; src /= 60;
|
||||
hours = src % 24; src /= 24;
|
||||
days = src % 7; src /= 7;
|
||||
weeks = src; src = 0;
|
||||
|
||||
x = 0;
|
||||
if (weeks) {
|
||||
T(fmt1(weeks, 'W', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (days) {
|
||||
T(fmt1(days, 'D', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (hours) {
|
||||
T(fmt1(hours, 'H', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (mins) {
|
||||
T(fmt1(mins, 'M', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
if (secs || !(weeks || days || hours || mins)) {
|
||||
T(fmt1(secs, 'S', &dst, &dstlen));
|
||||
x++;
|
||||
}
|
||||
|
||||
if (x > 1) {
|
||||
int ch;
|
||||
|
||||
for (p = odst; (ch = *p) != '\0'; p++)
|
||||
if (isascii(ch) && isupper(ch))
|
||||
*p = tolower(ch);
|
||||
}
|
||||
|
||||
return (dst - odst);
|
||||
}
|
||||
|
||||
int
|
||||
ns_parse_ttl(const char *src, u_long *dst) {
|
||||
u_long ttl, tmp;
|
||||
int ch, digits, dirty;
|
||||
|
||||
ttl = 0;
|
||||
tmp = 0;
|
||||
digits = 0;
|
||||
dirty = 0;
|
||||
while ((ch = *src++) != '\0') {
|
||||
if (!isascii(ch) || !isprint(ch))
|
||||
goto einval;
|
||||
if (isdigit(ch)) {
|
||||
tmp *= 10;
|
||||
tmp += (ch - '0');
|
||||
digits++;
|
||||
continue;
|
||||
}
|
||||
if (digits == 0)
|
||||
goto einval;
|
||||
if (islower(ch))
|
||||
ch = toupper(ch);
|
||||
switch (ch) {
|
||||
case 'W': tmp *= 7;
|
||||
case 'D': tmp *= 24;
|
||||
case 'H': tmp *= 60;
|
||||
case 'M': tmp *= 60;
|
||||
case 'S': break;
|
||||
default: goto einval;
|
||||
}
|
||||
ttl += tmp;
|
||||
tmp = 0;
|
||||
digits = 0;
|
||||
dirty = 1;
|
||||
}
|
||||
if (digits > 0) {
|
||||
if (dirty)
|
||||
goto einval;
|
||||
else
|
||||
ttl += tmp;
|
||||
}
|
||||
*dst = ttl;
|
||||
return (0);
|
||||
|
||||
einval:
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/* Private. */
|
||||
|
||||
static int
|
||||
fmt1(int t, char s, char **buf, size_t *buflen) {
|
||||
char tmp[50];
|
||||
size_t len;
|
||||
|
||||
len = SPRINTF((tmp, "%d%c", t, s));
|
||||
if (len + 1 > *buflen)
|
||||
return (-1);
|
||||
strcpy(*buf, tmp);
|
||||
*buf += len;
|
||||
*buflen -= len;
|
||||
return (0);
|
||||
}
|
||||
105
c/src/exec/libnetworking/libc/nsap_addr.c
Normal file
105
c/src/exec/libnetworking/libc/nsap_addr.c
Normal file
@@ -0,0 +1,105 @@
|
||||
/*
|
||||
* Copyright (c) 1996, 1998 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
|
||||
static char
|
||||
xtob(c)
|
||||
register int c;
|
||||
{
|
||||
return (c - (((c >= '0') && (c <= '9')) ? '0' : '7'));
|
||||
}
|
||||
|
||||
u_int
|
||||
inet_nsap_addr(ascii, binary, maxlen)
|
||||
const char *ascii;
|
||||
u_char *binary;
|
||||
int maxlen;
|
||||
{
|
||||
u_char c, nib;
|
||||
u_int len = 0;
|
||||
|
||||
while ((c = *ascii++) != '\0' && len < (u_int)maxlen) {
|
||||
if (c == '.' || c == '+' || c == '/')
|
||||
continue;
|
||||
if (!isascii(c))
|
||||
return (0);
|
||||
if (islower(c))
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
nib = xtob(c);
|
||||
c = *ascii++;
|
||||
if (c != '\0') {
|
||||
c = toupper(c);
|
||||
if (isxdigit(c)) {
|
||||
*binary++ = (nib << 4) | xtob(c);
|
||||
len++;
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
return (len);
|
||||
}
|
||||
|
||||
char *
|
||||
inet_nsap_ntoa(binlen, binary, ascii)
|
||||
int binlen;
|
||||
register const u_char *binary;
|
||||
register char *ascii;
|
||||
{
|
||||
register int nib;
|
||||
int i;
|
||||
static char tmpbuf[255*3];
|
||||
char *start;
|
||||
|
||||
if (ascii)
|
||||
start = ascii;
|
||||
else {
|
||||
ascii = tmpbuf;
|
||||
start = tmpbuf;
|
||||
}
|
||||
|
||||
if (binlen > 255)
|
||||
binlen = 255;
|
||||
|
||||
for (i = 0; i < binlen; i++) {
|
||||
nib = *binary >> 4;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
nib = *binary++ & 0x0f;
|
||||
*ascii++ = nib + (nib < 10 ? '0' : '7');
|
||||
if (((i % 2) == 0 && (i + 1) < binlen))
|
||||
*ascii++ = '.';
|
||||
}
|
||||
*ascii = '\0';
|
||||
return (start);
|
||||
}
|
||||
204
c/src/exec/libnetworking/libc/rcmd.3
Normal file
204
c/src/exec/libnetworking/libc/rcmd.3
Normal file
@@ -0,0 +1,204 @@
|
||||
.\" Copyright (c) 1983, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" From: @(#)rcmd.3 8.1 (Berkeley) 6/4/93
|
||||
.\" $Id$
|
||||
.\"
|
||||
.Dd February 15, 1996
|
||||
.Dt RCMD 3
|
||||
.Os BSD 4.2
|
||||
.Sh NAME
|
||||
.Nm rcmd ,
|
||||
.Nm rresvport ,
|
||||
.Nm iruserok ,
|
||||
.Nm ruserok
|
||||
.Nd routines for returning a stream to a remote command
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <unistd.h>
|
||||
.Ft int
|
||||
.Fn rcmd "char **ahost" "int inport" "const char *locuser" "const char *remuser" "const char *cmd" "int *fd2p"
|
||||
.Ft int
|
||||
.Fn rresvport "int *port"
|
||||
.Ft int
|
||||
.Fn iruserok "u_long raddr" "int superuser" "const char *ruser" "const char *luser"
|
||||
.Ft int
|
||||
.Fn ruserok "const char *rhost" "int superuser" "const char *ruser" "const char *luser"
|
||||
.Sh DESCRIPTION
|
||||
The
|
||||
.Fn rcmd
|
||||
function
|
||||
is used by the super-user to execute a command on
|
||||
a remote machine using an authentication scheme based
|
||||
on reserved port numbers.
|
||||
The
|
||||
.Fn rresvport
|
||||
function
|
||||
returns a descriptor to a socket
|
||||
with an address in the privileged port space.
|
||||
The
|
||||
.Fn ruserok
|
||||
function
|
||||
is used by servers
|
||||
to authenticate clients requesting service with
|
||||
.Fn rcmd .
|
||||
All three functions are present in the same file and are used
|
||||
by the
|
||||
.Xr rshd 8
|
||||
server (among others).
|
||||
.Pp
|
||||
The
|
||||
.Fn rcmd
|
||||
function
|
||||
looks up the host
|
||||
.Fa *ahost
|
||||
using
|
||||
.Xr gethostbyname 3 ,
|
||||
returning \-1 if the host does not exist.
|
||||
Otherwise
|
||||
.Fa *ahost
|
||||
is set to the standard name of the host
|
||||
and a connection is established to a server
|
||||
residing at the well-known Internet port
|
||||
.Fa inport .
|
||||
.Pp
|
||||
If the connection succeeds,
|
||||
a socket in the Internet domain of type
|
||||
.Dv SOCK_STREAM
|
||||
is returned to the caller, and given to the remote
|
||||
command as
|
||||
.Em stdin
|
||||
and
|
||||
.Em stdout .
|
||||
If
|
||||
.Fa fd2p
|
||||
is non-zero, then an auxiliary channel to a control
|
||||
process will be set up, and a descriptor for it will be placed
|
||||
in
|
||||
.Fa *fd2p .
|
||||
The control process will return diagnostic
|
||||
output from the command (unit 2) on this channel, and will also
|
||||
accept bytes on this channel as being
|
||||
.Tn UNIX
|
||||
signal numbers, to be
|
||||
forwarded to the process group of the command.
|
||||
If
|
||||
.Fa fd2p
|
||||
is 0, then the
|
||||
.Em stderr
|
||||
(unit 2 of the remote
|
||||
command) will be made the same as the
|
||||
.Em stdout
|
||||
and no
|
||||
provision is made for sending arbitrary signals to the remote process,
|
||||
although you may be able to get its attention by using out-of-band data.
|
||||
.Pp
|
||||
The protocol is described in detail in
|
||||
.Xr rshd 8 .
|
||||
.Pp
|
||||
The
|
||||
.Fn rresvport
|
||||
function is used to obtain a socket with a privileged
|
||||
address bound to it. This socket is suitable for use
|
||||
by
|
||||
.Fn rcmd
|
||||
and several other functions. Privileged Internet ports are those
|
||||
in the range 0 to 1023. Only the super-user
|
||||
is allowed to bind an address of this sort to a socket.
|
||||
.Pp
|
||||
The
|
||||
.Fn iruserok
|
||||
and
|
||||
.Fn ruserok
|
||||
functions take a remote host's IP address or name, as returned by the
|
||||
.Xr gethostbyname 3
|
||||
routines, two user names and a flag indicating whether the local user's
|
||||
name is that of the super-user.
|
||||
Then, if the user is
|
||||
.Em NOT
|
||||
the super-user, it checks the
|
||||
.Pa /etc/hosts.equiv
|
||||
file.
|
||||
If that lookup is not done, or is unsuccessful, the
|
||||
.Pa .rhosts
|
||||
in the local user's home directory is checked to see if the request for
|
||||
service is allowed.
|
||||
.Pp
|
||||
If this file does not exist, is not a regular file, is owned by anyone
|
||||
other than the user or the super-user, or is writable by anyone other
|
||||
than the owner, the check automatically fails.
|
||||
Zero is returned if the machine name is listed in the
|
||||
.Dq Pa hosts.equiv
|
||||
file, or the host and remote user name are found in the
|
||||
.Dq Pa .rhosts
|
||||
file; otherwise
|
||||
.Fn iruserok
|
||||
and
|
||||
.Fn ruserok
|
||||
return \-1.
|
||||
If the local domain (as obtained from
|
||||
.Xr gethostname 3 )
|
||||
is the same as the remote domain, only the machine name need be specified.
|
||||
.Pp
|
||||
The
|
||||
.Fn iruserok
|
||||
function is strongly preferred for security reasons.
|
||||
It requires trusting the local DNS at most, while the
|
||||
.Fn ruserok
|
||||
function requires trusting the entire DNS, which can be spoofed.
|
||||
.Sh DIAGNOSTICS
|
||||
The
|
||||
.Fn rcmd
|
||||
function
|
||||
returns a valid socket descriptor on success.
|
||||
It returns \-1 on error and prints a diagnostic message on the standard error.
|
||||
.Pp
|
||||
The
|
||||
.Fn rresvport
|
||||
function
|
||||
returns a valid, bound socket descriptor on success.
|
||||
It returns \-1 on error with the global value
|
||||
.Va errno
|
||||
set according to the reason for failure.
|
||||
The error code
|
||||
.Dv EAGAIN
|
||||
is overloaded to mean ``All network ports in use.''
|
||||
.Sh SEE ALSO
|
||||
.Xr rlogin 1 ,
|
||||
.Xr rsh 1 ,
|
||||
.Xr intro 2 ,
|
||||
.Xr rexec 3 ,
|
||||
.Xr rexecd 8 ,
|
||||
.Xr rlogind 8 ,
|
||||
.Xr rshd 8
|
||||
.Sh HISTORY
|
||||
These
|
||||
functions appeared in
|
||||
.Bx 4.2 .
|
||||
518
c/src/exec/libnetworking/libc/rcmd.c
Normal file
518
c/src/exec/libnetworking/libc/rcmd.c
Normal file
@@ -0,0 +1,518 @@
|
||||
/*
|
||||
* Copyright (c) 1983, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)rcmd.c 8.3 (Berkeley) 3/26/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/stat.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <signal.h>
|
||||
#include <fcntl.h>
|
||||
#include <netdb.h>
|
||||
#include <unistd.h>
|
||||
#include <pwd.h>
|
||||
#include <errno.h>
|
||||
#include <stdio.h>
|
||||
#include <ctype.h>
|
||||
#include <string.h>
|
||||
#ifdef YP
|
||||
#include <rpc/rpc.h>
|
||||
#include <rpcsvc/yp_prot.h>
|
||||
#include <rpcsvc/ypclnt.h>
|
||||
#endif
|
||||
|
||||
extern int innetgr __P(( const char *, const char *, const char *, const char * ));
|
||||
|
||||
#define max(a, b) ((a > b) ? a : b)
|
||||
|
||||
int __ivaliduser __P((FILE *, u_long, const char *, const char *));
|
||||
static int __icheckhost __P((u_long, char *));
|
||||
|
||||
int
|
||||
rcmd(ahost, rport, locuser, remuser, cmd, fd2p)
|
||||
char **ahost;
|
||||
u_short rport;
|
||||
const char *locuser, *remuser, *cmd;
|
||||
int *fd2p;
|
||||
{
|
||||
struct hostent *hp;
|
||||
struct sockaddr_in sin, from;
|
||||
fd_set reads;
|
||||
long oldmask;
|
||||
pid_t pid;
|
||||
int s, lport, timo;
|
||||
char c;
|
||||
|
||||
pid = getpid();
|
||||
hp = gethostbyname(*ahost);
|
||||
if (hp == NULL) {
|
||||
herror(*ahost);
|
||||
return (-1);
|
||||
}
|
||||
*ahost = hp->h_name;
|
||||
oldmask = sigblock(sigmask(SIGURG));
|
||||
for (timo = 1, lport = IPPORT_RESERVED - 1;;) {
|
||||
s = rresvport(&lport);
|
||||
if (s < 0) {
|
||||
if (errno == EAGAIN)
|
||||
(void)fprintf(stderr,
|
||||
"rcmd: socket: All ports in use\n");
|
||||
else
|
||||
(void)fprintf(stderr, "rcmd: socket: %s\n",
|
||||
strerror(errno));
|
||||
sigsetmask(oldmask);
|
||||
return (-1);
|
||||
}
|
||||
fcntl(s, F_SETOWN, pid);
|
||||
bzero(&sin, sizeof sin);
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_family = hp->h_addrtype;
|
||||
sin.sin_port = rport;
|
||||
bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
|
||||
if (connect(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
|
||||
break;
|
||||
(void)close(s);
|
||||
if (errno == EADDRINUSE) {
|
||||
lport--;
|
||||
continue;
|
||||
}
|
||||
if (errno == ECONNREFUSED && timo <= 16) {
|
||||
(void)sleep(timo);
|
||||
timo *= 2;
|
||||
continue;
|
||||
}
|
||||
if (hp->h_addr_list[1] != NULL) {
|
||||
int oerrno = errno;
|
||||
|
||||
(void)fprintf(stderr, "connect to address %s: ",
|
||||
inet_ntoa(sin.sin_addr));
|
||||
errno = oerrno;
|
||||
perror(0);
|
||||
hp->h_addr_list++;
|
||||
bcopy(hp->h_addr_list[0], &sin.sin_addr, MIN(hp->h_length, sizeof sin.sin_addr));
|
||||
(void)fprintf(stderr, "Trying %s...\n",
|
||||
inet_ntoa(sin.sin_addr));
|
||||
continue;
|
||||
}
|
||||
(void)fprintf(stderr, "%s: %s\n", hp->h_name, strerror(errno));
|
||||
sigsetmask(oldmask);
|
||||
return (-1);
|
||||
}
|
||||
lport--;
|
||||
if (fd2p == 0) {
|
||||
write(s, "", 1);
|
||||
lport = 0;
|
||||
} else {
|
||||
char num[8];
|
||||
int s2 = rresvport(&lport), s3;
|
||||
int len = sizeof(from);
|
||||
int nfds;
|
||||
|
||||
if (s2 < 0)
|
||||
goto bad;
|
||||
listen(s2, 1);
|
||||
(void)snprintf(num, sizeof(num), "%d", lport);
|
||||
if (write(s, num, strlen(num)+1) != strlen(num)+1) {
|
||||
(void)fprintf(stderr,
|
||||
"rcmd: write (setting up stderr): %s\n",
|
||||
strerror(errno));
|
||||
(void)close(s2);
|
||||
goto bad;
|
||||
}
|
||||
nfds = max(s, s2)+1;
|
||||
if(nfds > FD_SETSIZE) {
|
||||
fprintf(stderr, "rcmd: too many files\n");
|
||||
(void)close(s2);
|
||||
goto bad;
|
||||
}
|
||||
again:
|
||||
FD_ZERO(&reads);
|
||||
FD_SET(s, &reads);
|
||||
FD_SET(s2, &reads);
|
||||
errno = 0;
|
||||
if (select(nfds, &reads, 0, 0, 0) < 1 || !FD_ISSET(s2, &reads)){
|
||||
if (errno != 0)
|
||||
(void)fprintf(stderr,
|
||||
"rcmd: select (setting up stderr): %s\n",
|
||||
strerror(errno));
|
||||
else
|
||||
(void)fprintf(stderr,
|
||||
"select: protocol failure in circuit setup\n");
|
||||
(void)close(s2);
|
||||
goto bad;
|
||||
}
|
||||
s3 = accept(s2, (struct sockaddr *)&from, &len);
|
||||
/*
|
||||
* XXX careful for ftp bounce attacks. If discovered, shut them
|
||||
* down and check for the real auxiliary channel to connect.
|
||||
*/
|
||||
if (from.sin_family == AF_INET && from.sin_port == htons(20)) {
|
||||
close(s3);
|
||||
goto again;
|
||||
}
|
||||
(void)close(s2);
|
||||
if (s3 < 0) {
|
||||
(void)fprintf(stderr,
|
||||
"rcmd: accept: %s\n", strerror(errno));
|
||||
lport = 0;
|
||||
goto bad;
|
||||
}
|
||||
*fd2p = s3;
|
||||
from.sin_port = ntohs((u_short)from.sin_port);
|
||||
if (from.sin_family != AF_INET ||
|
||||
from.sin_port >= IPPORT_RESERVED ||
|
||||
from.sin_port < IPPORT_RESERVED / 2) {
|
||||
(void)fprintf(stderr,
|
||||
"socket: protocol failure in circuit setup.\n");
|
||||
goto bad2;
|
||||
}
|
||||
}
|
||||
(void)write(s, locuser, strlen(locuser)+1);
|
||||
(void)write(s, remuser, strlen(remuser)+1);
|
||||
(void)write(s, cmd, strlen(cmd)+1);
|
||||
if (read(s, &c, 1) != 1) {
|
||||
(void)fprintf(stderr,
|
||||
"rcmd: %s: %s\n", *ahost, strerror(errno));
|
||||
goto bad2;
|
||||
}
|
||||
if (c != 0) {
|
||||
while (read(s, &c, 1) == 1) {
|
||||
(void)write(STDERR_FILENO, &c, 1);
|
||||
if (c == '\n')
|
||||
break;
|
||||
}
|
||||
goto bad2;
|
||||
}
|
||||
sigsetmask(oldmask);
|
||||
return (s);
|
||||
bad2:
|
||||
if (lport)
|
||||
(void)close(*fd2p);
|
||||
bad:
|
||||
(void)close(s);
|
||||
sigsetmask(oldmask);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int
|
||||
rresvport(alport)
|
||||
int *alport;
|
||||
{
|
||||
struct sockaddr_in sin;
|
||||
int s;
|
||||
|
||||
bzero(&sin, sizeof sin);
|
||||
sin.sin_len = sizeof(struct sockaddr_in);
|
||||
sin.sin_family = AF_INET;
|
||||
sin.sin_addr.s_addr = INADDR_ANY;
|
||||
s = socket(AF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0)
|
||||
return (-1);
|
||||
#if 0 /* compat_exact_traditional_rresvport_semantics */
|
||||
sin.sin_port = htons((u_short)*alport);
|
||||
if (bind(s, (struct sockaddr *)&sin, sizeof(sin)) >= 0)
|
||||
return (s);
|
||||
if (errno != EADDRINUSE) {
|
||||
(void)close(s);
|
||||
return (-1);
|
||||
}
|
||||
#endif
|
||||
sin.sin_port = 0;
|
||||
if (bindresvport(s, &sin) == -1) {
|
||||
(void)close(s);
|
||||
return (-1);
|
||||
}
|
||||
*alport = (int)ntohs(sin.sin_port);
|
||||
return (s);
|
||||
}
|
||||
|
||||
int __check_rhosts_file = 1;
|
||||
char *__rcmd_errstr;
|
||||
|
||||
int
|
||||
ruserok(rhost, superuser, ruser, luser)
|
||||
const char *rhost, *ruser, *luser;
|
||||
int superuser;
|
||||
{
|
||||
struct hostent *hp;
|
||||
u_long addr;
|
||||
char **ap;
|
||||
|
||||
if ((hp = gethostbyname(rhost)) == NULL)
|
||||
return (-1);
|
||||
for (ap = hp->h_addr_list; *ap; ++ap) {
|
||||
bcopy(*ap, &addr, sizeof(addr));
|
||||
if (iruserok(addr, superuser, ruser, luser) == 0)
|
||||
return (0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* New .rhosts strategy: We are passed an ip address. We spin through
|
||||
* hosts.equiv and .rhosts looking for a match. When the .rhosts only
|
||||
* has ip addresses, we don't have to trust a nameserver. When it
|
||||
* contains hostnames, we spin through the list of addresses the nameserver
|
||||
* gives us and look for a match.
|
||||
*
|
||||
* Returns 0 if ok, -1 if not ok.
|
||||
*/
|
||||
int
|
||||
iruserok(raddr, superuser, ruser, luser)
|
||||
u_long raddr;
|
||||
int superuser;
|
||||
const char *ruser, *luser;
|
||||
{
|
||||
register char *cp;
|
||||
struct stat sbuf;
|
||||
struct passwd *pwd;
|
||||
FILE *hostf;
|
||||
uid_t uid;
|
||||
int first;
|
||||
char pbuf[MAXPATHLEN];
|
||||
|
||||
first = 1;
|
||||
hostf = superuser ? NULL : fopen(_PATH_HEQUIV, "r");
|
||||
again:
|
||||
if (hostf) {
|
||||
if (__ivaliduser(hostf, raddr, luser, ruser) == 0) {
|
||||
(void)fclose(hostf);
|
||||
return (0);
|
||||
}
|
||||
(void)fclose(hostf);
|
||||
}
|
||||
if (first == 1 && (__check_rhosts_file || superuser)) {
|
||||
first = 0;
|
||||
if ((pwd = getpwnam(luser)) == NULL)
|
||||
return (-1);
|
||||
(void)strcpy(pbuf, pwd->pw_dir);
|
||||
(void)strcat(pbuf, "/.rhosts");
|
||||
|
||||
/*
|
||||
* Change effective uid while opening .rhosts. If root and
|
||||
* reading an NFS mounted file system, can't read files that
|
||||
* are protected read/write owner only.
|
||||
*/
|
||||
uid = geteuid();
|
||||
(void)seteuid(pwd->pw_uid);
|
||||
hostf = fopen(pbuf, "r");
|
||||
(void)seteuid(uid);
|
||||
|
||||
if (hostf == NULL)
|
||||
return (-1);
|
||||
/*
|
||||
* If not a regular file, or is owned by someone other than
|
||||
* user or root or if writeable by anyone but the owner, quit.
|
||||
*/
|
||||
cp = NULL;
|
||||
if (lstat(pbuf, &sbuf) < 0)
|
||||
cp = ".rhosts lstat failed";
|
||||
else if (!S_ISREG(sbuf.st_mode))
|
||||
cp = ".rhosts not regular file";
|
||||
else if (fstat(fileno(hostf), &sbuf) < 0)
|
||||
cp = ".rhosts fstat failed";
|
||||
else if (sbuf.st_uid && sbuf.st_uid != pwd->pw_uid)
|
||||
cp = "bad .rhosts owner";
|
||||
else if (sbuf.st_mode & (S_IWGRP|S_IWOTH))
|
||||
cp = ".rhosts writeable by other than owner";
|
||||
/* If there were any problems, quit. */
|
||||
if (cp) {
|
||||
__rcmd_errstr = cp;
|
||||
(void)fclose(hostf);
|
||||
return (-1);
|
||||
}
|
||||
goto again;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX
|
||||
* Don't make static, used by lpd(8).
|
||||
*
|
||||
* Returns 0 if ok, -1 if not ok.
|
||||
*/
|
||||
int
|
||||
__ivaliduser(hostf, raddr, luser, ruser)
|
||||
FILE *hostf;
|
||||
u_long raddr;
|
||||
const char *luser, *ruser;
|
||||
{
|
||||
register char *user, *p;
|
||||
int ch;
|
||||
char buf[MAXHOSTNAMELEN + 128]; /* host + login */
|
||||
char hname[MAXHOSTNAMELEN];
|
||||
struct hostent *hp;
|
||||
/* Presumed guilty until proven innocent. */
|
||||
int userok = 0, hostok = 0;
|
||||
#ifdef YP
|
||||
char *ypdomain;
|
||||
|
||||
if (yp_get_default_domain(&ypdomain))
|
||||
ypdomain = NULL;
|
||||
#else
|
||||
#define ypdomain NULL
|
||||
#endif
|
||||
/* We need to get the damn hostname back for netgroup matching. */
|
||||
if ((hp = gethostbyaddr((char *)&raddr, sizeof(u_long),
|
||||
AF_INET)) == NULL)
|
||||
return (-1);
|
||||
strncpy(hname, hp->h_name, sizeof(hname));
|
||||
hname[sizeof(hname) - 1] = '\0';
|
||||
|
||||
while (fgets(buf, sizeof(buf), hostf)) {
|
||||
p = buf;
|
||||
/* Skip lines that are too long. */
|
||||
if (strchr(p, '\n') == NULL) {
|
||||
while ((ch = getc(hostf)) != '\n' && ch != EOF);
|
||||
continue;
|
||||
}
|
||||
if (*p == '\n' || *p == '#') {
|
||||
/* comment... */
|
||||
continue;
|
||||
}
|
||||
while (*p != '\n' && *p != ' ' && *p != '\t' && *p != '\0') {
|
||||
*p = isupper(*p) ? tolower(*p) : *p;
|
||||
p++;
|
||||
}
|
||||
if (*p == ' ' || *p == '\t') {
|
||||
*p++ = '\0';
|
||||
while (*p == ' ' || *p == '\t')
|
||||
p++;
|
||||
user = p;
|
||||
while (*p != '\n' && *p != ' ' &&
|
||||
*p != '\t' && *p != '\0')
|
||||
p++;
|
||||
} else
|
||||
user = p;
|
||||
*p = '\0';
|
||||
/*
|
||||
* Do +/- and +@/-@ checking. This looks really nasty,
|
||||
* but it matches SunOS's behavior so far as I can tell.
|
||||
*/
|
||||
switch(buf[0]) {
|
||||
case '+':
|
||||
if (!buf[1]) { /* '+' matches all hosts */
|
||||
hostok = 1;
|
||||
break;
|
||||
}
|
||||
if (buf[1] == '@') /* match a host by netgroup */
|
||||
hostok = innetgr((char *)&buf[2],
|
||||
(char *)&hname, NULL, ypdomain);
|
||||
else /* match a host by addr */
|
||||
hostok = __icheckhost(raddr,(char *)&buf[1]);
|
||||
break;
|
||||
case '-': /* reject '-' hosts and all their users */
|
||||
if (buf[1] == '@') {
|
||||
if (innetgr((char *)&buf[2],
|
||||
(char *)&hname, NULL, ypdomain))
|
||||
return(-1);
|
||||
} else {
|
||||
if (__icheckhost(raddr,(char *)&buf[1]))
|
||||
return(-1);
|
||||
}
|
||||
break;
|
||||
default: /* if no '+' or '-', do a simple match */
|
||||
hostok = __icheckhost(raddr, buf);
|
||||
break;
|
||||
}
|
||||
switch(*user) {
|
||||
case '+':
|
||||
if (!*(user+1)) { /* '+' matches all users */
|
||||
userok = 1;
|
||||
break;
|
||||
}
|
||||
if (*(user+1) == '@') /* match a user by netgroup */
|
||||
userok = innetgr(user+2, NULL, ruser, ypdomain);
|
||||
else /* match a user by direct specification */
|
||||
userok = !(strcmp(ruser, user+1));
|
||||
break;
|
||||
case '-': /* if we matched a hostname, */
|
||||
if (hostok) { /* check for user field rejections */
|
||||
if (!*(user+1))
|
||||
return(-1);
|
||||
if (*(user+1) == '@') {
|
||||
if (innetgr(user+2, NULL,
|
||||
ruser, ypdomain))
|
||||
return(-1);
|
||||
} else {
|
||||
if (!strcmp(ruser, user+1))
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
default: /* no rejections: try to match the user */
|
||||
if (hostok)
|
||||
userok = !(strcmp(ruser,*user ? user : luser));
|
||||
break;
|
||||
}
|
||||
if (hostok && userok)
|
||||
return(0);
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns "true" if match, 0 if no match.
|
||||
*/
|
||||
static int
|
||||
__icheckhost(raddr, lhost)
|
||||
u_long raddr;
|
||||
register char *lhost;
|
||||
{
|
||||
register struct hostent *hp;
|
||||
register u_long laddr;
|
||||
register char **pp;
|
||||
|
||||
/* Try for raw ip address first. */
|
||||
if (isdigit(*lhost) && (long)(laddr = inet_addr(lhost)) != -1)
|
||||
return (raddr == laddr);
|
||||
|
||||
/* Better be a hostname. */
|
||||
if ((hp = gethostbyname(lhost)) == NULL)
|
||||
return (0);
|
||||
|
||||
/* Spin through ip addresses. */
|
||||
for (pp = hp->h_addr_list; *pp; ++pp)
|
||||
if (!bcmp(&raddr, *pp, sizeof(u_long)))
|
||||
return (1);
|
||||
|
||||
/* No match. */
|
||||
return (0);
|
||||
}
|
||||
50
c/src/exec/libnetworking/libc/recv.c
Normal file
50
c/src/exec/libnetworking/libc/recv.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)recv.c 8.2 (Berkeley) 2/21/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ssize_t
|
||||
recv(s, buf, len, flags)
|
||||
int s, flags;
|
||||
size_t len;
|
||||
void *buf;
|
||||
{
|
||||
return (recvfrom(s, buf, len, flags, NULL, 0));
|
||||
}
|
||||
258
c/src/exec/libnetworking/libc/res_comp.c
Normal file
258
c/src/exec/libnetworking/libc/res_comp.c
Normal file
@@ -0,0 +1,258 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_comp.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_comp.c,v 8.11 1997/05/21 19:31:04 halley Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#define BIND_4_COMPAT
|
||||
|
||||
/*
|
||||
* Expand compressed domain name 'comp_dn' to full domain name.
|
||||
* 'msg' is a pointer to the begining of the message,
|
||||
* 'eomorig' points to the first location after the message,
|
||||
* 'exp_dn' is a pointer to a buffer of size 'length' for the result.
|
||||
* Return size of compressed name or -1 if there was an error.
|
||||
*/
|
||||
int
|
||||
dn_expand(const u_char *msg, const u_char *eom, const u_char *src,
|
||||
char *dst, int dstsiz)
|
||||
{
|
||||
int n = ns_name_uncompress(msg, eom, src, dst, (size_t)dstsiz);
|
||||
|
||||
if (n > 0 && dst[0] == '.')
|
||||
dst[0] = '\0';
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Pack domain name 'exp_dn' in presentation form into 'comp_dn'.
|
||||
* Return the size of the compressed name or -1.
|
||||
* 'length' is the size of the array pointed to by 'comp_dn'.
|
||||
*/
|
||||
int
|
||||
dn_comp(const char *src, u_char *dst, int dstsiz,
|
||||
u_char **dnptrs, u_char **lastdnptr)
|
||||
{
|
||||
return (ns_name_compress(src, dst, (size_t)dstsiz,
|
||||
(const u_char **)dnptrs,
|
||||
(const u_char **)lastdnptr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Skip over a compressed domain name. Return the size or -1.
|
||||
*/
|
||||
int
|
||||
dn_skipname(const u_char *ptr, const u_char *eom) {
|
||||
const u_char *saveptr = ptr;
|
||||
|
||||
if (ns_name_skip(&ptr, eom) == -1)
|
||||
return (-1);
|
||||
return (ptr - saveptr);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that a domain name uses an acceptable character set.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Note the conspicuous absence of ctype macros in these definitions. On
|
||||
* non-ASCII hosts, we can't depend on string literals or ctype macros to
|
||||
* tell us anything about network-format data. The rest of the BIND system
|
||||
* is not careful about this, but for some reason, we're doing it right here.
|
||||
*/
|
||||
#define PERIOD 0x2e
|
||||
#define hyphenchar(c) ((c) == 0x2d)
|
||||
#define bslashchar(c) ((c) == 0x5c)
|
||||
#define periodchar(c) ((c) == PERIOD)
|
||||
#define asterchar(c) ((c) == 0x2a)
|
||||
#define alphachar(c) (((c) >= 0x41 && (c) <= 0x5a) \
|
||||
|| ((c) >= 0x61 && (c) <= 0x7a))
|
||||
#define digitchar(c) ((c) >= 0x30 && (c) <= 0x39)
|
||||
|
||||
#define borderchar(c) (alphachar(c) || digitchar(c))
|
||||
#define middlechar(c) (borderchar(c) || hyphenchar(c))
|
||||
#define domainchar(c) ((c) > 0x20 && (c) < 0x7f)
|
||||
|
||||
int
|
||||
res_hnok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int ppch = '\0', pch = PERIOD, ch = *dn++;
|
||||
|
||||
while (ch != '\0') {
|
||||
int nch = *dn++;
|
||||
|
||||
if (periodchar(ch)) {
|
||||
(void)NULL;
|
||||
} else if (periodchar(pch)) {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else if (periodchar(nch) || nch == '\0') {
|
||||
if (!borderchar(ch))
|
||||
return (0);
|
||||
} else {
|
||||
if (!middlechar(ch))
|
||||
return (0);
|
||||
}
|
||||
ppch = pch, pch = ch, ch = nch;
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
/*
|
||||
* hostname-like (A, MX, WKS) owners can have "*" as their first label
|
||||
* but must otherwise be as a host name.
|
||||
*/
|
||||
int
|
||||
res_ownok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
if (asterchar(dn[0])) {
|
||||
if (periodchar(dn[1]))
|
||||
return (res_hnok(dn+2));
|
||||
if (dn[1] == '\0')
|
||||
return (1);
|
||||
}
|
||||
return (res_hnok(dn));
|
||||
}
|
||||
|
||||
/*
|
||||
* SOA RNAMEs and RP RNAMEs can have any printable character in their first
|
||||
* label, but the rest of the name has to look like a host name.
|
||||
*/
|
||||
int
|
||||
res_mailok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int ch, escaped = 0;
|
||||
|
||||
/* "." is a valid missing representation */
|
||||
if (*dn == '\0')
|
||||
return (1);
|
||||
|
||||
/* otherwise <label>.<hostname> */
|
||||
while ((ch = *dn++) != '\0') {
|
||||
if (!domainchar(ch))
|
||||
return (0);
|
||||
if (!escaped && periodchar(ch))
|
||||
break;
|
||||
if (escaped)
|
||||
escaped = 0;
|
||||
else if (bslashchar(ch))
|
||||
escaped = 1;
|
||||
}
|
||||
if (periodchar(ch))
|
||||
return (res_hnok(dn));
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* This function is quite liberal, since RFC 1034's character sets are only
|
||||
* recommendations.
|
||||
*/
|
||||
int
|
||||
res_dnok(dn)
|
||||
const char *dn;
|
||||
{
|
||||
int ch;
|
||||
|
||||
while ((ch = *dn++) != '\0')
|
||||
if (!domainchar(ch))
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#ifdef BIND_4_COMPAT
|
||||
/*
|
||||
* This module must export the following externally-visible symbols:
|
||||
* ___putlong
|
||||
* ___putshort
|
||||
* __getlong
|
||||
* __getshort
|
||||
* Note that one _ comes from C and the others come from us.
|
||||
*/
|
||||
void __putlong(u_int32_t src, u_char *dst) { ns_put32(src, dst); }
|
||||
void __putshort(u_int16_t src, u_char *dst) { ns_put16(src, dst); }
|
||||
u_int32_t _getlong(const u_char *src) { return (ns_get32(src)); }
|
||||
u_int16_t _getshort(const u_char *src) { return (ns_get16(src)); }
|
||||
#endif /*BIND_4_COMPAT*/
|
||||
8
c/src/exec/libnetworking/libc/res_config.h
Normal file
8
c/src/exec/libnetworking/libc/res_config.h
Normal file
@@ -0,0 +1,8 @@
|
||||
#define DEBUG 1 /* enable debugging code (needed for dig) */
|
||||
#define RESOLVSORT /* allow sorting of addresses in gethostbyname */
|
||||
#define RFC1535 /* comply with RFC1535 (STRONGLY reccomended by vixie)*/
|
||||
#undef USELOOPBACK /* res_init() bind to localhost */
|
||||
#undef SUNSECURITY /* verify gethostbyaddr() calls - WE DONT NEED IT */
|
||||
#define MULTI_PTRS_ARE_ALIASES 1 /* fold multiple PTR records into aliases */
|
||||
#define CHECK_SRVR_ADDR 1 /* confirm that the server requested sent the reply */
|
||||
#define BIND_UPDATE 1 /* update support */
|
||||
83
c/src/exec/libnetworking/libc/res_data.c
Normal file
83
c/src/exec/libnetworking/libc/res_data.c
Normal file
@@ -0,0 +1,83 @@
|
||||
/*
|
||||
* Copyright (c) 1995,1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
const char *_res_opcodes[] = {
|
||||
"QUERY",
|
||||
"IQUERY",
|
||||
"CQUERYM",
|
||||
"CQUERYU", /* experimental */
|
||||
"NOTIFY", /* experimental */
|
||||
"UPDATE",
|
||||
"6",
|
||||
"7",
|
||||
"8",
|
||||
"9",
|
||||
"10",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"ZONEINIT",
|
||||
"ZONEREF",
|
||||
};
|
||||
|
||||
const char *_res_resultcodes[] = {
|
||||
"NOERROR",
|
||||
"FORMERR",
|
||||
"SERVFAIL",
|
||||
"NXDOMAIN",
|
||||
"NOTIMP",
|
||||
"REFUSED",
|
||||
"YXDOMAIN",
|
||||
"YXRRSET",
|
||||
"NXRRSET",
|
||||
"NOTAUTH",
|
||||
"ZONEERR",
|
||||
"11",
|
||||
"12",
|
||||
"13",
|
||||
"14",
|
||||
"NOCHANGE",
|
||||
};
|
||||
|
||||
#ifdef BIND_UPDATE
|
||||
const char *_res_sectioncodes[] = {
|
||||
"ZONE",
|
||||
"PREREQUISITES",
|
||||
"UPDATE",
|
||||
"ADDITIONAL",
|
||||
};
|
||||
#endif
|
||||
966
c/src/exec/libnetworking/libc/res_debug.c
Normal file
966
c/src/exec/libnetworking/libc/res_debug.c
Normal file
@@ -0,0 +1,966 @@
|
||||
/*
|
||||
* Copyright (c) 1985
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1995 by International Business Machines, Inc.
|
||||
*
|
||||
* International Business Machines, Inc. (hereinafter called IBM) grants
|
||||
* permission under its copyrights to use, copy, modify, and distribute this
|
||||
* Software with or without fee, provided that the above copyright notice and
|
||||
* all paragraphs of this notice appear in all copies, and that the name of IBM
|
||||
* not be used in connection with the marketing of any product incorporating
|
||||
* the Software or modifications thereof, without specific, written prior
|
||||
* permission.
|
||||
*
|
||||
* To the extent it has a right to do so, IBM grants an immunity from suit
|
||||
* under its patents, if any, for the use, sale or manufacture of products to
|
||||
* the extent that such products are used for performing Domain Name System
|
||||
* dynamic updates in TCP/IP networks by means of the Software. No immunity is
|
||||
* granted for any product per se or for any other function of any product.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS", AND IBM DISCLAIMS ALL WARRANTIES,
|
||||
* INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
|
||||
* PARTICULAR PURPOSE. IN NO EVENT SHALL IBM BE LIABLE FOR ANY SPECIAL,
|
||||
* DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER ARISING
|
||||
* OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE, EVEN
|
||||
* IF IBM IS APPRISED OF THE POSSIBILITY OF SUCH DAMAGES.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_debug.c 8.1 (Berkeley) 6/4/93";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <math.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <time.h>
|
||||
|
||||
#define SPRINTF(x) sprintf x
|
||||
|
||||
extern const char *_res_opcodes[];
|
||||
extern const char *_res_resultcodes[];
|
||||
extern const char *_res_sectioncodes[];
|
||||
|
||||
/*
|
||||
* Print the current options.
|
||||
*/
|
||||
void
|
||||
fp_resstat(struct __res_state *statp, FILE *file) {
|
||||
u_long mask;
|
||||
|
||||
fprintf(file, ";; res options:");
|
||||
if (!statp)
|
||||
statp = &_res;
|
||||
for (mask = 1; mask != 0; mask <<= 1)
|
||||
if (statp->options & mask)
|
||||
fprintf(file, " %s", p_option(mask));
|
||||
putc('\n', file);
|
||||
}
|
||||
|
||||
static void
|
||||
do_section(ns_msg *handle, ns_sect section, int pflag, FILE *file) {
|
||||
int n, sflag, rrnum;
|
||||
char buf[2048]; /* XXX need to malloc */
|
||||
ns_opcode opcode;
|
||||
ns_rr rr;
|
||||
|
||||
/*
|
||||
* Print answer records.
|
||||
*/
|
||||
sflag = (_res.pfcode & pflag);
|
||||
if (_res.pfcode && !sflag)
|
||||
return;
|
||||
|
||||
opcode = ns_msg_getflag(*handle, ns_f_opcode);
|
||||
rrnum = 0;
|
||||
for (;;) {
|
||||
if (ns_parserr(handle, section, rrnum, &rr)) {
|
||||
if (errno != ENODEV)
|
||||
fprintf(file, ";; ns_parserr: %s\n",
|
||||
strerror(errno));
|
||||
else if (rrnum > 0 && sflag != 0 &&
|
||||
(_res.pfcode & RES_PRF_HEAD1))
|
||||
putc('\n', file);
|
||||
return;
|
||||
}
|
||||
if (rrnum == 0 && sflag != 0 && (_res.pfcode & RES_PRF_HEAD1))
|
||||
fprintf(file, ";; %s SECTION:\n",
|
||||
p_section(section, opcode));
|
||||
if (section == ns_s_qd)
|
||||
fprintf(file, ";;\t%s, type = %s, class = %s\n",
|
||||
ns_rr_name(rr),
|
||||
p_type(ns_rr_type(rr)),
|
||||
p_class(ns_rr_class(rr)));
|
||||
else {
|
||||
n = ns_sprintrr(handle, &rr, NULL, NULL,
|
||||
buf, sizeof buf);
|
||||
if (n < 0) {
|
||||
fprintf(file, ";; ns_sprintrr: %s\n",
|
||||
strerror(errno));
|
||||
return;
|
||||
}
|
||||
fputs(buf, file);
|
||||
fputc('\n', file);
|
||||
}
|
||||
rrnum++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
p_query(const u_char *msg) {
|
||||
fp_query(msg, stdout);
|
||||
}
|
||||
|
||||
void
|
||||
fp_query(const u_char *msg, FILE *file) {
|
||||
fp_nquery(msg, PACKETSZ, file);
|
||||
}
|
||||
|
||||
/*
|
||||
* Print the contents of a query.
|
||||
* This is intended to be primarily a debugging routine.
|
||||
*/
|
||||
void
|
||||
fp_nquery(const u_char *msg, int len, FILE *file) {
|
||||
ns_msg handle;
|
||||
int n, qdcount, ancount, nscount, arcount;
|
||||
u_int opcode, rcode, id;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1)
|
||||
return;
|
||||
|
||||
if (ns_initparse(msg, len, &handle) < 0) {
|
||||
fprintf(file, ";; ns_initparse: %s\n", strerror(errno));
|
||||
return;
|
||||
}
|
||||
opcode = ns_msg_getflag(handle, ns_f_opcode);
|
||||
rcode = ns_msg_getflag(handle, ns_f_rcode);
|
||||
id = ns_msg_id(handle);
|
||||
qdcount = ns_msg_count(handle, ns_s_qd);
|
||||
ancount = ns_msg_count(handle, ns_s_an);
|
||||
nscount = ns_msg_count(handle, ns_s_ns);
|
||||
arcount = ns_msg_count(handle, ns_s_ar);
|
||||
|
||||
/*
|
||||
* Print header fields.
|
||||
*/
|
||||
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX) || rcode)
|
||||
fprintf(file,
|
||||
";; ->>HEADER<<- opcode: %s, status: %s, id: %d\n",
|
||||
_res_opcodes[opcode], _res_resultcodes[rcode], id);
|
||||
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEADX))
|
||||
putc(';', file);
|
||||
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD2)) {
|
||||
fprintf(file, "; flags:");
|
||||
if (ns_msg_getflag(handle, ns_f_qr))
|
||||
fprintf(file, " qr");
|
||||
if (ns_msg_getflag(handle, ns_f_aa))
|
||||
fprintf(file, " aa");
|
||||
if (ns_msg_getflag(handle, ns_f_tc))
|
||||
fprintf(file, " tc");
|
||||
if (ns_msg_getflag(handle, ns_f_rd))
|
||||
fprintf(file, " rd");
|
||||
if (ns_msg_getflag(handle, ns_f_ra))
|
||||
fprintf(file, " ra");
|
||||
if (ns_msg_getflag(handle, ns_f_z))
|
||||
fprintf(file, " ??");
|
||||
if (ns_msg_getflag(handle, ns_f_ad))
|
||||
fprintf(file, " ad");
|
||||
if (ns_msg_getflag(handle, ns_f_cd))
|
||||
fprintf(file, " cd");
|
||||
}
|
||||
if ((!_res.pfcode) || (_res.pfcode & RES_PRF_HEAD1)) {
|
||||
fprintf(file, "; %s: %d",
|
||||
p_section(ns_s_qd, opcode), qdcount);
|
||||
fprintf(file, ", %s: %d",
|
||||
p_section(ns_s_an, opcode), ancount);
|
||||
fprintf(file, ", %s: %d",
|
||||
p_section(ns_s_ns, opcode), nscount);
|
||||
fprintf(file, ", %s: %d",
|
||||
p_section(ns_s_ar, opcode), arcount);
|
||||
}
|
||||
if ((!_res.pfcode) || (_res.pfcode &
|
||||
(RES_PRF_HEADX | RES_PRF_HEAD2 | RES_PRF_HEAD1))) {
|
||||
putc('\n',file);
|
||||
}
|
||||
/*
|
||||
* Print the various sections.
|
||||
*/
|
||||
do_section(&handle, ns_s_qd, RES_PRF_QUES, file);
|
||||
do_section(&handle, ns_s_an, RES_PRF_ANS, file);
|
||||
do_section(&handle, ns_s_ns, RES_PRF_AUTH, file);
|
||||
do_section(&handle, ns_s_ar, RES_PRF_ADD, file);
|
||||
if (qdcount == 0 && ancount == 0 &&
|
||||
nscount == 0 && arcount == 0)
|
||||
putc('\n', file);
|
||||
}
|
||||
|
||||
const u_char *
|
||||
p_cdnname(const u_char *cp, const u_char *msg, int len, FILE *file) {
|
||||
char name[MAXDNAME];
|
||||
int n;
|
||||
|
||||
if ((n = dn_expand(msg, msg + len, cp, name, sizeof name)) < 0)
|
||||
return (NULL);
|
||||
if (name[0] == '\0')
|
||||
putc('.', file);
|
||||
else
|
||||
fputs(name, file);
|
||||
return (cp + n);
|
||||
}
|
||||
|
||||
const u_char *
|
||||
p_cdname(const u_char *cp, const u_char *msg, FILE *file) {
|
||||
return (p_cdnname(cp, msg, PACKETSZ, file));
|
||||
}
|
||||
|
||||
/* Return a fully-qualified domain name from a compressed name (with
|
||||
length supplied). */
|
||||
|
||||
const u_char *
|
||||
p_fqnname(cp, msg, msglen, name, namelen)
|
||||
const u_char *cp, *msg;
|
||||
int msglen;
|
||||
char *name;
|
||||
int namelen;
|
||||
{
|
||||
int n, newlen;
|
||||
|
||||
if ((n = dn_expand(msg, cp + msglen, cp, name, namelen)) < 0)
|
||||
return (NULL);
|
||||
newlen = strlen(name);
|
||||
if (newlen == 0 || name[newlen - 1] != '.') {
|
||||
if (newlen + 1 >= namelen) /* Lack space for final dot */
|
||||
return (NULL);
|
||||
else
|
||||
strcpy(name + newlen, ".");
|
||||
}
|
||||
return (cp + n);
|
||||
}
|
||||
|
||||
/* XXX: the rest of these functions need to become length-limited, too. */
|
||||
|
||||
const u_char *
|
||||
p_fqname(const u_char *cp, const u_char *msg, FILE *file) {
|
||||
char name[MAXDNAME];
|
||||
const u_char *n;
|
||||
|
||||
n = p_fqnname(cp, msg, MAXCDNAME, name, sizeof name);
|
||||
if (n == NULL)
|
||||
return (NULL);
|
||||
fputs(name, file);
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Names of RR classes and qclasses. Classes and qclasses are the same, except
|
||||
* that C_ANY is a qclass but not a class. (You can ask for records of class
|
||||
* C_ANY, but you can't have any records of that class in the database.)
|
||||
*/
|
||||
const struct res_sym __p_class_syms[] = {
|
||||
{C_IN, "IN"},
|
||||
{C_CHAOS, "CHAOS"},
|
||||
{C_HS, "HS"},
|
||||
{C_HS, "HESIOD"},
|
||||
{C_ANY, "ANY"},
|
||||
{C_NONE, "NONE"},
|
||||
{C_IN, (char *)0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of message sections.
|
||||
*/
|
||||
const struct res_sym __p_default_section_syms[] = {
|
||||
{ns_s_qd, "QUERY"},
|
||||
{ns_s_an, "ANSWER"},
|
||||
{ns_s_ns, "AUTHORITY"},
|
||||
{ns_s_ar, "ADDITIONAL"},
|
||||
{0, (char *)0}
|
||||
};
|
||||
|
||||
const struct res_sym __p_update_section_syms[] = {
|
||||
{S_ZONE, "ZONE"},
|
||||
{S_PREREQ, "PREREQUISITE"},
|
||||
{S_UPDATE, "UPDATE"},
|
||||
{S_ADDT, "ADDITIONAL"},
|
||||
{0, (char *)0}
|
||||
};
|
||||
|
||||
/*
|
||||
* Names of RR types and qtypes. Types and qtypes are the same, except
|
||||
* that T_ANY is a qtype but not a type. (You can ask for records of type
|
||||
* T_ANY, but you can't have any records of that type in the database.)
|
||||
*/
|
||||
const struct res_sym __p_type_syms[] = {
|
||||
{T_A, "A", "address"},
|
||||
{T_NS, "NS", "name server"},
|
||||
{T_MD, "MD", "mail destination (deprecated)"},
|
||||
{T_MF, "MF", "mail forwarder (deprecated)"},
|
||||
{T_CNAME, "CNAME", "canonical name"},
|
||||
{T_SOA, "SOA", "start of authority"},
|
||||
{T_MB, "MB", "mailbox"},
|
||||
{T_MG, "MG", "mail group member"},
|
||||
{T_MR, "MR", "mail rename"},
|
||||
{T_NULL, "NULL", "null"},
|
||||
{T_WKS, "WKS", "well-known service (deprecated)"},
|
||||
{T_PTR, "PTR", "domain name pointer"},
|
||||
{T_HINFO, "HINFO", "host information"},
|
||||
{T_MINFO, "MINFO", "mailbox information"},
|
||||
{T_MX, "MX", "mail exchanger"},
|
||||
{T_TXT, "TXT", "text"},
|
||||
{T_RP, "RP", "responsible person"},
|
||||
{T_AFSDB, "AFSDB", "DCE or AFS server"},
|
||||
{T_X25, "X25", "X25 address"},
|
||||
{T_ISDN, "ISDN", "ISDN address"},
|
||||
{T_RT, "RT", "router"},
|
||||
{T_NSAP, "NSAP", "nsap address"},
|
||||
{T_NSAP_PTR, "NSAP_PTR", "domain name pointer"},
|
||||
{T_SIG, "SIG", "signature"},
|
||||
{T_KEY, "KEY", "key"},
|
||||
{T_PX, "PX", "mapping information"},
|
||||
{T_GPOS, "GPOS", "geographical position (withdrawn)"},
|
||||
{T_AAAA, "AAAA", "IPv6 address"},
|
||||
{T_LOC, "LOC", "location"},
|
||||
{T_NXT, "NXT", "next valid name (unimplemented)"},
|
||||
{T_EID, "EID", "endpoint identifier (unimplemented)"},
|
||||
{T_NIMLOC, "NIMLOC", "NIMROD locator (unimplemented)"},
|
||||
{T_SRV, "SRV", "server selection"},
|
||||
{T_ATMA, "ATMA", "ATM address (unimplemented)"},
|
||||
{T_IXFR, "IXFR", "incremental zone transfer"},
|
||||
{T_AXFR, "AXFR", "zone transfer"},
|
||||
{T_MAILB, "MAILB", "mailbox-related data (deprecated)"},
|
||||
{T_MAILA, "MAILA", "mail agent (deprecated)"},
|
||||
{T_NAPTR, "NAPTR", "URN Naming Authority"},
|
||||
{T_ANY, "ANY", "\"any\""},
|
||||
{0, NULL, NULL}
|
||||
};
|
||||
|
||||
int
|
||||
sym_ston(const struct res_sym *syms, const char *name, int *success) {
|
||||
for ((void)NULL; syms->name != 0; syms++) {
|
||||
if (strcasecmp (name, syms->name) == 0) {
|
||||
if (success)
|
||||
*success = 1;
|
||||
return (syms->number);
|
||||
}
|
||||
}
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (syms->number); /* The default value. */
|
||||
}
|
||||
|
||||
const char *
|
||||
sym_ntos(const struct res_sym *syms, int number, int *success) {
|
||||
static char unname[20];
|
||||
|
||||
for ((void)NULL; syms->name != 0; syms++) {
|
||||
if (number == syms->number) {
|
||||
if (success)
|
||||
*success = 1;
|
||||
return (syms->name);
|
||||
}
|
||||
}
|
||||
|
||||
sprintf(unname, "%d", number);
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
}
|
||||
|
||||
const char *
|
||||
sym_ntop(const struct res_sym *syms, int number, int *success) {
|
||||
static char unname[20];
|
||||
|
||||
for ((void)NULL; syms->name != 0; syms++) {
|
||||
if (number == syms->number) {
|
||||
if (success)
|
||||
*success = 1;
|
||||
return (syms->humanname);
|
||||
}
|
||||
}
|
||||
sprintf(unname, "%d", number);
|
||||
if (success)
|
||||
*success = 0;
|
||||
return (unname);
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string for the type.
|
||||
*/
|
||||
const char *
|
||||
p_type(int type) {
|
||||
return (sym_ntos(__p_type_syms, type, (int *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a string for the type.
|
||||
*/
|
||||
const char *
|
||||
p_section(int section, int opcode) {
|
||||
const struct res_sym *symbols;
|
||||
|
||||
switch (opcode) {
|
||||
case ns_o_update:
|
||||
symbols = __p_update_section_syms;
|
||||
break;
|
||||
default:
|
||||
symbols = __p_default_section_syms;
|
||||
break;
|
||||
}
|
||||
return (sym_ntos(symbols, section, (int *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a mnemonic for class.
|
||||
*/
|
||||
const char *
|
||||
p_class(int class) {
|
||||
return (sym_ntos(__p_class_syms, class, (int *)0));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a mnemonic for an option
|
||||
*/
|
||||
const char *
|
||||
p_option(u_long option) {
|
||||
static char nbuf[40];
|
||||
|
||||
switch (option) {
|
||||
case RES_INIT: return "init";
|
||||
case RES_DEBUG: return "debug";
|
||||
case RES_AAONLY: return "aaonly(unimpl)";
|
||||
case RES_USEVC: return "usevc";
|
||||
case RES_PRIMARY: return "primry(unimpl)";
|
||||
case RES_IGNTC: return "igntc";
|
||||
case RES_RECURSE: return "recurs";
|
||||
case RES_DEFNAMES: return "defnam";
|
||||
case RES_STAYOPEN: return "styopn";
|
||||
case RES_DNSRCH: return "dnsrch";
|
||||
case RES_INSECURE1: return "insecure1";
|
||||
case RES_INSECURE2: return "insecure2";
|
||||
default: sprintf(nbuf, "?0x%lx?", (u_long)option);
|
||||
return (nbuf);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Return a mnemonic for a time to live.
|
||||
*/
|
||||
const char *
|
||||
p_time(u_int32_t value) {
|
||||
static char nbuf[40];
|
||||
|
||||
if (ns_format_ttl(value, nbuf, sizeof nbuf) < 0)
|
||||
sprintf(nbuf, "%u", value);
|
||||
return (nbuf);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* routines to convert between on-the-wire RR format and zone file format.
|
||||
* Does not contain conversion to/from decimal degrees; divide or multiply
|
||||
* by 60*60*1000 for that.
|
||||
*/
|
||||
|
||||
static unsigned int poweroften[10] = {1, 10, 100, 1000, 10000, 100000,
|
||||
1000000,10000000,100000000,1000000000};
|
||||
|
||||
/* takes an XeY precision/size value, returns a string representation. */
|
||||
static const char *
|
||||
precsize_ntoa(prec)
|
||||
u_int8_t prec;
|
||||
{
|
||||
static char retbuf[sizeof "90000000.00"];
|
||||
unsigned long val;
|
||||
int mantissa, exponent;
|
||||
|
||||
mantissa = (int)((prec >> 4) & 0x0f) % 10;
|
||||
exponent = (int)((prec >> 0) & 0x0f) % 10;
|
||||
|
||||
val = mantissa * poweroften[exponent];
|
||||
|
||||
(void) sprintf(retbuf, "%ld.%.2ld", val/100, val%100);
|
||||
return (retbuf);
|
||||
}
|
||||
|
||||
/* converts ascii size/precision X * 10**Y(cm) to 0xXY. moves pointer. */
|
||||
static u_int8_t
|
||||
precsize_aton(strptr)
|
||||
char **strptr;
|
||||
{
|
||||
unsigned int mval = 0, cmval = 0;
|
||||
u_int8_t retval = 0;
|
||||
char *cp;
|
||||
int exponent;
|
||||
int mantissa;
|
||||
|
||||
cp = *strptr;
|
||||
|
||||
while (isdigit(*cp))
|
||||
mval = mval * 10 + (*cp++ - '0');
|
||||
|
||||
if (*cp == '.') { /* centimeters */
|
||||
cp++;
|
||||
if (isdigit(*cp)) {
|
||||
cmval = (*cp++ - '0') * 10;
|
||||
if (isdigit(*cp)) {
|
||||
cmval += (*cp++ - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
cmval = (mval * 100) + cmval;
|
||||
|
||||
for (exponent = 0; exponent < 9; exponent++)
|
||||
if (cmval < poweroften[exponent+1])
|
||||
break;
|
||||
|
||||
mantissa = cmval / poweroften[exponent];
|
||||
if (mantissa > 9)
|
||||
mantissa = 9;
|
||||
|
||||
retval = (mantissa << 4) | exponent;
|
||||
|
||||
*strptr = cp;
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* converts ascii lat/lon to unsigned encoded 32-bit number. moves pointer. */
|
||||
static u_int32_t
|
||||
latlon2ul(latlonstrptr,which)
|
||||
char **latlonstrptr;
|
||||
int *which;
|
||||
{
|
||||
char *cp;
|
||||
u_int32_t retval;
|
||||
int deg = 0, min = 0, secs = 0, secsfrac = 0;
|
||||
|
||||
cp = *latlonstrptr;
|
||||
|
||||
while (isdigit(*cp))
|
||||
deg = deg * 10 + (*cp++ - '0');
|
||||
|
||||
while (isspace(*cp))
|
||||
cp++;
|
||||
|
||||
if (!(isdigit(*cp)))
|
||||
goto fndhemi;
|
||||
|
||||
while (isdigit(*cp))
|
||||
min = min * 10 + (*cp++ - '0');
|
||||
|
||||
while (isspace(*cp))
|
||||
cp++;
|
||||
|
||||
if (!(isdigit(*cp)))
|
||||
goto fndhemi;
|
||||
|
||||
while (isdigit(*cp))
|
||||
secs = secs * 10 + (*cp++ - '0');
|
||||
|
||||
if (*cp == '.') { /* decimal seconds */
|
||||
cp++;
|
||||
if (isdigit(*cp)) {
|
||||
secsfrac = (*cp++ - '0') * 100;
|
||||
if (isdigit(*cp)) {
|
||||
secsfrac += (*cp++ - '0') * 10;
|
||||
if (isdigit(*cp)) {
|
||||
secsfrac += (*cp++ - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
while (!isspace(*cp)) /* if any trailing garbage */
|
||||
cp++;
|
||||
|
||||
while (isspace(*cp))
|
||||
cp++;
|
||||
|
||||
fndhemi:
|
||||
switch (*cp) {
|
||||
case 'N': case 'n':
|
||||
case 'E': case 'e':
|
||||
retval = ((unsigned)1<<31)
|
||||
+ (((((deg * 60) + min) * 60) + secs) * 1000)
|
||||
+ secsfrac;
|
||||
break;
|
||||
case 'S': case 's':
|
||||
case 'W': case 'w':
|
||||
retval = ((unsigned)1<<31)
|
||||
- (((((deg * 60) + min) * 60) + secs) * 1000)
|
||||
- secsfrac;
|
||||
break;
|
||||
default:
|
||||
retval = 0; /* invalid value -- indicates error */
|
||||
break;
|
||||
}
|
||||
|
||||
switch (*cp) {
|
||||
case 'N': case 'n':
|
||||
case 'S': case 's':
|
||||
*which = 1; /* latitude */
|
||||
break;
|
||||
case 'E': case 'e':
|
||||
case 'W': case 'w':
|
||||
*which = 2; /* longitude */
|
||||
break;
|
||||
default:
|
||||
*which = 0; /* error */
|
||||
break;
|
||||
}
|
||||
|
||||
cp++; /* skip the hemisphere */
|
||||
|
||||
while (!isspace(*cp)) /* if any trailing garbage */
|
||||
cp++;
|
||||
|
||||
while (isspace(*cp)) /* move to next field */
|
||||
cp++;
|
||||
|
||||
*latlonstrptr = cp;
|
||||
|
||||
return (retval);
|
||||
}
|
||||
|
||||
/* converts a zone file representation in a string to an RDATA on-the-wire
|
||||
* representation. */
|
||||
int
|
||||
loc_aton(ascii, binary)
|
||||
const char *ascii;
|
||||
u_char *binary;
|
||||
{
|
||||
const char *cp, *maxcp;
|
||||
u_char *bcp;
|
||||
|
||||
u_int32_t latit = 0, longit = 0, alt = 0;
|
||||
u_int32_t lltemp1 = 0, lltemp2 = 0;
|
||||
int altmeters = 0, altfrac = 0, altsign = 1;
|
||||
u_int8_t hp = 0x16; /* default = 1e6 cm = 10000.00m = 10km */
|
||||
u_int8_t vp = 0x13; /* default = 1e3 cm = 10.00m */
|
||||
u_int8_t siz = 0x12; /* default = 1e2 cm = 1.00m */
|
||||
int which1 = 0, which2 = 0;
|
||||
|
||||
cp = ascii;
|
||||
maxcp = cp + strlen(ascii);
|
||||
|
||||
lltemp1 = latlon2ul(&cp, &which1);
|
||||
|
||||
lltemp2 = latlon2ul(&cp, &which2);
|
||||
|
||||
switch (which1 + which2) {
|
||||
case 3: /* 1 + 2, the only valid combination */
|
||||
if ((which1 == 1) && (which2 == 2)) { /* normal case */
|
||||
latit = lltemp1;
|
||||
longit = lltemp2;
|
||||
} else if ((which1 == 2) && (which2 == 1)) { /* reversed */
|
||||
longit = lltemp1;
|
||||
latit = lltemp2;
|
||||
} else { /* some kind of brokenness */
|
||||
return (0);
|
||||
}
|
||||
break;
|
||||
default: /* we didn't get one of each */
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* altitude */
|
||||
if (*cp == '-') {
|
||||
altsign = -1;
|
||||
cp++;
|
||||
}
|
||||
|
||||
if (*cp == '+')
|
||||
cp++;
|
||||
|
||||
while (isdigit(*cp))
|
||||
altmeters = altmeters * 10 + (*cp++ - '0');
|
||||
|
||||
if (*cp == '.') { /* decimal meters */
|
||||
cp++;
|
||||
if (isdigit(*cp)) {
|
||||
altfrac = (*cp++ - '0') * 10;
|
||||
if (isdigit(*cp)) {
|
||||
altfrac += (*cp++ - '0');
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
alt = (10000000 + (altsign * (altmeters * 100 + altfrac)));
|
||||
|
||||
while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
|
||||
cp++;
|
||||
|
||||
while (isspace(*cp) && (cp < maxcp))
|
||||
cp++;
|
||||
|
||||
if (cp >= maxcp)
|
||||
goto defaults;
|
||||
|
||||
siz = precsize_aton(&cp);
|
||||
|
||||
while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
|
||||
cp++;
|
||||
|
||||
while (isspace(*cp) && (cp < maxcp))
|
||||
cp++;
|
||||
|
||||
if (cp >= maxcp)
|
||||
goto defaults;
|
||||
|
||||
hp = precsize_aton(&cp);
|
||||
|
||||
while (!isspace(*cp) && (cp < maxcp)) /* if trailing garbage or m */
|
||||
cp++;
|
||||
|
||||
while (isspace(*cp) && (cp < maxcp))
|
||||
cp++;
|
||||
|
||||
if (cp >= maxcp)
|
||||
goto defaults;
|
||||
|
||||
vp = precsize_aton(&cp);
|
||||
|
||||
defaults:
|
||||
|
||||
bcp = binary;
|
||||
*bcp++ = (u_int8_t) 0; /* version byte */
|
||||
*bcp++ = siz;
|
||||
*bcp++ = hp;
|
||||
*bcp++ = vp;
|
||||
PUTLONG(latit,bcp);
|
||||
PUTLONG(longit,bcp);
|
||||
PUTLONG(alt,bcp);
|
||||
|
||||
return (16); /* size of RR in octets */
|
||||
}
|
||||
|
||||
/* takes an on-the-wire LOC RR and formats it in a human readable format. */
|
||||
const char *
|
||||
loc_ntoa(binary, ascii)
|
||||
const u_char *binary;
|
||||
char *ascii;
|
||||
{
|
||||
static char *error = "?";
|
||||
const u_char *cp = binary;
|
||||
|
||||
int latdeg, latmin, latsec, latsecfrac;
|
||||
int longdeg, longmin, longsec, longsecfrac;
|
||||
char northsouth, eastwest;
|
||||
int altmeters, altfrac, altsign;
|
||||
|
||||
const u_int32_t referencealt = 100000 * 100;
|
||||
|
||||
int32_t latval, longval, altval;
|
||||
u_int32_t templ;
|
||||
u_int8_t sizeval, hpval, vpval, versionval;
|
||||
|
||||
char *sizestr, *hpstr, *vpstr;
|
||||
|
||||
versionval = *cp++;
|
||||
|
||||
if (versionval) {
|
||||
(void) sprintf(ascii, "; error: unknown LOC RR version");
|
||||
return (ascii);
|
||||
}
|
||||
|
||||
sizeval = *cp++;
|
||||
|
||||
hpval = *cp++;
|
||||
vpval = *cp++;
|
||||
|
||||
GETLONG(templ, cp);
|
||||
latval = (templ - ((unsigned)1<<31));
|
||||
|
||||
GETLONG(templ, cp);
|
||||
longval = (templ - ((unsigned)1<<31));
|
||||
|
||||
GETLONG(templ, cp);
|
||||
if (templ < referencealt) { /* below WGS 84 spheroid */
|
||||
altval = referencealt - templ;
|
||||
altsign = -1;
|
||||
} else {
|
||||
altval = templ - referencealt;
|
||||
altsign = 1;
|
||||
}
|
||||
|
||||
if (latval < 0) {
|
||||
northsouth = 'S';
|
||||
latval = -latval;
|
||||
} else
|
||||
northsouth = 'N';
|
||||
|
||||
latsecfrac = latval % 1000;
|
||||
latval = latval / 1000;
|
||||
latsec = latval % 60;
|
||||
latval = latval / 60;
|
||||
latmin = latval % 60;
|
||||
latval = latval / 60;
|
||||
latdeg = latval;
|
||||
|
||||
if (longval < 0) {
|
||||
eastwest = 'W';
|
||||
longval = -longval;
|
||||
} else
|
||||
eastwest = 'E';
|
||||
|
||||
longsecfrac = longval % 1000;
|
||||
longval = longval / 1000;
|
||||
longsec = longval % 60;
|
||||
longval = longval / 60;
|
||||
longmin = longval % 60;
|
||||
longval = longval / 60;
|
||||
longdeg = longval;
|
||||
|
||||
altfrac = altval % 100;
|
||||
altmeters = (altval / 100) * altsign;
|
||||
|
||||
if ((sizestr = strdup(precsize_ntoa(sizeval))) == NULL)
|
||||
sizestr = error;
|
||||
if ((hpstr = strdup(precsize_ntoa(hpval))) == NULL)
|
||||
hpstr = error;
|
||||
if ((vpstr = strdup(precsize_ntoa(vpval))) == NULL)
|
||||
vpstr = error;
|
||||
|
||||
sprintf(ascii,
|
||||
"%d %.2d %.2d.%.3d %c %d %.2d %.2d.%.3d %c %d.%.2dm %sm %sm %sm",
|
||||
latdeg, latmin, latsec, latsecfrac, northsouth,
|
||||
longdeg, longmin, longsec, longsecfrac, eastwest,
|
||||
altmeters, altfrac, sizestr, hpstr, vpstr);
|
||||
|
||||
if (sizestr != error)
|
||||
free(sizestr);
|
||||
if (hpstr != error)
|
||||
free(hpstr);
|
||||
if (vpstr != error)
|
||||
free(vpstr);
|
||||
|
||||
return (ascii);
|
||||
}
|
||||
|
||||
|
||||
/* Return the number of DNS hierarchy levels in the name. */
|
||||
int
|
||||
dn_count_labels(const char *name) {
|
||||
int i, len, count;
|
||||
|
||||
len = strlen(name);
|
||||
for (i = 0, count = 0; i < len; i++) {
|
||||
/* XXX need to check for \. or use named's nlabels(). */
|
||||
if (name[i] == '.')
|
||||
count++;
|
||||
}
|
||||
|
||||
/* don't count initial wildcard */
|
||||
if (name[0] == '*')
|
||||
if (count)
|
||||
count--;
|
||||
|
||||
/* don't count the null label for root. */
|
||||
/* if terminating '.' not found, must adjust */
|
||||
/* count to include last label */
|
||||
if (len > 0 && name[len-1] != '.')
|
||||
count++;
|
||||
return (count);
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
* Make dates expressed in seconds-since-Jan-1-1970 easy to read.
|
||||
* SIG records are required to be printed like this, by the Secure DNS RFC.
|
||||
*/
|
||||
char *
|
||||
p_secstodate (u_long secs) {
|
||||
static char output[15]; /* YYYYMMDDHHMMSS and null */
|
||||
time_t clock = secs;
|
||||
struct tm *time;
|
||||
|
||||
time = gmtime(&clock);
|
||||
time->tm_year += 1900;
|
||||
time->tm_mon += 1;
|
||||
sprintf(output, "%04d%02d%02d%02d%02d%02d",
|
||||
time->tm_year, time->tm_mon, time->tm_mday,
|
||||
time->tm_hour, time->tm_min, time->tm_sec);
|
||||
return (output);
|
||||
}
|
||||
497
c/src/exec/libnetworking/libc/res_init.c
Normal file
497
c/src/exec/libnetworking/libc/res_init.c
Normal file
@@ -0,0 +1,497 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_init.c 8.1 (Berkeley) 6/7/93";
|
||||
static char orig_rcsid[] = "From: Id: res_init.c,v 8.7 1996/11/18 09:10:04 vixie Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
static void res_setoptions __P((char *, char *));
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
static const char sort_mask[] = "/&";
|
||||
#define ISSORTMASK(ch) (strchr(sort_mask, ch) != NULL)
|
||||
static u_int32_t net_mask __P((struct in_addr));
|
||||
#endif
|
||||
|
||||
#if !defined(isascii) /* XXX - could be a function */
|
||||
# define isascii(c) (!(c & 0200))
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Resolver state default settings.
|
||||
*/
|
||||
|
||||
struct __res_state _res
|
||||
# if defined(__BIND_RES_TEXT)
|
||||
= { RES_TIMEOUT, } /* Motorola, et al. */
|
||||
# endif
|
||||
;
|
||||
|
||||
|
||||
/*
|
||||
* Set up default settings. If the configuration file exist, the values
|
||||
* there will have precedence. Otherwise, the server address is set to
|
||||
* INADDR_ANY and the default domain name comes from the gethostname().
|
||||
*
|
||||
* An interrim version of this code (BIND 4.9, pre-4.4BSD) used 127.0.0.1
|
||||
* rather than INADDR_ANY ("0.0.0.0") as the default name server address
|
||||
* since it was noted that INADDR_ANY actually meant ``the first interface
|
||||
* you "ifconfig"'d at boot time'' and if this was a SLIP or PPP interface,
|
||||
* it had to be "up" in order for you to reach your own name server. It
|
||||
* was later decided that since the recommended practice is to always
|
||||
* install local static routes through 127.0.0.1 for all your network
|
||||
* interfaces, that we could solve this problem without a code change.
|
||||
*
|
||||
* The configuration file should always be used, since it is the only way
|
||||
* to specify a default domain. If you are running a server on your local
|
||||
* machine, you should say "nameserver 0.0.0.0" or "nameserver 127.0.0.1"
|
||||
* in the configuration file.
|
||||
*
|
||||
* Return 0 if completes successfully, -1 on error
|
||||
*/
|
||||
int
|
||||
res_init()
|
||||
{
|
||||
register FILE *fp;
|
||||
register char *cp, **pp;
|
||||
register int n;
|
||||
char buf[MAXDNAME];
|
||||
int nserv = 0; /* number of nameserver records read from file */
|
||||
int haveenv = 0;
|
||||
int havesearch = 0;
|
||||
#ifdef RESOLVSORT
|
||||
int nsort = 0;
|
||||
char *net;
|
||||
#endif
|
||||
#ifndef RFC1535
|
||||
int dots;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* These three fields used to be statically initialized. This made
|
||||
* it hard to use this code in a shared library. It is necessary,
|
||||
* now that we're doing dynamic initialization here, that we preserve
|
||||
* the old semantics: if an application modifies one of these three
|
||||
* fields of _res before res_init() is called, res_init() will not
|
||||
* alter them. Of course, if an application is setting them to
|
||||
* _zero_ before calling res_init(), hoping to override what used
|
||||
* to be the static default, we can't detect it and unexpected results
|
||||
* will follow. Zero for any of these fields would make no sense,
|
||||
* so one can safely assume that the applications were already getting
|
||||
* unexpected results.
|
||||
*
|
||||
* _res.options is tricky since some apps were known to diddle the bits
|
||||
* before res_init() was first called. We can't replicate that semantic
|
||||
* with dynamic initialization (they may have turned bits off that are
|
||||
* set in RES_DEFAULT). Our solution is to declare such applications
|
||||
* "broken". They could fool us by setting RES_INIT but none do (yet).
|
||||
*/
|
||||
if (!_res.retrans)
|
||||
_res.retrans = RES_TIMEOUT;
|
||||
if (!_res.retry)
|
||||
_res.retry = 4;
|
||||
if (!(_res.options & RES_INIT))
|
||||
_res.options = RES_DEFAULT;
|
||||
|
||||
/*
|
||||
* This one used to initialize implicitly to zero, so unless the app
|
||||
* has set it to something in particular, we can randomize it now.
|
||||
*/
|
||||
if (!_res.id)
|
||||
_res.id = res_randomid();
|
||||
|
||||
#ifdef USELOOPBACK
|
||||
_res.nsaddr.sin_addr = inet_makeaddr(IN_LOOPBACKNET, 1);
|
||||
#else
|
||||
_res.nsaddr.sin_addr.s_addr = INADDR_ANY;
|
||||
#endif
|
||||
_res.nsaddr.sin_family = AF_INET;
|
||||
_res.nsaddr.sin_port = htons(NAMESERVER_PORT);
|
||||
_res.nscount = 1;
|
||||
_res.ndots = 1;
|
||||
_res.pfcode = 0;
|
||||
|
||||
/*
|
||||
* RTEMS -- Set up name servers
|
||||
*/
|
||||
{
|
||||
#include <rtems/rtems_bsdnet_internal.h>
|
||||
int n = 0;
|
||||
while ((n < rtems_bsdnet_nameserver_count) && (nserv < MAXNS)) {
|
||||
_res.nsaddr_list[nserv].sin_addr = rtems_bsdnet_nameserver[n];
|
||||
_res.nsaddr_list[nserv].sin_family = AF_INET;
|
||||
_res.nsaddr_list[nserv].sin_port = htons(NAMESERVER_PORT);
|
||||
nserv++;
|
||||
n++;
|
||||
}
|
||||
if (rtems_bsdnet_domain_name)
|
||||
(void)strncpy(_res.defdname, rtems_bsdnet_domain_name, sizeof(_res.defdname) - 1);
|
||||
}
|
||||
|
||||
/* Allow user to override the local domain definition */
|
||||
if ((cp = getenv("LOCALDOMAIN")) != NULL) {
|
||||
(void)strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
haveenv++;
|
||||
|
||||
/*
|
||||
* Set search list to be blank-separated strings
|
||||
* from rest of env value. Permits users of LOCALDOMAIN
|
||||
* to still have a search list, and anyone to set the
|
||||
* one that they want to use as an individual (even more
|
||||
* important now that the rfc1535 stuff restricts searches)
|
||||
*/
|
||||
cp = _res.defdname;
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = cp;
|
||||
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
||||
if (*cp == '\n') /* silly backwards compat */
|
||||
break;
|
||||
else if (*cp == ' ' || *cp == '\t') {
|
||||
*cp = 0;
|
||||
n = 1;
|
||||
} else if (n) {
|
||||
*pp++ = cp;
|
||||
n = 0;
|
||||
havesearch = 1;
|
||||
}
|
||||
}
|
||||
/* null terminate last domain if there are excess */
|
||||
while (*cp != '\0' && *cp != ' ' && *cp != '\t' && *cp != '\n')
|
||||
cp++;
|
||||
*cp = '\0';
|
||||
*pp++ = 0;
|
||||
}
|
||||
|
||||
#define MATCH(line, name) \
|
||||
(!strncmp(line, name, sizeof(name) - 1) && \
|
||||
(line[sizeof(name) - 1] == ' ' || \
|
||||
line[sizeof(name) - 1] == '\t'))
|
||||
|
||||
if ((fp = fopen(_PATH_RESCONF, "r")) != NULL) {
|
||||
/* read the config file */
|
||||
while (fgets(buf, sizeof(buf), fp) != NULL) {
|
||||
/* skip comments */
|
||||
if (*buf == ';' || *buf == '#')
|
||||
continue;
|
||||
/* read default domain name */
|
||||
if (MATCH(buf, "domain")) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("domain") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
if ((cp = strpbrk(_res.defdname, " \t\n")) != NULL)
|
||||
*cp = '\0';
|
||||
havesearch = 0;
|
||||
continue;
|
||||
}
|
||||
/* set search list */
|
||||
if (MATCH(buf, "search")) {
|
||||
if (haveenv) /* skip if have from environ */
|
||||
continue;
|
||||
cp = buf + sizeof("search") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp == '\0') || (*cp == '\n'))
|
||||
continue;
|
||||
strncpy(_res.defdname, cp, sizeof(_res.defdname) - 1);
|
||||
if ((cp = strchr(_res.defdname, '\n')) != NULL)
|
||||
*cp = '\0';
|
||||
/*
|
||||
* Set search list to be blank-separated strings
|
||||
* on rest of line.
|
||||
*/
|
||||
cp = _res.defdname;
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = cp;
|
||||
for (n = 0; *cp && pp < _res.dnsrch + MAXDNSRCH; cp++) {
|
||||
if (*cp == ' ' || *cp == '\t') {
|
||||
*cp = 0;
|
||||
n = 1;
|
||||
} else if (n) {
|
||||
*pp++ = cp;
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
/* null terminate last domain if there are excess */
|
||||
while (*cp != '\0' && *cp != ' ' && *cp != '\t')
|
||||
cp++;
|
||||
*cp = '\0';
|
||||
*pp++ = 0;
|
||||
havesearch = 1;
|
||||
continue;
|
||||
}
|
||||
/* read nameservers to query */
|
||||
if (MATCH(buf, "nameserver") && nserv < MAXNS) {
|
||||
struct in_addr a;
|
||||
|
||||
cp = buf + sizeof("nameserver") - 1;
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if ((*cp != '\0') && (*cp != '\n') && inet_aton(cp, &a)) {
|
||||
_res.nsaddr_list[nserv].sin_addr = a;
|
||||
_res.nsaddr_list[nserv].sin_family = AF_INET;
|
||||
_res.nsaddr_list[nserv].sin_port =
|
||||
htons(NAMESERVER_PORT);
|
||||
nserv++;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#ifdef RESOLVSORT
|
||||
if (MATCH(buf, "sortlist")) {
|
||||
struct in_addr a;
|
||||
|
||||
cp = buf + sizeof("sortlist") - 1;
|
||||
while (nsort < MAXRESOLVSORT) {
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
if (*cp == '\0' || *cp == '\n' || *cp == ';')
|
||||
break;
|
||||
net = cp;
|
||||
while (*cp && !ISSORTMASK(*cp) && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
if (inet_aton(net, &a)) {
|
||||
_res.sort_list[nsort].addr = a;
|
||||
if (ISSORTMASK(n)) {
|
||||
*cp++ = n;
|
||||
net = cp;
|
||||
while (*cp && *cp != ';' &&
|
||||
isascii(*cp) && !isspace(*cp))
|
||||
cp++;
|
||||
n = *cp;
|
||||
*cp = 0;
|
||||
if (inet_aton(net, &a)) {
|
||||
_res.sort_list[nsort].mask = a.s_addr;
|
||||
} else {
|
||||
_res.sort_list[nsort].mask =
|
||||
net_mask(_res.sort_list[nsort].addr);
|
||||
}
|
||||
} else {
|
||||
_res.sort_list[nsort].mask =
|
||||
net_mask(_res.sort_list[nsort].addr);
|
||||
}
|
||||
nsort++;
|
||||
}
|
||||
*cp = n;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
if (MATCH(buf, "options")) {
|
||||
res_setoptions(buf + sizeof("options") - 1, "conf");
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (nserv > 1)
|
||||
_res.nscount = nserv;
|
||||
#ifdef RESOLVSORT
|
||||
_res.nsort = nsort;
|
||||
#endif
|
||||
(void) fclose(fp);
|
||||
}
|
||||
if (_res.defdname[0] == 0 &&
|
||||
gethostname(buf, sizeof(_res.defdname) - 1) == 0 &&
|
||||
(cp = strchr(buf, '.')) != NULL)
|
||||
strcpy(_res.defdname, cp + 1);
|
||||
|
||||
/* find components of local domain that might be searched */
|
||||
if (havesearch == 0) {
|
||||
pp = _res.dnsrch;
|
||||
*pp++ = _res.defdname;
|
||||
*pp = NULL;
|
||||
|
||||
#ifndef RFC1535
|
||||
dots = 0;
|
||||
for (cp = _res.defdname; *cp; cp++)
|
||||
dots += (*cp == '.');
|
||||
|
||||
cp = _res.defdname;
|
||||
while (pp < _res.dnsrch + MAXDFLSRCH) {
|
||||
if (dots < LOCALDOMAINPARTS)
|
||||
break;
|
||||
cp = strchr(cp, '.') + 1; /* we know there is one */
|
||||
*pp++ = cp;
|
||||
dots--;
|
||||
}
|
||||
*pp = NULL;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG) {
|
||||
printf(";; res_init()... default dnsrch list:\n");
|
||||
for (pp = _res.dnsrch; *pp; pp++)
|
||||
printf(";;\t%s\n", *pp);
|
||||
printf(";;\t..END..\n");
|
||||
}
|
||||
#endif
|
||||
#endif /* !RFC1535 */
|
||||
}
|
||||
|
||||
if ((cp = getenv("RES_OPTIONS")) != NULL)
|
||||
res_setoptions(cp, "env");
|
||||
_res.options |= RES_INIT;
|
||||
return (0);
|
||||
}
|
||||
|
||||
static void
|
||||
res_setoptions(options, source)
|
||||
char *options, *source;
|
||||
{
|
||||
char *cp = options;
|
||||
int i;
|
||||
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_setoptions(\"%s\", \"%s\")...\n",
|
||||
options, source);
|
||||
#endif
|
||||
while (*cp) {
|
||||
/* skip leading and inner runs of spaces */
|
||||
while (*cp == ' ' || *cp == '\t')
|
||||
cp++;
|
||||
/* search for and process individual options */
|
||||
if (!strncmp(cp, "ndots:", sizeof("ndots:") - 1)) {
|
||||
i = atoi(cp + sizeof("ndots:") - 1);
|
||||
if (i <= RES_MAXNDOTS)
|
||||
_res.ndots = i;
|
||||
else
|
||||
_res.ndots = RES_MAXNDOTS;
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";;\tndots=%d\n", _res.ndots);
|
||||
#endif
|
||||
} else if (!strncmp(cp, "debug", sizeof("debug") - 1)) {
|
||||
#ifdef DEBUG
|
||||
if (!(_res.options & RES_DEBUG)) {
|
||||
printf(";; res_setoptions(\"%s\", \"%s\")..\n",
|
||||
options, source);
|
||||
_res.options |= RES_DEBUG;
|
||||
}
|
||||
printf(";;\tdebug\n");
|
||||
#endif
|
||||
} else if (!strncmp(cp, "inet6", sizeof("inet6") - 1)) {
|
||||
_res.options |= RES_USE_INET6;
|
||||
} else if (!strncmp(cp, "no_tld_query", sizeof("no_tld_query") - 1)) {
|
||||
_res.options |= RES_NOTLDQUERY;
|
||||
} else {
|
||||
/* XXX - print a warning here? */
|
||||
}
|
||||
/* skip to next run of spaces */
|
||||
while (*cp && *cp != ' ' && *cp != '\t')
|
||||
cp++;
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef RESOLVSORT
|
||||
/* XXX - should really support CIDR which means explicit masks always. */
|
||||
static u_int32_t
|
||||
net_mask(in) /* XXX - should really use system's version of this */
|
||||
struct in_addr in;
|
||||
{
|
||||
register u_int32_t i = ntohl(in.s_addr);
|
||||
|
||||
if (IN_CLASSA(i))
|
||||
return (htonl(IN_CLASSA_NET));
|
||||
else if (IN_CLASSB(i))
|
||||
return (htonl(IN_CLASSB_NET));
|
||||
return (htonl(IN_CLASSC_NET));
|
||||
}
|
||||
#endif
|
||||
|
||||
u_int
|
||||
res_randomid()
|
||||
{
|
||||
struct timeval now;
|
||||
|
||||
gettimeofday(&now, NULL);
|
||||
return (0xffff & (now.tv_sec ^ now.tv_usec ^ getpid()));
|
||||
}
|
||||
199
c/src/exec/libnetworking/libc/res_mkquery.c
Normal file
199
c/src/exec/libnetworking/libc/res_mkquery.c
Normal file
@@ -0,0 +1,199 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_mkquery.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_mkquery.c,v 8.9 1997/04/24 22:22:36 vixie Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
/*
|
||||
* Form all types of queries.
|
||||
* Returns the size of the result or -1.
|
||||
*/
|
||||
int
|
||||
res_mkquery(op, dname, class, type, data, datalen, newrr_in, buf, buflen)
|
||||
int op; /* opcode of query */
|
||||
const char *dname; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
const u_char *data; /* resource record data */
|
||||
int datalen; /* length of data */
|
||||
const u_char *newrr_in; /* new rr for modify or append */
|
||||
u_char *buf; /* buffer to put query */
|
||||
int buflen; /* size of buffer */
|
||||
{
|
||||
register HEADER *hp;
|
||||
register u_char *cp;
|
||||
register int n;
|
||||
u_char *dnptrs[20], **dpp, **lastdnptr;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_mkquery(%d, %s, %d, %d)\n",
|
||||
op, dname, class, type);
|
||||
#endif
|
||||
/*
|
||||
* Initialize header fields.
|
||||
*/
|
||||
if ((buf == NULL) || (buflen < HFIXEDSZ))
|
||||
return (-1);
|
||||
memset(buf, 0, HFIXEDSZ);
|
||||
hp = (HEADER *) buf;
|
||||
hp->id = htons(++_res.id);
|
||||
hp->opcode = op;
|
||||
hp->rd = (_res.options & RES_RECURSE) != 0;
|
||||
hp->rcode = NOERROR;
|
||||
cp = buf + HFIXEDSZ;
|
||||
buflen -= HFIXEDSZ;
|
||||
dpp = dnptrs;
|
||||
*dpp++ = buf;
|
||||
*dpp++ = NULL;
|
||||
lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
|
||||
/*
|
||||
* perform opcode specific processing
|
||||
*/
|
||||
switch (op) {
|
||||
case QUERY: /*FALLTHROUGH*/
|
||||
case NS_NOTIFY_OP:
|
||||
if ((buflen -= QFIXEDSZ) < 0)
|
||||
return (-1);
|
||||
if ((n = dn_comp(dname, cp, buflen, dnptrs, lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
__putshort(type, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
hp->qdcount = htons(1);
|
||||
if (op == QUERY || data == NULL)
|
||||
break;
|
||||
/*
|
||||
* Make an additional record for completion domain.
|
||||
*/
|
||||
buflen -= RRFIXEDSZ;
|
||||
n = dn_comp((char *)data, cp, buflen, dnptrs, lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
buflen -= n;
|
||||
__putshort(T_NULL, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
__putlong(0, cp);
|
||||
cp += INT32SZ;
|
||||
__putshort(0, cp);
|
||||
cp += INT16SZ;
|
||||
hp->arcount = htons(1);
|
||||
break;
|
||||
|
||||
case IQUERY:
|
||||
/*
|
||||
* Initialize answer section
|
||||
*/
|
||||
if (buflen < 1 + RRFIXEDSZ + datalen)
|
||||
return (-1);
|
||||
*cp++ = '\0'; /* no domain name */
|
||||
__putshort(type, cp);
|
||||
cp += INT16SZ;
|
||||
__putshort(class, cp);
|
||||
cp += INT16SZ;
|
||||
__putlong(0, cp);
|
||||
cp += INT32SZ;
|
||||
__putshort(datalen, cp);
|
||||
cp += INT16SZ;
|
||||
if (datalen) {
|
||||
memcpy(cp, data, datalen);
|
||||
cp += datalen;
|
||||
}
|
||||
hp->ancount = htons(1);
|
||||
break;
|
||||
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
return (cp - buf);
|
||||
}
|
||||
414
c/src/exec/libnetworking/libc/res_mkupdate.c
Normal file
414
c/src/exec/libnetworking/libc/res_mkupdate.c
Normal file
@@ -0,0 +1,414 @@
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on the Dynamic DNS reference implementation by Viraj Bais
|
||||
* <viraj_bais@ccm.fm.intel.com>
|
||||
*/
|
||||
|
||||
#if !defined(lint) && !defined(SABER)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <ctype.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
static int getnum_str(u_char **, u_char *);
|
||||
static int getword_str(char *, int, u_char **, u_char *);
|
||||
|
||||
#define ShrinkBuffer(x) if ((buflen -= x) < 0) return (-2);
|
||||
|
||||
/*
|
||||
* Form update packets.
|
||||
* Returns the size of the resulting packet if no error
|
||||
* On error,
|
||||
* returns -1 if error in reading a word/number in rdata
|
||||
* portion for update packets
|
||||
* -2 if length of buffer passed is insufficient
|
||||
* -3 if zone section is not the first section in
|
||||
* the linked list, or section order has a problem
|
||||
* -4 on a number overflow
|
||||
* -5 unknown operation or no records
|
||||
*/
|
||||
int
|
||||
res_mkupdate(ns_updrec *rrecp_in, u_char *buf, int buflen) {
|
||||
ns_updrec *rrecp_start = rrecp_in;
|
||||
HEADER *hp;
|
||||
u_char c, *cp, *cp1, *sp1, *sp2, *startp, *endp;
|
||||
int n, i, j, found, soanum, multiline;
|
||||
ns_updrec *rrecp, *tmprrecp, *recptr = NULL;
|
||||
struct in_addr ina;
|
||||
char buf2[MAXDNAME];
|
||||
int section, numrrs = 0, counts[ns_s_max];
|
||||
u_int16_t rtype, rclass;
|
||||
u_int32_t n1, rttl;
|
||||
u_char *dnptrs[20], **dpp, **lastdnptr;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Initialize header fields.
|
||||
*/
|
||||
if ((buf == NULL) || (buflen < HFIXEDSZ))
|
||||
return (-1);
|
||||
memset(buf, 0, HFIXEDSZ);
|
||||
hp = (HEADER *) buf;
|
||||
hp->id = htons(++_res.id);
|
||||
hp->opcode = ns_o_update;
|
||||
hp->rcode = NOERROR;
|
||||
sp1 = buf + 2*INT16SZ; /* save pointer to zocount */
|
||||
cp = buf + HFIXEDSZ;
|
||||
buflen -= HFIXEDSZ;
|
||||
dpp = dnptrs;
|
||||
*dpp++ = buf;
|
||||
*dpp++ = NULL;
|
||||
lastdnptr = dnptrs + sizeof dnptrs / sizeof dnptrs[0];
|
||||
|
||||
if (rrecp_start == NULL)
|
||||
return (-5);
|
||||
else if (rrecp_start->r_section != S_ZONE)
|
||||
return (-3);
|
||||
|
||||
memset(counts, 0, sizeof counts);
|
||||
for (rrecp = rrecp_start; rrecp; rrecp = rrecp->r_grpnext) {
|
||||
numrrs++;
|
||||
section = rrecp->r_section;
|
||||
if (section < 0 || section >= ns_s_max)
|
||||
return (-1);
|
||||
counts[section]++;
|
||||
for (i = section + 1; i < ns_s_max; i++)
|
||||
if (counts[i])
|
||||
return (-3);
|
||||
rtype = rrecp->r_type;
|
||||
rclass = rrecp->r_class;
|
||||
rttl = rrecp->r_ttl;
|
||||
/* overload class and type */
|
||||
if (section == S_PREREQ) {
|
||||
rttl = 0;
|
||||
switch (rrecp->r_opcode) {
|
||||
case YXDOMAIN:
|
||||
rclass = C_ANY;
|
||||
rtype = T_ANY;
|
||||
rrecp->r_size = 0;
|
||||
break;
|
||||
case NXDOMAIN:
|
||||
rclass = C_NONE;
|
||||
rtype = T_ANY;
|
||||
rrecp->r_size = 0;
|
||||
break;
|
||||
case NXRRSET:
|
||||
rclass = C_NONE;
|
||||
rrecp->r_size = 0;
|
||||
break;
|
||||
case YXRRSET:
|
||||
if (rrecp->r_size == 0)
|
||||
rclass = C_ANY;
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"res_mkupdate: incorrect opcode: %d\n",
|
||||
rrecp->r_opcode);
|
||||
fflush(stderr);
|
||||
return (-1);
|
||||
}
|
||||
} else if (section == S_UPDATE) {
|
||||
switch (rrecp->r_opcode) {
|
||||
case DELETE:
|
||||
rclass = rrecp->r_size == 0 ? C_ANY : C_NONE;
|
||||
break;
|
||||
case ADD:
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr,
|
||||
"res_mkupdate: incorrect opcode: %d\n",
|
||||
rrecp->r_opcode);
|
||||
fflush(stderr);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* XXX appending default domain to owner name is omitted,
|
||||
* fqdn must be provided
|
||||
*/
|
||||
if ((n = dn_comp(rrecp->r_dname, cp, buflen, dnptrs,
|
||||
lastdnptr)) < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
ShrinkBuffer(n + 2*INT16SZ);
|
||||
PUTSHORT(rtype, cp);
|
||||
PUTSHORT(rclass, cp);
|
||||
if (section == S_ZONE) {
|
||||
if (numrrs != 1 || rrecp->r_type != T_SOA)
|
||||
return (-3);
|
||||
continue;
|
||||
}
|
||||
ShrinkBuffer(INT32SZ + INT16SZ);
|
||||
PUTLONG(rttl, cp);
|
||||
sp2 = cp; /* save pointer to length byte */
|
||||
cp += INT16SZ;
|
||||
if (rrecp->r_size == 0) {
|
||||
if (section == S_UPDATE && rclass != C_ANY)
|
||||
return (-1);
|
||||
else {
|
||||
PUTSHORT(0, sp2);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
startp = rrecp->r_data;
|
||||
endp = startp + rrecp->r_size - 1;
|
||||
/* XXX this should be done centrally. */
|
||||
switch (rrecp->r_type) {
|
||||
case T_A:
|
||||
if (!getword_str(buf2, sizeof buf2, &startp, endp))
|
||||
return (-1);
|
||||
if (!inet_aton(buf2, &ina))
|
||||
return (-1);
|
||||
n1 = ntohl(ina.s_addr);
|
||||
ShrinkBuffer(INT32SZ);
|
||||
PUTLONG(n1, cp);
|
||||
break;
|
||||
case T_CNAME:
|
||||
case T_MB:
|
||||
case T_MG:
|
||||
case T_MR:
|
||||
case T_NS:
|
||||
case T_PTR:
|
||||
if (!getword_str(buf2, sizeof buf2, &startp, endp))
|
||||
return (-1);
|
||||
n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
ShrinkBuffer(n);
|
||||
break;
|
||||
case T_MINFO:
|
||||
case T_SOA:
|
||||
case T_RP:
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!getword_str(buf2, sizeof buf2, &startp,
|
||||
endp))
|
||||
return (-1);
|
||||
n = dn_comp(buf2, cp, buflen,
|
||||
dnptrs, lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
ShrinkBuffer(n);
|
||||
}
|
||||
if (rrecp->r_type == T_SOA) {
|
||||
ShrinkBuffer(5 * INT32SZ);
|
||||
while (isspace(*startp) || !*startp)
|
||||
startp++;
|
||||
if (*startp == '(') {
|
||||
multiline = 1;
|
||||
startp++;
|
||||
} else
|
||||
multiline = 0;
|
||||
/* serial, refresh, retry, expire, minimum */
|
||||
for (i = 0; i < 5; i++) {
|
||||
soanum = getnum_str(&startp, endp);
|
||||
if (soanum < 0)
|
||||
return (-1);
|
||||
PUTLONG(soanum, cp);
|
||||
}
|
||||
if (multiline) {
|
||||
while (isspace(*startp) || !*startp)
|
||||
startp++;
|
||||
if (*startp != ')')
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case T_MX:
|
||||
case T_AFSDB:
|
||||
case T_RT:
|
||||
n = getnum_str(&startp, endp);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
PUTSHORT(n, cp);
|
||||
ShrinkBuffer(INT16SZ);
|
||||
if (!getword_str(buf2, sizeof buf2, &startp, endp))
|
||||
return (-1);
|
||||
n = dn_comp(buf2, cp, buflen, dnptrs, lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
ShrinkBuffer(n);
|
||||
break;
|
||||
case T_PX:
|
||||
n = getnum_str(&startp, endp);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
PUTSHORT(n, cp);
|
||||
ShrinkBuffer(INT16SZ);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (!getword_str(buf2, sizeof buf2, &startp,
|
||||
endp))
|
||||
return (-1);
|
||||
n = dn_comp(buf2, cp, buflen, dnptrs,
|
||||
lastdnptr);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
ShrinkBuffer(n);
|
||||
}
|
||||
break;
|
||||
case T_WKS:
|
||||
case T_HINFO:
|
||||
case T_TXT:
|
||||
case T_X25:
|
||||
case T_ISDN:
|
||||
case T_NSAP:
|
||||
case T_LOC:
|
||||
/* XXX - more fine tuning needed here */
|
||||
ShrinkBuffer(rrecp->r_size);
|
||||
memcpy(cp, rrecp->r_data, rrecp->r_size);
|
||||
cp += rrecp->r_size;
|
||||
break;
|
||||
default:
|
||||
return (-1);
|
||||
} /*switch*/
|
||||
n = (u_int16_t)((cp - sp2) - INT16SZ);
|
||||
PUTSHORT(n, sp2);
|
||||
} /*for*/
|
||||
|
||||
hp->qdcount = htons(counts[0]);
|
||||
hp->ancount = htons(counts[1]);
|
||||
hp->nscount = htons(counts[2]);
|
||||
hp->arcount = htons(counts[3]);
|
||||
return (cp - buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a whitespace delimited word from a string (not file)
|
||||
* into buf. modify the start pointer to point after the
|
||||
* word in the string.
|
||||
*/
|
||||
static int
|
||||
getword_str(char *buf, int size, u_char **startpp, u_char *endp) {
|
||||
char *cp;
|
||||
int c;
|
||||
|
||||
for (cp = buf; *startpp <= endp; ) {
|
||||
c = **startpp;
|
||||
if (isspace(c) || c == '\0') {
|
||||
if (cp != buf) /* trailing whitespace */
|
||||
break;
|
||||
else { /* leading whitespace */
|
||||
(*startpp)++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
(*startpp)++;
|
||||
if (cp >= buf+size-1)
|
||||
break;
|
||||
*cp++ = (u_char)c;
|
||||
}
|
||||
*cp = '\0';
|
||||
return (cp != buf);
|
||||
}
|
||||
|
||||
/*
|
||||
* Get a whitespace delimited number from a string (not file) into buf
|
||||
* update the start pointer to point after the number in the string.
|
||||
*/
|
||||
static int
|
||||
getnum_str(u_char **startpp, u_char *endp) {
|
||||
int c, n;
|
||||
int seendigit = 0;
|
||||
int seendecimal = 0;
|
||||
int m = 0;
|
||||
|
||||
for (n = 0; *startpp <= endp; ) {
|
||||
c = **startpp;
|
||||
if (isspace(c) || c == '\0') {
|
||||
if (seendigit) /* trailing whitespace */
|
||||
break;
|
||||
else { /* leading whitespace */
|
||||
(*startpp)++;
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if (c == ';') {
|
||||
while ((*startpp <= endp) &&
|
||||
((c = **startpp) != '\n'))
|
||||
(*startpp)++;
|
||||
if (seendigit)
|
||||
break;
|
||||
continue;
|
||||
}
|
||||
if (!isdigit(c)) {
|
||||
if (c == ')' && seendigit) {
|
||||
(*startpp)--;
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
(*startpp)++;
|
||||
n = n * 10 + (c - '0');
|
||||
seendigit = 1;
|
||||
}
|
||||
return (n + m);
|
||||
}
|
||||
|
||||
/*
|
||||
* Allocate a resource record buffer & save rr info.
|
||||
*/
|
||||
ns_updrec *
|
||||
res_mkupdrec(int section, const char *dname,
|
||||
u_int class, u_int type, u_long ttl) {
|
||||
ns_updrec *rrecp = (ns_updrec *)calloc(1, sizeof(ns_updrec));
|
||||
|
||||
if (!rrecp || !(rrecp->r_dname = strdup(dname)))
|
||||
return (NULL);
|
||||
rrecp->r_class = class;
|
||||
rrecp->r_type = type;
|
||||
rrecp->r_ttl = ttl;
|
||||
rrecp->r_section = section;
|
||||
return (rrecp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Free a resource record buffer created by res_mkupdrec.
|
||||
*/
|
||||
void
|
||||
res_freeupdrec(ns_updrec *rrecp) {
|
||||
/* Note: freeing r_dp is the caller's responsibility. */
|
||||
if (rrecp->r_dname != NULL)
|
||||
free(rrecp->r_dname);
|
||||
free(rrecp);
|
||||
}
|
||||
410
c/src/exec/libnetworking/libc/res_query.c
Normal file
410
c/src/exec/libnetworking/libc/res_query.c
Normal file
@@ -0,0 +1,410 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_query.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid = "From: Id: res_query.c,v 8.14 1997/06/09 17:47:05 halley Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <ctype.h>
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
#if PACKETSZ > 1024
|
||||
#define MAXPACKET PACKETSZ
|
||||
#else
|
||||
#define MAXPACKET 1024
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and await answer.
|
||||
* Returned answer is placed in supplied buffer "answer".
|
||||
* Perform preliminary check of answer, returning success only
|
||||
* if no error is indicated and the answer count is nonzero.
|
||||
* Return the size of the response on success, -1 on error.
|
||||
* Error number is left in h_errno.
|
||||
*
|
||||
* Caller must parse answer and determine whether it answers the question.
|
||||
*/
|
||||
int
|
||||
res_query(name, class, type, answer, anslen)
|
||||
const char *name; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer buffer */
|
||||
{
|
||||
u_char buf[MAXPACKET];
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
int n;
|
||||
|
||||
hp->rcode = NOERROR; /* default */
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query(%s, %d, %d)\n", name, class, type);
|
||||
#endif
|
||||
|
||||
n = res_mkquery(QUERY, name, class, type, NULL, 0, NULL,
|
||||
buf, sizeof(buf));
|
||||
if (n <= 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query: mkquery failed\n");
|
||||
#endif
|
||||
h_errno = NO_RECOVERY;
|
||||
return (n);
|
||||
}
|
||||
n = res_send(buf, n, answer, anslen);
|
||||
if (n < 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_query: send error\n");
|
||||
#endif
|
||||
h_errno = TRY_AGAIN;
|
||||
return (n);
|
||||
}
|
||||
|
||||
if (hp->rcode != NOERROR || ntohs(hp->ancount) == 0) {
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; rcode = %d, ancount=%d\n", hp->rcode,
|
||||
ntohs(hp->ancount));
|
||||
#endif
|
||||
switch (hp->rcode) {
|
||||
case NXDOMAIN:
|
||||
h_errno = HOST_NOT_FOUND;
|
||||
break;
|
||||
case SERVFAIL:
|
||||
h_errno = TRY_AGAIN;
|
||||
break;
|
||||
case NOERROR:
|
||||
h_errno = NO_DATA;
|
||||
break;
|
||||
case FORMERR:
|
||||
case NOTIMP:
|
||||
case REFUSED:
|
||||
default:
|
||||
h_errno = NO_RECOVERY;
|
||||
break;
|
||||
}
|
||||
return (-1);
|
||||
}
|
||||
return (n);
|
||||
}
|
||||
|
||||
/*
|
||||
* Formulate a normal query, send, and retrieve answer in supplied buffer.
|
||||
* Return the size of the response on success, -1 on error.
|
||||
* If enabled, implement search rules until answer or unrecoverable failure
|
||||
* is detected. Error code, if any, is left in h_errno.
|
||||
*/
|
||||
int
|
||||
res_search(name, class, type, answer, anslen)
|
||||
const char *name; /* domain name */
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
const char *cp, * const *domain;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
u_int dots;
|
||||
int trailing_dot, ret, saved_herrno;
|
||||
int got_nodata = 0, got_servfail = 0, tried_as_is = 0;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
errno = 0;
|
||||
h_errno = HOST_NOT_FOUND; /* default, if we never query */
|
||||
dots = 0;
|
||||
for (cp = name; *cp; cp++)
|
||||
dots += (*cp == '.');
|
||||
trailing_dot = 0;
|
||||
if (cp > name && *--cp == '.')
|
||||
trailing_dot++;
|
||||
|
||||
/* If there aren't any dots, it could be a user-level alias */
|
||||
if (!dots && (cp = hostalias(name)) != NULL)
|
||||
return (res_query(cp, class, type, answer, anslen));
|
||||
|
||||
/*
|
||||
* If there are dots in the name already, let's just give it a try
|
||||
* 'as is'. The threshold can be set with the "ndots" option.
|
||||
*/
|
||||
saved_herrno = -1;
|
||||
if (dots >= _res.ndots) {
|
||||
ret = res_querydomain(name, NULL, class, type, answer, anslen);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
saved_herrno = h_errno;
|
||||
tried_as_is++;
|
||||
}
|
||||
|
||||
/*
|
||||
* We do at least one level of search if
|
||||
* - there is no dot and RES_DEFNAME is set, or
|
||||
* - there is at least one dot, there is no trailing dot,
|
||||
* and RES_DNSRCH is set.
|
||||
*/
|
||||
if ((!dots && (_res.options & RES_DEFNAMES)) ||
|
||||
(dots && !trailing_dot && (_res.options & RES_DNSRCH))) {
|
||||
int done = 0;
|
||||
|
||||
for (domain = (const char * const *)_res.dnsrch;
|
||||
*domain && !done;
|
||||
domain++) {
|
||||
|
||||
ret = res_querydomain(name, *domain, class, type,
|
||||
answer, anslen);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
|
||||
/*
|
||||
* If no server present, give up.
|
||||
* If name isn't found in this domain,
|
||||
* keep trying higher domains in the search list
|
||||
* (if that's enabled).
|
||||
* On a NO_DATA error, keep trying, otherwise
|
||||
* a wildcard entry of another type could keep us
|
||||
* from finding this entry higher in the domain.
|
||||
* If we get some other error (negative answer or
|
||||
* server failure), then stop searching up,
|
||||
* but try the input name below in case it's
|
||||
* fully-qualified.
|
||||
*/
|
||||
if (errno == ECONNREFUSED) {
|
||||
h_errno = TRY_AGAIN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
switch (h_errno) {
|
||||
case NO_DATA:
|
||||
got_nodata++;
|
||||
/* FALLTHROUGH */
|
||||
case HOST_NOT_FOUND:
|
||||
/* keep trying */
|
||||
break;
|
||||
case TRY_AGAIN:
|
||||
if (hp->rcode == SERVFAIL) {
|
||||
/* try next search element, if any */
|
||||
got_servfail++;
|
||||
break;
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
default:
|
||||
/* anything else implies that we're done */
|
||||
done++;
|
||||
}
|
||||
|
||||
/* if we got here for some reason other than DNSRCH,
|
||||
* we only wanted one iteration of the loop, so stop.
|
||||
*/
|
||||
if (!(_res.options & RES_DNSRCH))
|
||||
done++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* If we have not already tried the name "as is", do that now.
|
||||
* note that we do this regardless of how many dots were in the
|
||||
* name or whether it ends with a dot unless NOTLDQUERY is set.
|
||||
*/
|
||||
if (!tried_as_is && (dots || !(_res.options & RES_NOTLDQUERY))) {
|
||||
ret = res_querydomain(name, NULL, class, type, answer, anslen);
|
||||
if (ret > 0)
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* if we got here, we didn't satisfy the search.
|
||||
* if we did an initial full query, return that query's h_errno
|
||||
* (note that we wouldn't be here if that query had succeeded).
|
||||
* else if we ever got a nodata, send that back as the reason.
|
||||
* else send back meaningless h_errno, that being the one from
|
||||
* the last DNSRCH we did.
|
||||
*/
|
||||
if (saved_herrno != -1)
|
||||
h_errno = saved_herrno;
|
||||
else if (got_nodata)
|
||||
h_errno = NO_DATA;
|
||||
else if (got_servfail)
|
||||
h_errno = TRY_AGAIN;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform a call on res_query on the concatenation of name and domain,
|
||||
* removing a trailing dot from name if domain is NULL.
|
||||
*/
|
||||
int
|
||||
res_querydomain(name, domain, class, type, answer, anslen)
|
||||
const char *name, *domain;
|
||||
int class, type; /* class and type of query */
|
||||
u_char *answer; /* buffer to put answer */
|
||||
int anslen; /* size of answer */
|
||||
{
|
||||
char nbuf[MAXDNAME];
|
||||
const char *longname = nbuf;
|
||||
int n, d;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
#ifdef DEBUG
|
||||
if (_res.options & RES_DEBUG)
|
||||
printf(";; res_querydomain(%s, %s, %d, %d)\n",
|
||||
name, domain?domain:"<Nil>", class, type);
|
||||
#endif
|
||||
if (domain == NULL) {
|
||||
/*
|
||||
* Check for trailing '.';
|
||||
* copy without '.' if present.
|
||||
*/
|
||||
n = strlen(name);
|
||||
if (n >= MAXDNAME) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (-1);
|
||||
}
|
||||
n--;
|
||||
if (n >= 0 && name[n] == '.') {
|
||||
strncpy(nbuf, name, n);
|
||||
nbuf[n] = '\0';
|
||||
} else
|
||||
longname = name;
|
||||
} else {
|
||||
n = strlen(name);
|
||||
d = strlen(domain);
|
||||
if (n + d + 1 >= MAXDNAME) {
|
||||
h_errno = NO_RECOVERY;
|
||||
return (-1);
|
||||
}
|
||||
sprintf(nbuf, "%s.%s", name, domain);
|
||||
}
|
||||
return (res_query(longname, class, type, answer, anslen));
|
||||
}
|
||||
|
||||
const char *
|
||||
hostalias(name)
|
||||
const char *name;
|
||||
{
|
||||
register char *cp1, *cp2;
|
||||
FILE *fp;
|
||||
char *file;
|
||||
char buf[BUFSIZ];
|
||||
static char abuf[MAXDNAME];
|
||||
|
||||
if (_res.options & RES_NOALIASES)
|
||||
return (NULL);
|
||||
if (issetugid())
|
||||
return (NULL);
|
||||
file = getenv("HOSTALIASES");
|
||||
if (file == NULL || (fp = fopen(file, "r")) == NULL)
|
||||
return (NULL);
|
||||
setbuf(fp, NULL);
|
||||
buf[sizeof(buf) - 1] = '\0';
|
||||
while (fgets(buf, sizeof(buf), fp)) {
|
||||
for (cp1 = buf; *cp1 && !isspace(*cp1); ++cp1)
|
||||
;
|
||||
if (!*cp1)
|
||||
break;
|
||||
*cp1 = '\0';
|
||||
if (!strcasecmp(buf, name)) {
|
||||
while (isspace(*++cp1))
|
||||
;
|
||||
if (!*cp1)
|
||||
break;
|
||||
for (cp2 = cp1 + 1; *cp2 && !isspace(*cp2); ++cp2)
|
||||
;
|
||||
abuf[sizeof(abuf) - 1] = *cp2 = '\0';
|
||||
strncpy(abuf, cp1, sizeof(abuf) - 1);
|
||||
fclose(fp);
|
||||
return (abuf);
|
||||
}
|
||||
}
|
||||
fclose(fp);
|
||||
return (NULL);
|
||||
}
|
||||
923
c/src/exec/libnetworking/libc/res_send.c
Normal file
923
c/src/exec/libnetworking/libc/res_send.c
Normal file
@@ -0,0 +1,923 @@
|
||||
/*
|
||||
* Copyright (c) 1985, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1993 by Digital Equipment Corporation.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies, and that
|
||||
* the name of Digital Equipment Corporation not be used in advertising or
|
||||
* publicity pertaining to distribution of the document or software without
|
||||
* specific, written prior permission.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND DIGITAL EQUIPMENT CORP. DISCLAIMS ALL
|
||||
* WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL DIGITAL EQUIPMENT
|
||||
* CORPORATION BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Portions Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)res_send.c 8.1 (Berkeley) 6/4/93";
|
||||
static char orig_rcsid[] = "From: Id: res_send.c,v 8.20 1998/04/06 23:27:51 halley Exp $";
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
/*
|
||||
* Send query to name server and wait for reply.
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/param.h>
|
||||
#include <sys/time.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#include <errno.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <poll.h>
|
||||
|
||||
#include "res_config.h"
|
||||
|
||||
#ifdef NOPOLL /* libc_r doesn't wrap poll yet() */
|
||||
static int use_poll = 0;
|
||||
#else
|
||||
static int use_poll = 1; /* adapt to poll() syscall availability */
|
||||
/* 0 = not present, 1 = try it, 2 = exists */
|
||||
#endif
|
||||
|
||||
static int s = -1; /* socket used for communications */
|
||||
static int connected = 0; /* is the socket connected */
|
||||
static int vc = 0; /* is the socket a virtual circuit? */
|
||||
static res_send_qhook Qhook = NULL;
|
||||
static res_send_rhook Rhook = NULL;
|
||||
|
||||
|
||||
#define CAN_RECONNECT 1
|
||||
|
||||
#ifndef DEBUG
|
||||
# define Dprint(cond, args) /*empty*/
|
||||
# define DprintQ(cond, args, query, size) /*empty*/
|
||||
# define Aerror(file, string, error, address) /*empty*/
|
||||
# define Perror(file, string, error) /*empty*/
|
||||
#else
|
||||
# define Dprint(cond, args) if (cond) {fprintf args;} else {}
|
||||
# define DprintQ(cond, args, query, size) if (cond) {\
|
||||
fprintf args;\
|
||||
__fp_nquery(query, size, stdout);\
|
||||
} else {}
|
||||
static void
|
||||
Aerror(file, string, error, address)
|
||||
FILE *file;
|
||||
char *string;
|
||||
int error;
|
||||
struct sockaddr_in address;
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (_res.options & RES_DEBUG) {
|
||||
fprintf(file, "res_send: %s ([%s].%u): %s\n",
|
||||
string,
|
||||
inet_ntoa(address.sin_addr),
|
||||
ntohs(address.sin_port),
|
||||
strerror(error));
|
||||
}
|
||||
errno = save;
|
||||
}
|
||||
static void
|
||||
Perror(file, string, error)
|
||||
FILE *file;
|
||||
char *string;
|
||||
int error;
|
||||
{
|
||||
int save = errno;
|
||||
|
||||
if (_res.options & RES_DEBUG) {
|
||||
fprintf(file, "res_send: %s: %s\n",
|
||||
string, strerror(error));
|
||||
}
|
||||
errno = save;
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
res_send_setqhook(hook)
|
||||
res_send_qhook hook;
|
||||
{
|
||||
|
||||
Qhook = hook;
|
||||
}
|
||||
|
||||
void
|
||||
res_send_setrhook(hook)
|
||||
res_send_rhook hook;
|
||||
{
|
||||
|
||||
Rhook = hook;
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_isourserver(ina)
|
||||
* looks up "ina" in _res.ns_addr_list[]
|
||||
* returns:
|
||||
* 0 : not found
|
||||
* >0 : found
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_isourserver(inp)
|
||||
const struct sockaddr_in *inp;
|
||||
{
|
||||
struct sockaddr_in ina;
|
||||
int ns, ret;
|
||||
|
||||
ina = *inp;
|
||||
ret = 0;
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
const struct sockaddr_in *srv = &_res.nsaddr_list[ns];
|
||||
|
||||
if (srv->sin_family == ina.sin_family &&
|
||||
srv->sin_port == ina.sin_port &&
|
||||
(srv->sin_addr.s_addr == INADDR_ANY ||
|
||||
srv->sin_addr.s_addr == ina.sin_addr.s_addr)) {
|
||||
ret++;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_nameinquery(name, type, class, buf, eom)
|
||||
* look for (name,type,class) in the query section of packet (buf,eom)
|
||||
* requires:
|
||||
* buf + HFIXEDSZ <= eom
|
||||
* returns:
|
||||
* -1 : format error
|
||||
* 0 : not found
|
||||
* >0 : found
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_nameinquery(name, type, class, buf, eom)
|
||||
const char *name;
|
||||
int type, class;
|
||||
const u_char *buf, *eom;
|
||||
{
|
||||
const u_char *cp = buf + HFIXEDSZ;
|
||||
int qdcount = ntohs(((HEADER*)buf)->qdcount);
|
||||
|
||||
while (qdcount-- > 0) {
|
||||
char tname[MAXDNAME+1];
|
||||
int n, ttype, tclass;
|
||||
|
||||
n = dn_expand(buf, eom, cp, tname, sizeof tname);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom)
|
||||
return (-1);
|
||||
ttype = ns_get16(cp); cp += INT16SZ;
|
||||
tclass = ns_get16(cp); cp += INT16SZ;
|
||||
if (ttype == type &&
|
||||
tclass == class &&
|
||||
strcasecmp(tname, name) == 0)
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* int
|
||||
* res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
* is there a 1:1 mapping of (name,type,class)
|
||||
* in (buf1,eom1) and (buf2,eom2)?
|
||||
* returns:
|
||||
* -1 : format error
|
||||
* 0 : not a 1:1 mapping
|
||||
* >0 : is a 1:1 mapping
|
||||
* author:
|
||||
* paul vixie, 29may94
|
||||
*/
|
||||
int
|
||||
res_queriesmatch(buf1, eom1, buf2, eom2)
|
||||
const u_char *buf1, *eom1;
|
||||
const u_char *buf2, *eom2;
|
||||
{
|
||||
const u_char *cp = buf1 + HFIXEDSZ;
|
||||
int qdcount = ntohs(((HEADER*)buf1)->qdcount);
|
||||
|
||||
if (buf1 + HFIXEDSZ > eom1 || buf2 + HFIXEDSZ > eom2)
|
||||
return (-1);
|
||||
|
||||
/*
|
||||
* Only header section present in replies to
|
||||
* dynamic update packets.
|
||||
*/
|
||||
if ( (((HEADER *)buf1)->opcode == ns_o_update) &&
|
||||
(((HEADER *)buf2)->opcode == ns_o_update) )
|
||||
return (1);
|
||||
|
||||
if (qdcount != ntohs(((HEADER*)buf2)->qdcount))
|
||||
return (0);
|
||||
while (qdcount-- > 0) {
|
||||
char tname[MAXDNAME+1];
|
||||
int n, ttype, tclass;
|
||||
|
||||
n = dn_expand(buf1, eom1, cp, tname, sizeof tname);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom1)
|
||||
return (-1);
|
||||
ttype = ns_get16(cp); cp += INT16SZ;
|
||||
tclass = ns_get16(cp); cp += INT16SZ;
|
||||
if (!res_nameinquery(tname, ttype, tclass, buf2, eom2))
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int
|
||||
res_send(buf, buflen, ans, anssiz)
|
||||
const u_char *buf;
|
||||
int buflen;
|
||||
u_char *ans;
|
||||
int anssiz;
|
||||
{
|
||||
HEADER *hp = (HEADER *) buf;
|
||||
HEADER *anhp = (HEADER *) ans;
|
||||
int gotsomewhere, connreset, terrno, try, v_circuit, resplen, ns, n;
|
||||
u_int badns; /* XXX NSMAX can't exceed #/bits in this variable */
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
/* errno should have been set by res_init() in this case. */
|
||||
return (-1);
|
||||
}
|
||||
if (anssiz < HFIXEDSZ) {
|
||||
errno = EINVAL;
|
||||
return (-1);
|
||||
}
|
||||
DprintQ((_res.options & RES_DEBUG) || (_res.pfcode & RES_PRF_QUERY),
|
||||
(stdout, ";; res_send()\n"), buf, buflen);
|
||||
v_circuit = (_res.options & RES_USEVC) || buflen > PACKETSZ;
|
||||
gotsomewhere = 0;
|
||||
connreset = 0;
|
||||
terrno = ETIMEDOUT;
|
||||
badns = 0;
|
||||
|
||||
/*
|
||||
* Send request, RETRY times, or until successful
|
||||
*/
|
||||
for (try = 0; try < _res.retry; try++) {
|
||||
for (ns = 0; ns < _res.nscount; ns++) {
|
||||
struct sockaddr_in *nsap = &_res.nsaddr_list[ns];
|
||||
same_ns:
|
||||
if (badns & (1 << ns)) {
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
|
||||
if (Qhook) {
|
||||
int done = 0, loops = 0;
|
||||
|
||||
do {
|
||||
res_sendhookact act;
|
||||
|
||||
act = (*Qhook)(&nsap, &buf, &buflen,
|
||||
ans, anssiz, &resplen);
|
||||
switch (act) {
|
||||
case res_goahead:
|
||||
done = 1;
|
||||
break;
|
||||
case res_nextns:
|
||||
res_close();
|
||||
goto next_ns;
|
||||
case res_done:
|
||||
return (resplen);
|
||||
case res_modified:
|
||||
/* give the hook another try */
|
||||
if (++loops < 42) /*doug adams*/
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case res_error:
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
} while (!done);
|
||||
}
|
||||
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; Querying server (# %d) address = %s\n",
|
||||
ns + 1, inet_ntoa(nsap->sin_addr)));
|
||||
|
||||
if (v_circuit) {
|
||||
int truncated;
|
||||
struct iovec iov[2];
|
||||
u_short len;
|
||||
u_char *cp;
|
||||
|
||||
/*
|
||||
* Use virtual circuit;
|
||||
* at most one attempt per server.
|
||||
*/
|
||||
try = _res.retry;
|
||||
truncated = 0;
|
||||
if (s < 0 || !vc || hp->opcode == ns_o_update) {
|
||||
if (s >= 0)
|
||||
res_close();
|
||||
|
||||
s = socket(PF_INET, SOCK_STREAM, 0);
|
||||
if (s < 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "socket(vc)", errno);
|
||||
return (-1);
|
||||
}
|
||||
errno = 0;
|
||||
if (connect(s, (struct sockaddr *)nsap,
|
||||
sizeof *nsap) < 0) {
|
||||
terrno = errno;
|
||||
Aerror(stderr, "connect/vc",
|
||||
errno, *nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
vc = 1;
|
||||
}
|
||||
/*
|
||||
* Send length & message
|
||||
*/
|
||||
putshort((u_short)buflen, (u_char*)&len);
|
||||
#if 0
|
||||
iov[0].iov_base = (caddr_t)&len;
|
||||
iov[0].iov_len = INT16SZ;
|
||||
iov[1].iov_base = (caddr_t)buf;
|
||||
iov[1].iov_len = buflen;
|
||||
if (writev(s, iov, 2) != (INT16SZ + buflen)) {
|
||||
#else
|
||||
/*
|
||||
* RTEMS doesn't have writev (yet)
|
||||
*/
|
||||
if ((write (s, len, INT16SZ) != INT16SZ)
|
||||
|| (write (s, buf, buflen) != buflen)) {
|
||||
#endif
|
||||
terrno = errno;
|
||||
Perror(stderr, "write failed", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
/*
|
||||
* Receive length & response
|
||||
*/
|
||||
read_len:
|
||||
cp = ans;
|
||||
len = INT16SZ;
|
||||
while ((n = read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
if ((len -= n) <= 0)
|
||||
break;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "read failed", errno);
|
||||
res_close();
|
||||
/*
|
||||
* A long running process might get its TCP
|
||||
* connection reset if the remote server was
|
||||
* restarted. Requery the server instead of
|
||||
* trying a new one. When there is only one
|
||||
* server, this means that a query might work
|
||||
* instead of failing. We only allow one reset
|
||||
* per query to prevent looping.
|
||||
*/
|
||||
if (terrno == ECONNRESET && !connreset) {
|
||||
connreset = 1;
|
||||
res_close();
|
||||
goto same_ns;
|
||||
}
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
resplen = ns_get16(ans);
|
||||
if (resplen > anssiz) {
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; response truncated\n")
|
||||
);
|
||||
truncated = 1;
|
||||
len = anssiz;
|
||||
} else
|
||||
len = resplen;
|
||||
if (len < HFIXEDSZ) {
|
||||
/*
|
||||
* Undersized message.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; undersized: %d\n", len));
|
||||
terrno = EMSGSIZE;
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
cp = ans;
|
||||
while (len != 0 &&
|
||||
(n = read(s, (char *)cp, (int)len)) > 0) {
|
||||
cp += n;
|
||||
len -= n;
|
||||
}
|
||||
if (n <= 0) {
|
||||
terrno = errno;
|
||||
Perror(stderr, "read(vc)", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
if (truncated) {
|
||||
/*
|
||||
* Flush rest of answer
|
||||
* so connection stays in synch.
|
||||
*/
|
||||
anhp->tc = 1;
|
||||
len = resplen - anssiz;
|
||||
while (len != 0) {
|
||||
char junk[PACKETSZ];
|
||||
|
||||
n = (len > sizeof(junk)
|
||||
? sizeof(junk)
|
||||
: len);
|
||||
if ((n = read(s, junk, n)) > 0)
|
||||
len -= n;
|
||||
else
|
||||
break;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* The calling applicating has bailed out of
|
||||
* a previous call and failed to arrange to have
|
||||
* the circuit closed or the server has got
|
||||
* itself confused. Anyway drop the packet and
|
||||
* wait for the correct one.
|
||||
*/
|
||||
if (hp->id != anhp->id) {
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; old answer (unexpected):\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto read_len;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Use datagrams.
|
||||
*/
|
||||
#ifndef NOPOLL
|
||||
struct pollfd pfd;
|
||||
int msec;
|
||||
#endif
|
||||
struct timeval timeout;
|
||||
fd_set dsmask, *dsmaskp;
|
||||
int dsmasklen;
|
||||
struct sockaddr_in from;
|
||||
int fromlen;
|
||||
|
||||
if ((s < 0) || vc) {
|
||||
if (vc)
|
||||
res_close();
|
||||
s = socket(PF_INET, SOCK_DGRAM, 0);
|
||||
if (s < 0) {
|
||||
#ifndef CAN_RECONNECT
|
||||
bad_dg_sock:
|
||||
#endif
|
||||
terrno = errno;
|
||||
Perror(stderr, "socket(dg)", errno);
|
||||
return (-1);
|
||||
}
|
||||
connected = 0;
|
||||
}
|
||||
#ifndef CANNOT_CONNECT_DGRAM
|
||||
/*
|
||||
* On a 4.3BSD+ machine (client and server,
|
||||
* actually), sending to a nameserver datagram
|
||||
* port with no nameserver will cause an
|
||||
* ICMP port unreachable message to be returned.
|
||||
* If our datagram socket is "connected" to the
|
||||
* server, we get an ECONNREFUSED error on the next
|
||||
* socket operation, and select returns if the
|
||||
* error message is received. We can thus detect
|
||||
* the absence of a nameserver without timing out.
|
||||
* If we have sent queries to at least two servers,
|
||||
* however, we don't want to remain connected,
|
||||
* as we wish to receive answers from the first
|
||||
* server to respond.
|
||||
*/
|
||||
if (_res.nscount == 1 || (try == 0 && ns == 0)) {
|
||||
/*
|
||||
* Connect only if we are sure we won't
|
||||
* receive a response from another server.
|
||||
*/
|
||||
if (!connected) {
|
||||
if (connect(s, (struct sockaddr *)nsap,
|
||||
sizeof *nsap
|
||||
) < 0) {
|
||||
Aerror(stderr,
|
||||
"connect(dg)",
|
||||
errno, *nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
connected = 1;
|
||||
}
|
||||
if (send(s, (char*)buf, buflen, 0) != buflen) {
|
||||
Perror(stderr, "send", errno);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
} else {
|
||||
/*
|
||||
* Disconnect if we want to listen
|
||||
* for responses from more than one server.
|
||||
*/
|
||||
if (connected) {
|
||||
#ifdef CAN_RECONNECT
|
||||
struct sockaddr_in no_addr;
|
||||
|
||||
no_addr.sin_family = AF_INET;
|
||||
no_addr.sin_addr.s_addr = INADDR_ANY;
|
||||
no_addr.sin_port = 0;
|
||||
(void) connect(s,
|
||||
(struct sockaddr *)
|
||||
&no_addr,
|
||||
sizeof no_addr);
|
||||
#else
|
||||
int s1 = socket(PF_INET, SOCK_DGRAM,0);
|
||||
if (s1 < 0)
|
||||
goto bad_dg_sock;
|
||||
(void) dup2(s1, s);
|
||||
(void) close(s1);
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; new DG socket\n"))
|
||||
#endif /* CAN_RECONNECT */
|
||||
connected = 0;
|
||||
errno = 0;
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
if (sendto(s, (char*)buf, buflen, 0,
|
||||
(struct sockaddr *)nsap,
|
||||
sizeof *nsap)
|
||||
!= buflen) {
|
||||
Aerror(stderr, "sendto", errno, *nsap);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#ifndef CANNOT_CONNECT_DGRAM
|
||||
}
|
||||
#endif /* !CANNOT_CONNECT_DGRAM */
|
||||
|
||||
/*
|
||||
* Wait for reply
|
||||
*/
|
||||
#ifndef NOPOLL
|
||||
othersyscall:
|
||||
if (use_poll) {
|
||||
msec = (_res.retrans << try) * 1000;
|
||||
if (try > 0)
|
||||
msec /= _res.nscount;
|
||||
if (msec <= 0)
|
||||
msec = 1000;
|
||||
} else {
|
||||
#endif
|
||||
timeout.tv_sec = (_res.retrans << try);
|
||||
if (try > 0)
|
||||
timeout.tv_sec /= _res.nscount;
|
||||
if ((long) timeout.tv_sec <= 0)
|
||||
timeout.tv_sec = 1;
|
||||
timeout.tv_usec = 0;
|
||||
#ifndef NOPOLL
|
||||
}
|
||||
#endif
|
||||
wait:
|
||||
if (s < 0) {
|
||||
Perror(stderr, "s out-of-bounds", EMFILE);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#ifndef NOPOLL
|
||||
if (use_poll) {
|
||||
struct sigaction sa, osa;
|
||||
int sigsys_installed = 0;
|
||||
|
||||
pfd.fd = s;
|
||||
pfd.events = POLLIN;
|
||||
if (use_poll == 1) {
|
||||
bzero(&sa, sizeof(sa));
|
||||
sa.sa_handler = SIG_IGN;
|
||||
if (sigaction(SIGSYS, &sa, &osa) >= 0)
|
||||
sigsys_installed = 1;
|
||||
}
|
||||
n = poll(&pfd, 1, msec);
|
||||
if (sigsys_installed == 1) {
|
||||
int oerrno = errno;
|
||||
sigaction(SIGSYS, &osa, NULL);
|
||||
errno = oerrno;
|
||||
}
|
||||
/* XXX why does nosys() return EINVAL? */
|
||||
if (n < 0 && (errno == ENOSYS ||
|
||||
errno == EINVAL)) {
|
||||
use_poll = 0;
|
||||
goto othersyscall;
|
||||
} else if (use_poll == 1)
|
||||
use_poll = 2;
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
goto wait;
|
||||
Perror(stderr, "poll", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
} else {
|
||||
#endif
|
||||
#ifndef NOSELECT
|
||||
dsmasklen = howmany(s + 1, NFDBITS) *
|
||||
sizeof(fd_mask);
|
||||
if (dsmasklen > sizeof(fd_set)) {
|
||||
dsmaskp = (fd_set *)malloc(dsmasklen);
|
||||
if (dsmaskp == NULL) {
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
} else
|
||||
dsmaskp = &dsmask;
|
||||
/* only zero what we need */
|
||||
bzero((char *)dsmaskp, dsmasklen);
|
||||
FD_SET(s, dsmaskp);
|
||||
n = select(s + 1, dsmaskp, (fd_set *)NULL,
|
||||
(fd_set *)NULL, &timeout);
|
||||
if (dsmaskp != &dsmask)
|
||||
free(dsmaskp);
|
||||
if (n < 0) {
|
||||
if (errno == EINTR)
|
||||
goto wait;
|
||||
Perror(stderr, "select", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#endif
|
||||
#ifndef NOPOLL
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NOSELECT
|
||||
setsockopt (s, SOL_SOCKET, SO_RCVTIMEO, &timeout, sizeof timeout);
|
||||
#else
|
||||
if (n == 0) {
|
||||
/*
|
||||
* timeout
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; timeout\n"));
|
||||
gotsomewhere = 1;
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#endif
|
||||
errno = 0;
|
||||
fromlen = sizeof(struct sockaddr_in);
|
||||
resplen = recvfrom(s, (char*)ans, anssiz, 0,
|
||||
(struct sockaddr *)&from, &fromlen);
|
||||
if (resplen <= 0) {
|
||||
#ifdef NOSELECT
|
||||
if (errno == ETIMEDOUT) {
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; timeout\n"));
|
||||
gotsomewhere = 1;
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
#endif
|
||||
Perror(stderr, "recvfrom", errno);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
gotsomewhere = 1;
|
||||
if (resplen < HFIXEDSZ) {
|
||||
/*
|
||||
* Undersized message.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; undersized: %d\n",
|
||||
resplen));
|
||||
terrno = EMSGSIZE;
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
goto next_ns;
|
||||
}
|
||||
if (hp->id != anhp->id) {
|
||||
/*
|
||||
* response from old query, ignore it.
|
||||
* XXX - potential security hazard could
|
||||
* be detected here.
|
||||
*/
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; old answer:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
#ifdef CHECK_SRVR_ADDR
|
||||
if (!(_res.options & RES_INSECURE1) &&
|
||||
!res_isourserver(&from)) {
|
||||
/*
|
||||
* response from wrong server? ignore it.
|
||||
* XXX - potential security hazard could
|
||||
* be detected here.
|
||||
*/
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; not our server:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
#endif
|
||||
if (!(_res.options & RES_INSECURE2) &&
|
||||
!res_queriesmatch(buf, buf + buflen,
|
||||
ans, ans + anssiz)) {
|
||||
/*
|
||||
* response contains wrong query? ignore it.
|
||||
* XXX - potential security hazard could
|
||||
* be detected here.
|
||||
*/
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ";; wrong query name:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
goto wait;
|
||||
}
|
||||
if (anhp->rcode == SERVFAIL ||
|
||||
anhp->rcode == NOTIMP ||
|
||||
anhp->rcode == REFUSED) {
|
||||
DprintQ(_res.options & RES_DEBUG,
|
||||
(stdout, "server rejected query:\n"),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
badns |= (1 << ns);
|
||||
res_close();
|
||||
/* don't retry if called from dig */
|
||||
if (!_res.pfcode)
|
||||
goto next_ns;
|
||||
}
|
||||
if (!(_res.options & RES_IGNTC) && anhp->tc) {
|
||||
/*
|
||||
* get rest of answer;
|
||||
* use TCP with same server.
|
||||
*/
|
||||
Dprint(_res.options & RES_DEBUG,
|
||||
(stdout, ";; truncated answer\n"));
|
||||
v_circuit = 1;
|
||||
res_close();
|
||||
goto same_ns;
|
||||
}
|
||||
} /*if vc/dg*/
|
||||
Dprint((_res.options & RES_DEBUG) ||
|
||||
((_res.pfcode & RES_PRF_REPLY) &&
|
||||
(_res.pfcode & RES_PRF_HEAD1)),
|
||||
(stdout, ";; got answer:\n"));
|
||||
DprintQ((_res.options & RES_DEBUG) ||
|
||||
(_res.pfcode & RES_PRF_REPLY),
|
||||
(stdout, ""),
|
||||
ans, (resplen>anssiz)?anssiz:resplen);
|
||||
/*
|
||||
* If using virtual circuits, we assume that the first server
|
||||
* is preferred over the rest (i.e. it is on the local
|
||||
* machine) and only keep that one open.
|
||||
* If we have temporarily opened a virtual circuit,
|
||||
* or if we haven't been asked to keep a socket open,
|
||||
* close the socket.
|
||||
*/
|
||||
if ((v_circuit && (!(_res.options & RES_USEVC) || ns != 0)) ||
|
||||
!(_res.options & RES_STAYOPEN)) {
|
||||
res_close();
|
||||
}
|
||||
if (Rhook) {
|
||||
int done = 0, loops = 0;
|
||||
|
||||
do {
|
||||
res_sendhookact act;
|
||||
|
||||
act = (*Rhook)(nsap, buf, buflen,
|
||||
ans, anssiz, &resplen);
|
||||
switch (act) {
|
||||
case res_goahead:
|
||||
case res_done:
|
||||
done = 1;
|
||||
break;
|
||||
case res_nextns:
|
||||
res_close();
|
||||
goto next_ns;
|
||||
case res_modified:
|
||||
/* give the hook another try */
|
||||
if (++loops < 42) /*doug adams*/
|
||||
break;
|
||||
/*FALLTHROUGH*/
|
||||
case res_error:
|
||||
/*FALLTHROUGH*/
|
||||
default:
|
||||
return (-1);
|
||||
}
|
||||
} while (!done);
|
||||
|
||||
}
|
||||
return (resplen);
|
||||
next_ns: ;
|
||||
} /*foreach ns*/
|
||||
} /*foreach retry*/
|
||||
res_close();
|
||||
if (!v_circuit) {
|
||||
if (!gotsomewhere)
|
||||
errno = ECONNREFUSED; /* no nameservers found */
|
||||
else
|
||||
errno = ETIMEDOUT; /* no answer obtained */
|
||||
} else
|
||||
errno = terrno;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
/*
|
||||
* This routine is for closing the socket if a virtual circuit is used and
|
||||
* the program wants to close it. This provides support for endhostent()
|
||||
* which expects to close the socket.
|
||||
*
|
||||
* This routine is not expected to be user visible.
|
||||
*/
|
||||
void
|
||||
res_close()
|
||||
{
|
||||
if (s >= 0) {
|
||||
(void) close(s);
|
||||
s = -1;
|
||||
connected = 0;
|
||||
vc = 0;
|
||||
}
|
||||
}
|
||||
75
c/src/exec/libnetworking/libc/res_stubs.c
Normal file
75
c/src/exec/libnetworking/libc/res_stubs.c
Normal file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (C) 1996 Peter Wemm <peter@freebsd.org>.
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* This file is for FreeBSD-3.0 that has a bind-4.9.5-P1 derived
|
||||
* resolver in the libc. It provides aliases for functions that
|
||||
* have moved since 4.9.4-P1.
|
||||
*
|
||||
* I'll save everybody the trouble and say it now: *THIS IS A HACK*!
|
||||
*
|
||||
* Yes, many of these are private functions to the resolver, but some are
|
||||
* needed as there is no other way to provide the functionality and they've
|
||||
* turned up all over the place. :-(
|
||||
*/
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__weak_reference(__inet_addr, inet_addr);
|
||||
__weak_reference(__inet_aton, inet_aton);
|
||||
__weak_reference(__inet_lnaof, inet_lnaof);
|
||||
__weak_reference(__inet_makeaddr, inet_makeaddr);
|
||||
__weak_reference(__inet_neta, inet_neta);
|
||||
__weak_reference(__inet_netof, inet_netof);
|
||||
__weak_reference(__inet_network, inet_network);
|
||||
__weak_reference(__inet_net_ntop, inet_net_ntop);
|
||||
__weak_reference(__inet_net_pton, inet_net_pton);
|
||||
__weak_reference(__inet_ntoa, inet_ntoa);
|
||||
__weak_reference(__inet_pton, inet_pton);
|
||||
__weak_reference(__inet_ntop, inet_ntop);
|
||||
__weak_reference(__inet_nsap_addr, inet_nsap_addr);
|
||||
__weak_reference(__inet_nsap_ntoa, inet_nsap_ntoa);
|
||||
|
||||
__weak_reference(__sym_ston, sym_ston);
|
||||
__weak_reference(__sym_ntos, sym_ntos);
|
||||
__weak_reference(__sym_ntop, sym_ntop);
|
||||
__weak_reference(__fp_resstat, fp_resstat);
|
||||
__weak_reference(__p_query, p_query);
|
||||
__weak_reference(__p_fqnname, p_fqnname);
|
||||
__weak_reference(__p_secstodate, p_secstodate);
|
||||
__weak_reference(__dn_count_labels, dn_count_labels);
|
||||
__weak_reference(__dn_comp, dn_comp);
|
||||
__weak_reference(__res_close, _res_close);
|
||||
__weak_reference(__dn_expand, dn_expand);
|
||||
__weak_reference(__res_init, res_init);
|
||||
__weak_reference(__res_query, res_query);
|
||||
__weak_reference(__res_search, res_search);
|
||||
__weak_reference(__res_querydomain, res_querydomain);
|
||||
__weak_reference(__res_mkquery, res_mkquery);
|
||||
__weak_reference(__res_send, res_send);
|
||||
516
c/src/exec/libnetworking/libc/res_update.c
Normal file
516
c/src/exec/libnetworking/libc/res_update.c
Normal file
@@ -0,0 +1,516 @@
|
||||
#if !defined(lint) && !defined(SABER)
|
||||
static char rcsid[] = "$Id$";
|
||||
#endif /* not lint */
|
||||
|
||||
/*
|
||||
* Copyright (c) 1996 by Internet Software Consortium.
|
||||
*
|
||||
* Permission to use, copy, modify, and distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND INTERNET SOFTWARE CONSORTIUM DISCLAIMS
|
||||
* ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES
|
||||
* OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL INTERNET SOFTWARE
|
||||
* CONSORTIUM BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL
|
||||
* DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR
|
||||
* PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS
|
||||
* ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
|
||||
* SOFTWARE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Based on the Dynamic DNS reference implementation by Viraj Bais
|
||||
* <viraj_bais@ccm.fm.intel.com>
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/time.h>
|
||||
#include <netinet/in.h>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <errno.h>
|
||||
#include <limits.h>
|
||||
#include <netdb.h>
|
||||
#include <resolv.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
/*
|
||||
* Separate a linked list of records into groups so that all records
|
||||
* in a group will belong to a single zone on the nameserver.
|
||||
* Create a dynamic update packet for each zone and send it to the
|
||||
* nameservers for that zone, and await answer.
|
||||
* Abort if error occurs in updating any zone.
|
||||
* Return the number of zones updated on success, < 0 on error.
|
||||
*
|
||||
* On error, caller must deal with the unsynchronized zones
|
||||
* eg. an A record might have been successfully added to the forward
|
||||
* zone but the corresponding PTR record would be missing if error
|
||||
* was encountered while updating the reverse zone.
|
||||
*/
|
||||
|
||||
#define NSMAX 16
|
||||
|
||||
struct ns1 {
|
||||
char nsname[MAXDNAME];
|
||||
struct in_addr nsaddr1;
|
||||
};
|
||||
|
||||
struct zonegrp {
|
||||
char z_origin[MAXDNAME];
|
||||
int16_t z_class;
|
||||
char z_soardata[MAXDNAME + 5 * INT32SZ];
|
||||
struct ns1 z_ns[NSMAX];
|
||||
int z_nscount;
|
||||
ns_updrec * z_rr;
|
||||
struct zonegrp *z_next;
|
||||
};
|
||||
|
||||
|
||||
int
|
||||
res_update(ns_updrec *rrecp_in) {
|
||||
ns_updrec *rrecp, *tmprrecp;
|
||||
u_char buf[PACKETSZ], answer[PACKETSZ], packet[2*PACKETSZ];
|
||||
char name[MAXDNAME], zname[MAXDNAME], primary[MAXDNAME],
|
||||
mailaddr[MAXDNAME];
|
||||
u_char soardata[2*MAXCDNAME+5*INT32SZ];
|
||||
char *dname, *svdname, *cp1, *target;
|
||||
u_char *cp, *eom;
|
||||
HEADER *hp = (HEADER *) answer;
|
||||
struct zonegrp *zptr = NULL, *tmpzptr, *prevzptr, *zgrp_start = NULL;
|
||||
int i, j, k = 0, n, ancount, nscount, arcount, rcode, rdatasize,
|
||||
newgroup, done, myzone, seen_before, numzones = 0;
|
||||
u_int16_t dlen, class, qclass, type, qtype;
|
||||
u_int32_t ttl;
|
||||
|
||||
if ((_res.options & RES_INIT) == 0 && res_init() == -1) {
|
||||
h_errno = NETDB_INTERNAL;
|
||||
return (-1);
|
||||
}
|
||||
|
||||
for (rrecp = rrecp_in; rrecp; rrecp = rrecp->r_next) {
|
||||
dname = rrecp->r_dname;
|
||||
n = strlen(dname);
|
||||
if (dname[n-1] == '.')
|
||||
dname[n-1] = '\0';
|
||||
qtype = T_SOA;
|
||||
qclass = rrecp->r_class;
|
||||
done = 0;
|
||||
seen_before = 0;
|
||||
|
||||
while (!done && dname) {
|
||||
if (qtype == T_SOA) {
|
||||
for (tmpzptr = zgrp_start;
|
||||
tmpzptr && !seen_before;
|
||||
tmpzptr = tmpzptr->z_next) {
|
||||
if (strcasecmp(dname,
|
||||
tmpzptr->z_origin) == 0 &&
|
||||
tmpzptr->z_class == qclass)
|
||||
seen_before++;
|
||||
for (tmprrecp = tmpzptr->z_rr;
|
||||
tmprrecp && !seen_before;
|
||||
tmprrecp = tmprrecp->r_grpnext)
|
||||
if (strcasecmp(dname, tmprrecp->r_dname) == 0
|
||||
&& tmprrecp->r_class == qclass) {
|
||||
seen_before++;
|
||||
break;
|
||||
}
|
||||
if (seen_before) {
|
||||
/*
|
||||
* Append to the end of
|
||||
* current group.
|
||||
*/
|
||||
for (tmprrecp = tmpzptr->z_rr;
|
||||
tmprrecp->r_grpnext;
|
||||
tmprrecp = tmprrecp->r_grpnext)
|
||||
(void)NULL;
|
||||
tmprrecp->r_grpnext = rrecp;
|
||||
rrecp->r_grpnext = NULL;
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
} else if (qtype == T_A) {
|
||||
for (tmpzptr = zgrp_start;
|
||||
tmpzptr && !done;
|
||||
tmpzptr = tmpzptr->z_next)
|
||||
for (i = 0; i < tmpzptr->z_nscount; i++)
|
||||
if (tmpzptr->z_class == qclass &&
|
||||
strcasecmp(tmpzptr->z_ns[i].nsname,
|
||||
dname) == 0 &&
|
||||
tmpzptr->z_ns[i].nsaddr1.s_addr != 0) {
|
||||
zptr->z_ns[k].nsaddr1.s_addr =
|
||||
tmpzptr->z_ns[i].nsaddr1.s_addr;
|
||||
done = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (done)
|
||||
break;
|
||||
n = res_mkquery(QUERY, dname, qclass, qtype, NULL,
|
||||
0, NULL, buf, sizeof buf);
|
||||
if (n <= 0) {
|
||||
fprintf(stderr, "res_update: mkquery failed\n");
|
||||
return (n);
|
||||
}
|
||||
n = res_send(buf, n, answer, sizeof answer);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "res_update: send error for %s\n",
|
||||
rrecp->r_dname);
|
||||
return (n);
|
||||
}
|
||||
if (n < HFIXEDSZ)
|
||||
return (-1);
|
||||
ancount = ntohs(hp->ancount);
|
||||
nscount = ntohs(hp->nscount);
|
||||
arcount = ntohs(hp->arcount);
|
||||
rcode = hp->rcode;
|
||||
cp = answer + HFIXEDSZ;
|
||||
eom = answer + n;
|
||||
/* skip the question section */
|
||||
n = dn_skipname(cp, eom);
|
||||
if (n < 0 || cp + n + 2 * INT16SZ > eom)
|
||||
return (-1);
|
||||
cp += n + 2 * INT16SZ;
|
||||
|
||||
if (qtype == T_SOA) {
|
||||
if (ancount == 0 && nscount == 0 && arcount == 0) {
|
||||
/*
|
||||
* if (rcode == NOERROR) then the dname exists but
|
||||
* has no soa record associated with it.
|
||||
* if (rcode == NXDOMAIN) then the dname does not
|
||||
* exist and the server is replying out of NCACHE.
|
||||
* in either case, proceed with the next try
|
||||
*/
|
||||
dname = strchr(dname, '.');
|
||||
if (dname != NULL)
|
||||
dname++;
|
||||
continue;
|
||||
} else if ((rcode == NOERROR || rcode == NXDOMAIN) &&
|
||||
ancount == 0 &&
|
||||
nscount == 1 && arcount == 0) {
|
||||
/*
|
||||
* name/data does not exist, soa record supplied in the
|
||||
* authority section
|
||||
*/
|
||||
/* authority section must contain the soa record */
|
||||
if ((n = dn_expand(answer, eom, cp, zname,
|
||||
sizeof zname)) < 0)
|
||||
return (n);
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom)
|
||||
return (-1);
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
if (type != T_SOA || class != qclass) {
|
||||
fprintf(stderr, "unknown answer\n");
|
||||
return (-1);
|
||||
}
|
||||
myzone = 0;
|
||||
svdname = dname;
|
||||
while (dname)
|
||||
if (strcasecmp(dname, zname) == 0) {
|
||||
myzone = 1;
|
||||
break;
|
||||
} else if ((dname = strchr(dname, '.')) != NULL)
|
||||
dname++;
|
||||
if (!myzone) {
|
||||
dname = strchr(svdname, '.');
|
||||
if (dname != NULL)
|
||||
dname++;
|
||||
continue;
|
||||
}
|
||||
nscount = 0;
|
||||
/* fallthrough */
|
||||
} else if (rcode == NOERROR && ancount == 1) {
|
||||
/*
|
||||
* found the zone name
|
||||
* new servers will supply NS records for the zone
|
||||
* in authority section and A records for those
|
||||
* nameservers in the additional section
|
||||
* older servers have to be explicitly queried for
|
||||
* NS records for the zone
|
||||
*/
|
||||
/* answer section must contain the soa record */
|
||||
if ((n = dn_expand(answer, eom, cp, zname,
|
||||
sizeof zname)) < 0)
|
||||
return (n);
|
||||
else
|
||||
cp += n;
|
||||
if (cp + 2 * INT16SZ > eom)
|
||||
return (-1);
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
if (type == T_CNAME) {
|
||||
dname = strchr(dname, '.');
|
||||
if (dname != NULL)
|
||||
dname++;
|
||||
continue;
|
||||
}
|
||||
if (strcasecmp(dname, zname) != 0 ||
|
||||
type != T_SOA ||
|
||||
class != rrecp->r_class) {
|
||||
fprintf(stderr, "unknown answer\n");
|
||||
return (-1);
|
||||
}
|
||||
/* FALLTHROUGH */
|
||||
} else {
|
||||
fprintf(stderr,
|
||||
"unknown response: ans=%d, auth=%d, add=%d, rcode=%d\n",
|
||||
ancount, nscount, arcount, hp->rcode);
|
||||
return (-1);
|
||||
}
|
||||
if (cp + INT32SZ + INT16SZ > eom)
|
||||
return (-1);
|
||||
/* continue processing the soa record */
|
||||
GETLONG(ttl, cp);
|
||||
GETSHORT(dlen, cp);
|
||||
if (cp + dlen > eom)
|
||||
return (-1);
|
||||
newgroup = 1;
|
||||
zptr = zgrp_start;
|
||||
prevzptr = NULL;
|
||||
while (zptr) {
|
||||
if (strcasecmp(zname, zptr->z_origin) == 0 &&
|
||||
type == T_SOA && class == qclass) {
|
||||
newgroup = 0;
|
||||
break;
|
||||
}
|
||||
prevzptr = zptr;
|
||||
zptr = zptr->z_next;
|
||||
}
|
||||
if (!newgroup) {
|
||||
for (tmprrecp = zptr->z_rr;
|
||||
tmprrecp->r_grpnext;
|
||||
tmprrecp = tmprrecp->r_grpnext)
|
||||
;
|
||||
tmprrecp->r_grpnext = rrecp;
|
||||
rrecp->r_grpnext = NULL;
|
||||
done = 1;
|
||||
cp += dlen;
|
||||
break;
|
||||
} else {
|
||||
if ((n = dn_expand(answer, eom, cp, primary,
|
||||
sizeof primary)) < 0)
|
||||
return (n);
|
||||
cp += n;
|
||||
/*
|
||||
* We don't have to bounds check here because the
|
||||
* next use of 'cp' is in dn_expand().
|
||||
*/
|
||||
cp1 = (char *)soardata;
|
||||
strcpy(cp1, primary);
|
||||
cp1 += strlen(cp1) + 1;
|
||||
if ((n = dn_expand(answer, eom, cp, mailaddr,
|
||||
sizeof mailaddr)) < 0)
|
||||
return (n);
|
||||
cp += n;
|
||||
strcpy(cp1, mailaddr);
|
||||
cp1 += strlen(cp1) + 1;
|
||||
if (cp + 5*INT32SZ > eom)
|
||||
return (-1);
|
||||
memcpy(cp1, cp, 5*INT32SZ);
|
||||
cp += 5*INT32SZ;
|
||||
cp1 += 5*INT32SZ;
|
||||
rdatasize = (u_char *)cp1 - soardata;
|
||||
zptr = calloc(1, sizeof(struct zonegrp));
|
||||
if (zptr == NULL)
|
||||
return (-1);
|
||||
if (zgrp_start == NULL)
|
||||
zgrp_start = zptr;
|
||||
else
|
||||
prevzptr->z_next = zptr;
|
||||
zptr->z_rr = rrecp;
|
||||
rrecp->r_grpnext = NULL;
|
||||
strcpy(zptr->z_origin, zname);
|
||||
zptr->z_class = class;
|
||||
memcpy(zptr->z_soardata, soardata, rdatasize);
|
||||
/* fallthrough to process NS and A records */
|
||||
}
|
||||
} else if (qtype == T_NS) {
|
||||
if (rcode == NOERROR && ancount > 0) {
|
||||
strcpy(zname, dname);
|
||||
for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
|
||||
if (strcasecmp(zname, zptr->z_origin) == 0)
|
||||
break;
|
||||
}
|
||||
if (zptr == NULL)
|
||||
/* should not happen */
|
||||
return (-1);
|
||||
if (nscount > 0) {
|
||||
/*
|
||||
* answer and authority sections contain
|
||||
* the same information, skip answer section
|
||||
*/
|
||||
for (j = 0; j < ancount; j++) {
|
||||
n = dn_skipname(cp, eom);
|
||||
if (n < 0)
|
||||
return (-1);
|
||||
n += 2*INT16SZ + INT32SZ;
|
||||
if (cp + n + INT16SZ > eom)
|
||||
return (-1);
|
||||
cp += n;
|
||||
GETSHORT(dlen, cp);
|
||||
cp += dlen;
|
||||
}
|
||||
} else
|
||||
nscount = ancount;
|
||||
/* fallthrough to process NS and A records */
|
||||
} else {
|
||||
fprintf(stderr, "cannot determine nameservers for %s:\
|
||||
ans=%d, auth=%d, add=%d, rcode=%d\n",
|
||||
dname, ancount, nscount, arcount, hp->rcode);
|
||||
return (-1);
|
||||
}
|
||||
} else if (qtype == T_A) {
|
||||
if (rcode == NOERROR && ancount > 0) {
|
||||
arcount = ancount;
|
||||
ancount = nscount = 0;
|
||||
/* fallthrough to process A records */
|
||||
} else {
|
||||
fprintf(stderr, "cannot determine address for %s:\
|
||||
ans=%d, auth=%d, add=%d, rcode=%d\n",
|
||||
dname, ancount, nscount, arcount, hp->rcode);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
/* process NS records for the zone */
|
||||
j = 0;
|
||||
for (i = 0; i < nscount; i++) {
|
||||
if ((n = dn_expand(answer, eom, cp, name,
|
||||
sizeof name)) < 0)
|
||||
return (n);
|
||||
cp += n;
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom)
|
||||
return (-1);
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
GETLONG(ttl, cp);
|
||||
GETSHORT(dlen, cp);
|
||||
if (cp + dlen > eom)
|
||||
return (-1);
|
||||
if (strcasecmp(name, zname) == 0 &&
|
||||
type == T_NS && class == qclass) {
|
||||
if ((n = dn_expand(answer, eom, cp,
|
||||
name, sizeof name)) < 0)
|
||||
return (n);
|
||||
target = zptr->z_ns[j++].nsname;
|
||||
strcpy(target, name);
|
||||
}
|
||||
cp += dlen;
|
||||
}
|
||||
if (zptr->z_nscount == 0)
|
||||
zptr->z_nscount = j;
|
||||
/* get addresses for the nameservers */
|
||||
for (i = 0; i < arcount; i++) {
|
||||
if ((n = dn_expand(answer, eom, cp, name,
|
||||
sizeof name)) < 0)
|
||||
return (n);
|
||||
cp += n;
|
||||
if (cp + 3 * INT16SZ + INT32SZ > eom)
|
||||
return (-1);
|
||||
GETSHORT(type, cp);
|
||||
GETSHORT(class, cp);
|
||||
GETLONG(ttl, cp);
|
||||
GETSHORT(dlen, cp);
|
||||
if (cp + dlen > eom)
|
||||
return (-1);
|
||||
if (type == T_A && dlen == INT32SZ && class == qclass) {
|
||||
for (j = 0; j < zptr->z_nscount; j++)
|
||||
if (strcasecmp(name, zptr->z_ns[j].nsname) == 0) {
|
||||
memcpy(&zptr->z_ns[j].nsaddr1.s_addr, cp,
|
||||
INT32SZ);
|
||||
break;
|
||||
}
|
||||
}
|
||||
cp += dlen;
|
||||
}
|
||||
if (zptr->z_nscount == 0) {
|
||||
dname = zname;
|
||||
qtype = T_NS;
|
||||
continue;
|
||||
}
|
||||
done = 1;
|
||||
for (k = 0; k < zptr->z_nscount; k++)
|
||||
if (zptr->z_ns[k].nsaddr1.s_addr == 0) {
|
||||
done = 0;
|
||||
dname = zptr->z_ns[k].nsname;
|
||||
qtype = T_A;
|
||||
}
|
||||
|
||||
} /* while */
|
||||
}
|
||||
|
||||
_res.options |= RES_DEBUG;
|
||||
for (zptr = zgrp_start; zptr; zptr = zptr->z_next) {
|
||||
|
||||
/* append zone section */
|
||||
rrecp = res_mkupdrec(ns_s_zn, zptr->z_origin,
|
||||
zptr->z_class, ns_t_soa, 0);
|
||||
if (rrecp == NULL) {
|
||||
fprintf(stderr, "saverrec error\n");
|
||||
fflush(stderr);
|
||||
return (-1);
|
||||
}
|
||||
rrecp->r_grpnext = zptr->z_rr;
|
||||
zptr->z_rr = rrecp;
|
||||
|
||||
n = res_mkupdate(zptr->z_rr, packet, sizeof packet);
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "res_mkupdate error\n");
|
||||
fflush(stderr);
|
||||
return (-1);
|
||||
} else
|
||||
fprintf(stdout, "res_mkupdate: packet size = %d\n", n);
|
||||
|
||||
/*
|
||||
* Override the list of NS records from res_init() with
|
||||
* the authoritative nameservers for the zone being updated.
|
||||
* Sort primary to be the first in the list of nameservers.
|
||||
*/
|
||||
for (i = 0; i < zptr->z_nscount; i++) {
|
||||
if (strcasecmp(zptr->z_ns[i].nsname,
|
||||
zptr->z_soardata) == 0) {
|
||||
struct in_addr tmpaddr;
|
||||
|
||||
if (i != 0) {
|
||||
strcpy(zptr->z_ns[i].nsname,
|
||||
zptr->z_ns[0].nsname);
|
||||
strcpy(zptr->z_ns[0].nsname,
|
||||
zptr->z_soardata);
|
||||
tmpaddr = zptr->z_ns[i].nsaddr1;
|
||||
zptr->z_ns[i].nsaddr1 =
|
||||
zptr->z_ns[0].nsaddr1;
|
||||
zptr->z_ns[0].nsaddr1 = tmpaddr;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < MAXNS; i++) {
|
||||
_res.nsaddr_list[i].sin_addr = zptr->z_ns[i].nsaddr1;
|
||||
_res.nsaddr_list[i].sin_family = AF_INET;
|
||||
_res.nsaddr_list[i].sin_port = htons(NAMESERVER_PORT);
|
||||
}
|
||||
_res.nscount = (zptr->z_nscount < MAXNS) ?
|
||||
zptr->z_nscount : MAXNS;
|
||||
n = res_send(packet, n, answer, sizeof(answer));
|
||||
if (n < 0) {
|
||||
fprintf(stderr, "res_send: send error, n=%d\n", n);
|
||||
break;
|
||||
} else
|
||||
numzones++;
|
||||
}
|
||||
|
||||
/* free malloc'ed memory */
|
||||
while(zgrp_start) {
|
||||
zptr = zgrp_start;
|
||||
zgrp_start = zgrp_start->z_next;
|
||||
res_freeupdrec(zptr->z_rr); /* Zone section we allocated. */
|
||||
free((char *)zptr);
|
||||
}
|
||||
|
||||
return (numzones);
|
||||
}
|
||||
351
c/src/exec/libnetworking/libc/resolver.3
Normal file
351
c/src/exec/libnetworking/libc/resolver.3
Normal file
@@ -0,0 +1,351 @@
|
||||
.\" Copyright (c) 1985, 1991, 1993
|
||||
.\" The Regents of the University of California. All rights reserved.
|
||||
.\"
|
||||
.\" Redistribution and use in source and binary forms, with or without
|
||||
.\" modification, are permitted provided that the following conditions
|
||||
.\" are met:
|
||||
.\" 1. Redistributions of source code must retain the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer.
|
||||
.\" 2. Redistributions in binary form must reproduce the above copyright
|
||||
.\" notice, this list of conditions and the following disclaimer in the
|
||||
.\" documentation and/or other materials provided with the distribution.
|
||||
.\" 3. All advertising materials mentioning features or use of this software
|
||||
.\" must display the following acknowledgement:
|
||||
.\" This product includes software developed by the University of
|
||||
.\" California, Berkeley and its contributors.
|
||||
.\" 4. Neither the name of the University nor the names of its contributors
|
||||
.\" may be used to endorse or promote products derived from this software
|
||||
.\" without specific prior written permission.
|
||||
.\"
|
||||
.\" THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
.\" ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
.\" IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
.\" ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
.\" FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
.\" DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
.\" OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
.\" HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
.\" LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
.\" OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
.\" SUCH DAMAGE.
|
||||
.\"
|
||||
.\" @(#)resolver.3 8.1 (Berkeley) 6/4/93
|
||||
.\"
|
||||
.Dd June 4, 1993
|
||||
.Dt RESOLVER 3
|
||||
.Os BSD 4.3
|
||||
.Sh NAME
|
||||
.Nm res_query ,
|
||||
.Nm res_search ,
|
||||
.Nm res_mkquery ,
|
||||
.Nm res_send ,
|
||||
.Nm res_init ,
|
||||
.Nm dn_comp ,
|
||||
.Nm dn_expand
|
||||
.Nd resolver routines
|
||||
.Sh SYNOPSIS
|
||||
.Fd #include <sys/types.h>
|
||||
.Fd #include <netinet/in.h>
|
||||
.Fd #include <arpa/nameser.h>
|
||||
.Fd #include <resolv.h>
|
||||
.Ft int
|
||||
.Fo res_query
|
||||
.Fa "const char *dname"
|
||||
.Fa "int class"
|
||||
.Fa "int type"
|
||||
.Fa "u_char *answer"
|
||||
.Fa "int anslen"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo res_search
|
||||
.Fa "const char *dname"
|
||||
.Fa "int class"
|
||||
.Fa "int type"
|
||||
.Fa "u_char *answer"
|
||||
.Fa "int anslen"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo res_mkquery
|
||||
.Fa "int op"
|
||||
.Fa "const char *dname"
|
||||
.Fa "int class"
|
||||
.Fa "int type"
|
||||
.Fa "const u_char *data"
|
||||
.Fa "int datalen"
|
||||
.Fa "const u_char *newrr_in"
|
||||
.Fa "u_char *buf"
|
||||
.Fa "int buflen"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo res_send
|
||||
.Fa "const u_char *msg"
|
||||
.Fa "int msglen"
|
||||
.Fa "u_char *answer"
|
||||
.Fa "int anslen"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fn res_init
|
||||
.Fo dn_comp
|
||||
.Fa "const char *exp_dn"
|
||||
.Fa "u_char *comp_dn"
|
||||
.Fa "int length"
|
||||
.Fa "u_char **dnptrs"
|
||||
.Fa "u_char **lastdnptr"
|
||||
.Fc
|
||||
.Ft int
|
||||
.Fo dn_expand
|
||||
.Fa "const u_char *msg"
|
||||
.Fa "const u_char *eomorig"
|
||||
.Fa "const u_char *comp_dn"
|
||||
.Fa "char *exp_dn"
|
||||
.Fa "int length"
|
||||
.Fc
|
||||
.Sh DESCRIPTION
|
||||
These routines are used for making, sending and interpreting
|
||||
query and reply messages with Internet domain name servers.
|
||||
.Pp
|
||||
Global configuration and state information that is used by the
|
||||
resolver routines is kept in the structure
|
||||
.Em _res .
|
||||
Most of the values have reasonable defaults and can be ignored.
|
||||
Options
|
||||
stored in
|
||||
.Em _res.options
|
||||
are defined in
|
||||
.Pa resolv.h
|
||||
and are as follows.
|
||||
Options are stored as a simple bit mask containing the bitwise ``or''
|
||||
of the options enabled.
|
||||
.Bl -tag -width RES_DEFNAMES
|
||||
.It Dv RES_INIT
|
||||
True if the initial name server address and default domain name are
|
||||
initialized (i.e.,
|
||||
.Fn res_init
|
||||
has been called).
|
||||
.It Dv RES_DEBUG
|
||||
Print debugging messages.
|
||||
.It Dv RES_AAONLY
|
||||
Accept authoritative answers only.
|
||||
With this option,
|
||||
.Fn res_send
|
||||
should continue until it finds an authoritative answer or finds an error.
|
||||
Currently this is not implemented.
|
||||
.It Dv RES_USEVC
|
||||
Use
|
||||
.Tn TCP
|
||||
connections for queries instead of
|
||||
.Tn UDP
|
||||
datagrams.
|
||||
.It Dv RES_STAYOPEN
|
||||
Used with
|
||||
.Dv RES_USEVC
|
||||
to keep the
|
||||
.Tn TCP
|
||||
connection open between
|
||||
queries.
|
||||
This is useful only in programs that regularly do many queries.
|
||||
.Tn UDP
|
||||
should be the normal mode used.
|
||||
.It Dv RES_IGNTC
|
||||
Unused currently (ignore truncation errors, i.e., don't retry with
|
||||
.Tn TCP ) .
|
||||
.It Dv RES_RECURSE
|
||||
Set the recursion-desired bit in queries.
|
||||
This is the default.
|
||||
.Pf ( Fn res_send
|
||||
does not do iterative queries and expects the name server
|
||||
to handle recursion.)
|
||||
.It Dv RES_DEFNAMES
|
||||
If set,
|
||||
.Fn res_search
|
||||
will append the default domain name to single-component names
|
||||
(those that do not contain a dot).
|
||||
This option is enabled by default.
|
||||
.It Dv RES_DNSRCH
|
||||
If this option is set,
|
||||
.Fn res_search
|
||||
will search for host names in the current domain and in parent domains; see
|
||||
.Xr hostname 7 .
|
||||
This is used by the standard host lookup routine
|
||||
.Xr gethostbyname 3 .
|
||||
This option is enabled by default.
|
||||
.It Dv RES_NOALIASES
|
||||
This option turns off the user level aliasing feature controlled by the
|
||||
.Dq Ev HOSTALIASES
|
||||
environment variable. Network daemons should set this option.
|
||||
.El
|
||||
.Pp
|
||||
The
|
||||
.Fn res_init
|
||||
routine
|
||||
reads the configuration file (if any; see
|
||||
.Xr resolver 5 )
|
||||
to get the default domain name,
|
||||
search list and
|
||||
the Internet address of the local name server(s).
|
||||
If no server is configured, the host running
|
||||
the resolver is tried.
|
||||
The current domain name is defined by the hostname
|
||||
if not specified in the configuration file;
|
||||
it can be overridden by the environment variable
|
||||
.Ev LOCALDOMAIN .
|
||||
This environment variable may contain several blank-separated
|
||||
tokens if you wish to override the
|
||||
.Em "search list"
|
||||
on a per-process basis. This is similar to the
|
||||
.Em search
|
||||
command in the configuration file.
|
||||
Another environment variable (
|
||||
.Dq Ev RES_OPTIONS
|
||||
can be set to
|
||||
override certain internal resolver options which are otherwise
|
||||
set by changing fields in the
|
||||
.Em _res
|
||||
structure or are inherited from the configuration file's
|
||||
.Em options
|
||||
command. The syntax of the
|
||||
.Dq Ev RES_OPTIONS
|
||||
environment variable is explained in
|
||||
.Xr resolver 5 .
|
||||
Initialization normally occurs on the first call
|
||||
to one of the following routines.
|
||||
.Pp
|
||||
The
|
||||
.Fn res_query
|
||||
function provides an interface to the server query mechanism.
|
||||
It constructs a query, sends it to the local server,
|
||||
awaits a response, and makes preliminary checks on the reply.
|
||||
The query requests information of the specified
|
||||
.Fa type
|
||||
and
|
||||
.Fa class
|
||||
for the specified fully-qualified domain name
|
||||
.Fa dname .
|
||||
The reply message is left in the
|
||||
.Fa answer
|
||||
buffer with length
|
||||
.Fa anslen
|
||||
supplied by the caller.
|
||||
.Pp
|
||||
The
|
||||
.Fn res_search
|
||||
routine makes a query and awaits a response like
|
||||
.Fn res_query ,
|
||||
but in addition, it implements the default and search rules
|
||||
controlled by the
|
||||
.Dv RES_DEFNAMES
|
||||
and
|
||||
.Dv RES_DNSRCH
|
||||
options.
|
||||
It returns the first successful reply.
|
||||
.Pp
|
||||
The remaining routines are lower-level routines used by
|
||||
.Fn res_query .
|
||||
The
|
||||
.Fn res_mkquery
|
||||
function
|
||||
constructs a standard query message and places it in
|
||||
.Fa buf .
|
||||
It returns the size of the query, or \-1 if the query is
|
||||
larger than
|
||||
.Fa buflen .
|
||||
The query type
|
||||
.Fa op
|
||||
is usually
|
||||
.Dv QUERY ,
|
||||
but can be any of the query types defined in
|
||||
.Aq Pa arpa/nameser.h .
|
||||
The domain name for the query is given by
|
||||
.Fa dname .
|
||||
.Fa Newrr
|
||||
is currently unused but is intended for making update messages.
|
||||
.Pp
|
||||
The
|
||||
.Fn res_send
|
||||
routine
|
||||
sends a pre-formatted query and returns an answer.
|
||||
It will call
|
||||
.Fn res_init
|
||||
if
|
||||
.Dv RES_INIT
|
||||
is not set, send the query to the local name server, and
|
||||
handle timeouts and retries.
|
||||
The length of the reply message is returned, or
|
||||
\-1 if there were errors.
|
||||
.Pp
|
||||
The
|
||||
.Fn dn_comp
|
||||
function
|
||||
compresses the domain name
|
||||
.Fa exp_dn
|
||||
and stores it in
|
||||
.Fa comp_dn .
|
||||
The size of the compressed name is returned or \-1 if there were errors.
|
||||
The size of the array pointed to by
|
||||
.Fa comp_dn
|
||||
is given by
|
||||
.Fa length .
|
||||
The compression uses
|
||||
an array of pointers
|
||||
.Fa dnptrs
|
||||
to previously-compressed names in the current message.
|
||||
The first pointer points to
|
||||
to the beginning of the message and the list ends with
|
||||
.Dv NULL .
|
||||
The limit to the array is specified by
|
||||
.Fa lastdnptr .
|
||||
A side effect of
|
||||
.Fn dn_comp
|
||||
is to update the list of pointers for
|
||||
labels inserted into the message
|
||||
as the name is compressed.
|
||||
If
|
||||
.Em dnptr
|
||||
is
|
||||
.Dv NULL, names are not compressed.
|
||||
If
|
||||
.Fa lastdnptr
|
||||
is
|
||||
.Dv NULL ,
|
||||
the list of labels is not updated.
|
||||
.Pp
|
||||
The
|
||||
.Fn dn_expand
|
||||
entry
|
||||
expands the compressed domain name
|
||||
.Fa comp_dn
|
||||
to a full domain name
|
||||
The compressed name is contained in a query or reply message;
|
||||
.Fa msg
|
||||
is a pointer to the beginning of the message.
|
||||
The uncompressed name is placed in the buffer indicated by
|
||||
.Fa exp_dn
|
||||
which is of size
|
||||
.Fa length .
|
||||
The size of compressed name is returned or \-1 if there was an error.
|
||||
.Sh FILES
|
||||
.Bl -tag -width Pa
|
||||
/etc/resolv.conf
|
||||
The configuration file
|
||||
see
|
||||
.Xr resolver 5 .
|
||||
.El
|
||||
.Sh SEE ALSO
|
||||
.Xr gethostbyname 3 ,
|
||||
.Xr resolver 5 ,
|
||||
.Xr hostname 7 ,
|
||||
.Xr named 8
|
||||
.Pp
|
||||
.%T RFC1032 ,
|
||||
.%T RFC1033 ,
|
||||
.%T RFC1034 ,
|
||||
.%T RFC1035 ,
|
||||
.%T RFC974
|
||||
.Rs
|
||||
.%T "Name Server Operations Guide for BIND"
|
||||
.Re
|
||||
.Sh HISTORY
|
||||
The
|
||||
.Nm
|
||||
function appeared in
|
||||
.Bx 4.3 .
|
||||
50
c/src/exec/libnetworking/libc/send.c
Normal file
50
c/src/exec/libnetworking/libc/send.c
Normal file
@@ -0,0 +1,50 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static char sccsid[] = "@(#)send.c 8.2 (Berkeley) 2/21/94";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/socket.h>
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
ssize_t
|
||||
send(s, msg, len, flags)
|
||||
int s, flags;
|
||||
size_t len;
|
||||
const void *msg;
|
||||
{
|
||||
return (sendto(s, msg, len, flags, NULL, 0));
|
||||
}
|
||||
85
c/src/exec/libnetworking/libc/strsep.c
Normal file
85
c/src/exec/libnetworking/libc/strsep.c
Normal file
@@ -0,0 +1,85 @@
|
||||
/*-
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "config.h"
|
||||
|
||||
#if defined(LIBC_SCCS) && !defined(lint)
|
||||
static const char sccsid[] = "@(#)strsep.c 8.1 (Berkeley) 6/4/93";
|
||||
#endif /* LIBC_SCCS and not lint */
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
|
||||
/*
|
||||
* Get next token from string *stringp, where tokens are possibly-empty
|
||||
* strings separated by characters from delim.
|
||||
*
|
||||
* Writes NULs into the string at *stringp to end tokens.
|
||||
* delim need not remain constant from call to call.
|
||||
* On return, *stringp points past the last NUL written (if there might
|
||||
* be further tokens), or is NULL (if there are definitely no more tokens).
|
||||
*
|
||||
* If *stringp is NULL, strsep returns NULL.
|
||||
*
|
||||
* PUBLIC: #ifndef HAVE_STRSEP
|
||||
* PUBLIC: char *strsep __P((char **, const char *));
|
||||
* PUBLIC: #endif
|
||||
*/
|
||||
char *
|
||||
strsep(stringp, delim)
|
||||
register char **stringp;
|
||||
register const char *delim;
|
||||
{
|
||||
register char *s;
|
||||
register const char *spanp;
|
||||
register int c, sc;
|
||||
char *tok;
|
||||
|
||||
if ((s = *stringp) == NULL)
|
||||
return (NULL);
|
||||
for (tok = s;;) {
|
||||
c = *s++;
|
||||
spanp = delim;
|
||||
do {
|
||||
if ((sc = *spanp++) == c) {
|
||||
if (c == 0)
|
||||
s = NULL;
|
||||
else
|
||||
s[-1] = 0;
|
||||
*stringp = s;
|
||||
return (tok);
|
||||
}
|
||||
} while (sc != 0);
|
||||
}
|
||||
/* NOTREACHED */
|
||||
}
|
||||
1
c/src/exec/libnetworking/loop.h
Normal file
1
c/src/exec/libnetworking/loop.h
Normal file
@@ -0,0 +1 @@
|
||||
#define NLOOP 1
|
||||
236
c/src/exec/libnetworking/net/bpf.h
Normal file
236
c/src/exec/libnetworking/net/bpf.h
Normal file
@@ -0,0 +1,236 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1991, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* This code is derived from the Stanford/CMU enet packet filter,
|
||||
* (net/enet.c) distributed as part of 4.3BSD, and code contributed
|
||||
* to Berkeley by Steven McCanne and Van Jacobson both of Lawrence
|
||||
* Berkeley Laboratory.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)bpf.h 8.1 (Berkeley) 6/10/93
|
||||
* @(#)bpf.h 1.34 (LBL) 6/16/96
|
||||
*
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_BPF_H_
|
||||
#define _NET_BPF_H_
|
||||
|
||||
/* BSD style release date */
|
||||
#define BPF_RELEASE 199606
|
||||
|
||||
typedef int32_t bpf_int32;
|
||||
typedef u_int32_t bpf_u_int32;
|
||||
|
||||
/*
|
||||
* Alignment macros. BPF_WORDALIGN rounds up to the next
|
||||
* even multiple of BPF_ALIGNMENT.
|
||||
*/
|
||||
#define BPF_ALIGNMENT sizeof(bpf_int32)
|
||||
#define BPF_WORDALIGN(x) (((x)+(BPF_ALIGNMENT-1))&~(BPF_ALIGNMENT-1))
|
||||
|
||||
#define BPF_MAXINSNS 512
|
||||
#define BPF_MAXBUFSIZE 0x8000
|
||||
#define BPF_MINBUFSIZE 32
|
||||
|
||||
/*
|
||||
* Structure for BIOCSETF.
|
||||
*/
|
||||
struct bpf_program {
|
||||
u_int bf_len;
|
||||
struct bpf_insn *bf_insns;
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct returned by BIOCGSTATS.
|
||||
*/
|
||||
struct bpf_stat {
|
||||
u_int bs_recv; /* number of packets received */
|
||||
u_int bs_drop; /* number of packets dropped */
|
||||
};
|
||||
|
||||
/*
|
||||
* Struct return by BIOCVERSION. This represents the version number of
|
||||
* the filter language described by the instruction encodings below.
|
||||
* bpf understands a program iff kernel_major == filter_major &&
|
||||
* kernel_minor >= filter_minor, that is, if the value returned by the
|
||||
* running kernel has the same major number and a minor number equal
|
||||
* equal to or less than the filter being downloaded. Otherwise, the
|
||||
* results are undefined, meaning an error may be returned or packets
|
||||
* may be accepted haphazardly.
|
||||
* It has nothing to do with the source code version.
|
||||
*/
|
||||
struct bpf_version {
|
||||
u_short bv_major;
|
||||
u_short bv_minor;
|
||||
};
|
||||
/* Current version number of filter architecture. */
|
||||
#define BPF_MAJOR_VERSION 1
|
||||
#define BPF_MINOR_VERSION 1
|
||||
|
||||
#define BIOCGBLEN _IOR('B',102, u_int)
|
||||
#define BIOCSBLEN _IOWR('B',102, u_int)
|
||||
#define BIOCSETF _IOW('B',103, struct bpf_program)
|
||||
#define BIOCFLUSH _IO('B',104)
|
||||
#define BIOCPROMISC _IO('B',105)
|
||||
#define BIOCGDLT _IOR('B',106, u_int)
|
||||
#define BIOCGETIF _IOR('B',107, struct ifreq)
|
||||
#define BIOCSETIF _IOW('B',108, struct ifreq)
|
||||
#define BIOCSRTIMEOUT _IOW('B',109, struct timeval)
|
||||
#define BIOCGRTIMEOUT _IOR('B',110, struct timeval)
|
||||
#define BIOCGSTATS _IOR('B',111, struct bpf_stat)
|
||||
#define BIOCIMMEDIATE _IOW('B',112, u_int)
|
||||
#define BIOCVERSION _IOR('B',113, struct bpf_version)
|
||||
#define BIOCGRSIG _IOR('B',114, u_int)
|
||||
#define BIOCSRSIG _IOW('B',115, u_int)
|
||||
|
||||
/*
|
||||
* Structure prepended to each packet.
|
||||
*/
|
||||
struct bpf_hdr {
|
||||
struct timeval bh_tstamp; /* time stamp */
|
||||
bpf_u_int32 bh_caplen; /* length of captured portion */
|
||||
bpf_u_int32 bh_datalen; /* original length of packet */
|
||||
u_short bh_hdrlen; /* length of bpf header (this struct
|
||||
plus alignment padding) */
|
||||
};
|
||||
/*
|
||||
* Because the structure above is not a multiple of 4 bytes, some compilers
|
||||
* will insist on inserting padding; hence, sizeof(struct bpf_hdr) won't work.
|
||||
* Only the kernel needs to know about it; applications use bh_hdrlen.
|
||||
*/
|
||||
#ifdef KERNEL
|
||||
#define SIZEOF_BPF_HDR 18
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Data-link level type codes.
|
||||
*/
|
||||
#define DLT_NULL 0 /* no link-layer encapsulation */
|
||||
#define DLT_EN10MB 1 /* Ethernet (10Mb) */
|
||||
#define DLT_EN3MB 2 /* Experimental Ethernet (3Mb) */
|
||||
#define DLT_AX25 3 /* Amateur Radio AX.25 */
|
||||
#define DLT_PRONET 4 /* Proteon ProNET Token Ring */
|
||||
#define DLT_CHAOS 5 /* Chaos */
|
||||
#define DLT_IEEE802 6 /* IEEE 802 Networks */
|
||||
#define DLT_ARCNET 7 /* ARCNET */
|
||||
#define DLT_SLIP 8 /* Serial Line IP */
|
||||
#define DLT_PPP 9 /* Point-to-point Protocol */
|
||||
#define DLT_FDDI 10 /* FDDI */
|
||||
#define DLT_ATM_RFC1483 11 /* LLC/SNAP encapsulated atm */
|
||||
|
||||
/*
|
||||
* The instruction encodings.
|
||||
*/
|
||||
/* instruction classes */
|
||||
#define BPF_CLASS(code) ((code) & 0x07)
|
||||
#define BPF_LD 0x00
|
||||
#define BPF_LDX 0x01
|
||||
#define BPF_ST 0x02
|
||||
#define BPF_STX 0x03
|
||||
#define BPF_ALU 0x04
|
||||
#define BPF_JMP 0x05
|
||||
#define BPF_RET 0x06
|
||||
#define BPF_MISC 0x07
|
||||
|
||||
/* ld/ldx fields */
|
||||
#define BPF_SIZE(code) ((code) & 0x18)
|
||||
#define BPF_W 0x00
|
||||
#define BPF_H 0x08
|
||||
#define BPF_B 0x10
|
||||
#define BPF_MODE(code) ((code) & 0xe0)
|
||||
#define BPF_IMM 0x00
|
||||
#define BPF_ABS 0x20
|
||||
#define BPF_IND 0x40
|
||||
#define BPF_MEM 0x60
|
||||
#define BPF_LEN 0x80
|
||||
#define BPF_MSH 0xa0
|
||||
|
||||
/* alu/jmp fields */
|
||||
#define BPF_OP(code) ((code) & 0xf0)
|
||||
#define BPF_ADD 0x00
|
||||
#define BPF_SUB 0x10
|
||||
#define BPF_MUL 0x20
|
||||
#define BPF_DIV 0x30
|
||||
#define BPF_OR 0x40
|
||||
#define BPF_AND 0x50
|
||||
#define BPF_LSH 0x60
|
||||
#define BPF_RSH 0x70
|
||||
#define BPF_NEG 0x80
|
||||
#define BPF_JA 0x00
|
||||
#define BPF_JEQ 0x10
|
||||
#define BPF_JGT 0x20
|
||||
#define BPF_JGE 0x30
|
||||
#define BPF_JSET 0x40
|
||||
#define BPF_SRC(code) ((code) & 0x08)
|
||||
#define BPF_K 0x00
|
||||
#define BPF_X 0x08
|
||||
|
||||
/* ret - BPF_K and BPF_X also apply */
|
||||
#define BPF_RVAL(code) ((code) & 0x18)
|
||||
#define BPF_A 0x10
|
||||
|
||||
/* misc */
|
||||
#define BPF_MISCOP(code) ((code) & 0xf8)
|
||||
#define BPF_TAX 0x00
|
||||
#define BPF_TXA 0x80
|
||||
|
||||
/*
|
||||
* The instruction data structure.
|
||||
*/
|
||||
struct bpf_insn {
|
||||
u_short code;
|
||||
u_char jt;
|
||||
u_char jf;
|
||||
bpf_u_int32 k;
|
||||
};
|
||||
|
||||
/*
|
||||
* Macros for insn array initializers.
|
||||
*/
|
||||
#define BPF_STMT(code, k) { (u_short)(code), 0, 0, k }
|
||||
#define BPF_JUMP(code, k, jt, jf) { (u_short)(code), jt, jf, k }
|
||||
|
||||
#ifdef KERNEL
|
||||
int bpf_validate __P((struct bpf_insn *, int));
|
||||
void bpf_tap __P((struct ifnet *, u_char *, u_int));
|
||||
void bpf_mtap __P((struct ifnet *, struct mbuf *));
|
||||
void bpfattach __P((struct ifnet *, u_int, u_int));
|
||||
void bpfilterattach __P((int));
|
||||
u_int bpf_filter __P((struct bpf_insn *, u_char *, u_int, u_int));
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Number of scratch memory words (for BPF_LD|BPF_MEM and BPF_ST).
|
||||
*/
|
||||
#define BPF_MEMWORDS 16
|
||||
|
||||
#endif
|
||||
63
c/src/exec/libnetworking/net/ethernet.h
Normal file
63
c/src/exec/libnetworking/net/ethernet.h
Normal file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Fundamental constants relating to ethernet.
|
||||
*
|
||||
* $Id$
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef _NET_ETHERNET_H_
|
||||
#define _NET_ETHERNET_H_
|
||||
|
||||
/*
|
||||
* The number of bytes in an ethernet (MAC) address.
|
||||
*/
|
||||
#define ETHER_ADDR_LEN 6
|
||||
|
||||
/*
|
||||
* The number of bytes in the type field.
|
||||
*/
|
||||
#define ETHER_TYPE_LEN 2
|
||||
|
||||
/*
|
||||
* The number of bytes in the trailing CRC field.
|
||||
*/
|
||||
#define ETHER_CRC_LEN 4
|
||||
|
||||
/*
|
||||
* The length of the combined header.
|
||||
*/
|
||||
#define ETHER_HDR_LEN (ETHER_ADDR_LEN*2+ETHER_TYPE_LEN)
|
||||
|
||||
/*
|
||||
* The minimum packet length.
|
||||
*/
|
||||
#define ETHER_MIN_LEN 64
|
||||
|
||||
/*
|
||||
* The maximum packet length.
|
||||
*/
|
||||
#define ETHER_MAX_LEN 1518
|
||||
|
||||
/*
|
||||
* A macro to validate a length with
|
||||
*/
|
||||
#define ETHER_IS_VALID_LEN(foo) \
|
||||
((foo) >= ETHER_MIN_LEN && (foo) <= ETHER_MAX_LEN)
|
||||
|
||||
/*
|
||||
* Structure of a 10Mb/s Ethernet header.
|
||||
*/
|
||||
struct ether_header {
|
||||
u_char ether_dhost[ETHER_ADDR_LEN];
|
||||
u_char ether_shost[ETHER_ADDR_LEN];
|
||||
u_short ether_type;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure of a 48-bit Ethernet address.
|
||||
*/
|
||||
struct ether_addr {
|
||||
u_char octet[ETHER_ADDR_LEN];
|
||||
};
|
||||
|
||||
#endif
|
||||
783
c/src/exec/libnetworking/net/if.c
Normal file
783
c/src/exec/libnetworking/net/if.c
Normal file
@@ -0,0 +1,783 @@
|
||||
/*
|
||||
* Copyright (c) 1980, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if.c 8.3 (Berkeley) 1/4/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/proc.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/socketvar.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/radix.h>
|
||||
|
||||
/*
|
||||
* System initialization
|
||||
*/
|
||||
|
||||
static int ifconf __P((int, caddr_t));
|
||||
void ifinit __P((void *));
|
||||
static void if_qflush __P((struct ifqueue *));
|
||||
static void if_slowtimo __P((void *));
|
||||
static void link_rtrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
|
||||
SYSINIT(interfaces, SI_SUB_PROTO_IF, SI_ORDER_FIRST, ifinit, NULL)
|
||||
|
||||
|
||||
int ifqmaxlen = IFQ_MAXLEN;
|
||||
struct ifnet *ifnet;
|
||||
|
||||
/*
|
||||
* Network interface utility routines.
|
||||
*
|
||||
* Routines with ifa_ifwith* names take sockaddr *'s as
|
||||
* parameters.
|
||||
*
|
||||
* This routine assumes that it will be called at splimp() or higher.
|
||||
*/
|
||||
/* ARGSUSED*/
|
||||
void
|
||||
ifinit(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next)
|
||||
if (ifp->if_snd.ifq_maxlen == 0)
|
||||
ifp->if_snd.ifq_maxlen = ifqmaxlen;
|
||||
if_slowtimo(0);
|
||||
}
|
||||
|
||||
int if_index = 0;
|
||||
struct ifaddr **ifnet_addrs;
|
||||
|
||||
|
||||
/*
|
||||
* Attach an interface to the
|
||||
* list of "active" interfaces.
|
||||
*/
|
||||
void
|
||||
if_attach(ifp)
|
||||
struct ifnet *ifp;
|
||||
{
|
||||
unsigned socksize, ifasize;
|
||||
int namelen, masklen;
|
||||
char workbuf[64];
|
||||
register struct ifnet **p = &ifnet;
|
||||
register struct sockaddr_dl *sdl;
|
||||
register struct ifaddr *ifa;
|
||||
static int if_indexlim = 8;
|
||||
|
||||
|
||||
while (*p)
|
||||
p = &((*p)->if_next);
|
||||
*p = ifp;
|
||||
ifp->if_index = ++if_index;
|
||||
microtime(&ifp->if_lastchange);
|
||||
if (ifnet_addrs == 0 || if_index >= if_indexlim) {
|
||||
unsigned n = (if_indexlim <<= 1) * sizeof(ifa);
|
||||
struct ifaddr **q = (struct ifaddr **)
|
||||
malloc(n, M_IFADDR, M_WAITOK);
|
||||
bzero((caddr_t)q, n);
|
||||
if (ifnet_addrs) {
|
||||
bcopy((caddr_t)ifnet_addrs, (caddr_t)q, n/2);
|
||||
free((caddr_t)ifnet_addrs, M_IFADDR);
|
||||
}
|
||||
ifnet_addrs = q;
|
||||
}
|
||||
/*
|
||||
* create a Link Level name for this device
|
||||
*/
|
||||
namelen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
|
||||
#define _offsetof(t, m) ((int)((caddr_t)&((t *)0)->m))
|
||||
masklen = _offsetof(struct sockaddr_dl, sdl_data[0]) + namelen;
|
||||
socksize = masklen + ifp->if_addrlen;
|
||||
#define ROUNDUP(a) (1 + (((a) - 1) | (sizeof(long) - 1)))
|
||||
socksize = ROUNDUP(socksize);
|
||||
if (socksize < sizeof(*sdl))
|
||||
socksize = sizeof(*sdl);
|
||||
ifasize = sizeof(*ifa) + 2 * socksize;
|
||||
ifa = (struct ifaddr *)malloc(ifasize, M_IFADDR, M_WAITOK);
|
||||
if (ifa) {
|
||||
bzero((caddr_t)ifa, ifasize);
|
||||
sdl = (struct sockaddr_dl *)(ifa + 1);
|
||||
sdl->sdl_len = socksize;
|
||||
sdl->sdl_family = AF_LINK;
|
||||
bcopy(workbuf, sdl->sdl_data, namelen);
|
||||
sdl->sdl_nlen = namelen;
|
||||
sdl->sdl_index = ifp->if_index;
|
||||
sdl->sdl_type = ifp->if_type;
|
||||
ifnet_addrs[if_index - 1] = ifa;
|
||||
ifa->ifa_ifp = ifp;
|
||||
ifa->ifa_next = ifp->if_addrlist;
|
||||
ifa->ifa_rtrequest = link_rtrequest;
|
||||
ifp->if_addrlist = ifa;
|
||||
ifa->ifa_addr = (struct sockaddr *)sdl;
|
||||
|
||||
sdl = (struct sockaddr_dl *)(socksize + (caddr_t)sdl);
|
||||
ifa->ifa_netmask = (struct sockaddr *)sdl;
|
||||
sdl->sdl_len = masklen;
|
||||
while (namelen != 0)
|
||||
sdl->sdl_data[--namelen] = 0xff;
|
||||
}
|
||||
}
|
||||
/*
|
||||
* Locate an interface based on a complete address.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
struct ifaddr *
|
||||
ifa_ifwithaddr(addr)
|
||||
register struct sockaddr *addr;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
#define equal(a1, a2) \
|
||||
(bcmp((caddr_t)(a1), (caddr_t)(a2), ((struct sockaddr *)(a1))->sa_len) == 0)
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next)
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (equal(addr, ifa->ifa_addr))
|
||||
return (ifa);
|
||||
if ((ifp->if_flags & IFF_BROADCAST) && ifa->ifa_broadaddr &&
|
||||
equal(ifa->ifa_broadaddr, addr))
|
||||
return (ifa);
|
||||
}
|
||||
return ((struct ifaddr *)0);
|
||||
}
|
||||
/*
|
||||
* Locate the point to point interface with a given destination address.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
struct ifaddr *
|
||||
ifa_ifwithdstaddr(addr)
|
||||
register struct sockaddr *addr;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next)
|
||||
if (ifp->if_flags & IFF_POINTOPOINT)
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family != addr->sa_family)
|
||||
continue;
|
||||
if (ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr))
|
||||
return (ifa);
|
||||
}
|
||||
return ((struct ifaddr *)0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an interface on a specific network. If many, choice
|
||||
* is most specific found.
|
||||
*/
|
||||
struct ifaddr *
|
||||
ifa_ifwithnet(addr)
|
||||
struct sockaddr *addr;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifaddr *ifa;
|
||||
struct ifaddr *ifa_maybe = (struct ifaddr *) 0;
|
||||
u_int af = addr->sa_family;
|
||||
char *addr_data = addr->sa_data, *cplim;
|
||||
|
||||
if (af == AF_LINK) {
|
||||
register struct sockaddr_dl *sdl = (struct sockaddr_dl *)addr;
|
||||
if (sdl->sdl_index && sdl->sdl_index <= if_index)
|
||||
return (ifnet_addrs[sdl->sdl_index - 1]);
|
||||
}
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next) {
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
|
||||
register char *cp, *cp2, *cp3;
|
||||
|
||||
if (ifa->ifa_addr->sa_family != af)
|
||||
next: continue;
|
||||
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||
if (ifa->ifa_dstaddr != 0
|
||||
&& equal(addr, ifa->ifa_dstaddr))
|
||||
return (ifa);
|
||||
} else {
|
||||
/*
|
||||
* if we have a special address handler,
|
||||
* then use it instead of the generic one.
|
||||
*/
|
||||
if (ifa->ifa_claim_addr) {
|
||||
if ((*ifa->ifa_claim_addr)(ifa, addr)) {
|
||||
return (ifa);
|
||||
} else {
|
||||
continue;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Scan all the bits in the ifa's address.
|
||||
* If a bit dissagrees with what we are
|
||||
* looking for, mask it with the netmask
|
||||
* to see if it really matters.
|
||||
* (A byte at a time)
|
||||
*/
|
||||
if (ifa->ifa_netmask == 0)
|
||||
continue;
|
||||
cp = addr_data;
|
||||
cp2 = ifa->ifa_addr->sa_data;
|
||||
cp3 = ifa->ifa_netmask->sa_data;
|
||||
cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
|
||||
while (cp3 < cplim)
|
||||
if ((*cp++ ^ *cp2++) & *cp3++)
|
||||
goto next;
|
||||
if (ifa_maybe == 0 ||
|
||||
rn_refines((caddr_t)ifa->ifa_netmask,
|
||||
(caddr_t)ifa_maybe->ifa_netmask))
|
||||
ifa_maybe = ifa;
|
||||
}
|
||||
}
|
||||
}
|
||||
return (ifa_maybe);
|
||||
}
|
||||
|
||||
/*
|
||||
* Find an interface address specific to an interface best matching
|
||||
* a given address.
|
||||
*/
|
||||
struct ifaddr *
|
||||
ifaof_ifpforaddr(addr, ifp)
|
||||
struct sockaddr *addr;
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
register char *cp, *cp2, *cp3;
|
||||
register char *cplim;
|
||||
struct ifaddr *ifa_maybe = 0;
|
||||
u_int af = addr->sa_family;
|
||||
|
||||
if (af >= AF_MAX)
|
||||
return (0);
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next) {
|
||||
if (ifa->ifa_addr->sa_family != af)
|
||||
continue;
|
||||
if (ifa_maybe == 0)
|
||||
ifa_maybe = ifa;
|
||||
if (ifa->ifa_netmask == 0) {
|
||||
if (equal(addr, ifa->ifa_addr) ||
|
||||
(ifa->ifa_dstaddr && equal(addr, ifa->ifa_dstaddr)))
|
||||
return (ifa);
|
||||
continue;
|
||||
}
|
||||
if (ifp->if_flags & IFF_POINTOPOINT) {
|
||||
if (equal(addr, ifa->ifa_dstaddr))
|
||||
return (ifa);
|
||||
} else {
|
||||
cp = addr->sa_data;
|
||||
cp2 = ifa->ifa_addr->sa_data;
|
||||
cp3 = ifa->ifa_netmask->sa_data;
|
||||
cplim = ifa->ifa_netmask->sa_len + (char *)ifa->ifa_netmask;
|
||||
for (; cp3 < cplim; cp3++)
|
||||
if ((*cp++ ^ *cp2++) & *cp3)
|
||||
break;
|
||||
if (cp3 == cplim)
|
||||
return (ifa);
|
||||
}
|
||||
}
|
||||
return (ifa_maybe);
|
||||
}
|
||||
|
||||
#include <net/route.h>
|
||||
|
||||
/*
|
||||
* Default action when installing a route with a Link Level gateway.
|
||||
* Lookup an appropriate real ifa to point to.
|
||||
* This should be moved to /sys/net/link.c eventually.
|
||||
*/
|
||||
static void
|
||||
link_rtrequest(cmd, rt, sa)
|
||||
int cmd;
|
||||
register struct rtentry *rt;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
struct sockaddr *dst;
|
||||
struct ifnet *ifp;
|
||||
|
||||
if (cmd != RTM_ADD || ((ifa = rt->rt_ifa) == 0) ||
|
||||
((ifp = ifa->ifa_ifp) == 0) || ((dst = rt_key(rt)) == 0))
|
||||
return;
|
||||
ifa = ifaof_ifpforaddr(dst, ifp);
|
||||
if (ifa) {
|
||||
IFAFREE(rt->rt_ifa);
|
||||
rt->rt_ifa = ifa;
|
||||
ifa->ifa_refcnt++;
|
||||
if (ifa->ifa_rtrequest && ifa->ifa_rtrequest != link_rtrequest)
|
||||
ifa->ifa_rtrequest(cmd, rt, sa);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark an interface down and notify protocols of
|
||||
* the transition.
|
||||
* NOTE: must be called at splnet or eqivalent.
|
||||
*/
|
||||
void
|
||||
if_down(ifp)
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
|
||||
ifp->if_flags &= ~IFF_UP;
|
||||
microtime(&ifp->if_lastchange);
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
pfctlinput(PRC_IFDOWN, ifa->ifa_addr);
|
||||
if_qflush(&ifp->if_snd);
|
||||
rt_ifmsg(ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Mark an interface up and notify protocols of
|
||||
* the transition.
|
||||
* NOTE: must be called at splnet or eqivalent.
|
||||
*/
|
||||
void
|
||||
if_up(ifp)
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
|
||||
ifp->if_flags |= IFF_UP;
|
||||
microtime(&ifp->if_lastchange);
|
||||
#ifdef notyet
|
||||
register struct ifaddr *ifa;
|
||||
/* this has no effect on IP, and will kill all iso connections XXX */
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
pfctlinput(PRC_IFUP, ifa->ifa_addr);
|
||||
#endif
|
||||
rt_ifmsg(ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Flush an interface queue.
|
||||
*/
|
||||
static void
|
||||
if_qflush(ifq)
|
||||
register struct ifqueue *ifq;
|
||||
{
|
||||
register struct mbuf *m, *n;
|
||||
|
||||
n = ifq->ifq_head;
|
||||
while ((m = n) != 0) {
|
||||
n = m->m_act;
|
||||
m_freem(m);
|
||||
}
|
||||
ifq->ifq_head = 0;
|
||||
ifq->ifq_tail = 0;
|
||||
ifq->ifq_len = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Handle interface watchdog timer routines. Called
|
||||
* from softclock, we decrement timers (if set) and
|
||||
* call the appropriate interface routine on expiration.
|
||||
*/
|
||||
static void
|
||||
if_slowtimo(arg)
|
||||
void *arg;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
int s = splimp();
|
||||
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next) {
|
||||
if (ifp->if_timer == 0 || --ifp->if_timer)
|
||||
continue;
|
||||
if (ifp->if_watchdog)
|
||||
(*ifp->if_watchdog)(ifp);
|
||||
}
|
||||
splx(s);
|
||||
timeout(if_slowtimo, (void *)0, hz / IFNET_SLOWHZ);
|
||||
}
|
||||
|
||||
/*
|
||||
* Map interface name to
|
||||
* interface structure pointer.
|
||||
*/
|
||||
struct ifnet *
|
||||
ifunit(name)
|
||||
register char *name;
|
||||
{
|
||||
register char *cp;
|
||||
register struct ifnet *ifp;
|
||||
int unit;
|
||||
unsigned len;
|
||||
char *ep, c;
|
||||
|
||||
for (cp = name; cp < name + IFNAMSIZ && *cp; cp++)
|
||||
if (*cp >= '0' && *cp <= '9')
|
||||
break;
|
||||
if (*cp == '\0' || cp == name + IFNAMSIZ)
|
||||
return ((struct ifnet *)0);
|
||||
/*
|
||||
* Save first char of unit, and pointer to it,
|
||||
* so we can put a null there to avoid matching
|
||||
* initial substrings of interface names.
|
||||
*/
|
||||
len = cp - name + 1;
|
||||
c = *cp;
|
||||
ep = cp;
|
||||
for (unit = 0; *cp >= '0' && *cp <= '9'; )
|
||||
unit = unit * 10 + *cp++ - '0';
|
||||
if (*cp != '\0')
|
||||
return 0; /* no trailing garbage allowed */
|
||||
*ep = 0;
|
||||
for (ifp = ifnet; ifp; ifp = ifp->if_next) {
|
||||
if (bcmp(ifp->if_name, name, len))
|
||||
continue;
|
||||
if (unit == ifp->if_unit)
|
||||
break;
|
||||
}
|
||||
*ep = c;
|
||||
return (ifp);
|
||||
}
|
||||
|
||||
/*
|
||||
* Interface ioctls.
|
||||
*/
|
||||
int
|
||||
ifioctl(so, cmd, data, p)
|
||||
struct socket *so;
|
||||
int cmd;
|
||||
caddr_t data;
|
||||
struct proc *p;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register struct ifreq *ifr;
|
||||
int error;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCGIFCONF:
|
||||
case OSIOCGIFCONF:
|
||||
return (ifconf(cmd, data));
|
||||
}
|
||||
ifr = (struct ifreq *)data;
|
||||
ifp = ifunit(ifr->ifr_name);
|
||||
if (ifp == 0)
|
||||
return (ENXIO);
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCGIFFLAGS:
|
||||
ifr->ifr_flags = ifp->if_flags;
|
||||
break;
|
||||
|
||||
case SIOCGIFMETRIC:
|
||||
ifr->ifr_metric = ifp->if_metric;
|
||||
break;
|
||||
|
||||
case SIOCGIFMTU:
|
||||
ifr->ifr_mtu = ifp->if_mtu;
|
||||
break;
|
||||
|
||||
case SIOCGIFPHYS:
|
||||
ifr->ifr_phys = ifp->if_physical;
|
||||
break;
|
||||
|
||||
case SIOCSIFFLAGS:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
if (ifp->if_flags & IFF_UP && (ifr->ifr_flags & IFF_UP) == 0) {
|
||||
int s = splimp();
|
||||
if_down(ifp);
|
||||
splx(s);
|
||||
}
|
||||
if (ifr->ifr_flags & IFF_UP && (ifp->if_flags & IFF_UP) == 0) {
|
||||
int s = splimp();
|
||||
if_up(ifp);
|
||||
splx(s);
|
||||
}
|
||||
ifp->if_flags = (ifp->if_flags & IFF_CANTCHANGE) |
|
||||
(ifr->ifr_flags &~ IFF_CANTCHANGE);
|
||||
if (ifp->if_ioctl)
|
||||
(void) (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
microtime(&ifp->if_lastchange);
|
||||
break;
|
||||
|
||||
case SIOCSIFMETRIC:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
ifp->if_metric = ifr->ifr_metric;
|
||||
microtime(&ifp->if_lastchange);
|
||||
break;
|
||||
|
||||
case SIOCSIFPHYS:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return error;
|
||||
if (!ifp->if_ioctl)
|
||||
return EOPNOTSUPP;
|
||||
error = (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
if (error == 0)
|
||||
microtime(&ifp->if_lastchange);
|
||||
return(error);
|
||||
|
||||
case SIOCSIFMTU:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
if (ifp->if_ioctl == NULL)
|
||||
return (EOPNOTSUPP);
|
||||
/*
|
||||
* 72 was chosen below because it is the size of a TCP/IP
|
||||
* header (40) + the minimum mss (32).
|
||||
*/
|
||||
if (ifr->ifr_mtu < 72 || ifr->ifr_mtu > 65535)
|
||||
return (EINVAL);
|
||||
error = (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
if (error == 0)
|
||||
microtime(&ifp->if_lastchange);
|
||||
return(error);
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
if (ifp->if_ioctl == NULL)
|
||||
return (EOPNOTSUPP);
|
||||
error = (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
if (error == 0 )
|
||||
microtime(&ifp->if_lastchange);
|
||||
return(error);
|
||||
|
||||
case SIOCSIFMEDIA:
|
||||
error = suser(p->p_ucred, &p->p_acflag);
|
||||
if (error)
|
||||
return (error);
|
||||
if (ifp->if_ioctl == 0)
|
||||
return (EOPNOTSUPP);
|
||||
error = (*ifp->if_ioctl)(ifp, cmd, data);
|
||||
if (error == 0)
|
||||
microtime(&ifp->if_lastchange);
|
||||
return error;
|
||||
|
||||
case SIOCGIFMEDIA:
|
||||
if (ifp->if_ioctl == 0)
|
||||
return (EOPNOTSUPP);
|
||||
return ((*ifp->if_ioctl)(ifp, cmd, data));
|
||||
|
||||
default:
|
||||
if (so->so_proto == 0)
|
||||
return (EOPNOTSUPP);
|
||||
#ifndef COMPAT_43
|
||||
return ((*so->so_proto->pr_usrreqs->pru_control)(so, cmd,
|
||||
data,
|
||||
ifp));
|
||||
#else
|
||||
{
|
||||
int ocmd = cmd;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCSIFDSTADDR:
|
||||
case SIOCSIFADDR:
|
||||
case SIOCSIFBRDADDR:
|
||||
case SIOCSIFNETMASK:
|
||||
#if BYTE_ORDER != BIG_ENDIAN
|
||||
if (ifr->ifr_addr.sa_family == 0 &&
|
||||
ifr->ifr_addr.sa_len < 16) {
|
||||
ifr->ifr_addr.sa_family = ifr->ifr_addr.sa_len;
|
||||
ifr->ifr_addr.sa_len = 16;
|
||||
}
|
||||
#else
|
||||
if (ifr->ifr_addr.sa_len == 0)
|
||||
ifr->ifr_addr.sa_len = 16;
|
||||
#endif
|
||||
break;
|
||||
|
||||
case OSIOCGIFADDR:
|
||||
cmd = SIOCGIFADDR;
|
||||
break;
|
||||
|
||||
case OSIOCGIFDSTADDR:
|
||||
cmd = SIOCGIFDSTADDR;
|
||||
break;
|
||||
|
||||
case OSIOCGIFBRDADDR:
|
||||
cmd = SIOCGIFBRDADDR;
|
||||
break;
|
||||
|
||||
case OSIOCGIFNETMASK:
|
||||
cmd = SIOCGIFNETMASK;
|
||||
}
|
||||
error = ((*so->so_proto->pr_usrreqs->pru_control)(so,
|
||||
cmd,
|
||||
data,
|
||||
ifp));
|
||||
switch (ocmd) {
|
||||
|
||||
case OSIOCGIFADDR:
|
||||
case OSIOCGIFDSTADDR:
|
||||
case OSIOCGIFBRDADDR:
|
||||
case OSIOCGIFNETMASK:
|
||||
*(u_short *)&ifr->ifr_addr = ifr->ifr_addr.sa_family;
|
||||
}
|
||||
return (error);
|
||||
|
||||
}
|
||||
#endif
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Set/clear promiscuous mode on interface ifp based on the truth value
|
||||
* of pswitch. The calls are reference counted so that only the first
|
||||
* "on" request actually has an effect, as does the final "off" request.
|
||||
* Results are undefined if the "off" and "on" requests are not matched.
|
||||
*/
|
||||
int
|
||||
ifpromisc(ifp, pswitch)
|
||||
struct ifnet *ifp;
|
||||
int pswitch;
|
||||
{
|
||||
struct ifreq ifr;
|
||||
|
||||
if (pswitch) {
|
||||
/*
|
||||
* If the device is not configured up, we cannot put it in
|
||||
* promiscuous mode.
|
||||
*/
|
||||
if ((ifp->if_flags & IFF_UP) == 0)
|
||||
return (ENETDOWN);
|
||||
if (ifp->if_pcount++ != 0)
|
||||
return (0);
|
||||
ifp->if_flags |= IFF_PROMISC;
|
||||
log(LOG_INFO, "%s%d: promiscuous mode enabled\n",
|
||||
ifp->if_name, ifp->if_unit);
|
||||
} else {
|
||||
if (--ifp->if_pcount > 0)
|
||||
return (0);
|
||||
ifp->if_flags &= ~IFF_PROMISC;
|
||||
}
|
||||
ifr.ifr_flags = ifp->if_flags;
|
||||
return ((*ifp->if_ioctl)(ifp, SIOCSIFFLAGS, (caddr_t)&ifr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Return interface configuration
|
||||
* of system. List may be used
|
||||
* in later ioctl's (above) to get
|
||||
* other information.
|
||||
*/
|
||||
/*ARGSUSED*/
|
||||
static int
|
||||
ifconf(cmd, data)
|
||||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
register struct ifconf *ifc = (struct ifconf *)data;
|
||||
register struct ifnet *ifp = ifnet;
|
||||
register struct ifaddr *ifa;
|
||||
struct ifreq ifr, *ifrp;
|
||||
int space = ifc->ifc_len, error = 0;
|
||||
|
||||
ifrp = ifc->ifc_req;
|
||||
for (; space > sizeof (ifr) && ifp; ifp = ifp->if_next) {
|
||||
char workbuf[64];
|
||||
int ifnlen;
|
||||
|
||||
ifnlen = sprintf(workbuf, "%s%d", ifp->if_name, ifp->if_unit);
|
||||
if(ifnlen + 1 > sizeof ifr.ifr_name) {
|
||||
error = ENAMETOOLONG;
|
||||
} else {
|
||||
strcpy(ifr.ifr_name, workbuf);
|
||||
}
|
||||
|
||||
if ((ifa = ifp->if_addrlist) == 0) {
|
||||
bzero((caddr_t)&ifr.ifr_addr, sizeof(ifr.ifr_addr));
|
||||
error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
|
||||
sizeof (ifr));
|
||||
if (error)
|
||||
break;
|
||||
space -= sizeof (ifr), ifrp++;
|
||||
} else
|
||||
for ( ; space > sizeof (ifr) && ifa; ifa = ifa->ifa_next) {
|
||||
register struct sockaddr *sa = ifa->ifa_addr;
|
||||
#ifdef COMPAT_43
|
||||
if (cmd == OSIOCGIFCONF) {
|
||||
struct osockaddr *osa =
|
||||
(struct osockaddr *)&ifr.ifr_addr;
|
||||
ifr.ifr_addr = *sa;
|
||||
osa->sa_family = sa->sa_family;
|
||||
error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
|
||||
sizeof (ifr));
|
||||
ifrp++;
|
||||
} else
|
||||
#endif
|
||||
if (sa->sa_len <= sizeof(*sa)) {
|
||||
ifr.ifr_addr = *sa;
|
||||
error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
|
||||
sizeof (ifr));
|
||||
ifrp++;
|
||||
} else {
|
||||
space -= sa->sa_len - sizeof(*sa);
|
||||
if (space < sizeof (ifr))
|
||||
break;
|
||||
error = copyout((caddr_t)&ifr, (caddr_t)ifrp,
|
||||
sizeof (ifr.ifr_name));
|
||||
if (error == 0)
|
||||
error = copyout((caddr_t)sa,
|
||||
(caddr_t)&ifrp->ifr_addr, sa->sa_len);
|
||||
ifrp = (struct ifreq *)
|
||||
(sa->sa_len + (caddr_t)&ifrp->ifr_addr);
|
||||
}
|
||||
if (error)
|
||||
break;
|
||||
space -= sizeof (ifr);
|
||||
}
|
||||
}
|
||||
ifc->ifc_len -= space;
|
||||
return (error);
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_net, PF_LINK, link, CTLFLAG_RW, 0, "Link layers");
|
||||
SYSCTL_NODE(_net_link, 0, generic, CTLFLAG_RW, 0, "Generic link-management");
|
||||
467
c/src/exec/libnetworking/net/if.h
Normal file
467
c/src/exec/libnetworking/net/if.h
Normal file
@@ -0,0 +1,467 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_H_
|
||||
#define _NET_IF_H_
|
||||
|
||||
/*
|
||||
* Structures defining a network interface, providing a packet
|
||||
* transport mechanism (ala level 0 of the PUP protocols).
|
||||
*
|
||||
* Each interface accepts output datagrams of a specified maximum
|
||||
* length, and provides higher level routines with input datagrams
|
||||
* received from its medium.
|
||||
*
|
||||
* Output occurs when the routine if_output is called, with three parameters:
|
||||
* (*ifp->if_output)(ifp, m, dst, rt)
|
||||
* Here m is the mbuf chain to be sent and dst is the destination address.
|
||||
* The output routine encapsulates the supplied datagram if necessary,
|
||||
* and then transmits it on its medium.
|
||||
*
|
||||
* On input, each interface unwraps the data received by it, and either
|
||||
* places it on the input queue of a internetwork datagram routine
|
||||
* and posts the associated software interrupt, or passes the datagram to a raw
|
||||
* packet input routine.
|
||||
*
|
||||
* Routines exist for locating interfaces by their addresses
|
||||
* or for locating a interface on a certain network, as well as more general
|
||||
* routing and gateway routines maintaining information used to locate
|
||||
* interfaces. These routines live in the files if.c and route.c
|
||||
*/
|
||||
|
||||
#ifndef _TIME_ /* XXX fast fix for SNMP, going away soon */
|
||||
#include <sys/time.h>
|
||||
#endif
|
||||
|
||||
#ifdef __STDC__
|
||||
/*
|
||||
* Forward structure declarations for function prototypes [sic].
|
||||
*/
|
||||
struct mbuf;
|
||||
struct proc;
|
||||
struct rtentry;
|
||||
struct socket;
|
||||
struct ether_header;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Structure describing information about an interface
|
||||
* which may be of interest to management entities.
|
||||
*/
|
||||
struct if_data {
|
||||
/* generic interface information */
|
||||
u_char ifi_type; /* ethernet, tokenring, etc */
|
||||
u_char ifi_physical; /* e.g., AUI, Thinnet, 10base-T, etc */
|
||||
u_char ifi_addrlen; /* media address length */
|
||||
u_char ifi_hdrlen; /* media header length */
|
||||
u_char ifi_recvquota; /* polling quota for receive intrs */
|
||||
u_char ifi_xmitquota; /* polling quota for xmit intrs */
|
||||
u_long ifi_mtu; /* maximum transmission unit */
|
||||
u_long ifi_metric; /* routing metric (external only) */
|
||||
u_long ifi_baudrate; /* linespeed */
|
||||
/* volatile statistics */
|
||||
u_long ifi_ipackets; /* packets received on interface */
|
||||
u_long ifi_ierrors; /* input errors on interface */
|
||||
u_long ifi_opackets; /* packets sent on interface */
|
||||
u_long ifi_oerrors; /* output errors on interface */
|
||||
u_long ifi_collisions; /* collisions on csma interfaces */
|
||||
u_long ifi_ibytes; /* total number of octets received */
|
||||
u_long ifi_obytes; /* total number of octets sent */
|
||||
u_long ifi_imcasts; /* packets received via multicast */
|
||||
u_long ifi_omcasts; /* packets sent via multicast */
|
||||
u_long ifi_iqdrops; /* dropped on input, this interface */
|
||||
u_long ifi_noproto; /* destined for unsupported protocol */
|
||||
u_long ifi_recvtiming; /* usec spent receiving when timing */
|
||||
u_long ifi_xmittiming; /* usec spent xmitting when timing */
|
||||
struct timeval ifi_lastchange; /* time of last administrative change */
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure defining a queue for a network interface.
|
||||
*/
|
||||
struct ifqueue {
|
||||
struct mbuf *ifq_head;
|
||||
struct mbuf *ifq_tail;
|
||||
int ifq_len;
|
||||
int ifq_maxlen;
|
||||
int ifq_drops;
|
||||
};
|
||||
|
||||
/*
|
||||
* Structure defining a network interface.
|
||||
*
|
||||
* (Would like to call this struct ``if'', but C isn't PL/1.)
|
||||
*/
|
||||
struct ifnet {
|
||||
void *if_softc; /* pointer to driver state */
|
||||
char *if_name; /* name, e.g. ``en'' or ``lo'' */
|
||||
struct ifnet *if_next; /* all struct ifnets are chained */
|
||||
struct ifaddr *if_addrlist; /* linked list of addresses per if */
|
||||
int if_pcount; /* number of promiscuous listeners */
|
||||
struct bpf_if *if_bpf; /* packet filter structure */
|
||||
u_short if_index; /* numeric abbreviation for this if */
|
||||
short if_unit; /* sub-unit for lower level driver */
|
||||
short if_timer; /* time 'til if_watchdog called */
|
||||
short if_flags; /* up/down, broadcast, etc. */
|
||||
int if_ipending; /* interrupts pending */
|
||||
void *if_linkmib; /* link-type-specific MIB data */
|
||||
size_t if_linkmiblen; /* length of above data */
|
||||
struct if_data if_data;
|
||||
/* procedure handles */
|
||||
int (*if_output) /* output routine (enqueue) */
|
||||
__P((struct ifnet *, struct mbuf *, struct sockaddr *,
|
||||
struct rtentry *));
|
||||
void (*if_start) /* initiate output routine */
|
||||
__P((struct ifnet *));
|
||||
int (*if_done) /* output complete routine */
|
||||
__P((struct ifnet *)); /* (XXX not used; fake prototype) */
|
||||
int (*if_ioctl) /* ioctl routine */
|
||||
__P((struct ifnet *, int, caddr_t));
|
||||
void (*if_watchdog) /* timer routine */
|
||||
__P((struct ifnet *));
|
||||
int (*if_poll_recv) /* polled receive routine */
|
||||
__P((struct ifnet *, int *));
|
||||
int (*if_poll_xmit) /* polled transmit routine */
|
||||
__P((struct ifnet *, int *));
|
||||
void (*if_poll_intren) /* polled interrupt reenable routine */
|
||||
__P((struct ifnet *));
|
||||
void (*if_poll_slowinput) /* input routine for slow devices */
|
||||
__P((struct ifnet *, struct mbuf *));
|
||||
void (*if_init) /* Init routine */
|
||||
__P((void *));
|
||||
struct ifqueue if_snd; /* output queue */
|
||||
struct ifqueue *if_poll_slowq; /* input queue for slow devices */
|
||||
};
|
||||
typedef void if_init_f_t __P((void *));
|
||||
|
||||
#define if_mtu if_data.ifi_mtu
|
||||
#define if_type if_data.ifi_type
|
||||
#define if_physical if_data.ifi_physical
|
||||
#define if_addrlen if_data.ifi_addrlen
|
||||
#define if_hdrlen if_data.ifi_hdrlen
|
||||
#define if_metric if_data.ifi_metric
|
||||
#define if_baudrate if_data.ifi_baudrate
|
||||
#define if_ipackets if_data.ifi_ipackets
|
||||
#define if_ierrors if_data.ifi_ierrors
|
||||
#define if_opackets if_data.ifi_opackets
|
||||
#define if_oerrors if_data.ifi_oerrors
|
||||
#define if_collisions if_data.ifi_collisions
|
||||
#define if_ibytes if_data.ifi_ibytes
|
||||
#define if_obytes if_data.ifi_obytes
|
||||
#define if_imcasts if_data.ifi_imcasts
|
||||
#define if_omcasts if_data.ifi_omcasts
|
||||
#define if_iqdrops if_data.ifi_iqdrops
|
||||
#define if_noproto if_data.ifi_noproto
|
||||
#define if_lastchange if_data.ifi_lastchange
|
||||
#define if_recvquota if_data.ifi_recvquota
|
||||
#define if_xmitquota if_data.ifi_xmitquota
|
||||
#define if_rawoutput(if, m, sa) if_output(if, m, sa, (struct rtentry *)0)
|
||||
|
||||
#define IFF_UP 0x1 /* interface is up */
|
||||
#define IFF_BROADCAST 0x2 /* broadcast address valid */
|
||||
#define IFF_DEBUG 0x4 /* turn on debugging */
|
||||
#define IFF_LOOPBACK 0x8 /* is a loopback net */
|
||||
#define IFF_POINTOPOINT 0x10 /* interface is point-to-point link */
|
||||
/*#define IFF_NOTRAILERS 0x20 * obsolete: avoid use of trailers */
|
||||
#define IFF_RUNNING 0x40 /* resources allocated */
|
||||
#define IFF_NOARP 0x80 /* no address resolution protocol */
|
||||
#define IFF_PROMISC 0x100 /* receive all packets */
|
||||
#define IFF_ALLMULTI 0x200 /* receive all multicast packets */
|
||||
#define IFF_OACTIVE 0x400 /* transmission in progress */
|
||||
#define IFF_SIMPLEX 0x800 /* can't hear own transmissions */
|
||||
#define IFF_LINK0 0x1000 /* per link layer defined bit */
|
||||
#define IFF_LINK1 0x2000 /* per link layer defined bit */
|
||||
#define IFF_LINK2 0x4000 /* per link layer defined bit */
|
||||
#define IFF_ALTPHYS IFF_LINK2 /* use alternate physical connection */
|
||||
#define IFF_MULTICAST 0x8000 /* supports multicast */
|
||||
|
||||
/* flags set internally only: */
|
||||
#define IFF_CANTCHANGE \
|
||||
(IFF_BROADCAST|IFF_POINTOPOINT|IFF_RUNNING|IFF_OACTIVE|\
|
||||
IFF_SIMPLEX|IFF_MULTICAST|IFF_ALLMULTI)
|
||||
|
||||
|
||||
/*
|
||||
* These really don't belong here, but there's no other obviously appropriate
|
||||
* location.
|
||||
*/
|
||||
#define IFP_AUI 0
|
||||
#define IFP_10BASE2 1
|
||||
#define IFP_10BASET 2
|
||||
/* etc. */
|
||||
|
||||
/*
|
||||
* Bit values in if_ipending
|
||||
*/
|
||||
#define IFI_RECV 1 /* I want to receive */
|
||||
#define IFI_XMIT 2 /* I want to transmit */
|
||||
|
||||
/*
|
||||
* Output queues (ifp->if_snd) and slow device input queues (*ifp->if_slowq)
|
||||
* are queues of messages stored on ifqueue structures
|
||||
* (defined above). Entries are added to and deleted from these structures
|
||||
* by these macros, which should be called with ipl raised to splimp().
|
||||
*/
|
||||
#define IF_QFULL(ifq) ((ifq)->ifq_len >= (ifq)->ifq_maxlen)
|
||||
#define IF_DROP(ifq) ((ifq)->ifq_drops++)
|
||||
#define IF_ENQUEUE(ifq, m) { \
|
||||
(m)->m_nextpkt = 0; \
|
||||
if ((ifq)->ifq_tail == 0) \
|
||||
(ifq)->ifq_head = m; \
|
||||
else \
|
||||
(ifq)->ifq_tail->m_nextpkt = m; \
|
||||
(ifq)->ifq_tail = m; \
|
||||
(ifq)->ifq_len++; \
|
||||
}
|
||||
#define IF_PREPEND(ifq, m) { \
|
||||
(m)->m_nextpkt = (ifq)->ifq_head; \
|
||||
if ((ifq)->ifq_tail == 0) \
|
||||
(ifq)->ifq_tail = (m); \
|
||||
(ifq)->ifq_head = (m); \
|
||||
(ifq)->ifq_len++; \
|
||||
}
|
||||
#define IF_DEQUEUE(ifq, m) { \
|
||||
(m) = (ifq)->ifq_head; \
|
||||
if (m) { \
|
||||
if (((ifq)->ifq_head = (m)->m_nextpkt) == 0) \
|
||||
(ifq)->ifq_tail = 0; \
|
||||
(m)->m_nextpkt = 0; \
|
||||
(ifq)->ifq_len--; \
|
||||
} \
|
||||
}
|
||||
|
||||
#ifdef KERNEL
|
||||
#define IF_ENQ_DROP(ifq, m) if_enq_drop(ifq, m)
|
||||
|
||||
#if defined(__GNUC__) && defined(MT_HEADER)
|
||||
static inline int
|
||||
if_queue_drop(struct ifqueue *ifq, struct mbuf *m)
|
||||
{
|
||||
IF_DROP(ifq);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static inline int
|
||||
if_enq_drop(struct ifqueue *ifq, struct mbuf *m)
|
||||
{
|
||||
if (IF_QFULL(ifq) &&
|
||||
!if_queue_drop(ifq, m))
|
||||
return 0;
|
||||
IF_ENQUEUE(ifq, m);
|
||||
return 1;
|
||||
}
|
||||
#else
|
||||
|
||||
#ifdef MT_HEADER
|
||||
int if_enq_drop __P((struct ifqueue *, struct mbuf *));
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* KERNEL */
|
||||
|
||||
#define IFQ_MAXLEN 50
|
||||
#define IFNET_SLOWHZ 1 /* granularity is 1 second */
|
||||
|
||||
/*
|
||||
* The ifaddr structure contains information about one address
|
||||
* of an interface. They are maintained by the different address families,
|
||||
* are allocated and attached when an address is set, and are linked
|
||||
* together so all addresses for an interface can be located.
|
||||
*/
|
||||
struct ifaddr {
|
||||
struct sockaddr *ifa_addr; /* address of interface */
|
||||
struct sockaddr *ifa_dstaddr; /* other end of p-to-p link */
|
||||
#define ifa_broadaddr ifa_dstaddr /* broadcast address interface */
|
||||
struct sockaddr *ifa_netmask; /* used to determine subnet */
|
||||
struct ifnet *ifa_ifp; /* back-pointer to interface */
|
||||
struct ifaddr *ifa_next; /* next address for interface */
|
||||
void (*ifa_rtrequest) /* check or clean routes (+ or -)'d */
|
||||
__P((int, struct rtentry *, struct sockaddr *));
|
||||
u_short ifa_flags; /* mostly rt_flags for cloning */
|
||||
short ifa_refcnt; /* references to this structure */
|
||||
int ifa_metric; /* cost of going out this interface */
|
||||
#ifdef notdef
|
||||
struct rtentry *ifa_rt; /* XXXX for ROUTETOIF ????? */
|
||||
#endif
|
||||
int (*ifa_claim_addr) /* check if an addr goes to this if */
|
||||
__P((struct ifaddr *, struct sockaddr *));
|
||||
|
||||
};
|
||||
#define IFA_ROUTE RTF_UP /* route installed */
|
||||
|
||||
/*
|
||||
* Message format for use in obtaining information about interfaces
|
||||
* from getkerninfo and the routing socket
|
||||
*/
|
||||
struct if_msghdr {
|
||||
u_short ifm_msglen; /* to skip over non-understood messages */
|
||||
u_char ifm_version; /* future binary compatability */
|
||||
u_char ifm_type; /* message type */
|
||||
int ifm_addrs; /* like rtm_addrs */
|
||||
int ifm_flags; /* value of if_flags */
|
||||
u_short ifm_index; /* index for associated ifp */
|
||||
struct if_data ifm_data;/* statistics and other data about if */
|
||||
};
|
||||
|
||||
/*
|
||||
* Message format for use in obtaining information about interface addresses
|
||||
* from getkerninfo and the routing socket
|
||||
*/
|
||||
struct ifa_msghdr {
|
||||
u_short ifam_msglen; /* to skip over non-understood messages */
|
||||
u_char ifam_version; /* future binary compatability */
|
||||
u_char ifam_type; /* message type */
|
||||
int ifam_addrs; /* like rtm_addrs */
|
||||
int ifam_flags; /* value of ifa_flags */
|
||||
u_short ifam_index; /* index for associated ifp */
|
||||
int ifam_metric; /* value of ifa_metric */
|
||||
};
|
||||
|
||||
/*
|
||||
* Interface request structure used for socket
|
||||
* ioctl's. All interface ioctl's must have parameter
|
||||
* definitions which begin with ifr_name. The
|
||||
* remainder may be interface specific.
|
||||
*/
|
||||
struct ifreq {
|
||||
#define IFNAMSIZ 16
|
||||
char ifr_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
union {
|
||||
struct sockaddr ifru_addr;
|
||||
struct sockaddr ifru_dstaddr;
|
||||
struct sockaddr ifru_broadaddr;
|
||||
short ifru_flags;
|
||||
int ifru_metric;
|
||||
int ifru_mtu;
|
||||
int ifru_phys;
|
||||
int ifru_media;
|
||||
caddr_t ifru_data;
|
||||
} ifr_ifru;
|
||||
#define ifr_addr ifr_ifru.ifru_addr /* address */
|
||||
#define ifr_dstaddr ifr_ifru.ifru_dstaddr /* other end of p-to-p link */
|
||||
#define ifr_broadaddr ifr_ifru.ifru_broadaddr /* broadcast address */
|
||||
#define ifr_flags ifr_ifru.ifru_flags /* flags */
|
||||
#define ifr_metric ifr_ifru.ifru_metric /* metric */
|
||||
#define ifr_mtu ifr_ifru.ifru_mtu /* mtu */
|
||||
#define ifr_phys ifr_ifru.ifru_phys /* physical wire */
|
||||
#define ifr_media ifr_ifru.ifru_media /* physical media */
|
||||
#define ifr_data ifr_ifru.ifru_data /* for use by interface */
|
||||
};
|
||||
|
||||
struct ifaliasreq {
|
||||
char ifra_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
struct sockaddr ifra_addr;
|
||||
struct sockaddr ifra_broadaddr;
|
||||
struct sockaddr ifra_mask;
|
||||
};
|
||||
|
||||
struct ifmediareq {
|
||||
char ifm_name[IFNAMSIZ]; /* if name, e.g. "en0" */
|
||||
int ifm_current; /* current media options */
|
||||
int ifm_mask; /* don't care mask */
|
||||
int ifm_status; /* media status */
|
||||
int ifm_active; /* active options */
|
||||
int ifm_count; /* # entries in ifm_ulist array */
|
||||
int *ifm_ulist; /* media words */
|
||||
};
|
||||
/*
|
||||
* Structure used in SIOCGIFCONF request.
|
||||
* Used to retrieve interface configuration
|
||||
* for machine (useful for programs which
|
||||
* must know all networks accessible).
|
||||
*/
|
||||
struct ifconf {
|
||||
int ifc_len; /* size of associated buffer */
|
||||
union {
|
||||
caddr_t ifcu_buf;
|
||||
struct ifreq *ifcu_req;
|
||||
} ifc_ifcu;
|
||||
#define ifc_buf ifc_ifcu.ifcu_buf /* buffer address */
|
||||
#define ifc_req ifc_ifcu.ifcu_req /* array of structures returned */
|
||||
};
|
||||
|
||||
#include <net/if_arp.h>
|
||||
|
||||
#ifdef KERNEL
|
||||
#define IFAFREE(ifa) \
|
||||
if ((ifa)->ifa_refcnt <= 0) \
|
||||
ifafree(ifa); \
|
||||
else \
|
||||
(ifa)->ifa_refcnt--;
|
||||
|
||||
extern struct ifnet *ifnet;
|
||||
extern int ifqmaxlen;
|
||||
extern struct ifnet loif[];
|
||||
extern int if_index;
|
||||
extern struct ifaddr **ifnet_addrs;
|
||||
|
||||
void ether_ifattach __P((struct ifnet *));
|
||||
void ether_input __P((struct ifnet *, struct ether_header *, struct mbuf *));
|
||||
int ether_output __P((struct ifnet *,
|
||||
struct mbuf *, struct sockaddr *, struct rtentry *));
|
||||
int ether_ioctl __P((struct ifnet *, int , caddr_t ));
|
||||
|
||||
void if_attach __P((struct ifnet *));
|
||||
void if_down __P((struct ifnet *));
|
||||
void if_up __P((struct ifnet *));
|
||||
#ifdef vax
|
||||
void ifubareset __P((int));
|
||||
#endif
|
||||
/*void ifinit __P((void));*/ /* declared in systm.h for main() */
|
||||
int ifioctl __P((struct socket *, int, caddr_t, struct proc *));
|
||||
int ifpromisc __P((struct ifnet *, int));
|
||||
struct ifnet *ifunit __P((char *));
|
||||
|
||||
int if_poll_recv_slow __P((struct ifnet *ifp, int *quotap));
|
||||
void if_poll_xmit_slow __P((struct ifnet *ifp, int *quotap));
|
||||
void if_poll_throttle __P((void));
|
||||
void if_poll_unthrottle __P((void *));
|
||||
void if_poll_init __P((void));
|
||||
void if_poll __P((void));
|
||||
|
||||
struct ifaddr *ifa_ifwithaddr __P((struct sockaddr *));
|
||||
struct ifaddr *ifa_ifwithdstaddr __P((struct sockaddr *));
|
||||
struct ifaddr *ifa_ifwithnet __P((struct sockaddr *));
|
||||
struct ifaddr *ifa_ifwithroute __P((int, struct sockaddr *,
|
||||
struct sockaddr *));
|
||||
struct ifaddr *ifaof_ifpforaddr __P((struct sockaddr *, struct ifnet *));
|
||||
void ifafree __P((struct ifaddr *));
|
||||
|
||||
int looutput __P((struct ifnet *,
|
||||
struct mbuf *, struct sockaddr *, struct rtentry *));
|
||||
#endif /* KERNEL */
|
||||
|
||||
#endif /* !_NET_IF_H_ */
|
||||
91
c/src/exec/libnetworking/net/if_arp.h
Normal file
91
c/src/exec/libnetworking/net/if_arp.h
Normal file
@@ -0,0 +1,91 @@
|
||||
/*
|
||||
* Copyright (c) 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_arp.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_ARP_H_
|
||||
#define _NET_IF_ARP_H_
|
||||
|
||||
/*
|
||||
* Address Resolution Protocol.
|
||||
*
|
||||
* See RFC 826 for protocol description. ARP packets are variable
|
||||
* in size; the arphdr structure defines the fixed-length portion.
|
||||
* Protocol type values are the same as those for 10 Mb/s Ethernet.
|
||||
* It is followed by the variable-sized fields ar_sha, arp_spa,
|
||||
* arp_tha and arp_tpa in that order, according to the lengths
|
||||
* specified. Field names used correspond to RFC 826.
|
||||
*/
|
||||
struct arphdr {
|
||||
u_short ar_hrd; /* format of hardware address */
|
||||
#define ARPHRD_ETHER 1 /* ethernet hardware format */
|
||||
#define ARPHRD_FRELAY 15 /* frame relay hardware format */
|
||||
u_short ar_pro; /* format of protocol address */
|
||||
u_char ar_hln; /* length of hardware address */
|
||||
u_char ar_pln; /* length of protocol address */
|
||||
u_short ar_op; /* one of: */
|
||||
#define ARPOP_REQUEST 1 /* request to resolve address */
|
||||
#define ARPOP_REPLY 2 /* response to previous request */
|
||||
#define ARPOP_REVREQUEST 3 /* request protocol address given hardware */
|
||||
#define ARPOP_REVREPLY 4 /* response giving protocol address */
|
||||
#define ARPOP_INVREQUEST 8 /* request to identify peer */
|
||||
#define ARPOP_INVREPLY 9 /* response identifying peer */
|
||||
/*
|
||||
* The remaining fields are variable in size,
|
||||
* according to the sizes above.
|
||||
*/
|
||||
#ifdef COMMENT_ONLY
|
||||
u_char ar_sha[]; /* sender hardware address */
|
||||
u_char ar_spa[]; /* sender protocol address */
|
||||
u_char ar_tha[]; /* target hardware address */
|
||||
u_char ar_tpa[]; /* target protocol address */
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
* ARP ioctl request
|
||||
*/
|
||||
struct arpreq {
|
||||
struct sockaddr arp_pa; /* protocol address */
|
||||
struct sockaddr arp_ha; /* hardware address */
|
||||
int arp_flags; /* flags */
|
||||
};
|
||||
/* arp_flags and at_flags field values */
|
||||
#define ATF_INUSE 0x01 /* entry in use */
|
||||
#define ATF_COM 0x02 /* completed entry (enaddr valid) */
|
||||
#define ATF_PERM 0x04 /* permanent entry */
|
||||
#define ATF_PUBL 0x08 /* publish entry (respond for other host) */
|
||||
#define ATF_USETRAILERS 0x10 /* has requested trailers */
|
||||
|
||||
#endif /* !_NET_IF_ARP_H_ */
|
||||
86
c/src/exec/libnetworking/net/if_dl.h
Normal file
86
c/src/exec/libnetworking/net/if_dl.h
Normal file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 1990, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_dl.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_DL_H_
|
||||
#define _NET_IF_DL_H_
|
||||
|
||||
/*
|
||||
* A Link-Level Sockaddr may specify the interface in one of two
|
||||
* ways: either by means of a system-provided index number (computed
|
||||
* anew and possibly differently on every reboot), or by a human-readable
|
||||
* string such as "il0" (for managerial convenience).
|
||||
*
|
||||
* Census taking actions, such as something akin to SIOCGCONF would return
|
||||
* both the index and the human name.
|
||||
*
|
||||
* High volume transactions (such as giving a link-level ``from'' address
|
||||
* in a recvfrom or recvmsg call) may be likely only to provide the indexed
|
||||
* form, (which requires fewer copy operations and less space).
|
||||
*
|
||||
* The form and interpretation of the link-level address is purely a matter
|
||||
* of convention between the device driver and its consumers; however, it is
|
||||
* expected that all drivers for an interface of a given if_type will agree.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Structure of a Link-Level sockaddr:
|
||||
*/
|
||||
struct sockaddr_dl {
|
||||
u_char sdl_len; /* Total length of sockaddr */
|
||||
u_char sdl_family; /* AF_DLI */
|
||||
u_short sdl_index; /* if != 0, system given index for interface */
|
||||
u_char sdl_type; /* interface type */
|
||||
u_char sdl_nlen; /* interface name length, no trailing 0 reqd. */
|
||||
u_char sdl_alen; /* link level address length */
|
||||
u_char sdl_slen; /* link layer selector length */
|
||||
char sdl_data[12]; /* minimum work area, can be larger;
|
||||
contains both if name and ll address */
|
||||
};
|
||||
|
||||
#define LLADDR(s) ((caddr_t)((s)->sdl_data + (s)->sdl_nlen))
|
||||
|
||||
#ifndef KERNEL
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
|
||||
__BEGIN_DECLS
|
||||
void link_addr __P((const char *, struct sockaddr_dl *));
|
||||
char *link_ntoa __P((const struct sockaddr_dl *));
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !KERNEL */
|
||||
|
||||
#endif
|
||||
981
c/src/exec/libnetworking/net/if_ethersubr.c
Normal file
981
c/src/exec/libnetworking/net/if_ethersubr.c
Normal file
@@ -0,0 +1,981 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1989, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_ethersubr.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/malloc.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/protosw.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/syslog.h>
|
||||
#include <sys/sysctl.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/if_llc.h>
|
||||
#include <net/if_dl.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/ethernet.h>
|
||||
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_var.h>
|
||||
#endif
|
||||
#include <netinet/if_ether.h>
|
||||
|
||||
#ifdef IPX
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef NS
|
||||
#include <netns/ns.h>
|
||||
#include <netns/ns_if.h>
|
||||
ushort ns_nettype;
|
||||
int ether_outputdebug = 0;
|
||||
int ether_inputdebug = 0;
|
||||
#endif
|
||||
|
||||
#ifdef ISO
|
||||
#include <netiso/argo_debug.h>
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#include <netiso/iso_snpac.h>
|
||||
#endif
|
||||
|
||||
/*#ifdef LLC
|
||||
#include <netccitt/dll.h>
|
||||
#include <netccitt/llc_var.h>
|
||||
#endif*/
|
||||
|
||||
#if defined(LLC) && defined(CCITT)
|
||||
extern struct ifqueue pkintrq;
|
||||
#endif
|
||||
|
||||
#ifdef NETATALK
|
||||
#include <netatalk/at.h>
|
||||
#include <netatalk/at_var.h>
|
||||
#include <netatalk/at_extern.h>
|
||||
|
||||
#define llc_snap_org_code llc_un.type_snap.org_code
|
||||
#define llc_snap_ether_type llc_un.type_snap.ether_type
|
||||
|
||||
extern u_char at_org_code[ 3 ];
|
||||
extern u_char aarp_org_code[ 3 ];
|
||||
#endif NETATALK
|
||||
|
||||
u_char etherbroadcastaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
|
||||
#define senderr(e) { error = (e); goto bad;}
|
||||
|
||||
/*
|
||||
* Ethernet output routine.
|
||||
* Encapsulate a packet of type family for the local net.
|
||||
* Use trailer local net encapsulation if enough data in first
|
||||
* packet leaves a multiple of 512 bytes of data in remainder.
|
||||
* Assumes that ifp is actually pointer to arpcom structure.
|
||||
*/
|
||||
int
|
||||
ether_output(ifp, m0, dst, rt0)
|
||||
register struct ifnet *ifp;
|
||||
struct mbuf *m0;
|
||||
struct sockaddr *dst;
|
||||
struct rtentry *rt0;
|
||||
{
|
||||
short type;
|
||||
int s, error = 0;
|
||||
u_char *cp, edst[6];
|
||||
register struct mbuf *m2, *m = m0;
|
||||
register struct rtentry *rt;
|
||||
struct mbuf *mcopy = (struct mbuf *)0;
|
||||
register struct ether_header *eh;
|
||||
int off, len = m->m_pkthdr.len;
|
||||
struct arpcom *ac = (struct arpcom *)ifp;
|
||||
register struct ifqueue *inq;
|
||||
#ifdef NETATALK
|
||||
struct at_ifaddr *aa;
|
||||
#endif NETATALK
|
||||
|
||||
if ((ifp->if_flags & (IFF_UP|IFF_RUNNING)) != (IFF_UP|IFF_RUNNING))
|
||||
senderr(ENETDOWN);
|
||||
rt = rt0;
|
||||
if (rt) {
|
||||
if ((rt->rt_flags & RTF_UP) == 0) {
|
||||
rt0 = rt = rtalloc1(dst, 1, 0UL);
|
||||
if (rt0)
|
||||
rt->rt_refcnt--;
|
||||
else
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
if (rt->rt_flags & RTF_GATEWAY) {
|
||||
if (rt->rt_gwroute == 0)
|
||||
goto lookup;
|
||||
if (((rt = rt->rt_gwroute)->rt_flags & RTF_UP) == 0) {
|
||||
rtfree(rt); rt = rt0;
|
||||
lookup: rt->rt_gwroute = rtalloc1(rt->rt_gateway, 1,
|
||||
0UL);
|
||||
if ((rt = rt->rt_gwroute) == 0)
|
||||
senderr(EHOSTUNREACH);
|
||||
}
|
||||
}
|
||||
if (rt->rt_flags & RTF_REJECT)
|
||||
if (rt->rt_rmx.rmx_expire == 0 ||
|
||||
rtems_bsdnet_seconds_since_boot() < rt->rt_rmx.rmx_expire)
|
||||
senderr(rt == rt0 ? EHOSTDOWN : EHOSTUNREACH);
|
||||
}
|
||||
switch (dst->sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
if (!arpresolve(ac, rt, m, dst, edst, rt0))
|
||||
return (0); /* if not yet resolved */
|
||||
/* If broadcasting on a simplex interface, loopback a copy */
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
|
||||
mcopy = m_copy(m, 0, (int)M_COPYALL);
|
||||
off = m->m_pkthdr.len - m->m_len;
|
||||
type = htons(ETHERTYPE_IP);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
case AF_IPX:
|
||||
{
|
||||
struct ifaddr *ia;
|
||||
|
||||
type = htons(ETHERTYPE_IPX);
|
||||
bcopy((caddr_t)&(((struct sockaddr_ipx *)dst)->sipx_addr.x_host),
|
||||
(caddr_t)edst, sizeof (edst));
|
||||
for (ia = ifp->if_addrlist; ia != NULL; ia = ia->ifa_next)
|
||||
if(ia->ifa_addr->sa_family == AF_IPX &&
|
||||
!bcmp((caddr_t)edst,
|
||||
(caddr_t)&((struct ipx_ifaddr *)ia)->ia_addr.sipx_addr.x_host,
|
||||
sizeof(edst)))
|
||||
return (looutput(ifp, m, dst, rt));
|
||||
/* If broadcasting on a simplex interface, loopback a copy */
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
|
||||
mcopy = m_copy(m, 0, (int)M_COPYALL);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef NETATALK
|
||||
case AF_APPLETALK:
|
||||
{
|
||||
struct sockaddr_at *sat = (struct sockaddr_at *)dst;
|
||||
|
||||
/*
|
||||
* super hack..
|
||||
* Most of this loopback code should move into the appletalk
|
||||
* code, but it's here for now.. remember to move it! [JRE]
|
||||
* This may not get the same interface we started with
|
||||
* fix asap. XXX
|
||||
*/
|
||||
aa = at_ifawithnet( sat );
|
||||
if (aa == NULL) {
|
||||
goto bad;
|
||||
}
|
||||
if( aa->aa_ifa.ifa_ifp != ifp ) {
|
||||
(*aa->aa_ifa.ifa_ifp->if_output)(aa->aa_ifa.ifa_ifp,
|
||||
m,dst,rt);
|
||||
}
|
||||
if (((sat->sat_addr.s_net == ATADDR_ANYNET)
|
||||
&& (sat->sat_addr.s_node == ATADDR_ANYNODE))
|
||||
|| ((sat->sat_addr.s_net == aa->aa_addr.sat_addr.s_net )
|
||||
&& (sat->sat_addr.s_node == aa->aa_addr.sat_addr.s_node))) {
|
||||
(void) looutput(ifp, m, dst, rt);
|
||||
return(0);
|
||||
}
|
||||
|
||||
if (!aarpresolve(ac, m, (struct sockaddr_at *)dst, edst)) {
|
||||
#ifdef NETATALKDEBUG
|
||||
extern char *prsockaddr(struct sockaddr *);
|
||||
printf("aarpresolv: failed for %s\n", prsockaddr(dst));
|
||||
#endif NETATALKDEBUG
|
||||
return (0);
|
||||
}
|
||||
|
||||
/*
|
||||
* If broadcasting on a simplex interface, loopback a copy
|
||||
*/
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX))
|
||||
mcopy = m_copy(m, 0, (int)M_COPYALL);
|
||||
}
|
||||
/*
|
||||
* In the phase 2 case, we need to prepend an mbuf for the llc header.
|
||||
* Since we must preserve the value of m, which is passed to us by
|
||||
* value, we m_copy() the first mbuf, and use it for our llc header.
|
||||
*/
|
||||
if ( aa->aa_flags & AFA_PHASE2 ) {
|
||||
struct llc llc;
|
||||
|
||||
M_PREPEND(m, sizeof(struct llc), M_WAIT);
|
||||
len += sizeof(struct llc);
|
||||
llc.llc_dsap = llc.llc_ssap = LLC_SNAP_LSAP;
|
||||
llc.llc_control = LLC_UI;
|
||||
bcopy(at_org_code, llc.llc_snap_org_code, sizeof(at_org_code));
|
||||
llc.llc_snap_ether_type = htons( ETHERTYPE_AT );
|
||||
bcopy(&llc, mtod(m, caddr_t), sizeof(struct llc));
|
||||
type = htons(m->m_pkthdr.len);
|
||||
} else {
|
||||
type = htons(ETHERTYPE_AT);
|
||||
}
|
||||
break;
|
||||
#endif NETATALK
|
||||
#ifdef NS
|
||||
case AF_NS:
|
||||
switch(ns_nettype){
|
||||
default:
|
||||
case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
|
||||
type = 0x8137;
|
||||
break;
|
||||
case 0x0: /* Novell 802.3 */
|
||||
type = htons( m->m_pkthdr.len);
|
||||
break;
|
||||
case 0xe0e0: /* Novell 802.2 and Token-Ring */
|
||||
M_PREPEND(m, 3, M_WAIT);
|
||||
type = htons( m->m_pkthdr.len);
|
||||
cp = mtod(m, u_char *);
|
||||
*cp++ = 0xE0;
|
||||
*cp++ = 0xE0;
|
||||
*cp++ = 0x03;
|
||||
break;
|
||||
}
|
||||
bcopy((caddr_t)&(((struct sockaddr_ns *)dst)->sns_addr.x_host),
|
||||
(caddr_t)edst, sizeof (edst));
|
||||
if (!bcmp((caddr_t)edst, (caddr_t)&ns_thishost, sizeof(edst))){
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
schednetisr(NETISR_NS);
|
||||
inq = &nsintrq;
|
||||
s = splimp();
|
||||
if (IF_QFULL(inq)) {
|
||||
IF_DROP(inq);
|
||||
m_freem(m);
|
||||
} else
|
||||
IF_ENQUEUE(inq, m);
|
||||
splx(s);
|
||||
return (error);
|
||||
}
|
||||
if (!bcmp((caddr_t)edst, (caddr_t)&ns_broadhost, sizeof(edst))){
|
||||
m2 = m_copy(m, 0, (int)M_COPYALL);
|
||||
m2->m_pkthdr.rcvif = ifp;
|
||||
schednetisr(NETISR_NS);
|
||||
inq = &nsintrq;
|
||||
s = splimp();
|
||||
if (IF_QFULL(inq)) {
|
||||
IF_DROP(inq);
|
||||
m_freem(m2);
|
||||
} else
|
||||
IF_ENQUEUE(inq, m2);
|
||||
splx(s);
|
||||
}
|
||||
/* If broadcasting on a simplex interface, loopback a copy */
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX)){
|
||||
mcopy = m_copy(m, 0, (int)M_COPYALL);
|
||||
}
|
||||
break;
|
||||
#endif /* NS */
|
||||
#ifdef ISO
|
||||
case AF_ISO: {
|
||||
int snpalen;
|
||||
struct llc *l;
|
||||
register struct sockaddr_dl *sdl;
|
||||
|
||||
if (rt && (sdl = (struct sockaddr_dl *)rt->rt_gateway) &&
|
||||
sdl->sdl_family == AF_LINK && sdl->sdl_alen > 0) {
|
||||
bcopy(LLADDR(sdl), (caddr_t)edst, sizeof(edst));
|
||||
} else if (error =
|
||||
iso_snparesolve(ifp, (struct sockaddr_iso *)dst,
|
||||
(char *)edst, &snpalen))
|
||||
goto bad; /* Not Resolved */
|
||||
/* If broadcasting on a simplex interface, loopback a copy */
|
||||
if (*edst & 1)
|
||||
m->m_flags |= (M_BCAST|M_MCAST);
|
||||
if ((m->m_flags & M_BCAST) && (ifp->if_flags & IFF_SIMPLEX) &&
|
||||
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
|
||||
M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
|
||||
if (mcopy) {
|
||||
eh = mtod(mcopy, struct ether_header *);
|
||||
bcopy((caddr_t)edst,
|
||||
(caddr_t)eh->ether_dhost, sizeof (edst));
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)eh->ether_shost, sizeof (edst));
|
||||
}
|
||||
}
|
||||
M_PREPEND(m, 3, M_DONTWAIT);
|
||||
if (m == NULL)
|
||||
return (0);
|
||||
type = htons(m->m_pkthdr.len);
|
||||
l = mtod(m, struct llc *);
|
||||
l->llc_dsap = l->llc_ssap = LLC_ISO_LSAP;
|
||||
l->llc_control = LLC_UI;
|
||||
len += 3;
|
||||
IFDEBUG(D_ETHER)
|
||||
int i;
|
||||
printf("unoutput: sending pkt to: ");
|
||||
for (i=0; i<6; i++)
|
||||
printf("%x ", edst[i] & 0xff);
|
||||
printf("\n");
|
||||
ENDDEBUG
|
||||
} break;
|
||||
#endif /* ISO */
|
||||
#ifdef LLC
|
||||
/* case AF_NSAP: */
|
||||
case AF_CCITT: {
|
||||
register struct sockaddr_dl *sdl =
|
||||
(struct sockaddr_dl *) rt -> rt_gateway;
|
||||
|
||||
if (sdl && sdl->sdl_family == AF_LINK
|
||||
&& sdl->sdl_alen > 0) {
|
||||
bcopy(LLADDR(sdl), (char *)edst,
|
||||
sizeof(edst));
|
||||
} else goto bad; /* Not a link interface ? Funny ... */
|
||||
if ((ifp->if_flags & IFF_SIMPLEX) && (*edst & 1) &&
|
||||
(mcopy = m_copy(m, 0, (int)M_COPYALL))) {
|
||||
M_PREPEND(mcopy, sizeof (*eh), M_DONTWAIT);
|
||||
if (mcopy) {
|
||||
eh = mtod(mcopy, struct ether_header *);
|
||||
bcopy((caddr_t)edst,
|
||||
(caddr_t)eh->ether_dhost, sizeof (edst));
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)eh->ether_shost, sizeof (edst));
|
||||
}
|
||||
}
|
||||
type = htons(m->m_pkthdr.len);
|
||||
#ifdef LLC_DEBUG
|
||||
{
|
||||
int i;
|
||||
register struct llc *l = mtod(m, struct llc *);
|
||||
|
||||
printf("ether_output: sending LLC2 pkt to: ");
|
||||
for (i=0; i<6; i++)
|
||||
printf("%x ", edst[i] & 0xff);
|
||||
printf(" len 0x%x dsap 0x%x ssap 0x%x control 0x%x\n",
|
||||
type & 0xff, l->llc_dsap & 0xff, l->llc_ssap &0xff,
|
||||
l->llc_control & 0xff);
|
||||
|
||||
}
|
||||
#endif /* LLC_DEBUG */
|
||||
} break;
|
||||
#endif /* LLC */
|
||||
|
||||
case AF_UNSPEC:
|
||||
eh = (struct ether_header *)dst->sa_data;
|
||||
(void)memcpy(edst, eh->ether_dhost, sizeof (edst));
|
||||
type = eh->ether_type;
|
||||
break;
|
||||
|
||||
default:
|
||||
printf("%s%d: can't handle af%d\n", ifp->if_name, ifp->if_unit,
|
||||
dst->sa_family);
|
||||
senderr(EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
|
||||
if (mcopy)
|
||||
(void) looutput(ifp, mcopy, dst, rt);
|
||||
/*
|
||||
* Add local net header. If no space in first mbuf,
|
||||
* allocate another.
|
||||
*/
|
||||
M_PREPEND(m, sizeof (struct ether_header), M_DONTWAIT);
|
||||
if (m == 0)
|
||||
senderr(ENOBUFS);
|
||||
eh = mtod(m, struct ether_header *);
|
||||
(void)memcpy(&eh->ether_type, &type,
|
||||
sizeof(eh->ether_type));
|
||||
(void)memcpy(eh->ether_dhost, edst, sizeof (edst));
|
||||
(void)memcpy(eh->ether_shost, ac->ac_enaddr,
|
||||
sizeof(eh->ether_shost));
|
||||
s = splimp();
|
||||
/*
|
||||
* Queue message on interface, and start output if interface
|
||||
* not yet active.
|
||||
*/
|
||||
if (IF_QFULL(&ifp->if_snd)) {
|
||||
IF_DROP(&ifp->if_snd);
|
||||
splx(s);
|
||||
senderr(ENOBUFS);
|
||||
}
|
||||
IF_ENQUEUE(&ifp->if_snd, m);
|
||||
if ((ifp->if_flags & IFF_OACTIVE) == 0)
|
||||
(*ifp->if_start)(ifp);
|
||||
splx(s);
|
||||
ifp->if_obytes += len + sizeof (struct ether_header);
|
||||
if (m->m_flags & M_MCAST)
|
||||
ifp->if_omcasts++;
|
||||
return (error);
|
||||
|
||||
bad:
|
||||
if (m)
|
||||
m_freem(m);
|
||||
return (error);
|
||||
}
|
||||
|
||||
/*
|
||||
* Process a received Ethernet packet;
|
||||
* the packet is in the mbuf chain m without
|
||||
* the ether header, which is provided separately.
|
||||
*/
|
||||
void
|
||||
ether_input(ifp, eh, m)
|
||||
struct ifnet *ifp;
|
||||
register struct ether_header *eh;
|
||||
struct mbuf *m;
|
||||
{
|
||||
register struct ifqueue *inq;
|
||||
u_short ether_type, *checksum;
|
||||
int s;
|
||||
#if defined (ISO) || defined (LLC) || defined(NETATALK)
|
||||
register struct llc *l;
|
||||
#endif
|
||||
|
||||
if ((ifp->if_flags & IFF_UP) == 0) {
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
ifp->if_ibytes += m->m_pkthdr.len + sizeof (*eh);
|
||||
if (bcmp((caddr_t)etherbroadcastaddr, (caddr_t)eh->ether_dhost,
|
||||
sizeof(etherbroadcastaddr)) == 0)
|
||||
m->m_flags |= M_BCAST;
|
||||
else if (eh->ether_dhost[0] & 1)
|
||||
m->m_flags |= M_MCAST;
|
||||
if (m->m_flags & (M_BCAST|M_MCAST))
|
||||
ifp->if_imcasts++;
|
||||
|
||||
ether_type = ntohs(eh->ether_type);
|
||||
|
||||
switch (ether_type) {
|
||||
#ifdef INET
|
||||
case ETHERTYPE_IP:
|
||||
schednetisr(NETISR_IP);
|
||||
inq = &ipintrq;
|
||||
break;
|
||||
|
||||
case ETHERTYPE_ARP:
|
||||
schednetisr(NETISR_ARP);
|
||||
inq = &arpintrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
case ETHERTYPE_IPX:
|
||||
schednetisr(NETISR_IPX);
|
||||
inq = &ipxintrq;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS
|
||||
case 0x8137: /* Novell Ethernet_II Ethernet TYPE II */
|
||||
schednetisr(NETISR_NS);
|
||||
inq = &nsintrq;
|
||||
break;
|
||||
|
||||
#endif /* NS */
|
||||
#ifdef NETATALK
|
||||
case ETHERTYPE_AT:
|
||||
schednetisr(NETISR_ATALK);
|
||||
inq = &atintrq1;
|
||||
break;
|
||||
case ETHERTYPE_AARP:
|
||||
/* probably this should be done with a NETISR as well */
|
||||
aarpinput((struct arpcom *)ifp, m); /* XXX */
|
||||
return;
|
||||
#endif NETATALK
|
||||
default:
|
||||
#ifdef NS
|
||||
checksum = mtod(m, ushort *);
|
||||
/* Novell 802.3 */
|
||||
if ((ether_type <= ETHERMTU) &&
|
||||
((*checksum == 0xffff) || (*checksum == 0xE0E0))){
|
||||
if(*checksum == 0xE0E0) {
|
||||
m->m_pkthdr.len -= 3;
|
||||
m->m_len -= 3;
|
||||
m->m_data += 3;
|
||||
}
|
||||
schednetisr(NETISR_NS);
|
||||
inq = &nsintrq;
|
||||
break;
|
||||
}
|
||||
#endif /* NS */
|
||||
#if defined (ISO) || defined (LLC) || defined(NETATALK)
|
||||
if (ether_type > ETHERMTU)
|
||||
goto dropanyway;
|
||||
l = mtod(m, struct llc *);
|
||||
switch (l->llc_dsap) {
|
||||
#ifdef NETATALK
|
||||
case LLC_SNAP_LSAP:
|
||||
switch (l->llc_control) {
|
||||
case LLC_UI:
|
||||
if (l->llc_ssap != LLC_SNAP_LSAP)
|
||||
goto dropanyway;
|
||||
|
||||
if (Bcmp(&(l->llc_snap_org_code)[0], at_org_code,
|
||||
sizeof(at_org_code)) == 0 &&
|
||||
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AT) {
|
||||
inq = &atintrq2;
|
||||
m_adj( m, sizeof( struct llc ));
|
||||
schednetisr(NETISR_ATALK);
|
||||
break;
|
||||
}
|
||||
|
||||
if (Bcmp(&(l->llc_snap_org_code)[0], aarp_org_code,
|
||||
sizeof(aarp_org_code)) == 0 &&
|
||||
ntohs(l->llc_snap_ether_type) == ETHERTYPE_AARP) {
|
||||
m_adj( m, sizeof( struct llc ));
|
||||
aarpinput((struct arpcom *)ifp, m); /* XXX */
|
||||
return;
|
||||
}
|
||||
|
||||
default:
|
||||
goto dropanyway;
|
||||
}
|
||||
break;
|
||||
#endif NETATALK
|
||||
#ifdef ISO
|
||||
case LLC_ISO_LSAP:
|
||||
switch (l->llc_control) {
|
||||
case LLC_UI:
|
||||
/* LLC_UI_P forbidden in class 1 service */
|
||||
if ((l->llc_dsap == LLC_ISO_LSAP) &&
|
||||
(l->llc_ssap == LLC_ISO_LSAP)) {
|
||||
/* LSAP for ISO */
|
||||
if (m->m_pkthdr.len > ether_type)
|
||||
m_adj(m, ether_type - m->m_pkthdr.len);
|
||||
m->m_data += 3; /* XXX */
|
||||
m->m_len -= 3; /* XXX */
|
||||
m->m_pkthdr.len -= 3; /* XXX */
|
||||
M_PREPEND(m, sizeof *eh, M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return;
|
||||
*mtod(m, struct ether_header *) = *eh;
|
||||
IFDEBUG(D_ETHER)
|
||||
printf("clnp packet");
|
||||
ENDDEBUG
|
||||
schednetisr(NETISR_ISO);
|
||||
inq = &clnlintrq;
|
||||
break;
|
||||
}
|
||||
goto dropanyway;
|
||||
|
||||
case LLC_XID:
|
||||
case LLC_XID_P:
|
||||
if(m->m_len < 6)
|
||||
goto dropanyway;
|
||||
l->llc_window = 0;
|
||||
l->llc_fid = 9;
|
||||
l->llc_class = 1;
|
||||
l->llc_dsap = l->llc_ssap = 0;
|
||||
/* Fall through to */
|
||||
case LLC_TEST:
|
||||
case LLC_TEST_P:
|
||||
{
|
||||
struct sockaddr sa;
|
||||
register struct ether_header *eh2;
|
||||
int i;
|
||||
u_char c = l->llc_dsap;
|
||||
|
||||
l->llc_dsap = l->llc_ssap;
|
||||
l->llc_ssap = c;
|
||||
if (m->m_flags & (M_BCAST | M_MCAST))
|
||||
bcopy((caddr_t)ac->ac_enaddr,
|
||||
(caddr_t)eh->ether_dhost, 6);
|
||||
sa.sa_family = AF_UNSPEC;
|
||||
sa.sa_len = sizeof(sa);
|
||||
eh2 = (struct ether_header *)sa.sa_data;
|
||||
for (i = 0; i < 6; i++) {
|
||||
eh2->ether_shost[i] = c = eh->ether_dhost[i];
|
||||
eh2->ether_dhost[i] =
|
||||
eh->ether_dhost[i] = eh->ether_shost[i];
|
||||
eh->ether_shost[i] = c;
|
||||
}
|
||||
ifp->if_output(ifp, m, &sa, NULL);
|
||||
return;
|
||||
}
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
break;
|
||||
#endif /* ISO */
|
||||
#ifdef LLC
|
||||
case LLC_X25_LSAP:
|
||||
{
|
||||
if (m->m_pkthdr.len > ether_type)
|
||||
m_adj(m, ether_type - m->m_pkthdr.len);
|
||||
M_PREPEND(m, sizeof(struct sdl_hdr) , M_DONTWAIT);
|
||||
if (m == 0)
|
||||
return;
|
||||
if ( !sdl_sethdrif(ifp, eh->ether_shost, LLC_X25_LSAP,
|
||||
eh->ether_dhost, LLC_X25_LSAP, 6,
|
||||
mtod(m, struct sdl_hdr *)))
|
||||
panic("ETHER cons addr failure");
|
||||
mtod(m, struct sdl_hdr *)->sdlhdr_len = ether_type;
|
||||
#ifdef LLC_DEBUG
|
||||
printf("llc packet\n");
|
||||
#endif /* LLC_DEBUG */
|
||||
schednetisr(NETISR_CCITT);
|
||||
inq = &llcintrq;
|
||||
break;
|
||||
}
|
||||
#endif /* LLC */
|
||||
dropanyway:
|
||||
default:
|
||||
m_freem(m);
|
||||
return;
|
||||
}
|
||||
#else /* ISO || LLC || NETATALK */
|
||||
m_freem(m);
|
||||
return;
|
||||
#endif /* ISO || LLC || NETATALK */
|
||||
}
|
||||
|
||||
s = splimp();
|
||||
if (IF_QFULL(inq)) {
|
||||
IF_DROP(inq);
|
||||
m_freem(m);
|
||||
} else
|
||||
IF_ENQUEUE(inq, m);
|
||||
splx(s);
|
||||
}
|
||||
|
||||
/*
|
||||
* Perform common duties while attaching to interface list
|
||||
*/
|
||||
void
|
||||
ether_ifattach(ifp)
|
||||
register struct ifnet *ifp;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
register struct sockaddr_dl *sdl;
|
||||
|
||||
ifp->if_type = IFT_ETHER;
|
||||
ifp->if_addrlen = 6;
|
||||
ifp->if_hdrlen = 14;
|
||||
ifp->if_mtu = ETHERMTU;
|
||||
if (ifp->if_baudrate == 0)
|
||||
ifp->if_baudrate = 10000000;
|
||||
for (ifa = ifp->if_addrlist; ifa; ifa = ifa->ifa_next)
|
||||
if ((sdl = (struct sockaddr_dl *)ifa->ifa_addr) &&
|
||||
sdl->sdl_family == AF_LINK) {
|
||||
sdl->sdl_type = IFT_ETHER;
|
||||
sdl->sdl_alen = ifp->if_addrlen;
|
||||
bcopy((caddr_t)((struct arpcom *)ifp)->ac_enaddr,
|
||||
LLADDR(sdl), ifp->if_addrlen);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static u_char ether_ipmulticast_min[6] =
|
||||
{ 0x01, 0x00, 0x5e, 0x00, 0x00, 0x00 };
|
||||
static u_char ether_ipmulticast_max[6] =
|
||||
{ 0x01, 0x00, 0x5e, 0x7f, 0xff, 0xff };
|
||||
/*
|
||||
* Add an Ethernet multicast address or range of addresses to the list for a
|
||||
* given interface.
|
||||
*/
|
||||
int
|
||||
ether_addmulti(ifr, ac)
|
||||
struct ifreq *ifr;
|
||||
register struct arpcom *ac;
|
||||
{
|
||||
register struct ether_multi *enm;
|
||||
struct sockaddr_in *sin;
|
||||
u_char addrlo[6];
|
||||
u_char addrhi[6];
|
||||
int set_allmulti = 0;
|
||||
int s = splimp();
|
||||
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
|
||||
case AF_UNSPEC:
|
||||
bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
|
||||
bcopy(addrlo, addrhi, 6);
|
||||
break;
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)&(ifr->ifr_addr);
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY) {
|
||||
/*
|
||||
* An IP address of INADDR_ANY means listen to all
|
||||
* of the Ethernet multicast addresses used for IP.
|
||||
* (This is for the sake of IP multicast routers.)
|
||||
*/
|
||||
bcopy(ether_ipmulticast_min, addrlo, 6);
|
||||
bcopy(ether_ipmulticast_max, addrhi, 6);
|
||||
set_allmulti = 1;
|
||||
}
|
||||
else {
|
||||
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
|
||||
bcopy(addrlo, addrhi, 6);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
splx(s);
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Verify that we have valid Ethernet multicast addresses.
|
||||
*/
|
||||
if ((addrlo[0] & 0x01) != 1 || (addrhi[0] & 0x01) != 1) {
|
||||
splx(s);
|
||||
return (EINVAL);
|
||||
}
|
||||
/*
|
||||
* See if the address range is already in the list.
|
||||
*/
|
||||
ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
|
||||
if (enm != NULL) {
|
||||
/*
|
||||
* Found it; just increment the reference count.
|
||||
*/
|
||||
++enm->enm_refcount;
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* New address or range; malloc a new multicast record
|
||||
* and link it into the interface's multicast list.
|
||||
*/
|
||||
enm = (struct ether_multi *)malloc(sizeof(*enm), M_IFMADDR, M_NOWAIT);
|
||||
if (enm == NULL) {
|
||||
splx(s);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
bcopy(addrlo, enm->enm_addrlo, 6);
|
||||
bcopy(addrhi, enm->enm_addrhi, 6);
|
||||
enm->enm_ac = ac;
|
||||
enm->enm_refcount = 1;
|
||||
enm->enm_next = ac->ac_multiaddrs;
|
||||
ac->ac_multiaddrs = enm;
|
||||
ac->ac_multicnt++;
|
||||
splx(s);
|
||||
if (set_allmulti)
|
||||
ac->ac_if.if_flags |= IFF_ALLMULTI;
|
||||
|
||||
/*
|
||||
* Return ENETRESET to inform the driver that the list has changed
|
||||
* and its reception filter should be adjusted accordingly.
|
||||
*/
|
||||
return (ENETRESET);
|
||||
}
|
||||
|
||||
/*
|
||||
* Delete a multicast address record.
|
||||
*/
|
||||
int
|
||||
ether_delmulti(ifr, ac)
|
||||
struct ifreq *ifr;
|
||||
register struct arpcom *ac;
|
||||
{
|
||||
register struct ether_multi *enm;
|
||||
register struct ether_multi **p;
|
||||
struct sockaddr_in *sin;
|
||||
u_char addrlo[6];
|
||||
u_char addrhi[6];
|
||||
int unset_allmulti = 0;
|
||||
int s = splimp();
|
||||
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
|
||||
case AF_UNSPEC:
|
||||
bcopy(ifr->ifr_addr.sa_data, addrlo, 6);
|
||||
bcopy(addrlo, addrhi, 6);
|
||||
break;
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
sin = (struct sockaddr_in *)&(ifr->ifr_addr);
|
||||
if (sin->sin_addr.s_addr == INADDR_ANY) {
|
||||
/*
|
||||
* An IP address of INADDR_ANY means stop listening
|
||||
* to the range of Ethernet multicast addresses used
|
||||
* for IP.
|
||||
*/
|
||||
bcopy(ether_ipmulticast_min, addrlo, 6);
|
||||
bcopy(ether_ipmulticast_max, addrhi, 6);
|
||||
unset_allmulti = 1;
|
||||
}
|
||||
else {
|
||||
ETHER_MAP_IP_MULTICAST(&sin->sin_addr, addrlo);
|
||||
bcopy(addrlo, addrhi, 6);
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
splx(s);
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
|
||||
/*
|
||||
* Look up the address in our list.
|
||||
*/
|
||||
ETHER_LOOKUP_MULTI(addrlo, addrhi, ac, enm);
|
||||
if (enm == NULL) {
|
||||
splx(s);
|
||||
return (ENXIO);
|
||||
}
|
||||
if (--enm->enm_refcount != 0) {
|
||||
/*
|
||||
* Still some claims to this record.
|
||||
*/
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
/*
|
||||
* No remaining claims to this record; unlink and free it.
|
||||
*/
|
||||
for (p = &enm->enm_ac->ac_multiaddrs;
|
||||
*p != enm;
|
||||
p = &(*p)->enm_next)
|
||||
continue;
|
||||
*p = (*p)->enm_next;
|
||||
free(enm, M_IFMADDR);
|
||||
ac->ac_multicnt--;
|
||||
splx(s);
|
||||
if (unset_allmulti)
|
||||
ac->ac_if.if_flags &= ~IFF_ALLMULTI;
|
||||
|
||||
/*
|
||||
* Return ENETRESET to inform the driver that the list has changed
|
||||
* and its reception filter should be adjusted accordingly.
|
||||
*/
|
||||
return (ENETRESET);
|
||||
}
|
||||
|
||||
SYSCTL_NODE(_net_link, IFT_ETHER, ether, CTLFLAG_RW, 0, "Ethernet");
|
||||
|
||||
int
|
||||
ether_ioctl(struct ifnet *ifp, int command, caddr_t data)
|
||||
{
|
||||
struct ifaddr *ifa = (struct ifaddr *) data;
|
||||
struct ifreq *ifr = (struct ifreq *) data;
|
||||
int error = 0;
|
||||
|
||||
switch (command) {
|
||||
case SIOCSIFADDR:
|
||||
ifp->if_flags |= IFF_UP;
|
||||
|
||||
switch (ifa->ifa_addr->sa_family) {
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
ifp->if_init(ifp->if_softc); /* before arpwhohas */
|
||||
arp_ifinit((struct arpcom *)ifp, ifa);
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
/*
|
||||
* XXX - This code is probably wrong
|
||||
*/
|
||||
case AF_IPX:
|
||||
{
|
||||
register struct ipx_addr *ina = &(IA_SIPX(ifa)->sipx_addr);
|
||||
struct arpcom *ac = (struct arpcom *) (ifp->if_softc);
|
||||
|
||||
if (ipx_nullhost(*ina))
|
||||
ina->x_host =
|
||||
*(union ipx_host *)
|
||||
ac->ac_enaddr;
|
||||
else {
|
||||
bcopy((caddr_t) ina->x_host.c_host,
|
||||
(caddr_t) ac->ac_enaddr,
|
||||
sizeof(ac->ac_enaddr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new address
|
||||
*/
|
||||
ifp->if_init(ifp->if_softc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#ifdef NS
|
||||
/*
|
||||
* XXX - This code is probably wrong
|
||||
*/
|
||||
case AF_NS:
|
||||
{
|
||||
register struct ns_addr *ina = &(IA_SNS(ifa)->sns_addr);
|
||||
struct arpcom *ac = (struct arpcom *) (ifp->if_softc);
|
||||
|
||||
if (ns_nullhost(*ina))
|
||||
ina->x_host =
|
||||
*(union ns_host *) (ac->ac_enaddr);
|
||||
else {
|
||||
bcopy((caddr_t) ina->x_host.c_host,
|
||||
(caddr_t) ac->ac_enaddr,
|
||||
sizeof(ac->ac_enaddr));
|
||||
}
|
||||
|
||||
/*
|
||||
* Set new address
|
||||
*/
|
||||
ifp->if_init(ifp->if_softc);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
default:
|
||||
ifp->if_init(ifp->if_softc);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCGIFADDR:
|
||||
{
|
||||
struct sockaddr *sa;
|
||||
|
||||
sa = (struct sockaddr *) & ifr->ifr_data;
|
||||
bcopy(((struct arpcom *)ifp->if_softc)->ac_enaddr,
|
||||
(caddr_t) sa->sa_data, ETHER_ADDR_LEN);
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSIFMTU:
|
||||
/*
|
||||
* Set the interface MTU.
|
||||
*/
|
||||
if (ifr->ifr_mtu > ETHERMTU) {
|
||||
error = EINVAL;
|
||||
} else {
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
145
c/src/exec/libnetworking/net/if_llc.h
Normal file
145
c/src/exec/libnetworking/net/if_llc.h
Normal file
@@ -0,0 +1,145 @@
|
||||
/*
|
||||
* Copyright (c) 1988, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_llc.h 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_LLC_H_
|
||||
#define _NET_IF_LLC_H_
|
||||
|
||||
/*
|
||||
* IEEE 802.2 Link Level Control headers, for use in conjunction with
|
||||
* 802.{3,4,5} media access control methods.
|
||||
*
|
||||
* Headers here do not use bit fields due to shortcomings in many
|
||||
* compilers.
|
||||
*/
|
||||
|
||||
struct llc {
|
||||
u_char llc_dsap;
|
||||
u_char llc_ssap;
|
||||
union {
|
||||
struct {
|
||||
u_char control;
|
||||
u_char format_id;
|
||||
u_char class;
|
||||
u_char window_x2;
|
||||
} type_u;
|
||||
struct {
|
||||
u_char num_snd_x2;
|
||||
u_char num_rcv_x2;
|
||||
} type_i;
|
||||
struct {
|
||||
u_char control;
|
||||
u_char num_rcv_x2;
|
||||
} type_s;
|
||||
struct {
|
||||
u_char control;
|
||||
struct frmrinfo {
|
||||
u_char rej_pdu_0;
|
||||
u_char rej_pdu_1;
|
||||
u_char frmr_control;
|
||||
u_char frmr_control_ext;
|
||||
u_char frmr_cause;
|
||||
} frmrinfo;
|
||||
} type_frmr;
|
||||
struct {
|
||||
u_char control;
|
||||
u_char org_code[3];
|
||||
u_short ether_type;
|
||||
} type_snap;
|
||||
struct {
|
||||
u_char control;
|
||||
u_char control_ext;
|
||||
} type_raw;
|
||||
} llc_un;
|
||||
};
|
||||
#define llc_control llc_un.type_u.control
|
||||
#define llc_control_ext llc_un.type_raw.control_ext
|
||||
#define llc_fid llc_un.type_u.format_id
|
||||
#define llc_class llc_un.type_u.class
|
||||
#define llc_window llc_un.type_u.window_x2
|
||||
#define llc_frmrinfo llc_un.type_frmr.frmrinfo
|
||||
#define llc_frmr_pdu0 llc_un.type_frmr.frmrinfo.rej_pdu0
|
||||
#define llc_frmr_pdu1 llc_un.type_frmr.frmrinfo.rej_pdu1
|
||||
#define llc_frmr_control llc_un.type_frmr.frmrinfo.frmr_control
|
||||
#define llc_frmr_control_ext llc_un.type_frmr.frmrinfo.frmr_control_ext
|
||||
#define llc_frmr_cause llc_un.type_frmr.frmrinfo.frmr_control_ext
|
||||
|
||||
/*
|
||||
* Don't use sizeof(struct llc_un) for LLC header sizes
|
||||
*/
|
||||
#define LLC_ISFRAMELEN 4
|
||||
#define LLC_UFRAMELEN 3
|
||||
#define LLC_FRMRLEN 7
|
||||
|
||||
/*
|
||||
* Unnumbered LLC format commands
|
||||
*/
|
||||
#define LLC_UI 0x3
|
||||
#define LLC_UI_P 0x13
|
||||
#define LLC_DISC 0x43
|
||||
#define LLC_DISC_P 0x53
|
||||
#define LLC_UA 0x63
|
||||
#define LLC_UA_P 0x73
|
||||
#define LLC_TEST 0xe3
|
||||
#define LLC_TEST_P 0xf3
|
||||
#define LLC_FRMR 0x87
|
||||
#define LLC_FRMR_P 0x97
|
||||
#define LLC_DM 0x0f
|
||||
#define LLC_DM_P 0x1f
|
||||
#define LLC_XID 0xaf
|
||||
#define LLC_XID_P 0xbf
|
||||
#define LLC_SABME 0x6f
|
||||
#define LLC_SABME_P 0x7f
|
||||
|
||||
/*
|
||||
* Supervisory LLC commands
|
||||
*/
|
||||
#define LLC_RR 0x01
|
||||
#define LLC_RNR 0x05
|
||||
#define LLC_REJ 0x09
|
||||
|
||||
/*
|
||||
* Info format - dummy only
|
||||
*/
|
||||
#define LLC_INFO 0x00
|
||||
|
||||
/*
|
||||
* ISO PDTR 10178 contains among others
|
||||
*/
|
||||
#define LLC_X25_LSAP 0x7e
|
||||
#define LLC_SNAP_LSAP 0xaa
|
||||
#define LLC_ISO_LSAP 0xfe
|
||||
|
||||
#endif
|
||||
301
c/src/exec/libnetworking/net/if_loop.c
Normal file
301
c/src/exec/libnetworking/net/if_loop.c
Normal file
@@ -0,0 +1,301 @@
|
||||
/*
|
||||
* Copyright (c) 1982, 1986, 1993
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_loop.c 8.1 (Berkeley) 6/10/93
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
/*
|
||||
* Loopback interface driver for protocol testing and timing.
|
||||
*/
|
||||
#include "loop.h"
|
||||
#if NLOOP > 0
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/systm.h>
|
||||
#include <sys/kernel.h>
|
||||
#include <sys/mbuf.h>
|
||||
#include <sys/socket.h>
|
||||
#include <sys/errno.h>
|
||||
#include <sys/ioctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <net/if.h>
|
||||
#include <net/if_types.h>
|
||||
#include <net/netisr.h>
|
||||
#include <net/route.h>
|
||||
#include <net/bpf.h>
|
||||
|
||||
#ifdef INET
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/in_systm.h>
|
||||
#include <netinet/in_var.h>
|
||||
#include <netinet/ip.h>
|
||||
#endif
|
||||
|
||||
#ifdef IPX
|
||||
#include <netipx/ipx.h>
|
||||
#include <netipx/ipx_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef NS
|
||||
#include <netns/ns.h>
|
||||
#include <netns/ns_if.h>
|
||||
#endif
|
||||
|
||||
#ifdef ISO
|
||||
#include <netiso/iso.h>
|
||||
#include <netiso/iso_var.h>
|
||||
#endif
|
||||
|
||||
#ifdef NETATALK
|
||||
#include <netinet/if_ether.h>
|
||||
#include <netatalk/at.h>
|
||||
#include <netatalk/at_var.h>
|
||||
#endif NETATALK
|
||||
|
||||
#include "bpfilter.h"
|
||||
|
||||
static int loioctl __P((struct ifnet *, int, caddr_t));
|
||||
static void lortrequest __P((int, struct rtentry *, struct sockaddr *));
|
||||
|
||||
void rtems_bsdnet_loopattach __P((void *));
|
||||
PSEUDO_SET(loopattach, if_loop);
|
||||
|
||||
#ifdef TINY_LOMTU
|
||||
#define LOMTU (1024+512)
|
||||
#else
|
||||
#define LOMTU 16384
|
||||
#endif
|
||||
|
||||
struct ifnet loif[NLOOP];
|
||||
|
||||
/* ARGSUSED */
|
||||
void
|
||||
rtems_bsdnet_loopattach(dummy)
|
||||
void *dummy;
|
||||
{
|
||||
register struct ifnet *ifp;
|
||||
register int i = 0;
|
||||
|
||||
for (ifp = loif; i < NLOOP; ifp++) {
|
||||
ifp->if_name = "lo";
|
||||
ifp->if_next = NULL;
|
||||
ifp->if_unit = i++;
|
||||
ifp->if_mtu = LOMTU;
|
||||
ifp->if_flags = IFF_LOOPBACK | IFF_MULTICAST;
|
||||
ifp->if_ioctl = loioctl;
|
||||
ifp->if_output = looutput;
|
||||
ifp->if_type = IFT_LOOP;
|
||||
ifp->if_hdrlen = 0;
|
||||
ifp->if_addrlen = 0;
|
||||
if_attach(ifp);
|
||||
#if NBPFILTER > 0
|
||||
bpfattach(ifp, DLT_NULL, sizeof(u_int));
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
int
|
||||
looutput(ifp, m, dst, rt)
|
||||
struct ifnet *ifp;
|
||||
register struct mbuf *m;
|
||||
struct sockaddr *dst;
|
||||
register struct rtentry *rt;
|
||||
{
|
||||
int s, isr;
|
||||
register struct ifqueue *ifq = 0;
|
||||
|
||||
if ((m->m_flags & M_PKTHDR) == 0)
|
||||
panic("looutput no HDR");
|
||||
#if NBPFILTER > 0
|
||||
/* BPF write needs to be handled specially */
|
||||
if (dst->sa_family == AF_UNSPEC) {
|
||||
dst->sa_family = *(mtod(m, int *));
|
||||
m->m_len -= sizeof(int);
|
||||
m->m_pkthdr.len -= sizeof(int);
|
||||
m->m_data += sizeof(int);
|
||||
}
|
||||
|
||||
if (ifp->if_bpf) {
|
||||
/*
|
||||
* We need to prepend the address family as
|
||||
* a four byte field. Cons up a dummy header
|
||||
* to pacify bpf. This is safe because bpf
|
||||
* will only read from the mbuf (i.e., it won't
|
||||
* try to free it or keep a pointer a to it).
|
||||
*/
|
||||
struct mbuf m0;
|
||||
u_int af = dst->sa_family;
|
||||
|
||||
m0.m_next = m;
|
||||
m0.m_len = 4;
|
||||
m0.m_data = (char *)⁡
|
||||
|
||||
bpf_mtap(ifp, &m0);
|
||||
}
|
||||
#endif
|
||||
m->m_pkthdr.rcvif = ifp;
|
||||
|
||||
if (rt && rt->rt_flags & (RTF_REJECT|RTF_BLACKHOLE)) {
|
||||
m_freem(m);
|
||||
return (rt->rt_flags & RTF_BLACKHOLE ? 0 :
|
||||
rt->rt_flags & RTF_HOST ? EHOSTUNREACH : ENETUNREACH);
|
||||
}
|
||||
ifp->if_opackets++;
|
||||
ifp->if_obytes += m->m_pkthdr.len;
|
||||
switch (dst->sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
ifq = &ipintrq;
|
||||
isr = NETISR_IP;
|
||||
break;
|
||||
#endif
|
||||
#ifdef IPX
|
||||
case AF_IPX:
|
||||
ifq = &ipxintrq;
|
||||
isr = NETISR_IPX;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NS
|
||||
case AF_NS:
|
||||
ifq = &nsintrq;
|
||||
isr = NETISR_NS;
|
||||
break;
|
||||
#endif
|
||||
#ifdef ISO
|
||||
case AF_ISO:
|
||||
ifq = &clnlintrq;
|
||||
isr = NETISR_ISO;
|
||||
break;
|
||||
#endif
|
||||
#ifdef NETATALK
|
||||
case AF_APPLETALK:
|
||||
ifq = &atintrq2;
|
||||
isr = NETISR_ATALK;
|
||||
break;
|
||||
#endif NETATALK
|
||||
default:
|
||||
printf("lo%d: can't handle af%d\n", ifp->if_unit,
|
||||
dst->sa_family);
|
||||
m_freem(m);
|
||||
return (EAFNOSUPPORT);
|
||||
}
|
||||
s = splimp();
|
||||
if (IF_QFULL(ifq)) {
|
||||
IF_DROP(ifq);
|
||||
m_freem(m);
|
||||
splx(s);
|
||||
return (ENOBUFS);
|
||||
}
|
||||
IF_ENQUEUE(ifq, m);
|
||||
schednetisr(isr);
|
||||
ifp->if_ipackets++;
|
||||
ifp->if_ibytes += m->m_pkthdr.len;
|
||||
splx(s);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* ARGSUSED */
|
||||
static void
|
||||
lortrequest(cmd, rt, sa)
|
||||
int cmd;
|
||||
struct rtentry *rt;
|
||||
struct sockaddr *sa;
|
||||
{
|
||||
if (rt) {
|
||||
rt->rt_rmx.rmx_mtu = rt->rt_ifp->if_mtu; /* for ISO */
|
||||
/*
|
||||
* For optimal performance, the send and receive buffers
|
||||
* should be at least twice the MTU plus a little more for
|
||||
* overhead.
|
||||
*/
|
||||
rt->rt_rmx.rmx_recvpipe =
|
||||
rt->rt_rmx.rmx_sendpipe = 3 * LOMTU;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Process an ioctl request.
|
||||
*/
|
||||
/* ARGSUSED */
|
||||
static int
|
||||
loioctl(ifp, cmd, data)
|
||||
register struct ifnet *ifp;
|
||||
int cmd;
|
||||
caddr_t data;
|
||||
{
|
||||
register struct ifaddr *ifa;
|
||||
register struct ifreq *ifr = (struct ifreq *)data;
|
||||
register int error = 0;
|
||||
|
||||
switch (cmd) {
|
||||
|
||||
case SIOCSIFADDR:
|
||||
ifp->if_flags |= IFF_UP | IFF_RUNNING;
|
||||
ifa = (struct ifaddr *)data;
|
||||
ifa->ifa_rtrequest = lortrequest;
|
||||
/*
|
||||
* Everything else is done at a higher level.
|
||||
*/
|
||||
break;
|
||||
|
||||
case SIOCADDMULTI:
|
||||
case SIOCDELMULTI:
|
||||
if (ifr == 0) {
|
||||
error = EAFNOSUPPORT; /* XXX */
|
||||
break;
|
||||
}
|
||||
switch (ifr->ifr_addr.sa_family) {
|
||||
|
||||
#ifdef INET
|
||||
case AF_INET:
|
||||
break;
|
||||
#endif
|
||||
|
||||
default:
|
||||
error = EAFNOSUPPORT;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case SIOCSIFMTU:
|
||||
ifp->if_mtu = ifr->ifr_mtu;
|
||||
break;
|
||||
|
||||
default:
|
||||
error = EINVAL;
|
||||
}
|
||||
return (error);
|
||||
}
|
||||
#endif /* NLOOP > 0 */
|
||||
101
c/src/exec/libnetworking/net/if_types.h
Normal file
101
c/src/exec/libnetworking/net/if_types.h
Normal file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 1989, 1993, 1994
|
||||
* The Regents of the University of California. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in the
|
||||
* documentation and/or other materials provided with the distribution.
|
||||
* 3. All advertising materials mentioning features or use of this software
|
||||
* must display the following acknowledgement:
|
||||
* This product includes software developed by the University of
|
||||
* California, Berkeley and its contributors.
|
||||
* 4. Neither the name of the University nor the names of its contributors
|
||||
* may be used to endorse or promote products derived from this software
|
||||
* without specific prior written permission.
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
* ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
|
||||
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
||||
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
||||
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
||||
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
||||
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
||||
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
||||
* SUCH DAMAGE.
|
||||
*
|
||||
* @(#)if_types.h 8.2 (Berkeley) 4/20/94
|
||||
* $Id$
|
||||
*/
|
||||
|
||||
#ifndef _NET_IF_TYPES_H_
|
||||
#define _NET_IF_TYPES_H_
|
||||
|
||||
/*
|
||||
* Interface types for benefit of parsing media address headers.
|
||||
* This list is derived from the SNMP list of ifTypes, currently
|
||||
* documented in RFC1573.
|
||||
*/
|
||||
|
||||
#define IFT_OTHER 0x1 /* none of the following */
|
||||
#define IFT_1822 0x2 /* old-style arpanet imp */
|
||||
#define IFT_HDH1822 0x3 /* HDH arpanet imp */
|
||||
#define IFT_X25DDN 0x4 /* x25 to imp */
|
||||
#define IFT_X25 0x5 /* PDN X25 interface (RFC877) */
|
||||
#define IFT_ETHER 0x6 /* Ethernet CSMACD */
|
||||
#define IFT_ISO88023 0x7 /* CMSA CD */
|
||||
#define IFT_ISO88024 0x8 /* Token Bus */
|
||||
#define IFT_ISO88025 0x9 /* Token Ring */
|
||||
#define IFT_ISO88026 0xa /* MAN */
|
||||
#define IFT_STARLAN 0xb
|
||||
#define IFT_P10 0xc /* Proteon 10MBit ring */
|
||||
#define IFT_P80 0xd /* Proteon 80MBit ring */
|
||||
#define IFT_HY 0xe /* Hyperchannel */
|
||||
#define IFT_FDDI 0xf
|
||||
#define IFT_LAPB 0x10
|
||||
#define IFT_SDLC 0x11
|
||||
#define IFT_T1 0x12
|
||||
#define IFT_CEPT 0x13 /* E1 - european T1 */
|
||||
#define IFT_ISDNBASIC 0x14
|
||||
#define IFT_ISDNPRIMARY 0x15
|
||||
#define IFT_PTPSERIAL 0x16 /* Proprietary PTP serial */
|
||||
#define IFT_PPP 0x17 /* RFC 1331 */
|
||||
#define IFT_LOOP 0x18 /* loopback */
|
||||
#define IFT_EON 0x19 /* ISO over IP */
|
||||
#define IFT_XETHER 0x1a /* obsolete 3MB experimental ethernet */
|
||||
#define IFT_NSIP 0x1b /* XNS over IP */
|
||||
#define IFT_SLIP 0x1c /* IP over generic TTY */
|
||||
#define IFT_ULTRA 0x1d /* Ultra Technologies */
|
||||
#define IFT_DS3 0x1e /* Generic T3 */
|
||||
#define IFT_SIP 0x1f /* SMDS */
|
||||
#define IFT_FRELAY 0x20 /* Frame Relay DTE only */
|
||||
#define IFT_RS232 0x21
|
||||
#define IFT_PARA 0x22 /* parallel-port */
|
||||
#define IFT_ARCNET 0x23
|
||||
#define IFT_ARCNETPLUS 0x24
|
||||
#define IFT_ATM 0x25 /* ATM cells */
|
||||
#define IFT_MIOX25 0x26
|
||||
#define IFT_SONET 0x27 /* SONET or SDH */
|
||||
#define IFT_X25PLE 0x28
|
||||
#define IFT_ISO88022LLC 0x29
|
||||
#define IFT_LOCALTALK 0x2a
|
||||
#define IFT_SMDSDXI 0x2b
|
||||
#define IFT_FRELAYDCE 0x2c /* Frame Relay DCE */
|
||||
#define IFT_V35 0x2d
|
||||
#define IFT_HSSI 0x2e
|
||||
#define IFT_HIPPI 0x2f
|
||||
#define IFT_MODEM 0x30 /* Generic Modem */
|
||||
#define IFT_AAL5 0x31 /* AAL5 over ATM */
|
||||
#define IFT_SONETPATH 0x32
|
||||
#define IFT_SONETVT 0x33
|
||||
#define IFT_SMDSICIP 0x34 /* SMDS InterCarrier Interface */
|
||||
#define IFT_PROPVIRTUAL 0x35 /* Proprietary Virtual/internal */
|
||||
#define IFT_PROPMUX 0x36 /* Proprietary Multiplexing */
|
||||
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user