From d7ce700605e1af0e455e31ec11f19ff21d26b525 Mon Sep 17 00:00:00 2001 From: darylm503 Date: Sat, 30 Jul 2011 00:30:44 +0000 Subject: [PATCH] Add Socket Libraries. Add Posix functions for porting compatibility. Fix compliance issues with ISO/IEC 9899:199409 New Functions: setenv(), fparseln(), GetFileNameFromPath(), rename(), realpath(), setprogname(), getprogname(), strlcat(), strlcpy(), strsep(), setitimer(), getitimer(), timegm(), getopt(), basename(), mkstemp(), ffs(), vsnprintf(), snprintf(), getpass(), usleep(), select(), writev(), strcasecmp(), getcwd(), chdir(), tcgetpgrp(), getpgrp(), gettimeofday(), bcopy(), git-svn-id: https://edk2.svn.sourceforge.net/svnroot/edk2/trunk/edk2@12061 6f19259b-4bc3-4df7-8a09-765794883524 --- StdLib/BsdSocketLib/BsdSocketLib.inf | 115 + StdLib/BsdSocketLib/SocketInternals.h | 190 + StdLib/BsdSocketLib/Socklib_internals.h | 42 + StdLib/BsdSocketLib/accept.c | 157 + StdLib/BsdSocketLib/base64.c | 357 ++ StdLib/BsdSocketLib/bind.c | 72 + StdLib/BsdSocketLib/close.c | 116 + StdLib/BsdSocketLib/connect.c | 94 + StdLib/BsdSocketLib/errno.c | 18 + StdLib/BsdSocketLib/gethostbydns.c | 814 ++++ StdLib/BsdSocketLib/gethostbyht.c | 207 + StdLib/BsdSocketLib/gethostbynis.c | 134 + StdLib/BsdSocketLib/gethostnamadr.c | 225 ++ StdLib/BsdSocketLib/gethostname.c | 92 + StdLib/BsdSocketLib/getnetbydns.c | 318 ++ StdLib/BsdSocketLib/getnetbyht.c | 169 + StdLib/BsdSocketLib/getnetbynis.c | 171 + StdLib/BsdSocketLib/getnetnamadr.c | 186 + StdLib/BsdSocketLib/getpeername.c | 73 + StdLib/BsdSocketLib/getproto.c | 54 + StdLib/BsdSocketLib/getprotoent.c | 118 + StdLib/BsdSocketLib/getprotoname.c | 61 + StdLib/BsdSocketLib/getservbyname.c | 77 + StdLib/BsdSocketLib/getservbyport.c | 72 + StdLib/BsdSocketLib/getservent.c | 277 ++ StdLib/BsdSocketLib/getsockname.c | 73 + StdLib/BsdSocketLib/getsockopt.c | 66 + StdLib/BsdSocketLib/herror.c | 134 + StdLib/BsdSocketLib/inet_net_ntop.c | 142 + StdLib/BsdSocketLib/inet_net_pton.c | 252 ++ StdLib/BsdSocketLib/inet_neta.c | 125 + StdLib/BsdSocketLib/inet_pton.c | 257 ++ StdLib/BsdSocketLib/listen.c | 65 + StdLib/BsdSocketLib/map_v4v6.c | 135 + StdLib/BsdSocketLib/ns_addr.c | 240 ++ StdLib/BsdSocketLib/ns_name.c | 633 +++ StdLib/BsdSocketLib/ns_netint.c | 54 + StdLib/BsdSocketLib/ns_ntoa.c | 103 + StdLib/BsdSocketLib/ns_parse.c | 230 ++ StdLib/BsdSocketLib/ns_print.c | 780 ++++ StdLib/BsdSocketLib/ns_ttl.c | 191 + StdLib/BsdSocketLib/nsap_addr.c | 108 + StdLib/BsdSocketLib/poll.c | 57 + StdLib/BsdSocketLib/read.c | 53 + StdLib/BsdSocketLib/recv.c | 63 + StdLib/BsdSocketLib/recvfrom.c | 197 + StdLib/BsdSocketLib/res_comp.c | 272 ++ StdLib/BsdSocketLib/res_config.h | 8 + StdLib/BsdSocketLib/res_data.c | 83 + StdLib/BsdSocketLib/res_debug.c | 988 +++++ StdLib/BsdSocketLib/res_init.c | 514 +++ StdLib/BsdSocketLib/res_mkquery.c | 211 + StdLib/BsdSocketLib/res_mkupdate.c | 454 +++ StdLib/BsdSocketLib/res_query.c | 430 +++ StdLib/BsdSocketLib/res_send.c | 934 +++++ StdLib/BsdSocketLib/res_update.c | 556 +++ StdLib/BsdSocketLib/send.c | 97 + StdLib/BsdSocketLib/sendto.c | 103 + StdLib/BsdSocketLib/sethostname.c | 117 + StdLib/BsdSocketLib/setsockopt.c | 65 + StdLib/BsdSocketLib/shutdown.c | 72 + StdLib/BsdSocketLib/socket.c | 286 ++ StdLib/BsdSocketLib/write.c | 51 + StdLib/Efi/etc/host.conf | 4 + StdLib/Efi/etc/hosts | 9 + StdLib/Efi/etc/networks | 3 + StdLib/Efi/etc/protocols | 59 + StdLib/Efi/etc/resolv.conf | 19 + StdLib/Efi/etc/services | 576 +++ StdLib/EfiSocketLib/EfiSocketLib.inf | 56 + StdLib/EfiSocketLib/Init.c | 87 + StdLib/EfiSocketLib/Service.c | 529 +++ StdLib/EfiSocketLib/Socket.c | 3091 +++++++++++++++ StdLib/EfiSocketLib/Socket.h | 1337 +++++++ StdLib/EfiSocketLib/Tcp4.c | 3415 +++++++++++++++++ StdLib/EfiSocketLib/Udp4.c | 2408 ++++++++++++ StdLib/EfiSocketLib/UseEfiSocketLib.c | 242 ++ StdLib/Include/Efi/EfiSocketLib.h | 679 ++++ StdLib/Include/Ia32/machine/limits.h | 11 + StdLib/Include/Protocol/EfiSocket.h | 606 +++ StdLib/Include/X64/machine/limits.h | 22 + StdLib/Include/arpa/ftp.h | 109 + StdLib/Include/arpa/nameser.h | 40 +- StdLib/Include/arpa/telnet.h | 340 ++ StdLib/Include/err.h | 25 + StdLib/Include/errno.h | 2 + StdLib/Include/glob.h | 109 + StdLib/Include/libgen.h | 14 + StdLib/Include/net/if.h | 227 ++ StdLib/Include/net/if_dl.h | 86 + StdLib/Include/net/radix.h | 170 + StdLib/Include/net/route.h | 292 ++ StdLib/Include/netatalk/at.h | 92 + StdLib/Include/netdb.h | 29 +- StdLib/Include/netinet/in_systm.h | 62 + StdLib/Include/netinet/ip.h | 197 + StdLib/Include/netns/ns.h | 157 + StdLib/Include/paths.h | 58 +- StdLib/Include/pwd.h | 145 + StdLib/Include/resolv.h | 293 ++ StdLib/Include/signal.h | 10 +- StdLib/Include/stdarg.h | 31 +- StdLib/Include/stdio.h | 85 +- StdLib/Include/stdlib.h | 44 +- StdLib/Include/string.h | 24 +- StdLib/Include/stringlist.h | 65 + StdLib/Include/sys/EfiCdefs.h | 25 +- StdLib/Include/sys/EfiSysCall.h | 7 +- StdLib/Include/sys/_posix.h | 97 + StdLib/Include/sys/cdefs_aout.h | 7 +- StdLib/Include/sys/file.h | 102 + StdLib/Include/sys/select.h | 1 + StdLib/Include/sys/signal.h | 10 +- StdLib/Include/sys/sockio.h | 100 + StdLib/Include/sys/stat.h | 2 +- StdLib/Include/sys/sysctl.h | 505 +++ StdLib/Include/sys/syslimits.h | 2 +- StdLib/Include/sys/time.h | 10 + StdLib/Include/sys/unistd.h | 68 +- StdLib/Include/sys/wait.h | 170 + StdLib/Include/sysexits.h | 122 + StdLib/Include/time.h | 100 +- StdLib/Include/unistd.h | 37 +- StdLib/Include/x86/limits.h | 10 - StdLib/LibC/Locale/Locale.inf | 9 - StdLib/LibC/Locale/_wcstoul.h | 6 +- StdLib/LibC/Locale/multibyte_sb.c | 27 +- StdLib/LibC/Main/Main.c | 70 +- StdLib/LibC/Main/assert.c | 1 - StdLib/LibC/Main/x86flt_rounds.c | 1 - StdLib/LibC/NetUtil/NetUtil.inf | 9 - StdLib/LibC/StdLib/Environs.c | 38 +- StdLib/LibC/StdLib/NumericInt.c | 144 +- StdLib/LibC/StdLib/StdLib.inf | 5 +- StdLib/LibC/StdLib/realpath.c | 57 + StdLib/LibC/StdLib/setprogname.c | 64 + StdLib/LibC/StdLib/strtoumax.c | 6 +- StdLib/LibC/Stdio/Stdio.inf | 1 + StdLib/LibC/Stdio/freopen.c | 4 +- StdLib/LibC/Stdio/fseeko.c | 5 +- StdLib/LibC/Stdio/gettemp.c | 2 +- StdLib/LibC/Stdio/local.h | 10 +- StdLib/LibC/Stdio/mkstemp.c | 2 +- StdLib/LibC/Stdio/setbuffer.c | 23 +- StdLib/LibC/Stdio/vfwprintf.c | 35 +- StdLib/LibC/Stdio/vfwscanf.c | 11 +- StdLib/LibC/Stdio/vprintf.c | 2 +- StdLib/LibC/Stdio/vsnprintf.c | 2 +- StdLib/LibC/Stdio/vsnprintf_ss.c | 2 +- StdLib/LibC/Stdio/vsprintf.c | 2 +- StdLib/LibC/String/Comparison.c | 11 +- StdLib/LibC/String/String.inf | 3 + StdLib/LibC/String/strlcat.c | 86 + StdLib/LibC/String/strlcpy.c | 82 + StdLib/LibC/String/strncasecmp.c | 1 - StdLib/LibC/String/strsep.c | 82 + StdLib/LibC/Time/Time.c | 17 +- StdLib/LibC/Time/Time.inf | 2 + StdLib/LibC/Time/TimeEfi.c | 2 - StdLib/LibC/Time/TimeVals.h | 4 +- StdLib/LibC/Time/ZoneProc.c | 2 - StdLib/LibC/Time/gettimeofday.c | 1 - StdLib/LibC/Time/itimer.c | 277 ++ StdLib/LibC/Time/strftime.c | 10 +- StdLib/LibC/Time/timegm.c | 113 + StdLib/LibC/Uefi/Devices/Console/daConsole.c | 198 +- StdLib/LibC/Uefi/Devices/UefiShell/daShell.c | 89 +- StdLib/LibC/Uefi/Devices/Utility/DevGenisis.c | 18 +- StdLib/LibC/Uefi/Devices/Utility/Path.c | 59 +- StdLib/LibC/Uefi/Devices/daConsole.inf | 14 +- StdLib/LibC/Uefi/Devices/daShell.inf | 14 +- StdLib/LibC/Uefi/Devices/daUtility.inf | 14 +- StdLib/LibC/Uefi/GetPass.c | 57 + StdLib/LibC/Uefi/StubFunctions.c | 79 + StdLib/LibC/Uefi/SysCalls.c | 96 +- StdLib/LibC/Uefi/Uefi.inf | 8 +- StdLib/LibC/Uefi/compat.c | 847 ++++ StdLib/LibC/Uefi/select.c | 256 ++ StdLib/LibC/Uefi/writev.c | 143 + StdLib/PosixLib/Err/LibErr.inf | 42 + StdLib/PosixLib/Err/warn_err.c | 99 + StdLib/PosixLib/Gen/LibGen.inf | 41 + StdLib/PosixLib/Gen/dirname.c | 88 + StdLib/PosixLib/Glob/DirFunctions.c | 135 + StdLib/PosixLib/Glob/LibGlob.inf | 47 + StdLib/PosixLib/Glob/glob.c | 1033 +++++ StdLib/PosixLib/Glob/internal.h | 23 + StdLib/PosixLib/Stringlist/LibStringlist.inf | 41 + StdLib/PosixLib/Stringlist/stringlist.c | 154 + StdLib/SocketDxe/ComponentName.c | 182 + StdLib/SocketDxe/DriverBinding.c | 198 + StdLib/SocketDxe/EntryUnload.c | 296 ++ StdLib/SocketDxe/Socket.h | 175 + StdLib/SocketDxe/SocketDxe.inf | 62 + StdLib/StdLib.dec | 15 + StdLib/StdLib.dsc | 85 +- StdLib/StdLib.inc | 115 + StdLib/UseSocketDxe/UseSocketDxe.c | 160 + StdLib/UseSocketDxe/UseSocketDxe.inf | 45 + 199 files changed, 36115 insertions(+), 686 deletions(-) create mode 100644 StdLib/BsdSocketLib/BsdSocketLib.inf create mode 100644 StdLib/BsdSocketLib/SocketInternals.h create mode 100644 StdLib/BsdSocketLib/Socklib_internals.h create mode 100644 StdLib/BsdSocketLib/accept.c create mode 100644 StdLib/BsdSocketLib/base64.c create mode 100644 StdLib/BsdSocketLib/bind.c create mode 100644 StdLib/BsdSocketLib/close.c create mode 100644 StdLib/BsdSocketLib/connect.c create mode 100644 StdLib/BsdSocketLib/errno.c create mode 100644 StdLib/BsdSocketLib/gethostbydns.c create mode 100644 StdLib/BsdSocketLib/gethostbyht.c create mode 100644 StdLib/BsdSocketLib/gethostbynis.c create mode 100644 StdLib/BsdSocketLib/gethostnamadr.c create mode 100644 StdLib/BsdSocketLib/gethostname.c create mode 100644 StdLib/BsdSocketLib/getnetbydns.c create mode 100644 StdLib/BsdSocketLib/getnetbyht.c create mode 100644 StdLib/BsdSocketLib/getnetbynis.c create mode 100644 StdLib/BsdSocketLib/getnetnamadr.c create mode 100644 StdLib/BsdSocketLib/getpeername.c create mode 100644 StdLib/BsdSocketLib/getproto.c create mode 100644 StdLib/BsdSocketLib/getprotoent.c create mode 100644 StdLib/BsdSocketLib/getprotoname.c create mode 100644 StdLib/BsdSocketLib/getservbyname.c create mode 100644 StdLib/BsdSocketLib/getservbyport.c create mode 100644 StdLib/BsdSocketLib/getservent.c create mode 100644 StdLib/BsdSocketLib/getsockname.c create mode 100644 StdLib/BsdSocketLib/getsockopt.c create mode 100644 StdLib/BsdSocketLib/herror.c create mode 100644 StdLib/BsdSocketLib/inet_net_ntop.c create mode 100644 StdLib/BsdSocketLib/inet_net_pton.c create mode 100644 StdLib/BsdSocketLib/inet_neta.c create mode 100644 StdLib/BsdSocketLib/inet_pton.c create mode 100644 StdLib/BsdSocketLib/listen.c create mode 100644 StdLib/BsdSocketLib/map_v4v6.c create mode 100644 StdLib/BsdSocketLib/ns_addr.c create mode 100644 StdLib/BsdSocketLib/ns_name.c create mode 100644 StdLib/BsdSocketLib/ns_netint.c create mode 100644 StdLib/BsdSocketLib/ns_ntoa.c create mode 100644 StdLib/BsdSocketLib/ns_parse.c create mode 100644 StdLib/BsdSocketLib/ns_print.c create mode 100644 StdLib/BsdSocketLib/ns_ttl.c create mode 100644 StdLib/BsdSocketLib/nsap_addr.c create mode 100644 StdLib/BsdSocketLib/poll.c create mode 100644 StdLib/BsdSocketLib/read.c create mode 100644 StdLib/BsdSocketLib/recv.c create mode 100644 StdLib/BsdSocketLib/recvfrom.c create mode 100644 StdLib/BsdSocketLib/res_comp.c create mode 100644 StdLib/BsdSocketLib/res_config.h create mode 100644 StdLib/BsdSocketLib/res_data.c create mode 100644 StdLib/BsdSocketLib/res_debug.c create mode 100644 StdLib/BsdSocketLib/res_init.c create mode 100644 StdLib/BsdSocketLib/res_mkquery.c create mode 100644 StdLib/BsdSocketLib/res_mkupdate.c create mode 100644 StdLib/BsdSocketLib/res_query.c create mode 100644 StdLib/BsdSocketLib/res_send.c create mode 100644 StdLib/BsdSocketLib/res_update.c create mode 100644 StdLib/BsdSocketLib/send.c create mode 100644 StdLib/BsdSocketLib/sendto.c create mode 100644 StdLib/BsdSocketLib/sethostname.c create mode 100644 StdLib/BsdSocketLib/setsockopt.c create mode 100644 StdLib/BsdSocketLib/shutdown.c create mode 100644 StdLib/BsdSocketLib/socket.c create mode 100644 StdLib/BsdSocketLib/write.c create mode 100644 StdLib/Efi/etc/host.conf create mode 100644 StdLib/Efi/etc/hosts create mode 100644 StdLib/Efi/etc/networks create mode 100644 StdLib/Efi/etc/protocols create mode 100644 StdLib/Efi/etc/resolv.conf create mode 100644 StdLib/Efi/etc/services create mode 100644 StdLib/EfiSocketLib/EfiSocketLib.inf create mode 100644 StdLib/EfiSocketLib/Init.c create mode 100644 StdLib/EfiSocketLib/Service.c create mode 100644 StdLib/EfiSocketLib/Socket.c create mode 100644 StdLib/EfiSocketLib/Socket.h create mode 100644 StdLib/EfiSocketLib/Tcp4.c create mode 100644 StdLib/EfiSocketLib/Udp4.c create mode 100644 StdLib/EfiSocketLib/UseEfiSocketLib.c create mode 100644 StdLib/Include/Efi/EfiSocketLib.h create mode 100644 StdLib/Include/Protocol/EfiSocket.h create mode 100644 StdLib/Include/arpa/ftp.h create mode 100644 StdLib/Include/arpa/telnet.h create mode 100644 StdLib/Include/err.h create mode 100644 StdLib/Include/glob.h create mode 100644 StdLib/Include/libgen.h create mode 100644 StdLib/Include/net/if.h create mode 100644 StdLib/Include/net/if_dl.h create mode 100644 StdLib/Include/net/radix.h create mode 100644 StdLib/Include/net/route.h create mode 100644 StdLib/Include/netatalk/at.h create mode 100644 StdLib/Include/netinet/in_systm.h create mode 100644 StdLib/Include/netinet/ip.h create mode 100644 StdLib/Include/netns/ns.h create mode 100644 StdLib/Include/pwd.h create mode 100644 StdLib/Include/resolv.h create mode 100644 StdLib/Include/stringlist.h create mode 100644 StdLib/Include/sys/_posix.h create mode 100644 StdLib/Include/sys/file.h create mode 100644 StdLib/Include/sys/sockio.h create mode 100644 StdLib/Include/sys/sysctl.h create mode 100644 StdLib/Include/sys/wait.h create mode 100644 StdLib/Include/sysexits.h create mode 100644 StdLib/LibC/StdLib/realpath.c create mode 100644 StdLib/LibC/StdLib/setprogname.c create mode 100644 StdLib/LibC/String/strlcat.c create mode 100644 StdLib/LibC/String/strlcpy.c create mode 100644 StdLib/LibC/String/strsep.c create mode 100644 StdLib/LibC/Time/itimer.c create mode 100644 StdLib/LibC/Time/timegm.c create mode 100644 StdLib/LibC/Uefi/GetPass.c create mode 100644 StdLib/LibC/Uefi/StubFunctions.c create mode 100644 StdLib/LibC/Uefi/compat.c create mode 100644 StdLib/LibC/Uefi/select.c create mode 100644 StdLib/LibC/Uefi/writev.c create mode 100644 StdLib/PosixLib/Err/LibErr.inf create mode 100644 StdLib/PosixLib/Err/warn_err.c create mode 100644 StdLib/PosixLib/Gen/LibGen.inf create mode 100644 StdLib/PosixLib/Gen/dirname.c create mode 100644 StdLib/PosixLib/Glob/DirFunctions.c create mode 100644 StdLib/PosixLib/Glob/LibGlob.inf create mode 100644 StdLib/PosixLib/Glob/glob.c create mode 100644 StdLib/PosixLib/Glob/internal.h create mode 100644 StdLib/PosixLib/Stringlist/LibStringlist.inf create mode 100644 StdLib/PosixLib/Stringlist/stringlist.c create mode 100644 StdLib/SocketDxe/ComponentName.c create mode 100644 StdLib/SocketDxe/DriverBinding.c create mode 100644 StdLib/SocketDxe/EntryUnload.c create mode 100644 StdLib/SocketDxe/Socket.h create mode 100644 StdLib/SocketDxe/SocketDxe.inf create mode 100644 StdLib/StdLib.inc create mode 100644 StdLib/UseSocketDxe/UseSocketDxe.c create mode 100644 StdLib/UseSocketDxe/UseSocketDxe.inf diff --git a/StdLib/BsdSocketLib/BsdSocketLib.inf b/StdLib/BsdSocketLib/BsdSocketLib.inf new file mode 100644 index 0000000000..3337acb3a9 --- /dev/null +++ b/StdLib/BsdSocketLib/BsdSocketLib.inf @@ -0,0 +1,115 @@ +#/** @file +# Component description file for the socket library. +# +# This module implements the socket library. +# Copyright (c) 2011, Intel Corporation +# +# All rights reserved. This program and the accompanying materials +# are licensed and made available under the terms and conditions of the BSD License +# which accompanies this distribution. The full text of the license may be found at +# http://opensource.org/licenses/bsd-license.php +# THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, +# WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. +# +#**/ + +[Defines] + INF_VERSION = 0x00010005 + BASE_NAME = BsdSocketLib + FILE_GUID = E7A79769-DD6E-48f7-B90B-D4C510AC1741 + MODULE_TYPE = BASE + VERSION_STRING = 1.0 + LIBRARY_CLASS = BsdSocketLib + +# +# VALID_ARCHITECTURES = IA32 X64 IPF EBC +# + +[Sources.common] + accept.c + base64.c + bind.c + close.c + connect.c + gethostbydns.c + gethostbyht.c + gethostbynis.c + gethostname.c + gethostnamadr.c + gethostbynis.c + getnetbydns.c + getnetbynis.c + getnetbyht.c + getnetnamadr.c + getpeername.c + getprotoent.c + getprotoname.c + getproto.c + getservbyname.c + getservbyport.c + getservent.c + getsockname.c + getsockopt.c + herror.c +# inet_addr.c +# inet_lnaof.c +# inet_makeaddr.c + inet_net_ntop.c + inet_net_pton.c + inet_neta.c +# inet_netof.c +# inet_network.c +# inet_ntoa.c +# inet_ntop.c + inet_pton.c + listen.c + map_v4v6.c + ns_addr.c + ns_name.c + ns_netint.c + ns_ntoa.c + ns_parse.c + ns_print.c + ns_ttl.c + nsap_addr.c + poll.c + read.c + recv.c + recvfrom.c + res_comp.c + res_config.h + res_data.c + res_debug.c + res_init.c + res_mkquery.c + res_mkupdate.c + res_query.c + res_send.c + res_update.c + send.c + sendto.c + sethostname.c + setsockopt.c + shutdown.c + socket.c + SocketInternals.h + write.c + +[Packages] + StdLib/StdLib.dec + StdLibPrivateInternalFiles/DoNotUse.dec + MdePkg/MdePkg.dec + MdeModulePkg/MdeModulePkg.dec +# SocketPkg/SocketPkg.dec + +[LibraryClasses] + BaseLib + BaseMemoryLib + DebugLib + DevUtility + UefiBootServicesTableLib + UefiLib + +[Protocols] + gEfiSocketServiceBindingProtocolGuid + gEfiSocketProtocolGuid diff --git a/StdLib/BsdSocketLib/SocketInternals.h b/StdLib/BsdSocketLib/SocketInternals.h new file mode 100644 index 0000000000..57eed94f3c --- /dev/null +++ b/StdLib/BsdSocketLib/SocketInternals.h @@ -0,0 +1,190 @@ +/** @file + Definitions for the socket library. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SOCKET_INTERNALS_H_ +#define _SOCKET_INTERNALS_H_ + +#include + +//---------------------------------------------------------------------- +// +// The following private files are required to support file descriptors +// + +#include +#include + +#include + +// +// End of private files +// +//---------------------------------------------------------------------- + +#include +#include +#include + +#include +#include + +#include +#include +#include +#include + +//------------------------------------------------------------------------------ +// Support Routines +//------------------------------------------------------------------------------ + +/** + Translate from the socket file descriptor to the socket protocol. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] ppDescriptor Address to receive the descriptor structure + address for the file + @param [in] pErrno Address of the errno variable + + @returns A pointer to the socket protocol structure or NULL if + an invalid file descriptor was passed in. + + **/ +EFI_SOCKET_PROTOCOL * +BslFdToSocketProtocol ( + int s, + struct __filedes ** ppDescriptor, + int * pErrno + ); + +/** + Close the socket + + @param [in] pDescriptor Descriptor address for the file + + @returns This routine returns 0 upon success and -1 upon failure. + In the case of failure, errno contains more information. + +**/ +INT32 +BslSocketClose ( + struct __filedes * pDescriptor + ); + +/** + Worker routine to close the socket. + + @param [in] pSocketProtocol Socket protocol structure address + + @param [in] pErrno Address of the errno variable + + @retval EFI_SUCCESS Successfully closed the socket + +**/ +EFI_STATUS +BslSocketCloseWork ( + IN EFI_SOCKET_PROTOCOL * pSocketProtocol, + IN int * pErrno + ); + +/** + Poll the socket for activity + + @param [in] pDescriptor Descriptor address for the file + + @param [in] Events Mask of events to detect + + @returns Detected events for the socket + + **/ +short +BslSocketPoll ( + IN struct __filedes * pDescriptor, + IN short Events + ); + +/** + Build a file descriptor for a socket. + + @param [in] pSocketProtocol Socket protocol structure address + + @param [in] pErrno Address of the errno variable + + @returns The file descriptor for the socket or -1 if an error occurs. + + **/ +int +BslSocketProtocolToFd ( + IN EFI_SOCKET_PROTOCOL * pSocketProtocol, + IN int * pErrno + ); + +/** + Read support routine for sockets + + @param [in] pDescriptor Descriptor address for the file + @param [in] pOffset File offset + @param [in] LengthInBytes Number of bytes to read + @param [in] pBuffer Address of the buffer to receive the data + + @returns The number of bytes read or -1 if an error occurs. + +**/ +ssize_t +BslSocketRead ( + struct __filedes *pDescriptor, + off_t * pOffset, + size_t LengthInBytes, + void * pBuffer + ); + +/** + Write support routine for sockets + + @param [in] pDescriptor Descriptor address for the file + @param [in] pOffset File offset + @param [in] LengthInBytes Number of bytes to write + @param [in] pBuffer Address of the data + + @returns The number of bytes written or -1 if an error occurs. + +**/ +ssize_t +BslSocketWrite ( + struct __filedes *pDescriptor, + off_t * pOffset, + size_t LengthInBytes, + const void * pBuffer + ); + +/** + Validate the socket's file descriptor + + @param [in] pDescriptor Descriptor for the file + + @param [in] pErrno Address of the errno variable + + @returns A pointer to the socket protocol structure or NULL if + an invalid file descriptor was passed in. + + **/ +EFI_SOCKET_PROTOCOL * +BslValidateSocketFd ( + struct __filedes * pDescriptor, + int * pErrno + ); + +//------------------------------------------------------------------------------ + +#endif // _SOCKET_INTERNALS_H_ diff --git a/StdLib/BsdSocketLib/Socklib_internals.h b/StdLib/BsdSocketLib/Socklib_internals.h new file mode 100644 index 0000000000..802aaebcc6 --- /dev/null +++ b/StdLib/BsdSocketLib/Socklib_internals.h @@ -0,0 +1,42 @@ +/** @file + Definitions for the socket library functions that are used internally. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#ifndef _SOCKLIB_INTERNALS_H_ +#define _SOCKLIB_INTERNALS_H_ + +void _sethosthtent(int); +void _endhosthtent(void); +void _sethostdnsent(int); +void _endhostdnsent(void); +void _setnethtent(int); +void _endnethtent(void); +void _setnetdnsent(int); +void _endnetdnsent(void); + +struct hostent * _gethostbyhtname(const char *, int); +struct hostent * _gethostbydnsname(const char *, int); +struct hostent * _gethostbynisname(const char *, int); +struct hostent * _gethostbyhtaddr(const char *, int, int); +struct hostent * _gethostbydnsaddr(const char *, int, int); +struct hostent * _gethostbynisaddr(const char *, int, int); +struct netent * _getnetbyhtname(const char *); +struct netent * _getnetbydnsname(const char *); +struct netent * _getnetbynisname(const char *); +struct netent * _getnetbyhtaddr(unsigned long, int); +struct netent * _getnetbydnsaddr(unsigned long, int); +struct netent * _getnetbynisaddr(unsigned long, int); +void _map_v4v6_address(const char *src, char *dst); +void _map_v4v6_hostent(struct hostent *hp, char **bp, int *len); +#endif + diff --git a/StdLib/BsdSocketLib/accept.c b/StdLib/BsdSocketLib/accept.c new file mode 100644 index 0000000000..3dbfe97013 --- /dev/null +++ b/StdLib/BsdSocketLib/accept.c @@ -0,0 +1,157 @@ +/** @file + Implement the accept API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Worker routine for ::Accept and ::AcceptNB + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] bBlocking TRUE if this is a blocking call + @param [in] address Address of a buffer to receive the remote network address. + + @param [in, out] address_len Address of a buffer containing the Length in bytes + of the remote network address buffer. Upon return, + contains the length of the remote network address. + + @returns ::accept returns zero if successful and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +AcceptWork ( + int s, + BOOLEAN bBlocking, + struct sockaddr * address, + socklen_t * address_len + ) +{ + INT32 NewSocketFd; + struct __filedes * pDescriptor; + EFI_SOCKET_PROTOCOL * pNewSocket; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Assume failure + // + NewSocketFd = -1; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, + &pDescriptor, + &errno ); + if ( NULL != pSocketProtocol ) { + // + // TODO: Update bBlocking by anding with check for NON_BLOCKING + // + + // + // Attempt to accept a new network connection + // + do { + Status = pSocketProtocol->pfnAccept ( pSocketProtocol, + address, + address_len, + &pNewSocket, + &errno ); + } while ( bBlocking && ( EFI_NOT_READY == Status )); + + // + // Convert the protocol to a socket + // + NewSocketFd = BslSocketProtocolToFd ( pNewSocket, &errno ); + if ( -1 == NewSocketFd ) { + // + // Close the socket + // + BslSocketCloseWork ( pNewSocket, NULL ); + } + } + + // + // Return the new socket file descriptor + // + return NewSocketFd; +} + + +/** + Accept a network connection. + + The ::accept routine waits for a network connection to the socket. + It is able to return the remote network address to the caller if + requested. The + POSIX + documentation is available online. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] address Address of a buffer to receive the remote network address. + + @param [in, out] address_len Address of a buffer containing the Length in bytes + of the remote network address buffer. Upon return, + contains the length of the remote network address. + + @returns ::accept returns zero if successful and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +accept ( + int s, + struct sockaddr * address, + socklen_t * address_len + ) +{ + // + // Wait for the accept call to complete + // + return AcceptWork ( s, TRUE, address, address_len ); +} + + +/** + Non blocking version of accept. + + See ::accept + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] address Address of a buffer to receive the remote network address. + + @param [in, out] address_len Address of a buffer containing the Length in bytes + of the remote network address buffer. Upon return, + contains the length of the remote network address. + + @returns This routine returns zero if successful and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +AcceptNB ( + int s, + struct sockaddr * address, + socklen_t * address_len + ) +{ + // + // Attempt to accept a network connection + // + return AcceptWork ( s, FALSE, address, address_len ); +} diff --git a/StdLib/BsdSocketLib/base64.c b/StdLib/BsdSocketLib/base64.c new file mode 100644 index 0000000000..593360535c --- /dev/null +++ b/StdLib/BsdSocketLib/base64.c @@ -0,0 +1,357 @@ +/* + * 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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(LINT) && !defined(CODECENTER) +static char rcsid[] = "$Id: base64.c,v 1.1.1.1 2003/11/19 01:51:25 kyu3 Exp $"; +#endif /* not lint */ + +#include +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#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 ((int)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( + 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] = (u_char)((pos - Base64) << 2); + } + state = 1; + break; + case 1: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (u_char)((pos - Base64) >> 4); + target[tarindex+1] = (u_char)(((pos - Base64) & 0x0f) + << 4) ; + } + tarindex++; + state = 2; + break; + case 2: + if (target) { + if ((size_t)tarindex + 1 >= targsize) + return (-1); + target[tarindex] |= (u_char)((pos - Base64) >> 2); + target[tarindex+1] = (u_char)(((pos - Base64) & 0x03) + << 6); + } + tarindex++; + state = 3; + break; + case 3: + if (target) { + if ((size_t)tarindex >= targsize) + return (-1); + target[tarindex] |= (u_char)(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); +} diff --git a/StdLib/BsdSocketLib/bind.c b/StdLib/BsdSocketLib/bind.c new file mode 100644 index 0000000000..fc24ea420a --- /dev/null +++ b/StdLib/BsdSocketLib/bind.c @@ -0,0 +1,72 @@ +/** @file + Implement the bind API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Bind a name to a socket. + + The ::bind routine connects a name to a socket on the local machine. The + POSIX + documentation for the bind routine is available online for reference. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] name Address of a sockaddr structure that contains the + connection point on the local machine. An IPv4 address + of INADDR_ANY specifies that the connection is made to + all of the network stacks on the platform. Specifying a + specific IPv4 address restricts the connection to the + network stack supporting that address. Specifying zero + for the port causes the network layer to assign a port + number from the dynamic range. Specifying a specific + port number causes the network layer to use that port. + + @param [in] namelen Specifies the length in bytes of the sockaddr structure. + + @returns The bind routine returns zero (0) if successful and -1 upon failure. + + **/ +int +bind ( + IN int s, + IN const struct sockaddr * name, + IN socklen_t namelen + ) +{ + int BindStatus; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Bind the socket + // + Status = pSocketProtocol->pfnBind ( pSocketProtocol, + name, + namelen, + &errno ); + } + + // + // Return the operation stauts + // + BindStatus = ( 0 == errno ) ? 0 : -1; + return BindStatus; +} diff --git a/StdLib/BsdSocketLib/close.c b/StdLib/BsdSocketLib/close.c new file mode 100644 index 0000000000..7d70e4f126 --- /dev/null +++ b/StdLib/BsdSocketLib/close.c @@ -0,0 +1,116 @@ +/** @file + Implement the close API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Worker routine to close the socket. + + @param [in] pSocketProtocol Socket protocol structure address + + @param [in] pErrno Address of the errno variable + + @retval EFI_SUCCESS Successfully closed the socket + +**/ +EFI_STATUS +BslSocketCloseWork ( + IN EFI_SOCKET_PROTOCOL * pSocketProtocol, + IN int * pErrno + ) +{ + EFI_SERVICE_BINDING_PROTOCOL * pServiceBinding; + EFI_STATUS Status; + + // + // Start closing the socket + // + Status = pSocketProtocol->pfnCloseStart ( pSocketProtocol, + FALSE, + pErrno ); + + // + // Wait for the socket to close or an error + // + while ( EFI_NOT_READY == Status ) { + Status = pSocketProtocol->pfnClosePoll ( pSocketProtocol, + pErrno ); + } + if ( !EFI_ERROR ( Status )) { + // + // Locate the socket protocol + // + Status = gBS->LocateProtocol ( &gEfiSocketServiceBindingProtocolGuid, + NULL, + (VOID **) &pServiceBinding ); + if ( !EFI_ERROR ( Status )) { + // + // Release the handle + // + Status = pServiceBinding->DestroyChild ( pServiceBinding, + pSocketProtocol->SocketHandle ); + } + if ( EFI_ERROR ( Status )) { + *pErrno = EIO; + } + } + else { + DEBUG (( DEBUG_ERROR, + "ERROR - Failed to close the socket: %r\r\n", + Status )); + *pErrno = EIO; + } + + // + // Return the close status + // + return Status; +} + + +/** + Close the socket + + @param [in] pDescriptor Descriptor address for the file + + @returns This routine returns 0 upon success and -1 upon failure. + In the case of failure, errno contains more information. + +**/ +int +BslSocketClose ( + struct __filedes * pDescriptor + ) +{ + int CloseStatus; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + + // + // Locate the socket protocol + // + pSocketProtocol = BslValidateSocketFd ( pDescriptor, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Close the socket + // + BslSocketCloseWork ( pSocketProtocol, &errno ); + } + + // + // Return the close status + // + CloseStatus = ( errno == 0 ) ? 0 : -1; + return CloseStatus; +} diff --git a/StdLib/BsdSocketLib/connect.c b/StdLib/BsdSocketLib/connect.c new file mode 100644 index 0000000000..e02762efa3 --- /dev/null +++ b/StdLib/BsdSocketLib/connect.c @@ -0,0 +1,94 @@ +/** @file + Implement the connect API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Connect to a remote system via the network. + + The ::connect routine attempts to establish a connection to a + socket on the local or remote system using the specified address. + The + POSIX + documentation is available online. + + There are three states associated with a connection: +
    +
  • Not connected
  • +
  • Connection in progress
  • +
  • Connected
  • +
