Convert miniperl sources to ANSI C. Several passes of
[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>
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 */
49static int
50my_inet_aton(cp, addr)
51register const char *cp;
52struct 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 147static int
148not_here(s)
149char *s;
150{
151 croak("Socket::%s not implemented on this architecture", s);
152 return -1;
153}
154
155static double
156constant(name, arg)
157char *name;
158int 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
686not_there:
687 errno = ENOENT;
688 return 0;
689}
690
8e07c86e 691
a0d0e21e 692MODULE = Socket PACKAGE = Socket
693
694double
695constant(name,arg)
696 char * name
697 int arg
698
8e07c86e 699
700void
701inet_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
722void
723inet_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
743void
4633a7c4 744pack_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
760void
761unpack_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
790void
791pack_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
806void
807unpack_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
836void
837INADDR_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
845void
846INADDR_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
854void
855INADDR_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
863void
864INADDR_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 }