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