1 #define PERL_NO_GET_CONTEXT
9 # include <sys/types.h>
11 #if !defined(ultrix) /* Avoid double definition. */
12 # include <sys/socket.h>
14 #if defined(USE_SOCKS) && defined(I_SOCKS)
18 # define PF_INET AF_INET
19 # define PF_UNIX AF_UNIX
25 /* XXX Configure test for <netinet/in_systm.h needed XXX */
26 #if defined(NeXT) || defined(__NeXT__)
27 # include <netinet/in_systm.h>
29 #if defined(__sgi) && !defined(AF_LINK) && defined(PF_LINK) && PF_LINK == AF_LNK
32 #if defined(I_NETINET_IN) || defined(__ultrix__)
33 # include <netinet/in.h>
35 #if defined(I_NETINET_IP)
36 # include <netinet/ip.h>
39 # if !defined(ultrix) /* Avoid double definition. */
44 # include <arpa/inet.h>
47 # include <netinet/tcp.h>
50 #if defined(WIN32) && !defined(UNDER_CE)
51 # include <ws2tcpip.h>
56 /* VC 6 with its original headers doesn't know about sockaddr_storage, VC 2003 does*/
59 # define _SS_MAXSIZE 128
60 # define _SS_ALIGNSIZE (sizeof(__int64))
62 # define _SS_PAD1SIZE (_SS_ALIGNSIZE - sizeof (short))
63 # define _SS_PAD2SIZE (_SS_MAXSIZE - (sizeof (short) + _SS_PAD1SIZE \
66 struct sockaddr_storage {
68 char __ss_pad1[_SS_PAD1SIZE];
70 char __ss_pad2[_SS_PAD2SIZE];
73 typedef int socklen_t;
75 #define in6_addr in_addr6
77 #define INET_ADDRSTRLEN 22
78 #define INET6_ADDRSTRLEN 65
82 static int inet_pton(int af, const char *src, void *dst)
84 struct sockaddr_storage ss;
85 int size = sizeof(ss);
86 ss.ss_family = af; /* per MSDN */
88 if (WSAStringToAddress((char*)src, af, NULL, (struct sockaddr *)&ss, &size) != 0)
93 *(struct in_addr *)dst = ((struct sockaddr_in *)&ss)->sin_addr;
96 *(struct in6_addr *)dst = ((struct sockaddr_in6 *)&ss)->sin6_addr;
99 WSASetLastError(WSAEAFNOSUPPORT);
104 static const char *inet_ntop(int af, const void *src, char *dst, socklen_t size)
106 struct sockaddr_storage ss;
107 unsigned long s = size;
109 ZeroMemory(&ss, sizeof(ss));
114 ((struct sockaddr_in *)&ss)->sin_addr = *(struct in_addr *)src;
117 ((struct sockaddr_in6 *)&ss)->sin6_addr = *(struct in6_addr *)src;
123 /* cannot directly use &size because of strict aliasing rules */
124 if (WSAAddressToString((struct sockaddr *)&ss, sizeof(ss), NULL, dst, &s) != 0)
136 NETINET_DEFINE_CONTEXT
140 # include <sys/uio.h>
152 # define INADDR_NONE 0xffffffff
153 #endif /* INADDR_NONE */
154 #ifndef INADDR_BROADCAST
155 # define INADDR_BROADCAST 0xffffffff
156 #endif /* INADDR_BROADCAST */
157 #ifndef INADDR_LOOPBACK
158 # define INADDR_LOOPBACK 0x7F000001
159 #endif /* INADDR_LOOPBACK */
161 #ifndef INET_ADDRSTRLEN
162 #define INET_ADDRSTRLEN 16
165 #ifndef C_ARRAY_LENGTH
166 #define C_ARRAY_LENGTH(arr) (sizeof(arr) / sizeof(*(arr)))
167 #endif /* !C_ARRAY_LENGTH */
169 #ifndef PERL_UNUSED_VAR
170 # define PERL_UNUSED_VAR(x) ((void)x)
171 #endif /* !PERL_UNUSED_VAR */
173 #ifndef PERL_UNUSED_ARG
174 # define PERL_UNUSED_ARG(x) PERL_UNUSED_VAR(x)
175 #endif /* !PERL_UNUSED_ARG */
178 # define Newx(v,n,t) New(0,v,n,t)
182 #if defined(__GNUC__) && !defined(PERL_GCC_BRACE_GROUPS_FORBIDDEN)
183 # define SvPVx_nolen(sv) ({SV *_sv = (sv); SvPV_nolen(_sv); })
185 # define SvPVx_nolen(sv) ((PL_Sv = (sv)), SvPV_nolen(PL_Sv))
187 #endif /* !SvPVx_nolen */
190 # define croak_sv(sv) croak(SvPVx_nolen(sv))
194 # define hv_stores(hv, keystr, val) \
195 hv_store(hv, ""keystr"", sizeof(keystr)-1, val, 0)
196 #endif /* !hv_stores */
198 #ifndef newSVpvn_flags
199 # define newSVpvn_flags(s,len,flags) my_newSVpvn_flags(aTHX_ s,len,flags)
200 static SV *my_newSVpvn_flags(pTHX_ const char *s, STRLEN len, U32 flags)
202 SV *sv = newSVpvn(s, len);
203 SvFLAGS(sv) |= (flags & SVf_UTF8);
204 return (flags & SVs_TEMP) ? sv_2mortal(sv) : sv;
206 #endif /* !newSVpvn_flags */
209 # define SvRV_set(sv, val) (SvRV(sv) = (val))
210 #endif /* !SvRV_set */
213 # define SvPV_nomg SvPV
214 #endif /* !SvPV_nomg */
217 # define HEK_FLAGS(hek) 0
218 # define HVhek_UTF8 1
219 #endif /* !HEK_FLAGS */
222 /* These magic numbers are arbitrarily chosen (copied from perl core in fact)
223 * and only have to match between this definition and the code that uses them
225 # define HV_FETCH_ISSTORE 0x04
226 # define HV_FETCH_LVALUE 0x10
227 # define hv_common(hv, keysv, key, klen, flags, act, val, hash) \
228 my_hv_common(aTHX_ hv, keysv, key, klen, flags, act, val, hash)
229 static void *my_hv_common(pTHX_ HV *hv, SV *keysv, const char *key, STRLEN klen,
230 int flags, int act, SV *val, U32 hash)
233 * This only handles the usage actually made by the code
234 * generated by ExtUtils::Constant. EU:C really ought to arrange
235 * portability of its generated code itself.
238 keysv = sv_2mortal(newSVpvn(key, klen));
239 if (flags & HVhek_UTF8)
242 if (act == HV_FETCH_LVALUE) {
243 return (void*)hv_fetch_ent(hv, keysv, 1, hash);
244 } else if (act == HV_FETCH_ISSTORE) {
245 return (void*)hv_store_ent(hv, keysv, val, hash);
247 croak("panic: my_hv_common: act=0x%x", act);
250 #endif /* !hv_common */
252 #ifndef hv_common_key_len
253 # define hv_common_key_len(hv, key, kl, act, val, hash) \
254 my_hv_common_key_len(aTHX_ hv, key, kl, act, val, hash)
255 static void *my_hv_common_key_len(pTHX_ HV *hv, const char *key, I32 kl,
256 int act, SV *val, U32 hash)
267 return hv_common(hv, NULL, key, klen, flags, act, val, hash);
269 #endif /* !hv_common_key_len */
272 # define mPUSHi(i) sv_setiv_mg(PUSHs(sv_newmortal()), (IV)(i))
275 # define mPUSHp(p,l) sv_setpvn_mg(PUSHs(sv_newmortal()), (p), (l))
278 # define mPUSHs(s) PUSHs(sv_2mortal(s))
283 # define newCONSTSUB(stash, name, val) my_newCONSTSUB(aTHX_ stash, name, val)
284 static CV *my_newCONSTSUB(pTHX_ HV *stash, char *name, SV *val)
287 * This has to satisfy code generated by ExtUtils::Constant.
288 * It depends on the 5.8+ layout of constant subs. It has
289 * two calls to newCONSTSUB(): one for real constants, and one
290 * for undefined constants. In the latter case, it turns the
291 * initially-generated constant subs into something else, and
292 * it needs the return value from newCONSTSUB() which Perl 5.6
297 Perl_newCONSTSUB(aTHX_ stash, name, val);
299 SAVESPTR(PL_curstash);
301 gv = gv_fetchpv(name, 0, SVt_PVCV);
304 CvXSUBANY(cv).any_ptr = &PL_sv_undef;
307 # define CvCONST_off(cv) my_CvCONST_off(aTHX_ cv)
308 static void my_CvCONST_off(pTHX_ CV *cv)
314 #endif /* !CvCONST_on */
316 #ifndef HAS_INET_ATON
319 * Check whether "cp" is a valid ascii representation
320 * of an Internet address and convert to a binary address.
321 * Returns 1 if the address is valid, 0 if not.
322 * This replaces inet_addr, the return value from which
323 * cannot distinguish between failure and a local broadcast address.
326 my_inet_aton(register const char *cp, struct in_addr *addr)
334 unsigned int parts[4];
335 register unsigned int *pp = parts;
341 * Collect number up to ".".
342 * Values are specified as for C:
343 * 0x=hex, 0=octal, other=decimal.
347 if (*++cp == 'x' || *cp == 'X')
352 while ((c = *cp) != '\0') {
354 val = (val * base) + (c - '0');
358 if (base == 16 && (s=strchr(PL_hexdigit,c))) {
360 ((s - PL_hexdigit) & 15);
370 * a.b.c (with c treated as 16-bits)
371 * a.b (with b treated as 24 bits)
373 if (pp >= parts + 3 || val > 0xff)
380 * Check for trailing characters.
382 if (*cp && !isSPACE(*cp))
385 * Concoct the address according to
386 * the number of parts specified.
388 nparts = pp - parts + 1; /* force to an int for switch() */
391 case 1: /* a -- 32 bits */
394 case 2: /* a.b -- 8.24 bits */
397 val |= parts[0] << 24;
400 case 3: /* a.b.c -- 8.8.16 bits */
403 val |= (parts[0] << 24) | (parts[1] << 16);
406 case 4: /* a.b.c.d -- 8.8.8.8 bits */
409 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
412 addr->s_addr = htonl(val);
417 #define inet_aton my_inet_aton
419 #endif /* ! HAS_INET_ATON */
421 /* These are not gni() constants; they're extensions for the perl API */
422 /* The definitions in Socket.pm and Socket.xs must match */
423 #define NIx_NOHOST (1 << 0)
424 #define NIx_NOSERV (1 << 1)
426 /* On Windows, ole2.h defines a macro called "interface". We don't need that,
427 * and it will complicate the variables in pack_ip_mreq() etc. (RT87389)
431 /* STRUCT_OFFSET should have come from from perl.h, but if not,
432 * roll our own (not using offsetof() since that is C99). */
433 #ifndef STRUCT_OFFSET
434 # define STRUCT_OFFSET(s,m) (Size_t)(&(((s *)0)->m))
438 not_here(const char *s)
440 croak("Socket::%s not implemented on this architecture", s);
444 #define PERL_IN_ADDR_S_ADDR_SIZE 4
447 * Bad assumptions possible here.
449 * Bad Assumption 1: struct in_addr has no other fields
450 * than the s_addr (which is the field we care about
451 * in here, really). However, we can be fed either 4-byte
452 * addresses (from pack("N", ...), or va.b.c.d, or ...),
453 * or full struct in_addrs (from e.g. pack_sockaddr_in()),
454 * which may or may not be 4 bytes in size.
456 * Bad Assumption 2: the s_addr field is a simple type
457 * (such as an int, u_int32_t). It can be a bit field,
458 * in which case using & (address-of) on it or taking sizeof()
459 * wouldn't go over too well. (Those are not attempted
460 * now but in case someone thinks to change the below code
461 * to use addr.s_addr instead of addr, you have been warned.)
463 * Bad Assumption 3: the s_addr is the first field in
464 * an in_addr, or that its bytes are the first bytes in
467 * These bad assumptions are wrong in UNICOS which has
468 * struct in_addr { struct { u_long st_addr:32; } s_da };
469 * #define s_addr s_da.st_addr
470 * and u_long is 64 bits.
474 #include "const-c.inc"
476 #ifdef HAS_GETADDRINFO
477 static SV *err_to_SV(pTHX_ int err)
479 SV *ret = sv_newmortal();
480 (void) SvUPGRADE(ret, SVt_PVNV);
483 const char *error = gai_strerror(err);
484 sv_setpv(ret, error);
490 SvIV_set(ret, err); SvIOK_on(ret);
495 static void xs_getaddrinfo(pTHX_ CV *cv)
503 char *hostname = NULL;
504 char *servicename = NULL;
506 struct addrinfo hints_s;
507 struct addrinfo *res;
508 struct addrinfo *res_iter;
514 croak("Usage: Socket::getaddrinfo(host, service, hints)");
524 service = &PL_sv_undef;
535 hostname = SvPV_nomg(host, len);
542 servicename = SvPV_nomg(service, len);
547 Zero(&hints_s, sizeof(hints_s), char);
548 hints_s.ai_family = PF_UNSPEC;
550 if(hints && SvOK(hints)) {
554 if(!SvROK(hints) || SvTYPE(SvRV(hints)) != SVt_PVHV)
555 croak("hints is not a HASH reference");
557 hintshash = (HV*)SvRV(hints);
559 if((valp = hv_fetch(hintshash, "flags", 5, 0)) != NULL && SvOK(*valp))
560 hints_s.ai_flags = SvIV(*valp);
561 if((valp = hv_fetch(hintshash, "family", 6, 0)) != NULL && SvOK(*valp))
562 hints_s.ai_family = SvIV(*valp);
563 if((valp = hv_fetch(hintshash, "socktype", 8, 0)) != NULL && SvOK(*valp))
564 hints_s.ai_socktype = SvIV(*valp);
565 if((valp = hv_fetch(hintshash, "protocol", 8, 0)) != NULL && SvOK(*valp))
566 hints_s.ai_protocol = SvIV(*valp);
569 err = getaddrinfo(hostname, servicename, &hints_s, &res);
571 XPUSHs(err_to_SV(aTHX_ err));
577 for(res_iter = res; res_iter; res_iter = res_iter->ai_next) {
578 HV *res_hv = newHV();
580 (void)hv_stores(res_hv, "family", newSViv(res_iter->ai_family));
581 (void)hv_stores(res_hv, "socktype", newSViv(res_iter->ai_socktype));
582 (void)hv_stores(res_hv, "protocol", newSViv(res_iter->ai_protocol));
584 (void)hv_stores(res_hv, "addr", newSVpvn((char*)res_iter->ai_addr, res_iter->ai_addrlen));
586 if(res_iter->ai_canonname)
587 (void)hv_stores(res_hv, "canonname", newSVpv(res_iter->ai_canonname, 0));
589 (void)hv_stores(res_hv, "canonname", newSV(0));
591 XPUSHs(sv_2mortal(newRV_noinc((SV*)res_hv)));
601 #ifdef HAS_GETNAMEINFO
602 static void xs_getnameinfo(pTHX_ CV *cv)
612 char *sa; /* we'll cast to struct sockaddr * when necessary */
616 int want_host, want_serv;
619 if(items < 1 || items > 3)
620 croak("Usage: Socket::getnameinfo(addr, flags=0, xflags=0)");
635 xflags = SvIV(ST(2));
637 want_host = !(xflags & NIx_NOHOST);
638 want_serv = !(xflags & NIx_NOSERV);
641 croak("addr is not a string");
643 addr_len = SvCUR(addr);
645 /* We need to ensure the sockaddr is aligned, because a random SvPV might
646 * not be due to SvOOK */
647 Newx(sa, addr_len, char);
648 Copy(SvPV_nolen(addr), sa, addr_len, char);
649 #ifdef HAS_SOCKADDR_SA_LEN
650 ((struct sockaddr *)sa)->sa_len = addr_len;
653 err = getnameinfo((struct sockaddr *)sa, addr_len,
654 want_host ? host : NULL, want_host ? sizeof(host) : 0,
655 want_serv ? serv : NULL, want_serv ? sizeof(serv) : 0,
660 XPUSHs(err_to_SV(aTHX_ err));
665 XPUSHs(want_host ? sv_2mortal(newSVpv(host, 0)) : &PL_sv_undef);
666 XPUSHs(want_serv ? sv_2mortal(newSVpv(serv, 0)) : &PL_sv_undef);
672 MODULE = Socket PACKAGE = Socket
674 INCLUDE: const-xs.inc
677 #ifdef HAS_GETADDRINFO
678 newXS("Socket::getaddrinfo", xs_getaddrinfo, __FILE__);
680 #ifdef HAS_GETNAMEINFO
681 newXS("Socket::getnameinfo", xs_getnameinfo, __FILE__);
689 struct in_addr ip_address;
690 struct hostent * phe;
692 if ((*host != '\0') && inet_aton(host, &ip_address)) {
693 ST(0) = sv_2mortal(newSVpvn((char *)&ip_address, sizeof(ip_address)));
697 phe = gethostbyname(host);
698 if (phe && phe->h_addrtype == AF_INET && phe->h_length == 4) {
699 ST(0) = sv_2mortal(newSVpvn((char *)phe->h_addr, phe->h_length));
707 inet_ntoa(ip_address_sv)
714 if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
715 croak("Wide character in %s", "Socket::inet_ntoa");
716 ip_address = SvPVbyte(ip_address_sv, addrlen);
717 if (addrlen == sizeof(addr) || addrlen == 4)
719 (ip_address[0] & 0xFF) << 24 |
720 (ip_address[1] & 0xFF) << 16 |
721 (ip_address[2] & 0xFF) << 8 |
722 (ip_address[3] & 0xFF);
724 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
725 "Socket::inet_ntoa", (UV)addrlen, (UV)sizeof(addr));
726 /* We could use inet_ntoa() but that is broken
727 * in HP-UX + GCC + 64bitint (returns "0.0.0.0"),
728 * so let's use this sprintf() workaround everywhere.
729 * This is also more threadsafe than using inet_ntoa(). */
730 ST(0) = sv_2mortal(Perl_newSVpvf(aTHX_ "%d.%d.%d.%d", /* IPv6? */
731 (int)((addr.s_addr >> 24) & 0xFF),
732 (int)((addr.s_addr >> 16) & 0xFF),
733 (int)((addr.s_addr >> 8) & 0xFF),
734 (int)( addr.s_addr & 0xFF)));
738 sockaddr_family(sockaddr)
742 char *sockaddr_pv = SvPVbyte(sockaddr, sockaddr_len);
744 if (sockaddr_len < STRUCT_OFFSET(struct sockaddr, sa_data))
745 croak("Bad arg length for %s, length is %"UVuf", should be at least %"UVuf,
746 "Socket::sockaddr_family", (UV)sockaddr_len,
747 (UV)STRUCT_OFFSET(struct sockaddr, sa_data));
748 ST(0) = sv_2mortal(newSViv(((struct sockaddr*)sockaddr_pv)->sa_family));
751 pack_sockaddr_un(pathname)
756 struct sockaddr_un sun_ad; /* fear using sun */
761 Zero(&sun_ad, sizeof(sun_ad), char);
762 sun_ad.sun_family = AF_UNIX;
763 pathname_pv = SvPV(pathname,len);
764 if (len > sizeof(sun_ad.sun_path))
765 len = sizeof(sun_ad.sun_path);
766 # ifdef OS2 /* Name should start with \socket\ and contain backslashes! */
771 if (pathname_pv[0] != '/' && pathname_pv[0] != '\\')
772 croak("Relative UNIX domain socket name '%s' unsupported",
775 || pathname_pv[7] != '/' && pathname_pv[7] != '\\'
776 || !strnicmp(pathname_pv + 1, "socket", 6))
779 off = 0; /* Preserve names starting with \socket\ */
780 Copy("\\socket", sun_ad.sun_path, off, char);
781 Copy(pathname_pv, sun_ad.sun_path + off, len, char);
783 s = sun_ad.sun_path + off - 1;
789 # else /* !( defined OS2 ) */
790 Copy(pathname_pv, sun_ad.sun_path, len, char);
792 if (0) not_here("dummy");
793 if (len > 1 && sun_ad.sun_path[0] == '\0') {
794 /* Linux-style abstract-namespace socket.
795 * The name is not a file name, but an array of arbitrary
796 * character, starting with \0 and possibly including \0s,
797 * therefore the length of the structure must denote the
798 * end of that character array */
799 addr_len = (char *)&(sun_ad.sun_path) - (char *)&sun_ad + len;
801 addr_len = sizeof(sun_ad);
803 # ifdef HAS_SOCKADDR_SA_LEN
804 sun_ad.sun_len = addr_len;
806 ST(0) = sv_2mortal(newSVpvn((char *)&sun_ad, addr_len));
808 ST(0) = (SV*)not_here("pack_sockaddr_un");
814 unpack_sockaddr_un(sun_sv)
819 struct sockaddr_un addr;
821 char * sun_ad = SvPVbyte(sun_sv,sockaddrlen);
823 # if defined(__linux__) || defined(HAS_SOCKADDR_SA_LEN)
824 /* On Linux or *BSD sockaddrlen on sockets returned by accept, recvfrom,
825 getpeername and getsockname is not equal to sizeof(addr). */
826 if (sockaddrlen < sizeof(addr)) {
827 Copy(sun_ad, &addr, sockaddrlen, char);
828 Zero(((char*)&addr) + sockaddrlen, sizeof(addr) - sockaddrlen, char);
830 Copy(sun_ad, &addr, sizeof(addr), char);
832 # ifdef HAS_SOCKADDR_SA_LEN
833 /* In this case, sun_len must be checked */
834 if (sockaddrlen != addr.sun_len)
835 croak("Invalid arg sun_len field for %s, length is %"UVuf", but sun_len is %"UVuf,
836 "Socket::unpack_sockaddr_un", (UV)sockaddrlen, (UV)addr.sun_len);
839 if (sockaddrlen != sizeof(addr))
840 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
841 "Socket::unpack_sockaddr_un", (UV)sockaddrlen, (UV)sizeof(addr));
842 Copy(sun_ad, &addr, sizeof(addr), char);
845 if (addr.sun_family != AF_UNIX)
846 croak("Bad address family for %s, got %d, should be %d",
847 "Socket::unpack_sockaddr_un", addr.sun_family, AF_UNIX);
849 if (addr.sun_path[0] == '\0') {
850 /* Linux-style abstract socket address begins with a nul
851 * and can contain nuls. */
852 addr_len = (char *)&addr - (char *)&(addr.sun_path) + sockaddrlen;
856 # if defined(HAS_SOCKADDR_SA_LEN)
857 /* On *BSD sun_path not always ends with a '\0' */
858 int maxlen = addr.sun_len - 2; /* should use STRUCT_OFFSET(struct sockaddr_un, sun_path) instead of 2 */
859 if (maxlen > (int)sizeof(addr.sun_path))
860 maxlen = (int)sizeof(addr.sun_path);
862 const int maxlen = (int)sizeof(addr.sun_path);
864 for (addr_len = 0; addr_len < maxlen
865 && addr.sun_path[addr_len]; addr_len++);
868 ST(0) = sv_2mortal(newSVpvn(addr.sun_path, addr_len));
870 ST(0) = (SV*)not_here("unpack_sockaddr_un");
875 pack_sockaddr_in(port, ip_address_sv)
880 struct sockaddr_in sin;
884 if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
885 croak("Wide character in %s", "Socket::pack_sockaddr_in");
886 ip_address = SvPVbyte(ip_address_sv, addrlen);
887 if (addrlen == sizeof(addr) || addrlen == 4)
889 (unsigned int)(ip_address[0] & 0xFF) << 24 |
890 (unsigned int)(ip_address[1] & 0xFF) << 16 |
891 (unsigned int)(ip_address[2] & 0xFF) << 8 |
892 (unsigned int)(ip_address[3] & 0xFF);
894 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
895 "Socket::pack_sockaddr_in",
896 (UV)addrlen, (UV)sizeof(addr));
897 Zero(&sin, sizeof(sin), char);
898 sin.sin_family = AF_INET;
899 sin.sin_port = htons(port);
900 sin.sin_addr.s_addr = htonl(addr.s_addr);
901 # ifdef HAS_SOCKADDR_SA_LEN
902 sin.sin_len = sizeof(sin);
904 ST(0) = sv_2mortal(newSVpvn((char *)&sin, sizeof(sin)));
908 unpack_sockaddr_in(sin_sv)
913 struct sockaddr_in addr;
915 char * sin = SvPVbyte(sin_sv,sockaddrlen);
916 if (sockaddrlen != sizeof(addr)) {
917 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
918 "Socket::unpack_sockaddr_in", (UV)sockaddrlen, (UV)sizeof(addr));
920 Copy(sin, &addr, sizeof(addr), char);
921 if (addr.sin_family != AF_INET) {
922 croak("Bad address family for %s, got %d, should be %d",
923 "Socket::unpack_sockaddr_in", addr.sin_family, AF_INET);
925 ip_address_sv = newSVpvn((char *)&addr.sin_addr, sizeof(addr.sin_addr));
927 if(GIMME_V == G_ARRAY) {
929 mPUSHi(ntohs(addr.sin_port));
930 mPUSHs(ip_address_sv);
933 mPUSHs(ip_address_sv);
938 pack_sockaddr_in6(port, sin6_addr, scope_id=0, flowinfo=0)
941 unsigned long scope_id
942 unsigned long flowinfo
945 #ifdef HAS_SOCKADDR_IN6
946 struct sockaddr_in6 sin6;
949 if (DO_UTF8(sin6_addr) && !sv_utf8_downgrade(sin6_addr, 1))
950 croak("Wide character in %s", "Socket::pack_sockaddr_in6");
951 addrbytes = SvPVbyte(sin6_addr, addrlen);
952 if (addrlen != sizeof(sin6.sin6_addr))
953 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
954 "Socket::pack_sockaddr_in6", (UV)addrlen, (UV)sizeof(sin6.sin6_addr));
955 Zero(&sin6, sizeof(sin6), char);
956 sin6.sin6_family = AF_INET6;
957 sin6.sin6_port = htons(port);
958 sin6.sin6_flowinfo = htonl(flowinfo);
959 Copy(addrbytes, &sin6.sin6_addr, sizeof(sin6.sin6_addr), char);
960 # ifdef HAS_SIN6_SCOPE_ID
961 sin6.sin6_scope_id = scope_id;
964 warn("%s cannot represent non-zero scope_id %d",
965 "Socket::pack_sockaddr_in6", scope_id);
967 # ifdef HAS_SOCKADDR_SA_LEN
968 sin6.sin6_len = sizeof(sin6);
970 ST(0) = sv_2mortal(newSVpvn((char *)&sin6, sizeof(sin6)));
972 PERL_UNUSED_VAR(port);
973 PERL_UNUSED_VAR(sin6_addr);
974 ST(0) = (SV*)not_here("pack_sockaddr_in6");
979 unpack_sockaddr_in6(sin6_sv)
983 #ifdef HAS_SOCKADDR_IN6
985 struct sockaddr_in6 sin6;
986 char * addrbytes = SvPVbyte(sin6_sv, addrlen);
988 if (addrlen != sizeof(sin6))
989 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
990 "Socket::unpack_sockaddr_in6", (UV)addrlen, (UV)sizeof(sin6));
991 Copy(addrbytes, &sin6, sizeof(sin6), char);
992 if (sin6.sin6_family != AF_INET6)
993 croak("Bad address family for %s, got %d, should be %d",
994 "Socket::unpack_sockaddr_in6", sin6.sin6_family, AF_INET6);
995 ip_address_sv = newSVpvn((char *)&sin6.sin6_addr, sizeof(sin6.sin6_addr));
997 if(GIMME_V == G_ARRAY) {
999 mPUSHi(ntohs(sin6.sin6_port));
1000 mPUSHs(ip_address_sv);
1001 # ifdef HAS_SIN6_SCOPE_ID
1002 mPUSHi(sin6.sin6_scope_id);
1006 mPUSHi(ntohl(sin6.sin6_flowinfo));
1009 mPUSHs(ip_address_sv);
1012 PERL_UNUSED_VAR(sin6_sv);
1013 ST(0) = (SV*)not_here("pack_sockaddr_in6");
1018 inet_ntop(af, ip_address_sv)
1025 struct in6_addr addr;
1026 char str[INET6_ADDRSTRLEN];
1028 struct in_addr addr;
1029 char str[INET_ADDRSTRLEN];
1033 if (DO_UTF8(ip_address_sv) && !sv_utf8_downgrade(ip_address_sv, 1))
1034 croak("Wide character in %s", "Socket::inet_ntop");
1036 ip_address = SvPV(ip_address_sv, addrlen);
1041 croak("Bad address length for Socket::inet_ntop on AF_INET;"
1042 " got %"UVuf", should be 4", (UV)addrlen);
1047 croak("Bad address length for Socket::inet_ntop on AF_INET6;"
1048 " got %"UVuf", should be 16", (UV)addrlen);
1052 croak("Bad address family for %s, got %d, should be"
1054 " either AF_INET or AF_INET6",
1058 "Socket::inet_ntop", af);
1061 if(addrlen < sizeof(addr)) {
1062 Copy(ip_address, &addr, addrlen, char);
1063 Zero(((char*)&addr) + addrlen, sizeof(addr) - addrlen, char);
1066 Copy(ip_address, &addr, sizeof addr, char);
1068 inet_ntop(af, &addr, str, sizeof str);
1070 ST(0) = sv_2mortal(newSVpvn(str, strlen(str)));
1072 PERL_UNUSED_VAR(af);
1073 PERL_UNUSED_VAR(ip_address_sv);
1074 ST(0) = (SV*)not_here("inet_ntop");
1086 struct in6_addr ip_address;
1088 struct in_addr ip_address;
1101 croak("Bad address family for %s, got %d, should be"
1103 " either AF_INET or AF_INET6",
1107 "Socket::inet_pton", af);
1109 ok = (*host != '\0') && inet_pton(af, host, &ip_address);
1111 ST(0) = sv_newmortal();
1113 sv_setpvn( ST(0), (char *)&ip_address, addrlen);
1116 PERL_UNUSED_VAR(af);
1117 PERL_UNUSED_VAR(host);
1118 ST(0) = (SV*)not_here("inet_pton");
1122 pack_ip_mreq(multiaddr, interface=&PL_sv_undef)
1128 struct ip_mreq mreq;
1129 char * multiaddrbytes;
1130 char * interfacebytes;
1132 if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
1133 croak("Wide character in %s", "Socket::pack_ip_mreq");
1134 multiaddrbytes = SvPVbyte(multiaddr, len);
1135 if (len != sizeof(mreq.imr_multiaddr))
1136 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1137 "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
1138 Zero(&mreq, sizeof(mreq), char);
1139 Copy(multiaddrbytes, &mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr), char);
1140 if(SvOK(interface)) {
1141 if (DO_UTF8(interface) && !sv_utf8_downgrade(interface, 1))
1142 croak("Wide character in %s", "Socket::pack_ip_mreq");
1143 interfacebytes = SvPVbyte(interface, len);
1144 if (len != sizeof(mreq.imr_interface))
1145 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1146 "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_interface));
1147 Copy(interfacebytes, &mreq.imr_interface, sizeof(mreq.imr_interface), char);
1150 mreq.imr_interface.s_addr = INADDR_ANY;
1151 ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
1153 not_here("pack_ip_mreq");
1158 unpack_ip_mreq(mreq_sv)
1163 struct ip_mreq mreq;
1165 char * mreqbytes = SvPVbyte(mreq_sv, mreqlen);
1166 if (mreqlen != sizeof(mreq))
1167 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
1168 "Socket::unpack_ip_mreq", (UV)mreqlen, (UV)sizeof(mreq));
1169 Copy(mreqbytes, &mreq, sizeof(mreq), char);
1171 mPUSHp((char *)&mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr));
1172 mPUSHp((char *)&mreq.imr_interface, sizeof(mreq.imr_interface));
1174 not_here("unpack_ip_mreq");
1179 pack_ip_mreq_source(multiaddr, source, interface=&PL_sv_undef)
1185 #if defined(HAS_IP_MREQ_SOURCE) && defined (IP_ADD_SOURCE_MEMBERSHIP)
1186 struct ip_mreq_source mreq;
1187 char * multiaddrbytes;
1189 char * interfacebytes;
1191 if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
1192 croak("Wide character in %s", "Socket::pack_ip_mreq_source");
1193 multiaddrbytes = SvPVbyte(multiaddr, len);
1194 if (len != sizeof(mreq.imr_multiaddr))
1195 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1196 "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_multiaddr));
1197 if (DO_UTF8(source) && !sv_utf8_downgrade(source, 1))
1198 croak("Wide character in %s", "Socket::pack_ip_mreq_source");
1199 if (len != sizeof(mreq.imr_sourceaddr))
1200 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1201 "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_sourceaddr));
1202 sourcebytes = SvPVbyte(source, len);
1203 Zero(&mreq, sizeof(mreq), char);
1204 Copy(multiaddrbytes, &mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr), char);
1205 Copy(sourcebytes, &mreq.imr_sourceaddr, sizeof(mreq.imr_sourceaddr), char);
1206 if(SvOK(interface)) {
1207 if (DO_UTF8(interface) && !sv_utf8_downgrade(interface, 1))
1208 croak("Wide character in %s", "Socket::pack_ip_mreq");
1209 interfacebytes = SvPVbyte(interface, len);
1210 if (len != sizeof(mreq.imr_interface))
1211 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1212 "Socket::pack_ip_mreq", (UV)len, (UV)sizeof(mreq.imr_interface));
1213 Copy(interfacebytes, &mreq.imr_interface, sizeof(mreq.imr_interface), char);
1216 mreq.imr_interface.s_addr = INADDR_ANY;
1217 ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
1219 PERL_UNUSED_VAR(multiaddr);
1220 PERL_UNUSED_VAR(source);
1221 not_here("pack_ip_mreq_source");
1226 unpack_ip_mreq_source(mreq_sv)
1230 #if defined(HAS_IP_MREQ_SOURCE) && defined (IP_ADD_SOURCE_MEMBERSHIP)
1231 struct ip_mreq_source mreq;
1233 char * mreqbytes = SvPVbyte(mreq_sv, mreqlen);
1234 if (mreqlen != sizeof(mreq))
1235 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
1236 "Socket::unpack_ip_mreq_source", (UV)mreqlen, (UV)sizeof(mreq));
1237 Copy(mreqbytes, &mreq, sizeof(mreq), char);
1239 mPUSHp((char *)&mreq.imr_multiaddr, sizeof(mreq.imr_multiaddr));
1240 mPUSHp((char *)&mreq.imr_sourceaddr, sizeof(mreq.imr_sourceaddr));
1241 mPUSHp((char *)&mreq.imr_interface, sizeof(mreq.imr_interface));
1243 PERL_UNUSED_VAR(mreq_sv);
1244 not_here("unpack_ip_mreq_source");
1249 pack_ipv6_mreq(multiaddr, ifindex)
1251 unsigned int ifindex
1254 #ifdef HAS_IPV6_MREQ
1255 struct ipv6_mreq mreq;
1256 char * multiaddrbytes;
1258 if (DO_UTF8(multiaddr) && !sv_utf8_downgrade(multiaddr, 1))
1259 croak("Wide character in %s", "Socket::pack_ipv6_mreq");
1260 multiaddrbytes = SvPVbyte(multiaddr, len);
1261 if (len != sizeof(mreq.ipv6mr_multiaddr))
1262 croak("Bad arg length %s, length is %"UVuf", should be %"UVuf,
1263 "Socket::pack_ipv6_mreq", (UV)len, (UV)sizeof(mreq.ipv6mr_multiaddr));
1264 Zero(&mreq, sizeof(mreq), char);
1265 Copy(multiaddrbytes, &mreq.ipv6mr_multiaddr, sizeof(mreq.ipv6mr_multiaddr), char);
1266 mreq.ipv6mr_interface = ifindex;
1267 ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
1269 PERL_UNUSED_VAR(multiaddr);
1270 PERL_UNUSED_VAR(ifindex);
1271 not_here("pack_ipv6_mreq");
1276 unpack_ipv6_mreq(mreq_sv)
1280 #ifdef HAS_IPV6_MREQ
1281 struct ipv6_mreq mreq;
1283 char * mreqbytes = SvPVbyte(mreq_sv, mreqlen);
1284 if (mreqlen != sizeof(mreq))
1285 croak("Bad arg length for %s, length is %"UVuf", should be %"UVuf,
1286 "Socket::unpack_ipv6_mreq", (UV)mreqlen, (UV)sizeof(mreq));
1287 Copy(mreqbytes, &mreq, sizeof(mreq), char);
1289 mPUSHp((char *)&mreq.ipv6mr_multiaddr, sizeof(mreq.ipv6mr_multiaddr));
1290 mPUSHi(mreq.ipv6mr_interface);
1292 PERL_UNUSED_VAR(mreq_sv);
1293 not_here("unpack_ipv6_mreq");