7 # include <sys/types.h>
9 #include <sys/socket.h>
11 # define PF_INET AF_INET
12 # define PF_UNIX AF_UNIX
19 # include <netinet/in.h>
23 # include <arpa/inet.h>
26 #include "sockadapt.h"
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 */
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.
57 my_inet_aton(register const char *cp, struct in_addr *addr)
64 unsigned int parts[4];
65 register unsigned int *pp = parts;
71 * Collect number up to ``.''.
72 * Values are specified as for C:
73 * 0x=hex, 0=octal, other=decimal.
77 if (*++cp == 'x' || *cp == 'X')
82 while ((c = *cp) != '\0') {
84 val = (val * base) + (c - '0');
88 if (base == 16 && (s=strchr(PL_hexdigit,c))) {
90 ((s - PL_hexdigit) & 15);
100 * a.b.c (with c treated as 16-bits)
101 * a.b (with b treated as 24 bits)
103 if (pp >= parts + 3 || val > 0xff)
110 * Check for trailing characters.
112 if (*cp && !isSPACE(*cp))
115 * Concoct the address according to
116 * the number of parts specified.
118 nparts = pp - parts + 1; /* force to an int for switch() */
121 case 1: /* a -- 32 bits */
124 case 2: /* a.b -- 8.24 bits */
127 val |= parts[0] << 24;
130 case 3: /* a.b.c -- 8.8.16 bits */
133 val |= (parts[0] << 24) | (parts[1] << 16);
136 case 4: /* a.b.c.d -- 8.8.8.8 bits */
139 val |= (parts[0] << 24) | (parts[1] << 16) | (parts[2] << 8);
142 addr->s_addr = htonl(val);
147 #define inet_aton my_inet_aton
149 #endif /* ! HAS_INET_ATON */
155 croak("Socket::%s not implemented on this architecture", s);
160 constant(char *name, int arg)
165 if (strEQ(name, "AF_802"))
171 if (strEQ(name, "AF_APPLETALK"))
177 if (strEQ(name, "AF_CCITT"))
183 if (strEQ(name, "AF_CHAOS"))
189 if (strEQ(name, "AF_DATAKIT"))
195 if (strEQ(name, "AF_DECnet"))
201 if (strEQ(name, "AF_DLI"))
207 if (strEQ(name, "AF_ECMA"))
213 if (strEQ(name, "AF_GOSIP"))
219 if (strEQ(name, "AF_HYLINK"))
225 if (strEQ(name, "AF_IMPLINK"))
231 if (strEQ(name, "AF_INET"))
237 if (strEQ(name, "AF_LAT"))
243 if (strEQ(name, "AF_MAX"))
249 if (strEQ(name, "AF_NBS"))
255 if (strEQ(name, "AF_NIT"))
261 if (strEQ(name, "AF_NS"))
267 if (strEQ(name, "AF_OSI"))
273 if (strEQ(name, "AF_OSINET"))
279 if (strEQ(name, "AF_PUP"))
285 if (strEQ(name, "AF_SNA"))
291 if (strEQ(name, "AF_UNIX"))
297 if (strEQ(name, "AF_UNSPEC"))
303 if (strEQ(name, "AF_X25"))
333 if (strEQ(name, "MSG_CTLFLAGS"))
339 if (strEQ(name, "MSG_CTLIGNORE"))
341 return MSG_CTLIGNORE;
345 if (strEQ(name, "MSG_CTRUNC"))
346 #if defined(MSG_TRUNC) || defined(HAS_MSG_CTRUNC) /* might be an enum */
351 if (strEQ(name, "MSG_DONTROUTE"))
352 #if defined(MSG_DONTROUTE) || defined(HAS_MSG_DONTROUTE) /* might be an enum */
353 return MSG_DONTROUTE;
357 if (strEQ(name, "MSG_DONTWAIT"))
363 if (strEQ(name, "MSG_EOF"))
369 if (strEQ(name, "MSG_EOR"))
375 if (strEQ(name, "MSG_ERRQUEUE"))
381 if (strEQ(name, "MSG_FIN"))
387 if (strEQ(name, "MSG_MAXIOVLEN"))
389 return MSG_MAXIOVLEN;
393 if (strEQ(name, "MSG_NOSIGNAL"))
399 if (strEQ(name, "MSG_OOB"))
400 #if defined(MSG_OOB) || defined(HAS_MSG_OOB) /* might be an enum */
405 if (strEQ(name, "MSG_PEEK"))
406 #if defined(MSG_PEEK) || defined(HAS_MSG_PEEK) /* might be an enum */
411 if (strEQ(name, "MSG_PROXY"))
412 #if defined(MSG_PROXY) || defined(HAS_MSG_PROXY) /* might be an enum */
417 if (strEQ(name, "MSG_RST"))
423 if (strEQ(name, "MSG_SYN"))
429 if (strEQ(name, "MSG_TRUNC"))
435 if (strEQ(name, "MSG_WAITALL"))
447 if (strEQ(name, "PF_802"))
453 if (strEQ(name, "PF_APPLETALK"))
459 if (strEQ(name, "PF_CCITT"))
465 if (strEQ(name, "PF_CHAOS"))
471 if (strEQ(name, "PF_DATAKIT"))
477 if (strEQ(name, "PF_DECnet"))
483 if (strEQ(name, "PF_DLI"))
489 if (strEQ(name, "PF_ECMA"))
495 if (strEQ(name, "PF_GOSIP"))
501 if (strEQ(name, "PF_HYLINK"))
507 if (strEQ(name, "PF_IMPLINK"))
513 if (strEQ(name, "PF_INET"))
519 if (strEQ(name, "PF_LAT"))
525 if (strEQ(name, "PF_MAX"))
531 if (strEQ(name, "PF_NBS"))
537 if (strEQ(name, "PF_NIT"))
543 if (strEQ(name, "PF_NS"))
549 if (strEQ(name, "PF_OSI"))
555 if (strEQ(name, "PF_OSINET"))
561 if (strEQ(name, "PF_PUP"))
567 if (strEQ(name, "PF_SNA"))
573 if (strEQ(name, "PF_UNIX"))
579 if (strEQ(name, "PF_UNSPEC"))
585 if (strEQ(name, "PF_X25"))
597 if (strEQ(name, "SCM_CONNECT"))
603 if (strEQ(name, "SCM_CREDENTIALS"))
604 #ifdef SCM_CREDENTIALS
605 return SCM_CREDENTIALS;
609 if (strEQ(name, "SCM_CREDS"))
615 if (strEQ(name, "SCM_RIGHTS"))
616 #if defined(SCM_RIGHTS) || defined(HAS_SCM_RIGHTS) /* might be an enum */
621 if (strEQ(name, "SCM_TIMESTAMP"))
623 return SCM_TIMESTAMP;
627 if (strEQ(name, "SOCK_DGRAM"))
633 if (strEQ(name, "SOCK_RAW"))
639 if (strEQ(name, "SOCK_RDM"))
645 if (strEQ(name, "SOCK_SEQPACKET"))
646 #ifdef SOCK_SEQPACKET
647 return SOCK_SEQPACKET;
651 if (strEQ(name, "SOCK_STREAM"))
657 if (strEQ(name, "SOL_SOCKET"))
663 if (strEQ(name, "SOMAXCONN"))
669 if (strEQ(name, "SO_ACCEPTCONN"))
671 return SO_ACCEPTCONN;
675 if (strEQ(name, "SO_BROADCAST"))
681 if (strEQ(name, "SO_DEBUG"))
687 if (strEQ(name, "SO_DONTLINGER"))
689 return SO_DONTLINGER;
693 if (strEQ(name, "SO_DONTROUTE"))
699 if (strEQ(name, "SO_ERROR"))
705 if (strEQ(name, "SO_KEEPALIVE"))
711 if (strEQ(name, "SO_LINGER"))
717 if (strEQ(name, "SO_OOBINLINE"))
723 if (strEQ(name, "SO_RCVBUF"))
729 if (strEQ(name, "SO_RCVLOWAT"))
735 if (strEQ(name, "SO_RCVTIMEO"))
741 if (strEQ(name, "SO_REUSEADDR"))
747 if (strEQ(name, "SO_REUSEPORT"))
753 if (strEQ(name, "SO_SNDBUF"))
759 if (strEQ(name, "SO_SNDLOWAT"))
765 if (strEQ(name, "SO_SNDTIMEO"))
771 if (strEQ(name, "SO_TYPE"))
777 if (strEQ(name, "SO_USELOOPBACK"))
778 #ifdef SO_USELOOPBACK
779 return SO_USELOOPBACK;
808 MODULE = Socket PACKAGE = Socket
821 struct in_addr ip_address;
822 struct hostent * phe;
823 int ok = inet_aton(host, &ip_address);
825 if (!ok && (phe = gethostbyname(host))) {
826 Copy( phe->h_addr, &ip_address, phe->h_length, char );
830 ST(0) = sv_newmortal();
832 sv_setpvn( ST(0), (char *)&ip_address, sizeof ip_address );
837 inet_ntoa(ip_address_sv)
844 char * ip_address = SvPV(ip_address_sv,addrlen);
845 if (addrlen != sizeof(addr)) {
846 croak("Bad arg length for %s, length is %d, should be %d",
848 addrlen, sizeof(addr));
851 Copy( ip_address, &addr, sizeof addr, char );
852 addr_str = inet_ntoa(addr);
854 ST(0) = sv_2mortal(newSVpv(addr_str, strlen(addr_str)));
858 pack_sockaddr_un(pathname)
863 struct sockaddr_un sun_ad; /* fear using sun */
865 Zero( &sun_ad, sizeof sun_ad, char );
866 sun_ad.sun_family = AF_UNIX;
867 len = strlen(pathname);
868 if (len > sizeof(sun_ad.sun_path))
869 len = sizeof(sun_ad.sun_path);
870 Copy( pathname, sun_ad.sun_path, len, char );
871 ST(0) = sv_2mortal(newSVpv((char *)&sun_ad, sizeof sun_ad));
873 ST(0) = (SV *) not_here("pack_sockaddr_un");
879 unpack_sockaddr_un(sun_sv)
884 struct sockaddr_un addr;
886 char * sun_ad = SvPV(sun_sv,sockaddrlen);
889 if (sockaddrlen != sizeof(addr)) {
890 croak("Bad arg length for %s, length is %d, should be %d",
891 "Socket::unpack_sockaddr_un",
892 sockaddrlen, sizeof(addr));
895 Copy( sun_ad, &addr, sizeof addr, char );
897 if ( addr.sun_family != AF_UNIX ) {
898 croak("Bad address family for %s, got %d, should be %d",
899 "Socket::unpack_sockaddr_un",
904 while (*e && e < addr.sun_path + sizeof addr.sun_path)
906 ST(0) = sv_2mortal(newSVpv(addr.sun_path, e - addr.sun_path));
908 ST(0) = (SV *) not_here("unpack_sockaddr_un");
913 pack_sockaddr_in(port,ip_address)
918 struct sockaddr_in sin;
920 Zero( &sin, sizeof sin, char );
921 sin.sin_family = AF_INET;
922 sin.sin_port = htons(port);
923 Copy( ip_address, &sin.sin_addr, sizeof sin.sin_addr, char );
925 ST(0) = sv_2mortal(newSVpv((char *)&sin, sizeof sin));
929 unpack_sockaddr_in(sin_sv)
934 struct sockaddr_in addr;
936 struct in_addr ip_address;
937 char * sin = SvPV(sin_sv,sockaddrlen);
938 if (sockaddrlen != sizeof(addr)) {
939 croak("Bad arg length for %s, length is %d, should be %d",
940 "Socket::unpack_sockaddr_in",
941 sockaddrlen, sizeof(addr));
943 Copy( sin, &addr,sizeof addr, char );
944 if ( addr.sin_family != AF_INET ) {
945 croak("Bad address family for %s, got %d, should be %d",
946 "Socket::unpack_sockaddr_in",
950 port = ntohs(addr.sin_port);
951 ip_address = addr.sin_addr;
954 PUSHs(sv_2mortal(newSViv((IV) port)));
955 PUSHs(sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address)));
962 struct in_addr ip_address;
963 ip_address.s_addr = htonl(INADDR_ANY);
964 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address ));
971 struct in_addr ip_address;
972 ip_address.s_addr = htonl(INADDR_LOOPBACK);
973 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
980 struct in_addr ip_address;
981 ip_address.s_addr = htonl(INADDR_NONE);
982 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));
989 struct in_addr ip_address;
990 ip_address.s_addr = htonl(INADDR_BROADCAST);
991 ST(0) = sv_2mortal(newSVpv((char *)&ip_address,sizeof ip_address));