small tweaks from Jarkko Hietaniemi <jhi@cc.hut.fi>
[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 #ifdef I_ARPA_INET
18 # include <arpa/inet.h>
19 #endif
20 #else
21 #include "sockadapt.h"
22 #endif
23
24 #ifndef AF_NBS
25 #undef PF_NBS
26 #endif
27
28 #ifndef AF_X25
29 #undef PF_X25
30 #endif
31
32 #ifndef INADDR_NONE
33 #define INADDR_NONE     0xffffffff
34 #endif /* INADDR_NONE */
35 #ifndef INADDR_BROADCAST
36 #define INADDR_BROADCAST        0xffffffff
37 #endif /* INADDR_BROADCAST */
38 #ifndef INADDR_LOOPBACK
39 #define INADDR_LOOPBACK         0x7F000001
40 #endif /* INADDR_LOOPBACK */
41
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  */
51 static int
52 my_inet_aton(register const char *cp, 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(char *s)
149 {
150     croak("Socket::%s not implemented on this architecture", s);
151     return -1;
152 }
153
154 static double
155 constant(char *name, int arg)
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':
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
334         if (strEQ(name, "MSG_DONTROUTE"))
335 #if defined(MSG_DONTROUTE) || defined(HAS_GNULIBC) /* XXX it's an enum */
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"))
347 #if defined(MSG_OOB) || defined(HAS_GNULIBC) /* XXX it's an enum */
348             return MSG_OOB;
349 #else
350             goto not_there;
351 #endif
352         if (strEQ(name, "MSG_PEEK"))
353 #if defined(MSG_PEEK) || defined(HAS_GNULIBC) /* XXX it's an enum */
354             return MSG_PEEK;
355 #else
356             goto not_there;
357 #endif
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
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
695 not_there:
696     errno = ENOENT;
697     return 0;
698 }
699
700
701 MODULE = Socket         PACKAGE = Socket
702
703 double
704 constant(name,arg)
705         char *          name
706         int             arg
707
708
709 void
710 inet_aton(host)
711         char *  host
712         CODE:
713         {
714         struct in_addr ip_address;
715         struct hostent * phe;
716         int ok = inet_aton(host, &ip_address);
717
718         if (!ok && (phe = gethostbyname(host))) {
719                 Copy( phe->h_addr, &ip_address, phe->h_length, char );
720                 ok = 1;
721         }
722
723         ST(0) = sv_newmortal();
724         if (ok) {
725                 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
726         }
727         }
728
729 void
730 inet_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
750 void
751 pack_sockaddr_un(pathname)
752         char *  pathname
753         CODE:
754         {
755 #ifdef I_SYS_UN
756         struct sockaddr_un sun_ad; /* fear using sun */
757         STRLEN len;
758         Zero( &sun_ad, sizeof sun_ad, char );
759         sun_ad.sun_family = AF_UNIX;
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 );
764         ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
765 #else
766         ST(0) = (SV *) not_here("pack_sockaddr_un");
767 #endif
768         
769         }
770
771 void
772 unpack_sockaddr_un(sun_sv)
773         SV *    sun_sv
774         CODE:
775         {
776 #ifdef I_SYS_UN
777         struct sockaddr_un addr;
778         STRLEN sockaddrlen;
779         char * sun_ad = SvPV(sun_sv,sockaddrlen);
780         char * e;
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);
795         }
796         e = addr.sun_path;
797         while (*e && e < addr.sun_path + sizeof addr.sun_path)
798             ++e;
799         ST(0) = sv_2mortal(newSVpv(addr.sun_path, e - addr.sun_path));
800 #else
801         ST(0) = (SV *) not_here("unpack_sockaddr_un");
802 #endif
803         }
804
805 void
806 pack_sockaddr_in(port,ip_address)
807         unsigned short  port
808         char *  ip_address
809         CODE:
810         {
811         struct sockaddr_in sin;
812
813         Zero( &sin, sizeof sin, char );
814         sin.sin_family = AF_INET;
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
821 void
822 unpack_sockaddr_in(sin_sv)
823         SV *    sin_sv
824         PPCODE:
825         {
826         STRLEN sockaddrlen;
827         struct sockaddr_in addr;
828         unsigned short  port;
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         }
836         Copy( sin, &addr,sizeof addr, char );
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         } 
843         port = ntohs(addr.sin_port);
844         ip_address = addr.sin_addr;
845
846         EXTEND(SP, 2);
847         PUSHs(sv_2mortal(newSViv((IV) port)));
848         PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
849         }
850
851 void
852 INADDR_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
860 void
861 INADDR_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
869 void
870 INADDR_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         }
877
878 void
879 INADDR_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         }