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