add files and tweaks needed for MPE/iX port (via PM)
[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 MPE
11 # define PF_INET AF_INET
12 # define PF_UNIX AF_UNIX
13 # define SOCK_RAW 3
14 #endif
15 #ifdef I_SYS_UN
16 #include <sys/un.h>
17 #endif
18 # ifdef I_NETINET_IN
19 #  include <netinet/in.h>
20 # endif
21 #include <netdb.h>
22 #ifdef I_ARPA_INET
23 # include <arpa/inet.h>
24 #endif
25 #else
26 #include "sockadapt.h"
27 #endif
28
29 #ifndef AF_NBS
30 #undef PF_NBS
31 #endif
32
33 #ifndef AF_X25
34 #undef PF_X25
35 #endif
36
37 #ifndef INADDR_NONE
38 #define INADDR_NONE     0xffffffff
39 #endif /* INADDR_NONE */
40 #ifndef INADDR_BROADCAST
41 #define INADDR_BROADCAST        0xffffffff
42 #endif /* INADDR_BROADCAST */
43 #ifndef INADDR_LOOPBACK
44 #define INADDR_LOOPBACK         0x7F000001
45 #endif /* INADDR_LOOPBACK */
46
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  */
56 static int
57 my_inet_aton(register const char *cp, struct in_addr *addr)
58 {
59         register U32 val;
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
67         if (!cp)
68                 return 0;
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                         }
88                         if (base == 16 && (s=strchr(hexdigit,c))) {
89                                 val = (val << 4) + 
90                                         ((s - hexdigit) & 15);
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
151
152 static int
153 not_here(char *s)
154 {
155     croak("Socket::%s not implemented on this architecture", s);
156     return -1;
157 }
158
159 static double
160 constant(char *name, int arg)
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':
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
339         if (strEQ(name, "MSG_DONTROUTE"))
340 #if defined(MSG_DONTROUTE) || defined(HAS_GNULIBC) /* XXX it's an enum */
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"))
352 #if defined(MSG_OOB) || defined(HAS_GNULIBC) /* XXX it's an enum */
353             return MSG_OOB;
354 #else
355             goto not_there;
356 #endif
357         if (strEQ(name, "MSG_PEEK"))
358 #if defined(MSG_PEEK) || defined(HAS_GNULIBC) /* XXX it's an enum */
359             return MSG_PEEK;
360 #else
361             goto not_there;
362 #endif
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
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
700 not_there:
701     errno = ENOENT;
702     return 0;
703 }
704
705
706 MODULE = Socket         PACKAGE = Socket
707
708 double
709 constant(name,arg)
710         char *          name
711         int             arg
712
713
714 void
715 inet_aton(host)
716         char *  host
717         CODE:
718         {
719         struct in_addr ip_address;
720         struct hostent * phe;
721         int ok = inet_aton(host, &ip_address);
722
723         if (!ok && (phe = gethostbyname(host))) {
724                 Copy( phe->h_addr, &ip_address, phe->h_length, char );
725                 ok = 1;
726         }
727
728         ST(0) = sv_newmortal();
729         if (ok) {
730                 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
731         }
732         }
733
734 void
735 inet_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
755 void
756 pack_sockaddr_un(pathname)
757         char *  pathname
758         CODE:
759         {
760 #ifdef I_SYS_UN
761         struct sockaddr_un sun_ad; /* fear using sun */
762         STRLEN len;
763         Zero( &sun_ad, sizeof sun_ad, char );
764         sun_ad.sun_family = AF_UNIX;
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 );
769         ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
770 #else
771         ST(0) = (SV *) not_here("pack_sockaddr_un");
772 #endif
773         
774         }
775
776 void
777 unpack_sockaddr_un(sun_sv)
778         SV *    sun_sv
779         CODE:
780         {
781 #ifdef I_SYS_UN
782         struct sockaddr_un addr;
783         STRLEN sockaddrlen;
784         char * sun_ad = SvPV(sun_sv,sockaddrlen);
785         char * e;
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);
800         }
801         e = addr.sun_path;
802         while (*e && e < addr.sun_path + sizeof addr.sun_path)
803             ++e;
804         ST(0) = sv_2mortal(newSVpv(addr.sun_path, e - addr.sun_path));
805 #else
806         ST(0) = (SV *) not_here("unpack_sockaddr_un");
807 #endif
808         }
809
810 void
811 pack_sockaddr_in(port,ip_address)
812         unsigned short  port
813         char *  ip_address
814         CODE:
815         {
816         struct sockaddr_in sin;
817
818         Zero( &sin, sizeof sin, char );
819         sin.sin_family = AF_INET;
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
826 void
827 unpack_sockaddr_in(sin_sv)
828         SV *    sin_sv
829         PPCODE:
830         {
831         STRLEN sockaddrlen;
832         struct sockaddr_in addr;
833         unsigned short  port;
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         }
841         Copy( sin, &addr,sizeof addr, char );
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         } 
848         port = ntohs(addr.sin_port);
849         ip_address = addr.sin_addr;
850
851         EXTEND(SP, 2);
852         PUSHs(sv_2mortal(newSViv((IV) port)));
853         PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
854         }
855
856 void
857 INADDR_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
865 void
866 INADDR_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
874 void
875 INADDR_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         }
882
883 void
884 INADDR_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         }