Commit | Line | Data |
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 | */ |
60 | static int |
f0f333f4 |
61 | my_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 |
156 | static int |
f0f333f4 |
157 | not_here(char *s) |
a0d0e21e |
158 | { |
159 | croak("Socket::%s not implemented on this architecture", s); |
160 | return -1; |
161 | } |
162 | |
163 | static double |
f0f333f4 |
164 | constant(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 | |
830 | not_there: |
831 | errno = ENOENT; |
832 | return 0; |
833 | } |
834 | |
8e07c86e |
835 | |
a0d0e21e |
836 | MODULE = Socket PACKAGE = Socket |
837 | |
838 | double |
839 | constant(name,arg) |
840 | char * name |
841 | int arg |
842 | |
8e07c86e |
843 | |
844 | void |
845 | inet_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 | |
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(newSVpv(addr_str, strlen(addr_str))); |
883 | } |
884 | |
885 | void |
4633a7c4 |
886 | pack_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 | |
906 | void |
907 | unpack_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 | |
940 | void |
941 | pack_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 | |
956 | void |
957 | unpack_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 | |
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(newSVpv((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(newSVpv((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(newSVpv((char *)&ip_address,sizeof ip_address)); |
1011 | } |
7e1af8bc |
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(newSVpv((char *)&ip_address,sizeof ip_address)); |
1020 | } |