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