File: Multicast6.xs

package info (click to toggle)
libsocket-multicast6-perl 0.04-5
  • links: PTS, VCS
  • area: main
  • in suites: bookworm, forky, sid, trixie
  • size: 120 kB
  • sloc: perl: 64; makefile: 2
file content (184 lines) | stat: -rw-r--r-- 4,280 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
/*
    Copyright (C) 2006 Nicholas J Humfrey
    Copyright (C) 2006 Jonathan Steinert
    
    This library is free software; you can redistribute it and/or modify
    it under the same terms as Perl itself, either Perl version 5.6.1 or,
    at your option, any later version of Perl 5 you may have available.
*/

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"

#include <sys/socket.h>
#include <netinet/in.h>

#ifdef WIN32
// winsock.h is for winsock <= 1.1
// #include <winsock.h>

// ws2tcpip.h is for winsock >= 2.0
#include <ws2tcpip.h>
#endif

#include "const-c.inc"

MODULE = Socket::Multicast6		PACKAGE = Socket::Multicast6

INCLUDE: const-xs.inc

PROTOTYPES: ENABLE

void
pack_ip_mreq(imr_multiaddr_sv, imr_interface_sv)
	SV* imr_multiaddr_sv
	SV* imr_interface_sv
  CODE:
	{
	struct ip_mreq mreq;
	STRLEN addrlen;
	char * addr;
	
	// Clear out final struct
	Zero( &mreq, 1, struct ip_mreq );


	// Byte load multicast address
	addr = SvPVbyte(imr_multiaddr_sv, addrlen);

	if (addrlen == sizeof(mreq.imr_multiaddr) || addrlen == 4)

		// Copy across the multicast address
		Copy( addr, &mreq.imr_multiaddr, 1, struct in_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::pack_ip_mreq",
		      addrlen, sizeof(mreq.imr_multiaddr));



	// Byte load interface address
	addr = SvPVbyte(imr_interface_sv, addrlen);

	if (addrlen == sizeof(mreq.imr_interface) || addrlen == 4)

		// Copy across the interface address
		Copy( addr, &mreq.imr_interface, 1, struct in_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::pack_ip_mreq",
		      addrlen, sizeof(mreq.imr_interface));

	// new mortal string, return it.
	ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
	}



void
pack_ip_mreq_source(imr_multiaddr_sv, imr_source_sv, imr_interface_sv)
	SV* imr_multiaddr_sv
	SV* imr_source_sv
	SV* imr_interface_sv
  CODE:
	{
#ifdef IP_ADD_SOURCE_MEMBERSHIP
	struct ip_mreq_source mreq;
	STRLEN addrlen;
	char * addr;
	
	// Clear out final struct
	Zero( &mreq, 1, struct ip_mreq_source );


	// Byte load multicast address
	addr = SvPVbyte(imr_multiaddr_sv, addrlen);

	if (addrlen == sizeof(mreq.imr_multiaddr) || addrlen == 4)

		// Copy across the multicast address
		Copy( addr, &mreq.imr_multiaddr, 1, struct in_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::ip_mreq_source",
		      addrlen, sizeof(mreq.imr_multiaddr));



	// Byte load source address
	addr = SvPVbyte(imr_source_sv, addrlen);

	if (addrlen == sizeof(mreq.imr_sourceaddr) || addrlen == 4)

		// Copy across the source address
		Copy( addr, &mreq.imr_sourceaddr, 1, struct in_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::ip_mreq_source",
		      addrlen, sizeof(mreq.imr_sourceaddr));



	// Byte load interface address
	addr = SvPVbyte(imr_interface_sv, addrlen);

	if (addrlen == sizeof(mreq.imr_interface) || addrlen == 4)

		// Copy across the interface address
		Copy( addr, &mreq.imr_interface, 1, struct in_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::ip_mreq_source",
		      addrlen, sizeof(mreq.imr_interface));

	// new mortal string, return it.
	ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
#else 
	XSRETURN_UNDEF;
#endif
	}


void
pack_ipv6_mreq(imr_multiaddr_sv, imr_interface_idx)
	SV* imr_multiaddr_sv
	unsigned int imr_interface_idx
  CODE:
	{

	struct ipv6_mreq mreq;
	STRLEN addrlen;
	char * addr;

	// Clear out final struct
	Zero( &mreq, sizeof mreq, char );

	// Copy across the interface number
	mreq.ipv6mr_interface = imr_interface_idx;


	// Byte load multicast address
	addr = SvPVbyte(imr_multiaddr_sv, addrlen);

	if (addrlen == sizeof(mreq.ipv6mr_multiaddr) || addrlen == 16)

		// Copy accross the multicast address
		Copy( addr, &mreq.ipv6mr_multiaddr, 1, struct in6_addr );

	else
		croak("Bad arg length for %s, length is %d, should be %d",
		      "Socket::Multicast6::pack_ipv6_mreq",
		      addrlen, sizeof(mreq.ipv6mr_multiaddr));

	// new mortal string, return it.
	ST(0) = sv_2mortal(newSVpvn((char *)&mreq, sizeof(mreq)));
	}