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