This is a live mirror of the Perl 5 development currently hosted at https://github.com/perl/perl5
perlhist.pod 1.54, containing 5_53.
[perl5.git] / ext / Socket / Socket.xs
CommitLineData
a0d0e21e
LW
1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4
8e07c86e
AD
5#ifndef VMS
6# ifdef I_SYS_TYPES
7# include <sys/types.h>
8# endif
a0d0e21e 9#include <sys/socket.h>
1d84e8df
JH
10#ifdef MPE
11# define PF_INET AF_INET
12# define PF_UNIX AF_UNIX
13# define SOCK_RAW 3
14#endif
25f94b33 15#ifdef I_SYS_UN
4633a7c4 16#include <sys/un.h>
25f94b33 17#endif
8e07c86e
AD
18# ifdef I_NETINET_IN
19# include <netinet/in.h>
20# endif
21#include <netdb.h>
a3f9223b
GS
22#ifdef I_ARPA_INET
23# include <arpa/inet.h>
24#endif
8e07c86e
AD
25#else
26#include "sockadapt.h"
27#endif
a0d0e21e
LW
28
29#ifndef AF_NBS
30#undef PF_NBS
31#endif
32
33#ifndef AF_X25
34#undef PF_X25
35#endif
36
8e07c86e
AD
37#ifndef INADDR_NONE
38#define INADDR_NONE 0xffffffff
39#endif /* INADDR_NONE */
7e1af8bc
PP
40#ifndef INADDR_BROADCAST
41#define INADDR_BROADCAST 0xffffffff
42#endif /* INADDR_BROADCAST */
8e07c86e
AD
43#ifndef INADDR_LOOPBACK
44#define INADDR_LOOPBACK 0x7F000001
45#endif /* INADDR_LOOPBACK */
46
7e1af8bc
PP
47#ifndef HAS_INET_ATON
48
49/*
50 * Check whether "cp" is a valid ascii representation
51 * of an Internet address and convert to a binary address.
52 * Returns 1 if the address is valid, 0 if not.
53 * This replaces inet_addr, the return value from which
54 * cannot distinguish between failure and a local broadcast address.
55 */
56static int
f0f333f4 57my_inet_aton(register const char *cp, struct in_addr *addr)
7e1af8bc 58{
0caed002 59 register U32 val;
7e1af8bc
PP
60 register int base;
61 register char c;
62 int nparts;
63 const char *s;
64 unsigned int parts[4];
65 register unsigned int *pp = parts;
66
0caed002
CS
67 if (!cp)
68 return 0;
7e1af8bc
PP
69 for (;;) {
70 /*
71 * Collect number up to ``.''.
72 * Values are specified as for C:
73 * 0x=hex, 0=octal, other=decimal.
74 */
75 val = 0; base = 10;
76 if (*cp == '0') {
77 if (*++cp == 'x' || *cp == 'X')
78 base = 16, cp++;
79 else
80 base = 8;
81 }
82 while ((c = *cp) != '\0') {
83 if (isDIGIT(c)) {
84 val = (val * base) + (c - '0');
85 cp++;
86 continue;
87 }
3280af22 88 if (base == 16 && (s=strchr(PL_hexdigit,c))) {
7e1af8bc 89 val = (val << 4) +
3280af22 90 ((s - PL_hexdigit) & 15);
7e1af8bc
PP
91 cp++;
92 continue;
93 }
94 break;
95 }
96 if (*cp == '.') {
97 /*
98 * Internet format:
99 * a.b.c.d
100 * a.b.c (with c treated as 16-bits)
101 * a.b (with b treated as 24 bits)
102 */
103 if (pp >= parts + 3 || val > 0xff)
104 return 0;
105 *pp++ = val, cp++;
106 } else
107 break;
108 }
109 /*
110 * Check for trailing characters.
111 */
112 if (*cp && !isSPACE(*cp))
113 return 0;
114 /*
115 * Concoct the address according to
116 * the number of parts specified.
117 */
118 nparts = pp - parts + 1; /* force to an int for switch() */
119 switch (nparts) {
120
121 case 1: /* a -- 32 bits */
122 break;
123
124 case 2: /* a.b -- 8.24 bits */
125 if (val > 0xffffff)
126 return 0;
127 val |= parts[0] << 24;
128 break;
129
130 case 3: /* a.b.c -- 8.8.16 bits */
131 if (val > 0xffff)
132 return 0;
133 val |= (parts[0] << 24) | (parts[1] << 16);
134 break;
135
136 case 4: /* a.b.c.d -- 8.8.8.8 bits */
137 if (val > 0xff)
138 return 0;
139 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
140 break;
141 }
142 addr->s_addr = htonl(val);
143 return 1;
144}
145
146#undef inet_aton
147#define inet_aton my_inet_aton
148
149#endif /* ! HAS_INET_ATON */
150
8e07c86e 151
a0d0e21e 152static int
f0f333f4 153not_here(char *s)
a0d0e21e
LW
154{
155 croak("Socket::%s not implemented on this architecture", s);
156 return -1;
157}
158
159static double
f0f333f4 160constant(char *name, int arg)
a0d0e21e
LW
161{
162 errno = 0;
163 switch (*name) {
164 case 'A':
165 if (strEQ(name, "AF_802"))
166#ifdef AF_802
167 return AF_802;
168#else
169 goto not_there;
170#endif
171 if (strEQ(name, "AF_APPLETALK"))
172#ifdef AF_APPLETALK
173 return AF_APPLETALK;
174#else
175 goto not_there;
176#endif
177 if (strEQ(name, "AF_CCITT"))
178#ifdef AF_CCITT
179 return AF_CCITT;
180#else
181 goto not_there;
182#endif
183 if (strEQ(name, "AF_CHAOS"))
184#ifdef AF_CHAOS
185 return AF_CHAOS;
186#else
187 goto not_there;
188#endif
189 if (strEQ(name, "AF_DATAKIT"))
190#ifdef AF_DATAKIT
191 return AF_DATAKIT;
192#else
193 goto not_there;
194#endif
195 if (strEQ(name, "AF_DECnet"))
196#ifdef AF_DECnet
197 return AF_DECnet;
198#else
199 goto not_there;
200#endif
201 if (strEQ(name, "AF_DLI"))
202#ifdef AF_DLI
203 return AF_DLI;
204#else
205 goto not_there;
206#endif
207 if (strEQ(name, "AF_ECMA"))
208#ifdef AF_ECMA
209 return AF_ECMA;
210#else
211 goto not_there;
212#endif
213 if (strEQ(name, "AF_GOSIP"))
214#ifdef AF_GOSIP
215 return AF_GOSIP;
216#else
217 goto not_there;
218#endif
219 if (strEQ(name, "AF_HYLINK"))
220#ifdef AF_HYLINK
221 return AF_HYLINK;
222#else
223 goto not_there;
224#endif
225 if (strEQ(name, "AF_IMPLINK"))
226#ifdef AF_IMPLINK
227 return AF_IMPLINK;
228#else
229 goto not_there;
230#endif
231 if (strEQ(name, "AF_INET"))
232#ifdef AF_INET
233 return AF_INET;
234#else
235 goto not_there;
236#endif
237 if (strEQ(name, "AF_LAT"))
238#ifdef AF_LAT
239 return AF_LAT;
240#else
241 goto not_there;
242#endif
243 if (strEQ(name, "AF_MAX"))
244#ifdef AF_MAX
245 return AF_MAX;
246#else
247 goto not_there;
248#endif
249 if (strEQ(name, "AF_NBS"))
250#ifdef AF_NBS
251 return AF_NBS;
252#else
253 goto not_there;
254#endif
255 if (strEQ(name, "AF_NIT"))
256#ifdef AF_NIT
257 return AF_NIT;
258#else
259 goto not_there;
260#endif
261 if (strEQ(name, "AF_NS"))
262#ifdef AF_NS
263 return AF_NS;
264#else
265 goto not_there;
266#endif
267 if (strEQ(name, "AF_OSI"))
268#ifdef AF_OSI
269 return AF_OSI;
270#else
271 goto not_there;
272#endif
273 if (strEQ(name, "AF_OSINET"))
274#ifdef AF_OSINET
275 return AF_OSINET;
276#else
277 goto not_there;
278#endif
279 if (strEQ(name, "AF_PUP"))
280#ifdef AF_PUP
281 return AF_PUP;
282#else
283 goto not_there;
284#endif
285 if (strEQ(name, "AF_SNA"))
286#ifdef AF_SNA
287 return AF_SNA;
288#else
289 goto not_there;
290#endif
291 if (strEQ(name, "AF_UNIX"))
292#ifdef AF_UNIX
293 return AF_UNIX;
294#else
295 goto not_there;
296#endif
297 if (strEQ(name, "AF_UNSPEC"))
298#ifdef AF_UNSPEC
299 return AF_UNSPEC;
300#else
301 goto not_there;
302#endif
303 if (strEQ(name, "AF_X25"))
304#ifdef AF_X25
305 return AF_X25;
306#else
307 goto not_there;
308#endif
309 break;
310 case 'B':
311 break;
312 case 'C':
313 break;
314 case 'D':
315 break;
316 case 'E':
317 break;
318 case 'F':
319 break;
320 case 'G':
321 break;
322 case 'H':
323 break;
324 case 'I':
325 break;
326 case 'J':
327 break;
328 case 'K':
329 break;
330 case 'L':
331 break;
332 case 'M':
a1896f58
AD
333 if (strEQ(name, "MSG_CTRUNC"))
334#if defined(MSG_CTRUNC) || defined(HAS_GNULIBC) /* XXX it's an enum */
335 return MSG_CTRUNC;
336#else
337 goto not_there;
338#endif
a0d0e21e 339 if (strEQ(name, "MSG_DONTROUTE"))
a1896f58 340#if defined(MSG_DONTROUTE) || defined(HAS_GNULIBC) /* XXX it's an enum */
a0d0e21e
LW
341 return MSG_DONTROUTE;
342#else
343 goto not_there;
344#endif
345 if (strEQ(name, "MSG_MAXIOVLEN"))
346#ifdef MSG_MAXIOVLEN
347 return MSG_MAXIOVLEN;
348#else
349 goto not_there;
350#endif
351 if (strEQ(name, "MSG_OOB"))
a1896f58 352#if defined(MSG_OOB) || defined(HAS_GNULIBC) /* XXX it's an enum */
a0d0e21e
LW
353 return MSG_OOB;
354#else
355 goto not_there;
356#endif
357 if (strEQ(name, "MSG_PEEK"))
a1896f58 358#if defined(MSG_PEEK) || defined(HAS_GNULIBC) /* XXX it's an enum */
a0d0e21e
LW
359 return MSG_PEEK;
360#else
361 goto not_there;
362#endif
a1896f58
AD
363 if (strEQ(name, "MSG_PROXY"))
364#if defined(MSG_PROXY) || defined(HAS_GNULIBC) /* XXX it's an enum */
365 return MSG_PROXY;
366#else
367 goto not_there;
368#endif
a0d0e21e
LW
369 break;
370 case 'N':
371 break;
372 case 'O':
373 break;
374 case 'P':
375 if (strEQ(name, "PF_802"))
376#ifdef PF_802
377 return PF_802;
378#else
379 goto not_there;
380#endif
381 if (strEQ(name, "PF_APPLETALK"))
382#ifdef PF_APPLETALK
383 return PF_APPLETALK;
384#else
385 goto not_there;
386#endif
387 if (strEQ(name, "PF_CCITT"))
388#ifdef PF_CCITT
389 return PF_CCITT;
390#else
391 goto not_there;
392#endif
393 if (strEQ(name, "PF_CHAOS"))
394#ifdef PF_CHAOS
395 return PF_CHAOS;
396#else
397 goto not_there;
398#endif
399 if (strEQ(name, "PF_DATAKIT"))
400#ifdef PF_DATAKIT
401 return PF_DATAKIT;
402#else
403 goto not_there;
404#endif
405 if (strEQ(name, "PF_DECnet"))
406#ifdef PF_DECnet
407 return PF_DECnet;
408#else
409 goto not_there;
410#endif
411 if (strEQ(name, "PF_DLI"))
412#ifdef PF_DLI
413 return PF_DLI;
414#else
415 goto not_there;
416#endif
417 if (strEQ(name, "PF_ECMA"))
418#ifdef PF_ECMA
419 return PF_ECMA;
420#else
421 goto not_there;
422#endif
423 if (strEQ(name, "PF_GOSIP"))
424#ifdef PF_GOSIP
425 return PF_GOSIP;
426#else
427 goto not_there;
428#endif
429 if (strEQ(name, "PF_HYLINK"))
430#ifdef PF_HYLINK
431 return PF_HYLINK;
432#else
433 goto not_there;
434#endif
435 if (strEQ(name, "PF_IMPLINK"))
436#ifdef PF_IMPLINK
437 return PF_IMPLINK;
438#else
439 goto not_there;
440#endif
441 if (strEQ(name, "PF_INET"))
442#ifdef PF_INET
443 return PF_INET;
444#else
445 goto not_there;
446#endif
447 if (strEQ(name, "PF_LAT"))
448#ifdef PF_LAT
449 return PF_LAT;
450#else
451 goto not_there;
452#endif
453 if (strEQ(name, "PF_MAX"))
454#ifdef PF_MAX
455 return PF_MAX;
456#else
457 goto not_there;
458#endif
459 if (strEQ(name, "PF_NBS"))
460#ifdef PF_NBS
461 return PF_NBS;
462#else
463 goto not_there;
464#endif
465 if (strEQ(name, "PF_NIT"))
466#ifdef PF_NIT
467 return PF_NIT;
468#else
469 goto not_there;
470#endif
471 if (strEQ(name, "PF_NS"))
472#ifdef PF_NS
473 return PF_NS;
474#else
475 goto not_there;
476#endif
477 if (strEQ(name, "PF_OSI"))
478#ifdef PF_OSI
479 return PF_OSI;
480#else
481 goto not_there;
482#endif
483 if (strEQ(name, "PF_OSINET"))
484#ifdef PF_OSINET
485 return PF_OSINET;
486#else
487 goto not_there;
488#endif
489 if (strEQ(name, "PF_PUP"))
490#ifdef PF_PUP
491 return PF_PUP;
492#else
493 goto not_there;
494#endif
495 if (strEQ(name, "PF_SNA"))
496#ifdef PF_SNA
497 return PF_SNA;
498#else
499 goto not_there;
500#endif
501 if (strEQ(name, "PF_UNIX"))
502#ifdef PF_UNIX
503 return PF_UNIX;
504#else
505 goto not_there;
506#endif
507 if (strEQ(name, "PF_UNSPEC"))
508#ifdef PF_UNSPEC
509 return PF_UNSPEC;
510#else
511 goto not_there;
512#endif
513 if (strEQ(name, "PF_X25"))
514#ifdef PF_X25
515 return PF_X25;
516#else
517 goto not_there;
518#endif
519 break;
520 case 'Q':
521 break;
522 case 'R':
523 break;
524 case 'S':
525 if (strEQ(name, "SOCK_DGRAM"))
526#ifdef SOCK_DGRAM
527 return SOCK_DGRAM;
528#else
529 goto not_there;
530#endif
531 if (strEQ(name, "SOCK_RAW"))
532#ifdef SOCK_RAW
533 return SOCK_RAW;
534#else
535 goto not_there;
536#endif
537 if (strEQ(name, "SOCK_RDM"))
538#ifdef SOCK_RDM
539 return SOCK_RDM;
540#else
541 goto not_there;
542#endif
543 if (strEQ(name, "SOCK_SEQPACKET"))
544#ifdef SOCK_SEQPACKET
545 return SOCK_SEQPACKET;
546#else
547 goto not_there;
548#endif
549 if (strEQ(name, "SOCK_STREAM"))
550#ifdef SOCK_STREAM
551 return SOCK_STREAM;
552#else
553 goto not_there;
554#endif
555 if (strEQ(name, "SOL_SOCKET"))
556#ifdef SOL_SOCKET
557 return SOL_SOCKET;
558#else
559 goto not_there;
560#endif
561 if (strEQ(name, "SOMAXCONN"))
562#ifdef SOMAXCONN
563 return SOMAXCONN;
564#else
565 goto not_there;
566#endif
567 if (strEQ(name, "SO_ACCEPTCONN"))
568#ifdef SO_ACCEPTCONN
569 return SO_ACCEPTCONN;
570#else
571 goto not_there;
572#endif
573 if (strEQ(name, "SO_BROADCAST"))
574#ifdef SO_BROADCAST
575 return SO_BROADCAST;
576#else
577 goto not_there;
578#endif
579 if (strEQ(name, "SO_DEBUG"))
580#ifdef SO_DEBUG
581 return SO_DEBUG;
582#else
583 goto not_there;
584#endif
585 if (strEQ(name, "SO_DONTLINGER"))
586#ifdef SO_DONTLINGER
587 return SO_DONTLINGER;
588#else
589 goto not_there;
590#endif
591 if (strEQ(name, "SO_DONTROUTE"))
592#ifdef SO_DONTROUTE
593 return SO_DONTROUTE;
594#else
595 goto not_there;
596#endif
597 if (strEQ(name, "SO_ERROR"))
598#ifdef SO_ERROR
599 return SO_ERROR;
600#else
601 goto not_there;
602#endif
603 if (strEQ(name, "SO_KEEPALIVE"))
604#ifdef SO_KEEPALIVE
605 return SO_KEEPALIVE;
606#else
607 goto not_there;
608#endif
609 if (strEQ(name, "SO_LINGER"))
610#ifdef SO_LINGER
611 return SO_LINGER;
612#else
613 goto not_there;
614#endif
615 if (strEQ(name, "SO_OOBINLINE"))
616#ifdef SO_OOBINLINE
617 return SO_OOBINLINE;
618#else
619 goto not_there;
620#endif
621 if (strEQ(name, "SO_RCVBUF"))
622#ifdef SO_RCVBUF
623 return SO_RCVBUF;
624#else
625 goto not_there;
626#endif
627 if (strEQ(name, "SO_RCVLOWAT"))
628#ifdef SO_RCVLOWAT
629 return SO_RCVLOWAT;
630#else
631 goto not_there;
632#endif
633 if (strEQ(name, "SO_RCVTIMEO"))
634#ifdef SO_RCVTIMEO
635 return SO_RCVTIMEO;
636#else
637 goto not_there;
638#endif
639 if (strEQ(name, "SO_REUSEADDR"))
640#ifdef SO_REUSEADDR
641 return SO_REUSEADDR;
642#else
643 goto not_there;
644#endif
645 if (strEQ(name, "SO_REUSEPORT"))
646#ifdef SO_REUSEPORT
647 return SO_REUSEPORT;
648#else
649 goto not_there;
650#endif
651 if (strEQ(name, "SO_SNDBUF"))
652#ifdef SO_SNDBUF
653 return SO_SNDBUF;
654#else
655 goto not_there;
656#endif
657 if (strEQ(name, "SO_SNDLOWAT"))
658#ifdef SO_SNDLOWAT
659 return SO_SNDLOWAT;
660#else
661 goto not_there;
662#endif
663 if (strEQ(name, "SO_SNDTIMEO"))
664#ifdef SO_SNDTIMEO
665 return SO_SNDTIMEO;
666#else
667 goto not_there;
668#endif
669 if (strEQ(name, "SO_TYPE"))
670#ifdef SO_TYPE
671 return SO_TYPE;
672#else
673 goto not_there;
674#endif
675 if (strEQ(name, "SO_USELOOPBACK"))
676#ifdef SO_USELOOPBACK
677 return SO_USELOOPBACK;
678#else
679 goto not_there;
680#endif
681 break;
682 case 'T':
683 break;
684 case 'U':
685 break;
686 case 'V':
687 break;
688 case 'W':
689 break;
690 case 'X':
691 break;
692 case 'Y':
693 break;
694 case 'Z':
695 break;
696 }
697 errno = EINVAL;
698 return 0;
699
700not_there:
701 errno = ENOENT;
702 return 0;
703}
704
8e07c86e 705
a0d0e21e
LW
706MODULE = Socket PACKAGE = Socket
707
708double
709constant(name,arg)
710 char * name
711 int arg
712
8e07c86e
AD
713
714void
715inet_aton(host)
716 char * host
717 CODE:
718 {
719 struct in_addr ip_address;
720 struct hostent * phe;
ac9fe1c2 721 int ok = inet_aton(host, &ip_address);
8e07c86e 722
ac9fe1c2 723 if (!ok && (phe = gethostbyname(host))) {
8e07c86e 724 Copy( phe->h_addr, &ip_address, phe->h_length, char );
7e1af8bc 725 ok = 1;
8e07c86e
AD
726 }
727
728 ST(0) = sv_newmortal();
7e1af8bc 729 if (ok) {
8e07c86e
AD
730 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
731 }
732 }
733
734void
735inet_ntoa(ip_address_sv)
736 SV * ip_address_sv
737 CODE:
738 {
739 STRLEN addrlen;
740 struct in_addr addr;
741 char * addr_str;
742 char * ip_address = SvPV(ip_address_sv,addrlen);
743 if (addrlen != sizeof(addr)) {
744 croak("Bad arg length for %s, length is %d, should be %d",
745 "Socket::inet_ntoa",
746 addrlen, sizeof(addr));
747 }
748
749 Copy( ip_address, &addr, sizeof addr, char );
750 addr_str = inet_ntoa(addr);
751
752 ST(0) = sv_2mortal(newSVpv(addr_str, strlen(addr_str)));
753 }
754
755void
4633a7c4
LW
756pack_sockaddr_un(pathname)
757 char * pathname
758 CODE:
759 {
25f94b33 760#ifdef I_SYS_UN
4633a7c4 761 struct sockaddr_un sun_ad; /* fear using sun */
fcdb74fc 762 STRLEN len;
4633a7c4
LW
763 Zero( &sun_ad, sizeof sun_ad, char );
764 sun_ad.sun_family = AF_UNIX;
20408e3c
GS
765 len = strlen(pathname);
766 if (len > sizeof(sun_ad.sun_path))
767 len = sizeof(sun_ad.sun_path);
768 Copy( pathname, sun_ad.sun_path, len, char );
4633a7c4 769 ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
25f94b33
AD
770#else
771 ST(0) = (SV *) not_here("pack_sockaddr_un");
772#endif
773
4633a7c4
LW
774 }
775
776void
777unpack_sockaddr_un(sun_sv)
778 SV * sun_sv
f13e1b2f 779 CODE:
4633a7c4 780 {
25f94b33 781#ifdef I_SYS_UN
4633a7c4 782 struct sockaddr_un addr;
fcdb74fc
TB
783 STRLEN sockaddrlen;
784 char * sun_ad = SvPV(sun_sv,sockaddrlen);
785 char * e;
4633a7c4
LW
786
787 if (sockaddrlen != sizeof(addr)) {
788 croak("Bad arg length for %s, length is %d, should be %d",
789 "Socket::unpack_sockaddr_un",
790 sockaddrlen, sizeof(addr));
791 }
792
793 Copy( sun_ad, &addr, sizeof addr, char );
794
795 if ( addr.sun_family != AF_UNIX ) {
796 croak("Bad address family for %s, got %d, should be %d",
797 "Socket::unpack_sockaddr_un",
798 addr.sun_family,
799 AF_UNIX);
fcdb74fc
TB
800 }
801 e = addr.sun_path;
802 while (*e && e < addr.sun_path + sizeof addr.sun_path)
803 ++e;
26893f8d 804 ST(0) = sv_2mortal(newSVpv(addr.sun_path, e - addr.sun_path));
25f94b33
AD
805#else
806 ST(0) = (SV *) not_here("unpack_sockaddr_un");
807#endif
4633a7c4
LW
808 }
809
810void
811pack_sockaddr_in(port,ip_address)
2c129a17 812 unsigned short port
8e07c86e
AD
813 char * ip_address
814 CODE:
815 {
816 struct sockaddr_in sin;
817
818 Zero( &sin, sizeof sin, char );
4633a7c4 819 sin.sin_family = AF_INET;
8e07c86e
AD
820 sin.sin_port = htons(port);
821 Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
822
823 ST(0) = sv_2mortal(newSVpv((char *)&sin, sizeof sin));
824 }
825
826void
827unpack_sockaddr_in(sin_sv)
828 SV * sin_sv
829 PPCODE:
830 {
831 STRLEN sockaddrlen;
832 struct sockaddr_in addr;
2c129a17 833 unsigned short port;
8e07c86e
AD
834 struct in_addr ip_address;
835 char * sin = SvPV(sin_sv,sockaddrlen);
836 if (sockaddrlen != sizeof(addr)) {
837 croak("Bad arg length for %s, length is %d, should be %d",
838 "Socket::unpack_sockaddr_in",
839 sockaddrlen, sizeof(addr));
840 }
8e07c86e 841 Copy( sin, &addr,sizeof addr, char );
4633a7c4
LW
842 if ( addr.sin_family != AF_INET ) {
843 croak("Bad address family for %s, got %d, should be %d",
844 "Socket::unpack_sockaddr_in",
845 addr.sin_family,
846 AF_INET);
847 }
8e07c86e
AD
848 port = ntohs(addr.sin_port);
849 ip_address = addr.sin_addr;
850
924508f0 851 EXTEND(SP, 2);
2c129a17 852 PUSHs(sv_2mortal(newSViv((IV) port)));
8e07c86e
AD
853 PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
854 }
855
856void
857INADDR_ANY()
858 CODE:
859 {
860 struct in_addr ip_address;
861 ip_address.s_addr = htonl(INADDR_ANY);
862 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address ));
863 }
864
865void
866INADDR_LOOPBACK()
867 CODE:
868 {
869 struct in_addr ip_address;
870 ip_address.s_addr = htonl(INADDR_LOOPBACK);
871 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
872 }
873
874void
875INADDR_NONE()
876 CODE:
877 {
878 struct in_addr ip_address;
879 ip_address.s_addr = htonl(INADDR_NONE);
880 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
881 }
7e1af8bc
PP
882
883void
884INADDR_BROADCAST()
885 CODE:
886 {
887 struct in_addr ip_address;
888 ip_address.s_addr = htonl(INADDR_BROADCAST);
889 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
890 }