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