avoid duplicate code
[p5sagit/p5-mst-13.2.git] / ext / Socket / Socket.xs
CommitLineData
a0d0e21e 1#include "EXTERN.h"
2#include "perl.h"
3#include "XSUB.h"
4
8e07c86e 5#ifndef VMS
6# ifdef I_SYS_TYPES
7# include <sys/types.h>
8# endif
a0d0e21e 9#include <sys/socket.h>
1d84e8df 10#ifdef MPE
11# define PF_INET AF_INET
12# define PF_UNIX AF_UNIX
13# define SOCK_RAW 3
14#endif
25f94b33 15#ifdef I_SYS_UN
4633a7c4 16#include <sys/un.h>
25f94b33 17#endif
8e07c86e 18# ifdef I_NETINET_IN
19# include <netinet/in.h>
20# endif
21#include <netdb.h>
a3f9223b 22#ifdef I_ARPA_INET
23# include <arpa/inet.h>
24#endif
8e07c86e 25#else
26#include "sockadapt.h"
27#endif
a0d0e21e 28
6b1016b5 29#ifdef I_SYSUIO
30# include <sys/uio.h>
31#endif
32
a0d0e21e 33#ifndef AF_NBS
34#undef PF_NBS
35#endif
36
37#ifndef AF_X25
38#undef PF_X25
39#endif
40
8e07c86e 41#ifndef INADDR_NONE
42#define INADDR_NONE 0xffffffff
43#endif /* INADDR_NONE */
7e1af8bc 44#ifndef INADDR_BROADCAST
45#define INADDR_BROADCAST 0xffffffff
46#endif /* INADDR_BROADCAST */
8e07c86e 47#ifndef INADDR_LOOPBACK
48#define INADDR_LOOPBACK 0x7F000001
49#endif /* INADDR_LOOPBACK */
50
7e1af8bc 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 */
60static int
f0f333f4 61my_inet_aton(register const char *cp, struct in_addr *addr)
7e1af8bc 62{
0caed002 63 register U32 val;
7e1af8bc 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
0caed002 71 if (!cp)
72 return 0;
7e1af8bc 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 }
3280af22 92 if (base == 16 && (s=strchr(PL_hexdigit,c))) {
7e1af8bc 93 val = (val << 4) +
3280af22 94 ((s - PL_hexdigit) & 15);
7e1af8bc 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
8e07c86e 155
a0d0e21e 156static int
f0f333f4 157not_here(char *s)
a0d0e21e 158{
159 croak("Socket::%s not implemented on this architecture", s);
160 return -1;
161}
162
163static double
f0f333f4 164constant(char *name, int arg)
a0d0e21e 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':
6b1016b5 329 if (strEQ(name, "IOV_MAX"))
330#ifdef IOV_MAX
331 return IOV_MAX;
332#else
333 goto not_there;
334#endif
a0d0e21e 335 break;
336 case 'J':
337 break;
338 case 'K':
339 break;
340 case 'L':
341 break;
342 case 'M':
6b1016b5 343 if (strEQ(name, "MSG_BCAST"))
344#ifdef MSG_BCAST
345 return MSG_BCAST;
346#else
347 goto not_there;
348#endif
de4597cb 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
a1896f58 361 if (strEQ(name, "MSG_CTRUNC"))
5b8dae3f 362#if defined(MSG_TRUNC) || defined(HAS_MSG_CTRUNC) /* might be an enum */
a1896f58 363 return MSG_CTRUNC;
364#else
365 goto not_there;
366#endif
a0d0e21e 367 if (strEQ(name, "MSG_DONTROUTE"))
5b8dae3f 368#if defined(MSG_DONTROUTE) || defined(HAS_MSG_DONTROUTE) /* might be an enum */
a0d0e21e 369 return MSG_DONTROUTE;
370#else
371 goto not_there;
372#endif
de4597cb 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
a0d0e21e 403 if (strEQ(name, "MSG_MAXIOVLEN"))
5b8dae3f 404#ifdef MSG_MAXIOVLEN
a0d0e21e 405 return MSG_MAXIOVLEN;
406#else
407 goto not_there;
408#endif
6b1016b5 409 if (strEQ(name, "MSG_MCAST"))
410#ifdef MSG_MCAST
411 return MSG_MCAST;
412#else
413 goto not_there;
414#endif
de4597cb 415 if (strEQ(name, "MSG_NOSIGNAL"))
416#ifdef MSG_NOSIGNAL
417 return MSG_NOSIGNAL;
418#else
419 goto not_there;
420#endif
a0d0e21e 421 if (strEQ(name, "MSG_OOB"))
5b8dae3f 422#if defined(MSG_OOB) || defined(HAS_MSG_OOB) /* might be an enum */
a0d0e21e 423 return MSG_OOB;
424#else
425 goto not_there;
426#endif
427 if (strEQ(name, "MSG_PEEK"))
5b8dae3f 428#if defined(MSG_PEEK) || defined(HAS_MSG_PEEK) /* might be an enum */
a0d0e21e 429 return MSG_PEEK;
430#else
431 goto not_there;
432#endif
a1896f58 433 if (strEQ(name, "MSG_PROXY"))
5b8dae3f 434#if defined(MSG_PROXY) || defined(HAS_MSG_PROXY) /* might be an enum */
a1896f58 435 return MSG_PROXY;
436#else
437 goto not_there;
438#endif
de4597cb 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
a0d0e21e 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':
de4597cb 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
b4be96ab 627 return SCM_CREDENTIALS;
de4597cb 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"))
5b8dae3f 638#if defined(SCM_RIGHTS) || defined(HAS_SCM_RIGHTS) /* might be an enum */
de4597cb 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
a0d0e21e 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':
6b1016b5 809 if (strEQ(name, "UIO_MAXIOV"))
810#ifdef UIO_MAXIOV
811 return UIO_MAXIOV;
812#else
813 goto not_there;
814#endif
a0d0e21e 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
830not_there:
831 errno = ENOENT;
832 return 0;
833}
834
8e07c86e 835
a0d0e21e 836MODULE = Socket PACKAGE = Socket
837
838double
839constant(name,arg)
840 char * name
841 int arg
842
8e07c86e 843
844void
845inet_aton(host)
846 char * host
847 CODE:
848 {
849 struct in_addr ip_address;
850 struct hostent * phe;
ac9fe1c2 851 int ok = inet_aton(host, &ip_address);
8e07c86e 852
ac9fe1c2 853 if (!ok && (phe = gethostbyname(host))) {
8e07c86e 854 Copy( phe->h_addr, &ip_address, phe->h_length, char );
7e1af8bc 855 ok = 1;
8e07c86e 856 }
857
858 ST(0) = sv_newmortal();
7e1af8bc 859 if (ok) {
8e07c86e 860 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
861 }
862 }
863
864void
865inet_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(newSVpv(addr_str, strlen(addr_str)));
883 }
884
885void
4633a7c4 886pack_sockaddr_un(pathname)
887 char * pathname
888 CODE:
889 {
25f94b33 890#ifdef I_SYS_UN
4633a7c4 891 struct sockaddr_un sun_ad; /* fear using sun */
fcdb74fc 892 STRLEN len;
4633a7c4 893 Zero( &sun_ad, sizeof sun_ad, char );
894 sun_ad.sun_family = AF_UNIX;
20408e3c 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 );
4633a7c4 899 ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
25f94b33 900#else
901 ST(0) = (SV *) not_here("pack_sockaddr_un");
902#endif
903
4633a7c4 904 }
905
906void
907unpack_sockaddr_un(sun_sv)
908 SV * sun_sv
f13e1b2f 909 CODE:
4633a7c4 910 {
25f94b33 911#ifdef I_SYS_UN
4633a7c4 912 struct sockaddr_un addr;
fcdb74fc 913 STRLEN sockaddrlen;
914 char * sun_ad = SvPV(sun_sv,sockaddrlen);
915 char * e;
4633a7c4 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);
fcdb74fc 930 }
931 e = addr.sun_path;
932 while (*e && e < addr.sun_path + sizeof addr.sun_path)
933 ++e;
26893f8d 934 ST(0) = sv_2mortal(newSVpv(addr.sun_path, e - addr.sun_path));
25f94b33 935#else
936 ST(0) = (SV *) not_here("unpack_sockaddr_un");
937#endif
4633a7c4 938 }
939
940void
941pack_sockaddr_in(port,ip_address)
2c129a17 942 unsigned short port
8e07c86e 943 char * ip_address
944 CODE:
945 {
946 struct sockaddr_in sin;
947
948 Zero( &sin, sizeof sin, char );
4633a7c4 949 sin.sin_family = AF_INET;
8e07c86e 950 sin.sin_port = htons(port);
951 Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
952
953 ST(0) = sv_2mortal(newSVpv((char *)&sin, sizeof sin));
954 }
955
956void
957unpack_sockaddr_in(sin_sv)
958 SV * sin_sv
959 PPCODE:
960 {
961 STRLEN sockaddrlen;
962 struct sockaddr_in addr;
2c129a17 963 unsigned short port;
8e07c86e 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 }
8e07c86e 971 Copy( sin, &addr,sizeof addr, char );
4633a7c4 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 }
8e07c86e 978 port = ntohs(addr.sin_port);
979 ip_address = addr.sin_addr;
980
924508f0 981 EXTEND(SP, 2);
2c129a17 982 PUSHs(sv_2mortal(newSViv((IV) port)));
8e07c86e 983 PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
984 }
985
986void
987INADDR_ANY()
988 CODE:
989 {
990 struct in_addr ip_address;
991 ip_address.s_addr = htonl(INADDR_ANY);
992 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address ));
993 }
994
995void
996INADDR_LOOPBACK()
997 CODE:
998 {
999 struct in_addr ip_address;
1000 ip_address.s_addr = htonl(INADDR_LOOPBACK);
1001 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
1002 }
1003
1004void
1005INADDR_NONE()
1006 CODE:
1007 {
1008 struct in_addr ip_address;
1009 ip_address.s_addr = htonl(INADDR_NONE);
1010 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
1011 }
7e1af8bc 1012
1013void
1014INADDR_BROADCAST()
1015 CODE:
1016 {
1017 struct in_addr ip_address;
1018 ip_address.s_addr = htonl(INADDR_BROADCAST);
1019 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
1020 }