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