+ In the "Not connected" state, calls to ::connect start the connection + processing and update the state to "Connection in progress". During + the "Connection in progress" state, connect polls for connection completion + and moves the state to "Connected" after the connection is established. + Note that these states are only visible when the file descriptor is marked + with O_NONBLOCK. Also, the POLL_WRITE bit is set when the connection + completes and may be used by poll or select as an indicator to call + connect again. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] address Network address of the remote system + + @param [in] address_len Length of the remote network address + + @returns ::connect returns zero if successful and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +connect ( + int s, + const struct sockaddr * address, + socklen_t address_len + ) +{ + BOOLEAN bBlocking; + int ConnectStatus; + struct __filedes * pDescriptor; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, + &pDescriptor, + &errno ); + if ( NULL != pSocketProtocol ) { + // + // TODO: Check for NON_BLOCKING + // + bBlocking = TRUE; + + // + // Attempt to connect to a remote system + // + do { + errno = 0; + Status = pSocketProtocol->pfnConnect ( pSocketProtocol, + address, + address_len, + &errno ); + } while ( bBlocking && ( EFI_NOT_READY == Status )); + } + + // + // Return the new socket file descriptor + // + ConnectStatus = (0 == errno) ? 0 : -1; + return ConnectStatus; +} diff --git a/StdLib/BsdSocketLib/errno.c b/StdLib/BsdSocketLib/errno.c new file mode 100644 index 0000000000..360609bd80 --- /dev/null +++ b/StdLib/BsdSocketLib/errno.c @@ -0,0 +1,18 @@ +/** @file + errno variable + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +int errno; diff --git a/StdLib/BsdSocketLib/gethostbydns.c b/StdLib/BsdSocketLib/gethostbydns.c new file mode 100644 index 0000000000..25e7c3b142 --- /dev/null +++ b/StdLib/BsdSocketLib/gethostbydns.c @@ -0,0 +1,814 @@ +/* + * ++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-- + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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[] = "@(#)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: gethostbydns.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef _ORG_FREEBSD_ +#include +#else +#include +u_int32_t _getlong(const u_char *src); +u_int16_t _getshort(const u_char *src); +#endif + +#include "res_config.h" +#include "Socklib_internals.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(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_RES +static void +dprintf(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(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)(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 = (int)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 = (int)strlen(bp) + 1; /* for the \0 */ + if (n >= MAXHOSTNAMELEN) { + had_error++; + continue; + } + bp += n; + buflen -= n; + /* Get canonical name. */ + n = (int)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 = (int)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) { +#ifdef _ORG_FREEBSD_ + 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)); +#endif + cp += n; + continue; /* XXX - had_error++ ? */ + } + switch (type) { + case T_PTR: + if (strcasecmp(tname, bp) != 0) { +#ifdef _ORG_FREEBSD_ + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, qname, bp); +#endif + 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 = (int)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) { +#ifdef _ORG_FREEBSD_ + syslog(LOG_NOTICE|LOG_AUTH, + AskedForGot, host.h_name, bp); +#endif + cp += n; + continue; /* XXX - had_error++ ? */ + } + if (n != host.h_length) { + cp += n; + continue; + } + if (!haveanswer) { + register int nn; + + host.h_name = bp; + nn = (int)strlen(bp) + 1; /* for the \0 */ + bp += nn; + buflen -= nn; + } + + bp += sizeof(align) - ((size_t)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; + } + *hap++ = bp; + bcopy(cp, 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 = (int)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(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(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, '.') && ( NULL != (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(const char *addr, int len, int 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 ( NULL == (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))) { +#ifdef _ORG_FREEBSD_ + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: No A record for %s (verifying [%s])", + hname2, inet_ntoa(*((struct in_addr *)addr))); +#endif + _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) { +#ifdef _ORG_FREEBSD_ + syslog(LOG_NOTICE|LOG_AUTH, + "gethostbyaddr: A record of %s != PTR record [%s]", + hname2, inet_ntoa(*((struct in_addr *)addr))); +#endif + 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(char **ap, int num) +{ + short i, j; + char **p; + short aval[MAXADDRS]; + short 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(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(); +} diff --git a/StdLib/BsdSocketLib/gethostbyht.c b/StdLib/BsdSocketLib/gethostbyht.c new file mode 100644 index 0000000000..ac31f8c915 --- /dev/null +++ b/StdLib/BsdSocketLib/gethostbyht.c @@ -0,0 +1,207 @@ +/*- + * Copyright (c) 1985, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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: gethostbyht.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* XXX */ +#include /* XXX */ +#include "Socklib_internals.h" + +#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(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 && ( NULL == (hostf = fopen(_PATH_HOSTS, "r" )))) { + h_errno = NETDB_INTERNAL; + return (NULL); + } + again: + if ( NULL == (p = fgets(hostbuf, sizeof hostbuf, hostf))) { + h_errno = HOST_NOT_FOUND; + return (NULL); + } + if (*p == '#') + goto again; + if ( NULL == (cp = strpbrk(p, "#\n"))) + goto again; + *cp = '\0'; + if ( NULL == (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\r")) != 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\r")) != NULL) + *cp++ = '\0'; + } + *q = NULL; + h_errno = NETDB_SUCCESS; + return (&host); +} + +struct hostent * +_gethostbyhtname(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(const char *addr, int len, int 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); +} diff --git a/StdLib/BsdSocketLib/gethostbynis.c b/StdLib/BsdSocketLib/gethostbynis.c new file mode 100644 index 0000000000..72081dc265 --- /dev/null +++ b/StdLib/BsdSocketLib/gethostbynis.c @@ -0,0 +1,134 @@ +/*- + * 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: gethostbynis.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +static char rcsid[] = "$Id: gethostbynis.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef YP +#include +#include +#include +#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(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(const char *name, int af) +{ + return _gethostbynis(name, "hosts.byname", af); +} + +struct hostent * +_gethostbynisaddr(const char *addr, int len, int af) +{ + return _gethostbynis(inet_ntoa(*(struct in_addr *)addr),"hosts.byaddr", af); +} diff --git a/StdLib/BsdSocketLib/gethostnamadr.c b/StdLib/BsdSocketLib/gethostnamadr.c new file mode 100644 index 0000000000..74a9ea1def --- /dev/null +++ b/StdLib/BsdSocketLib/gethostnamadr.c @@ -0,0 +1,225 @@ +/*- + * 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: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +static char rcsid[] = "$Id: gethostnamadr.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include /* XXX hack for _res */ +#include /* XXX hack for _res */ + +#include "Socklib_internals.h" + + +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 }, + { _PATH_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_HOSTS; + service_order[1] = SERVICE_BIND; + 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, socklen_t 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(int stayopen) +{ + _sethosthtent(stayopen); + _sethostdnsent(stayopen); +} + +void +endhostent() +{ + _endhosthtent(); + _endhostdnsent(); +} diff --git a/StdLib/BsdSocketLib/gethostname.c b/StdLib/BsdSocketLib/gethostname.c new file mode 100644 index 0000000000..1b0742ad7f --- /dev/null +++ b/StdLib/BsdSocketLib/gethostname.c @@ -0,0 +1,92 @@ +/* + * Copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and its + * contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be used to + * endorse or promote products derived from this software without specific + * prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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 +#include +#include + +/*++ + +Module Name: + + gethostname.c + +Abstract: + + Map FreeBSD gethostname call to EFI Interface + + +Revision History + +--*/ + +int +gethostname( + char *name, + size_t namelen + ) +/*++ + +Routine Description: + + Get the hostname for this system. + +Arguments: + + name - Pointer to storage for hostname. + namelen - Length of name + +Returns: + + 0 on success, -1 if not set + +--*/ +{ + char *pHost; + + pHost = getenv ("HOSTNAME"); + + if ( pHost == NULL ) { + *name = 0; + } else { + strncpy (name, pHost, namelen); + name[namelen-1] = 0; + } + + return (0); +} diff --git a/StdLib/BsdSocketLib/getnetbydns.c b/StdLib/BsdSocketLib/getnetbydns.c new file mode 100644 index 0000000000..b0fdef5d03 --- /dev/null +++ b/StdLib/BsdSocketLib/getnetbydns.c @@ -0,0 +1,318 @@ +/*- + * Copyright (c) 1985, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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: getnetbydns.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#ifdef _ORG_FREEBSD_ +#include +#endif + +#include "res_config.h" +#include "Socklib_internals.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(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(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(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(int stayopen) +{ + if (stayopen) + _res.options |= RES_STAYOPEN | RES_USEVC; +} + +void +_endnetdnsent() +{ + _res.options &= ~(RES_STAYOPEN | RES_USEVC); + res_close(); +} diff --git a/StdLib/BsdSocketLib/getnetbyht.c b/StdLib/BsdSocketLib/getnetbyht.c new file mode 100644 index 0000000000..08b80423b8 --- /dev/null +++ b/StdLib/BsdSocketLib/getnetbyht.c @@ -0,0 +1,169 @@ +/* + * 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: getnetbyht.c,v 1.1.1.1 2003/11/19 01:51:27 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +#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(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(register const char *name) +{ + register struct netent *p; + register char **cp; + + setnetent(_net_stayopen); + while ( NULL != (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(register unsigned long net, register int type) +{ + register struct netent *p; + + setnetent(_net_stayopen); + while ( NULL != (p = getnetent()) ) + if (p->n_addrtype == type && p->n_net == net) + break; + if (!_net_stayopen) + endnetent(); + return (p); +} diff --git a/StdLib/BsdSocketLib/getnetbynis.c b/StdLib/BsdSocketLib/getnetbynis.c new file mode 100644 index 0000000000..f81ca03c76 --- /dev/null +++ b/StdLib/BsdSocketLib/getnetbynis.c @@ -0,0 +1,171 @@ +/*- + * 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: getnetbynis.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $"; +static char rcsid[] = "$Id: getnetbynis.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#ifdef YP +#include +#include +#include +#endif + +#define MAXALIASES 35 +#define MAXADDRS 35 + +#ifdef YP +static char *host_aliases[MAXALIASES]; +#endif /* YP */ + +static struct netent * +_getnetbynis(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(const char *name) +{ + return _getnetbynis(name, "networks.byname", AF_INET); +} + +struct netent * +_getnetbynisaddr(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); +} diff --git a/StdLib/BsdSocketLib/getnetnamadr.c b/StdLib/BsdSocketLib/getnetnamadr.c new file mode 100644 index 0000000000..b2eb73753a --- /dev/null +++ b/StdLib/BsdSocketLib/getnetnamadr.c @@ -0,0 +1,186 @@ +/*- + * 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: getnetnamadr.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include "Socklib_internals.h" + +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 }, + { _PATH_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(uint32_t 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(int stayopen) +{ + _setnethtent(stayopen); + _setnetdnsent(stayopen); +} + +void +endnetent() +{ + _endnethtent(); + _endnetdnsent(); +} diff --git a/StdLib/BsdSocketLib/getpeername.c b/StdLib/BsdSocketLib/getpeername.c new file mode 100644 index 0000000000..850308a401 --- /dev/null +++ b/StdLib/BsdSocketLib/getpeername.c @@ -0,0 +1,73 @@ +/** @file + Implement the getpeername API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Get the remote address + + The ::getpeername routine retrieves the remote system address from the socket. + The + POSIX + documentation is available online. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [out] address Network address to receive the remote system address + + @param [in] address_len Length of the remote network address structure + + @returns ::getpeername returns zero (0) if successful or -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +getpeername ( + int s, + struct sockaddr * address, + socklen_t * address_len + ) +{ + int RetVal; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Assume failure + // + RetVal = -1; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Get the remote address + // + Status = pSocketProtocol->pfnGetPeer ( pSocketProtocol, + address, + address_len, + &errno ); + if ( !EFI_ERROR ( Status )) { + RetVal = 0; + } + } + + // + // Return the operation status + // + return RetVal; +} diff --git a/StdLib/BsdSocketLib/getproto.c b/StdLib/BsdSocketLib/getproto.c new file mode 100644 index 0000000000..9924d000bd --- /dev/null +++ b/StdLib/BsdSocketLib/getproto.c @@ -0,0 +1,54 @@ +/* + * 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 + +extern int _proto_stayopen; + +struct protoent * +getprotobynumber(register int proto) +{ + register struct protoent *p; + + setprotoent(_proto_stayopen); + while ( NULL != (p = getprotoent()) ) + if (p->p_proto == proto) + break; + if (!_proto_stayopen) + endprotoent(); + return (p); +} diff --git a/StdLib/BsdSocketLib/getprotoent.c b/StdLib/BsdSocketLib/getprotoent.c new file mode 100644 index 0000000000..3360812c49 --- /dev/null +++ b/StdLib/BsdSocketLib/getprotoent.c @@ -0,0 +1,118 @@ +/* + * 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 +#include +#include +#include +#include +#include + +#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(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); +} diff --git a/StdLib/BsdSocketLib/getprotoname.c b/StdLib/BsdSocketLib/getprotoname.c new file mode 100644 index 0000000000..71b35e61b9 --- /dev/null +++ b/StdLib/BsdSocketLib/getprotoname.c @@ -0,0 +1,61 @@ +/* + * 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 +#include + +extern int _proto_stayopen; + +struct protoent * +getprotobyname(register const char *name) +{ + register struct protoent *p; + register char **cp; + + setprotoent(_proto_stayopen); + while ( NULL != (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); +} diff --git a/StdLib/BsdSocketLib/getservbyname.c b/StdLib/BsdSocketLib/getservbyname.c new file mode 100644 index 0000000000..f17c240b37 --- /dev/null +++ b/StdLib/BsdSocketLib/getservbyname.c @@ -0,0 +1,77 @@ +/* + * 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 +#include + +extern int _serv_stayopen; + +struct servent * +getservbyname(IN const char *name, IN const char *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 ( NULL != (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); +} diff --git a/StdLib/BsdSocketLib/getservbyport.c b/StdLib/BsdSocketLib/getservbyport.c new file mode 100644 index 0000000000..d93d8135b5 --- /dev/null +++ b/StdLib/BsdSocketLib/getservbyport.c @@ -0,0 +1,72 @@ +/* + * 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 +#include + +extern int _serv_stayopen; + +struct servent * +getservbyport(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 ( NULL != (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); +} diff --git a/StdLib/BsdSocketLib/getservent.c b/StdLib/BsdSocketLib/getservent.c new file mode 100644 index 0000000000..572b5978fc --- /dev/null +++ b/StdLib/BsdSocketLib/getservent.c @@ -0,0 +1,277 @@ +/* + * 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 +#include +#include +#include +#include +#include +#ifdef YP +#include +#include +#include +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(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); +} diff --git a/StdLib/BsdSocketLib/getsockname.c b/StdLib/BsdSocketLib/getsockname.c new file mode 100644 index 0000000000..0b72edcf29 --- /dev/null +++ b/StdLib/BsdSocketLib/getsockname.c @@ -0,0 +1,73 @@ +/** @file + Implement the getsockname API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Get the local socket address. + + The ::getsockname routine retrieves the local system address from the socket. + The + POSIX + documentation is available online. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [out] address Network address to receive the local system address + + @param [in] address_len Length of the local network address structure + + @returns ::getsockname returns zero (0) if successful or -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +int +getsockname ( + int s, + struct sockaddr * address, + socklen_t * address_len + ) +{ + int RetVal; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Assume failure + // + RetVal = -1; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Get the local socket address + // + Status = pSocketProtocol->pfnGetLocal ( pSocketProtocol, + address, + address_len, + &errno ); + if ( !EFI_ERROR ( Status )) { + RetVal = 0; + } + } + + // + // Return the operation status + // + return RetVal; +} diff --git a/StdLib/BsdSocketLib/getsockopt.c b/StdLib/BsdSocketLib/getsockopt.c new file mode 100644 index 0000000000..eac10544de --- /dev/null +++ b/StdLib/BsdSocketLib/getsockopt.c @@ -0,0 +1,66 @@ +/** @file + Implement the getsockopt API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Get the socket options + + @param [in] s Socket file descriptor returned from ::socket. + @param [in] level Option protocol level + @param [in] option_name Name of the option + @param [out] option_value Buffer to receive the option value + @param [in,out] option_len Length of the buffer in bytes, + upon return length of the option value in bytes + + @retval Zero (0) upon success + @retval Minus one (-1) upon failure, errno set with additional error information + +**/ +int +getsockopt ( + IN int s, + IN int level, + IN int option_name, + OUT void * __restrict option_value, + IN OUT socklen_t * __restrict option_len + ) +{ + int OptionStatus; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Get the socket option + // + Status = pSocketProtocol->pfnOptionGet ( pSocketProtocol, + level, + option_name, + option_value, + option_len, + &errno ); + } + + // + // Return the operation stauts + // + OptionStatus = ( 0 == errno ) ? 0 : -1; + return OptionStatus; +} diff --git a/StdLib/BsdSocketLib/herror.c b/StdLib/BsdSocketLib/herror.c new file mode 100644 index 0000000000..e1c9b41f87 --- /dev/null +++ b/StdLib/BsdSocketLib/herror.c @@ -0,0 +1,134 @@ +/* + * Copyright (c) 1987, 1993 + * The Regents of the University of California. All rights reserved. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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: herror.c,v 1.1.1.1 2003/11/19 01:51:28 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +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; + +const char * +hstrerror( + int err + ); + +/* + * herror -- + * print the error indicated by the h_errno value. + */ +void +herror( + const char *s + ) +{ + struct iovec iov[4]; + register struct iovec *v = iov; + int i; + + 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; +#ifdef _ORG_FREEBSD_ + writev(STDERR_FILENO, iov, (v - iov) + 1); +#else + for (i = 0; i < (v - iov) + 1; i++) + fprintf( stderr, iov[i].iov_base); +#endif + +} + +const char * +hstrerror( + int err + ) +{ + if (err < 0) + return ("Resolver internal error"); + else if (err < h_nerr) + return (h_errlist[err]); + return ("Unknown resolver error"); +} diff --git a/StdLib/BsdSocketLib/inet_net_ntop.c b/StdLib/BsdSocketLib/inet_net_ntop.c new file mode 100644 index 0000000000..3925727878 --- /dev/null +++ b/StdLib/BsdSocketLib/inet_net_ntop.c @@ -0,0 +1,142 @@ +/* + * 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: inet_net_ntop.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $"; +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static char * inet_net_ntop_ipv4 (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( + 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( + 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); +} diff --git a/StdLib/BsdSocketLib/inet_net_pton.c b/StdLib/BsdSocketLib/inet_net_pton.c new file mode 100644 index 0000000000..4e4424a0c0 --- /dev/null +++ b/StdLib/BsdSocketLib/inet_net_pton.c @@ -0,0 +1,252 @@ +/* + * 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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 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: inet_net_pton.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $"; +#endif + +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include + +#ifdef SPRINTF_CHAR +# define SPRINTF(x) strlen(sprintf/**/x) +#else +# define SPRINTF(x) ((size_t)sprintf x) +#endif + +static int inet_net_pton_ipv4 (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( + 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( + const char *src, + u_char *dst, + size_t size + ) +{ + static const char xdigits[] = "0123456789abcdef"; + static const char digits[] = "0123456789"; + int n; + int ch; + int tmp; + int dirty; + int 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 = (int)(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 = (int)(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 = (int)(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 = (int)(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); +} diff --git a/StdLib/BsdSocketLib/inet_neta.c b/StdLib/BsdSocketLib/inet_neta.c new file mode 100644 index 0000000000..b313b13505 --- /dev/null +++ b/StdLib/BsdSocketLib/inet_neta.c @@ -0,0 +1,125 @@ +/* + * 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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 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: inet_neta.c,v 1.1.1.1 2003/11/19 01:51:29 kyu3 Exp $"; +#endif + +#include +#include +#include +#include + +#include +#include +#include + +#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( + u_long src, + char *dst, + size_t size + ) +{ + char *odst = dst; + char *tp; + + while (src & 0xffffffff) { + u_char b = (u_char)((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); +} diff --git a/StdLib/BsdSocketLib/inet_pton.c b/StdLib/BsdSocketLib/inet_pton.c new file mode 100644 index 0000000000..32e1ab8690 --- /dev/null +++ b/StdLib/BsdSocketLib/inet_pton.c @@ -0,0 +1,257 @@ +/* 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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: inet_pton.c,v 1.1.1.1 2003/11/19 01:51:30 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +/* + * 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 (const char *src, u_char *dst); +static int inet_pton6 (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( + 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( + 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 + (u_int)(pch - digits); + + if (new > 255) + return (0); + *tp = (u_char)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( + 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 = (int)(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); +} diff --git a/StdLib/BsdSocketLib/listen.c b/StdLib/BsdSocketLib/listen.c new file mode 100644 index 0000000000..5e14876652 --- /dev/null +++ b/StdLib/BsdSocketLib/listen.c @@ -0,0 +1,65 @@ +/** @file + Implement the listen API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Establish the known port to listen for network connections. + + The ::listen routine places the port into a state that enables connection + attempts. Connections are placed into FIFO order in a queue to be serviced + by the application. The application calls the ::accept routine to remove + the next connection from the queue and get the associated socket. The + POSIX + documentation for the bind routine is available online for reference. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] backlog backlog specifies the maximum FIFO depth for the connections + waiting for the application to call accept. Connection attempts + received while the queue is full are refused. + + @returns The listen routine returns zero (0) if successful and -1 upon failure. + + **/ +int +listen ( + IN int s, + IN int backlog + ) +{ + int ListenStatus; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Enable connections on the known port + // + Status = pSocketProtocol->pfnListen ( pSocketProtocol, + backlog, + &errno ); + } + + // + // Return the operation stauts + // + ListenStatus = ( 0 == errno ) ? 0 : -1; + return ListenStatus; +} diff --git a/StdLib/BsdSocketLib/map_v4v6.c b/StdLib/BsdSocketLib/map_v4v6.c new file mode 100644 index 0000000000..5ad73c85ce --- /dev/null +++ b/StdLib/BsdSocketLib/map_v4v6.c @@ -0,0 +1,135 @@ +/* + * ++Copyright++ 1985, 1988, 1993 + * - + * Copyright (c) 1985, 1988, 1993 + * The Regents of the University of California. All rights reserved. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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: map_v4v6.c,v 1.1.1.1 2003/11/19 01:51:31 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#ifdef _ORG_FREEBSD_ +#include +#endif +#include "Socklib_internals.h" + +typedef union { + int32_t al; + char ac; +} align; + +void +_map_v4v6_address(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(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 = (int)(sizeof(align) - ((size_t)*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; + } +} diff --git a/StdLib/BsdSocketLib/ns_addr.c b/StdLib/BsdSocketLib/ns_addr.c new file mode 100644 index 0000000000..81fd6253e7 --- /dev/null +++ b/StdLib/BsdSocketLib/ns_addr.c @@ -0,0 +1,240 @@ +/* + * 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. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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 +#include +#include +#include + +static struct ns_addr addr, zero_addr; + +static void Field(), cvtbase(); + +struct ns_addr +ns_addr( + 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( + 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( + 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] = (u_char)sum; /* accumulate remainder */ + } + for (d=0; d < reslen; d++) + result[d] = 0; +} diff --git a/StdLib/BsdSocketLib/ns_name.c b/StdLib/BsdSocketLib/ns_name.c new file mode 100644 index 0000000000..9303b3f437 --- /dev/null +++ b/StdLib/BsdSocketLib/ns_name.c @@ -0,0 +1,633 @@ +/* + * 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. + * + */ + +#ifndef lint +static char rcsid[] = "$Id: ns_name.c,v 1.1.1.1 2003/11/19 01:51:32 kyu3 Exp $"; +#endif + +#include + +#include +#include + +#include +#include +#include + +/* 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 ((int)(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 = (int)(cp - digits) * 100; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (int)(cp - digits) * 10; + if ((c = *src++) == 0 || + (cp = strchr(digits, c)) == NULL) { + errno = EMSGSIZE; + return (-1); + } + n += (int)(cp - digits); + if (n > 255) { + errno = EMSGSIZE; + return (-1); + } + c = n; + } + escaped = 0; + } else if (c == '\\') { + escaped = 1; + continue; + } else if (c == '.') { + c = ((int)(bp - label) - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = (u_char)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 = ((int)(bp - label) - 1); + if ((c & NS_CMPRSFLGS) != 0) { /* Label too big. */ + errno = EMSGSIZE; + return (-1); + } + if (label >= eom) { + errno = EMSGSIZE; + return (-1); + } + *label = (u_char)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, 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++ = (u_char)n; + memcpy(dstp, srcp, n); + dstp += n; + srcp += n; + break; + + case NS_CMPRSFLGS: + if (srcp >= eom) { + errno = EMSGSIZE; + return (-1); + } + if (len < 0) + len = (int)(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 = (int)(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++ = (u_char)((l >> 8) | NS_CMPRSFLGS ); + *dstp++ = (u_char)( l % 256 ); + return ((int)(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 ((int)(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, (int)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 ((int)(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); +} diff --git a/StdLib/BsdSocketLib/ns_netint.c b/StdLib/BsdSocketLib/ns_netint.c new file mode 100644 index 0000000000..6a3b290ead --- /dev/null +++ b/StdLib/BsdSocketLib/ns_netint.c @@ -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: ns_netint.c,v 1.1.1.1 2003/11/19 01:51:33 kyu3 Exp $"; +#endif + +/* Import. */ + +#include +#include + +#include +#include + +uint16_t +ns_get16(const u_char *src) { + uint16_t dst; + + NS_GET16(dst, src); + return (dst); +} + +uint32_t +ns_get32(const u_char *src) { + uint32_t dst; + + NS_GET32(dst, src); + return (dst); +} + +void +ns_put16(uint16_t src, u_char *dst) { + NS_PUT16(src, dst); +} + +void +ns_put32(uint32_t src, u_char *dst) { + NS_PUT32(src, dst); +} diff --git a/StdLib/BsdSocketLib/ns_ntoa.c b/StdLib/BsdSocketLib/ns_ntoa.c new file mode 100644 index 0000000000..1162b4d69a --- /dev/null +++ b/StdLib/BsdSocketLib/ns_ntoa.c @@ -0,0 +1,103 @@ +/* + * 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 +#include +#include + +static char *spectHex(); + +char * +ns_ntoa( + 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; + + 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( + 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); +} diff --git a/StdLib/BsdSocketLib/ns_parse.c b/StdLib/BsdSocketLib/ns_parse.c new file mode 100644 index 0000000000..b050cdee1f --- /dev/null +++ b/StdLib/BsdSocketLib/ns_parse.c @@ -0,0 +1,230 @@ +/* + * 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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. + * + */ + +#ifndef lint +static char rcsid[] = "$Id: ns_parse.c,v 1.1.1.1 2003/11/19 01:51:33 kyu3 Exp $"; +#endif + +#include + +#include +#include + +#include +#include +#include + +/* 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 ((int)(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->_msg_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->_msg_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->_msg_ptr = handle->_sections[(int)section]; + } + + b = skiprr(handle->_msg, handle->_eom, section, + rrnum - handle->_rrnum); + if (b < 0) + return (-1); + handle->_msg_ptr += b; + handle->_rrnum = rrnum; + + /* Do the parse. */ + b = dn_expand(handle->_msg, handle->_eom, + handle->_msg_ptr, rr->name, NS_MAXDNAME); + if (b < 0) + return (-1); + handle->_msg_ptr += b; + if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) + goto emsgsize; + NS_GET16(rr->type, handle->_msg_ptr); + if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) + goto emsgsize; + NS_GET16(rr->rr_class, handle->_msg_ptr); + if (section == ns_s_qd) { + rr->ttl = 0; + rr->rdlength = 0; + rr->rdata = NULL; + } else { + if (handle->_msg_ptr + NS_INT32SZ > handle->_eom) + goto emsgsize; + NS_GET32(rr->ttl, handle->_msg_ptr); + if (handle->_msg_ptr + NS_INT16SZ > handle->_eom) + goto emsgsize; + NS_GET16(rr->rdlength, handle->_msg_ptr); + if (handle->_msg_ptr + rr->rdlength > handle->_eom) + goto emsgsize; + rr->rdata = handle->_msg_ptr; + handle->_msg_ptr += rr->rdlength; + } + handle->_rrnum++; + + /* All done. */ + return (0); + enodev: + errno = ENODEV; + return (-1); + emsgsize: + errno = EMSGSIZE; + return (-1); +} diff --git a/StdLib/BsdSocketLib/ns_print.c b/StdLib/BsdSocketLib/ns_print.c new file mode 100644 index 0000000000..83aeeb32a0 --- /dev/null +++ b/StdLib/BsdSocketLib/ns_print.c @@ -0,0 +1,780 @@ +/* + * 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) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. + * + */ + +#ifndef lint +static char rcsid[] = "$Id: ns_print.c,v 1.1.1.1 2003/11/19 01:51:34 kyu3 Exp $"; +#endif + +/* Import. */ + +#include +#include + +#include +#include +#include + +#include +#include +#include +#include +#include + +#define SPRINTF(x) (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 ((ssize_t)(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 x; + size_t len; + + static char base64_key[NS_MD5RSA_MAX_BASE64]; + static char t[255*3]; + + /* + * 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, (socklen_t)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: { + + (void) inet_nsap_ntoa((int)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, (socklen_t)buflen); + addlen(strlen(buf), &buf, &buflen); + break; + + case ns_t_loc: { + /* 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; + + 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 ((ssize_t)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; + + 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, (socklen_t)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: { + 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 ((ssize_t)len < 0) + goto formerr; + if (len > 15) { + T(addstr(" (", 2, &buf, &buflen)); + leader = "\n\t\t"; + spaced = 0; + } else + leader = " "; + for (n = 0; n < (int)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: { + 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((int)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 ((ssize_t)len < 0) + goto formerr; + for (n = 0; n < (int)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 = (int)(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 ((int)(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, (int)(edata - rdata)); + for (m = 0; m < n; m++) + p += SPRINTF((p, "%02x ", rdata[m])); + T(addstr(tmp, (u_int)(p - tmp), &buf, &buflen)); + if (n < 16) { + T(addstr(")", 1, &buf, &buflen)); + T(addtab((u_int)(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, (u_int)(p - tmp), &buf, &buflen)); + rdata += n; + } + return ((int)(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 ((size_t)(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 ((size_t)(name - oname)); +} + +/* + * int + * charstr(rdata, edata, buf, buflen) + * Format a 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 ((int)(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, (int)(*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 ((int)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 = (int)(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); +} diff --git a/StdLib/BsdSocketLib/ns_ttl.c b/StdLib/BsdSocketLib/ns_ttl.c new file mode 100644 index 0000000000..a5a57449eb --- /dev/null +++ b/StdLib/BsdSocketLib/ns_ttl.c @@ -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. + */ + +/* + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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 Intel Corporation and + * its contributors. + * + * 4. Neither the name of Intel Corporation or its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY INTEL CORPORATION 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 INTEL CORPORATION 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. + * + */ + +#ifndef lint +static char rcsid[] = "$Id: ns_ttl.c,v 1.1.1.1 2003/11/19 01:51:34 kyu3 Exp $"; +#endif + +/* Import. */ + +#include + +#include +#include +#include +#include + +#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 *p; + + secs = (int)(src % 60); src /= 60; + mins = (int)(src % 60); src /= 60; + hours = (int)(src % 24); src /= 24; + days = (int)(src % 7); src /= 7; + weeks = (int)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 = (char)( tolower(ch)); + } + + return ((int)(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); +} diff --git a/StdLib/BsdSocketLib/nsap_addr.c b/StdLib/BsdSocketLib/nsap_addr.c new file mode 100644 index 0000000000..957c97f55f --- /dev/null +++ b/StdLib/BsdSocketLib/nsap_addr.c @@ -0,0 +1,108 @@ +/* + * 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: nsap_addr.c,v 1.1.1.1 2003/11/19 01:51:31 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include + +static char +xtob( + register int c + ) +{ + return (char)(c - (((c >= '0') && (c <= '9')) ? '0' : '7')); +} + +u_int +inet_nsap_addr( + 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 = (u_char)( toupper(c)); + if (isxdigit(c)) { + nib = xtob(c); + c = *ascii++; + if (c != '\0') { + c = (u_char)( 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( + 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++ = (char)( nib + (nib < 10 ? '0' : '7')); + nib = *binary++ & 0x0f; + *ascii++ = (char)( nib + (nib < 10 ? '0' : '7')); + if (((i % 2) == 0 && (i + 1) < binlen)) + *ascii++ = '.'; + } + *ascii = '\0'; + return (start); +} diff --git a/StdLib/BsdSocketLib/poll.c b/StdLib/BsdSocketLib/poll.c new file mode 100644 index 0000000000..fdf50e8b68 --- /dev/null +++ b/StdLib/BsdSocketLib/poll.c @@ -0,0 +1,57 @@ +/** @file + Implement the poll API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Poll the socket for activity + + @param [in] pDescriptor Descriptor address for the file + + @param [in] Events Mask of events to detect + + @returns Detected events for the socket + + **/ +short +BslSocketPoll ( + IN struct __filedes * pDescriptor, + IN short Events + ) +{ + short DetectedEvents; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + + // + // Locate the socket protocol + // + DetectedEvents = 0; + pSocketProtocol = BslValidateSocketFd ( pDescriptor, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Poll the socket + // + Status = pSocketProtocol->pfnPoll ( pSocketProtocol, + Events, + &DetectedEvents, + &errno ); + } + + // + // Return the detected events + // + return DetectedEvents; +} diff --git a/StdLib/BsdSocketLib/read.c b/StdLib/BsdSocketLib/read.c new file mode 100644 index 0000000000..eb72f5cbf7 --- /dev/null +++ b/StdLib/BsdSocketLib/read.c @@ -0,0 +1,53 @@ +/** @file + Implement the read API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Read support routine for sockets + + @param [in] pDescriptor Descriptor address for the file + @param [in] pOffset File offset + @param [in] LengthInBytes Number of bytes to read + @param [in] pBuffer Address of the buffer to receive the data + + @returns The number of bytes read or -1 if an error occurs. + +**/ +ssize_t +BslSocketRead ( + struct __filedes *pDescriptor, + off_t * pOffset, + size_t LengthInBytes, + void * pBuffer + ) +{ + ssize_t BytesRead; + + // + // Receive the data from the remote system + // + BytesRead = recvfrom ( pDescriptor->MyFD, + pBuffer, + LengthInBytes, + 0, + NULL, + NULL ); + + // + // Return the number of bytes read + // + return BytesRead; +} diff --git a/StdLib/BsdSocketLib/recv.c b/StdLib/BsdSocketLib/recv.c new file mode 100644 index 0000000000..735e1dbddd --- /dev/null +++ b/StdLib/BsdSocketLib/recv.c @@ -0,0 +1,63 @@ +/** @file + Implement the recv API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Receive data from a network connection. + + The ::recv routine waits for receive data from a remote network + connection. The + POSIX + documentation is available online. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] buffer Address of a buffer to receive the data. + + @param [in] length Length of the buffer in bytes. + + @param [in] flags Message control flags + + @returns ::recv returns the number of valid bytes in the buffer, + zero if no data was received, and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +ssize_t +recv ( + int s, + void * buffer, + size_t length, + int flags + ) +{ + ssize_t BytesRead; + + // + // Receive the data from the remote system + // + BytesRead = recvfrom ( s, + buffer, + length, + flags, + NULL, + NULL ); + + // + // Return the number of bytes read + // + return BytesRead; +} diff --git a/StdLib/BsdSocketLib/recvfrom.c b/StdLib/BsdSocketLib/recvfrom.c new file mode 100644 index 0000000000..a8d1ab54ee --- /dev/null +++ b/StdLib/BsdSocketLib/recvfrom.c @@ -0,0 +1,197 @@ +/** @file + Implement the recvfrom API. + + Copyright (c) 2011, Intel Corporation + All rights reserved. This program and the accompanying materials + are licensed and made available under the terms and conditions of the BSD License + which accompanies this distribution. The full text of the license may be found at + http://opensource.org/licenses/bsd-license.php + + THE PROGRAM IS DISTRIBUTED UNDER THE BSD LICENSE ON AN "AS IS" BASIS, + WITHOUT WARRANTIES OR REPRESENTATIONS OF ANY KIND, EITHER EXPRESS OR IMPLIED. + +**/ + +#include + + +/** + Receive data from a network connection and return the remote system's address. + + The ::recvfrom routine waits for receive data from a remote network + connection. The + POSIX + documentation is available online. + + @param [in] s Socket file descriptor returned from ::socket. + + @param [in] buffer Address of a buffer to receive the data. + + @param [in] length Length of the buffer in bytes. + + @param [in] flags Message control flags + + @param [out] address Network address to receive the remote system address + + @param [in] address_len Length of the remote network address structure + + @returns ::recvfrom returns the number of valid bytes in the buffer, + zero if no data was received, and -1 when an error occurs. + In the case of an error, errno contains more details. + + **/ +ssize_t +recvfrom ( + int s, + void * buffer, + size_t length, + int flags, + struct sockaddr * address, + socklen_t * address_len + ) +{ + socklen_t ByteCount; + ssize_t LengthInBytes; + UINT8 * pData; + EFI_SOCKET_PROTOCOL * pSocketProtocol; + EFI_STATUS Status; + struct timeval TimeVal; + EFI_EVENT pTimer; + UINT64 Timeout; + ssize_t TotalBytes; + + // + // Assume failure + // + LengthInBytes = -1; + + // + // Locate the context for this socket + // + pSocketProtocol = BslFdToSocketProtocol ( s, NULL, &errno ); + if ( NULL != pSocketProtocol ) { + // + // Receive the data from the socket + // + Status = pSocketProtocol->pfnReceive ( pSocketProtocol, + flags, + length, + buffer, + (size_t *)&LengthInBytes, + address, + address_len, + &errno ); + if ( EFI_ERROR ( Status )) { + LengthInBytes = -1; + if ( EAGAIN == errno ) { + // + // Get the timeout + // + ByteCount = sizeof ( TimeVal ); + LengthInBytes = getsockopt ( s, + SOL_SOCKET, + SO_RCVTIMEO, + &TimeVal, + &ByteCount ); + if ( 0 == LengthInBytes ) { + // + // Compute the timeout + // + Timeout = TimeVal.tv_sec; + Timeout *= 1000 * 1000; + Timeout += TimeVal.tv_usec; + Timeout *= 10; + + // + // The timer is only necessary if a timeout is running + // + LengthInBytes = -1; + Status = EFI_SUCCESS; + pTimer = NULL; + if ( 0 != Timeout ) { + Status = gBS->CreateEvent ( EVT_TIMER, + TPL_NOTIFY, + NULL, + NULL, + &pTimer ); + } + if ( !EFI_ERROR ( Status )) { + // + // Start the timer + // + if ( NULL != pTimer ) { + Status = gBS->SetTimer ( pTimer, + TimerRelative, + Timeout ); + } + if ( !EFI_ERROR ( Status )) { + // + // Loop until data is received or the timeout + // expires + // + TotalBytes = 0; + pData = (UINT8 *)buffer; + do { + // + // Determine if the timeout expired + // + if ( NULL != pTimer ) { + Status = gBS->CheckEvent ( pTimer ); + if ( EFI_SUCCESS == Status ) { + errno = ETIMEDOUT; + if ( 0 == TotalBytes ) { + TotalBytes = -1; + } + break; + } + } + + // + // Attempt to receive some data + // + Status = pSocketProtocol->pfnReceive ( pSocketProtocol, + flags, + length, + pData, + (size_t *)&LengthInBytes, + address, + address_len, + &errno ); + if ( !EFI_ERROR ( Status )) { + // + // Account for the data received + // + TotalBytes += LengthInBytes; + pData += LengthInBytes; + length -= LengthInBytes; + } + } while ( EFI_NOT_READY == Status ); + LengthInBytes = TotalBytes; + + // + // Stop the timer + // + if ( NULL != pTimer ) { + gBS->SetTimer ( pTimer, + TimerCancel, + 0 ); + } + } + + // + // Release the timer + // + if ( NULL != pTimer ) { + gBS->CloseEvent ( pTimer ); + } + } + } + } + } + } + + // + // Return the receive data length, -1 for errors + // + return LengthInBytes; +} diff --git a/StdLib/BsdSocketLib/res_comp.c b/StdLib/BsdSocketLib/res_comp.c new file mode 100644 index 0000000000..cddda3e150 --- /dev/null +++ b/StdLib/BsdSocketLib/res_comp.c @@ -0,0 +1,272 @@ +/* + * Copyright (c) 1985, 1993 + * The Regents of the University of California. All rights reserved. + * + * Portions copyright (c) 1999, 2000 + * Intel Corporation. + * 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, Intel Corporation, and its contributors. + * + * 4. Neither the name of University, Intel Corporation, or their respective + * 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, INTEL CORPORATION 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, + * INTEL CORPORATION 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: res_comp.c,v 1.1.1.1 2003/11/19 01:51:35 kyu3 Exp $"; +#endif /* LIBC_SCCS and not lint */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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 ((int)(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( + 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( + 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( + const char *dn + ) +{ + int ch, escaped = 0; + + /* "." is a valid missing representation */ + if (*dn == '\0') + return (1); + + /* otherwise