Net-SCTP
view release on metacpan or search on metacpan
#include <string.h>
#include <unistd.h>
#include <errno.h>
MODULE = Net::SCTP PACKAGE = Net::SCTP
##-----------------------------------------------------------------------------
#/Start Subroutine : _socket
#
# Purpose : Create a socket
# Params : b_inet6, b_many
# Returns : 0 on success -1 on failure
# b_inet6 : determines what version of ip to use for the
# for the socket.
# b_many : determines whether to socket
# is using the new style one to many (if true) socket
# or the old style (if false)
int
_socket(b_inet6, b_many)
bool b_inet6
bool b_many
CODE:
// AF_INET for IPv4, b_inet6 = false
// AF_INET6 for IPv6, b_inet6 = true
// SOCK_SEQPACKET for one to many, b_many = true
// SOCK_STREAM for one to one, b_many = false
// Set our return value equal to the function
// call so we can return that to perl
RETVAL = socket(((b_inet6) ? AF_INET6 : AF_INET),
((b_many) ? SOCK_SEQPACKET : SOCK_STREAM) , IPPROTO_SCTP);
// RETVAL was a failure, print out the error to the user because
// Perl cannot do it.
if( RETVAL < 0 )
{
printf("After socket errno: %d\n", errno);
perror("Description: ");
}
##-----------------------------------------------------------------------------
#/Start Subroutine : _bind
#
# Purpose : bind an address with a socket
# Returns : 0 on success -1 on failure
# i_sd : The socket descriptor to bind to.
# i_port : The port to bind to.
# sz_ip : The ip to bind to
# b_inet6 : Whether the connection is v6 or v4
int
_bind( i_sd, i_port, sz_ip, b_inet6)
int i_sd
int i_port
char* sz_ip
bool b_inet6
PREINIT:
// The structure that the addresses need to be inside of when passed to the
// actual sctp function.
struct sockaddr_in t_addr;
CODE:
// Zero out the memory of the structure
bzero( (void *)&t_addr, sizeof(struct sockaddr_in) );
// AF_INET for IPv4, b_inet is false
// AF_INET6 for IPv6, b_inet is true
// Build the structure to pass into the sctp function
t_addr.sin_family = ( (b_inet6) ? AF_INET6 : AF_INET );
t_addr.sin_port = htons(i_port);
t_addr.sin_addr.s_addr = inet_addr(sz_ip);
// Set our return value equal to the function
// call so we can return that to perl
RETVAL = bind(i_sd, (struct sockaddr *)&t_addr, sizeof(struct sockaddr_in));
// RETVAL was a failure, print out the error to the user because
// Perl cannot do it.
if( RETVAL < 0 )
##-----------------------------------------------------------------------------
#/Start Subroutine : _sctp_sendmsg
#
# Purpose : send a message to someone over sctp
# i_sd : The socket descriptor of the sender
# sz_msg : The message to be sent
# i_port : The port to send the message over
# sz_ip : The ip address to send the message to
# b_inet6 : ipv6 is true, ipv4 is false
# i_ppid : NYI
# i_flags : NYI
# i_stream : NYI
# i_pr_value : NYI
# i_context : NYI
int
_sctp_sendmsg( i_sd, sz_msg, i_msg_len, i_port, sz_ip, b_inet6, i_ppid = 0, i_flags = 0, i_stream = 0, i_pr_value = 0, i_pr_value = 0, i_context = 0 )
int i_sd
char* sz_msg
int i_msg_len
int i_port
char* sz_ip
bool b_inet6
int i_ppid
int i_flags
int i_stream
int i_pr_value
int i_context
PREINIT:
struct sockaddr_in t_addr = {0};
CODE:
// AF_INET for IPv4
// AF_INET6 for IPv6
t_addr.sin_family = ( (b_inet6) ? AF_INET6 : AF_INET );
t_addr.sin_port = htons(i_port);
t_addr.sin_addr.s_addr = inet_addr( sz_ip );
RETVAL = sctp_sendmsg( i_sd, (const void *)sz_msg, i_msg_len, (struct sockaddr *)&t_addr, sizeof(struct sockaddr_in), htonl(i_ppid), i_flags, i_stream /*stream 0*/, i_pr_value, i_context);
if( RETVAL < 0 )
{
printf("After sctp_sendmsg errno: %d\n", errno);
perror("Description: ");
##-----------------------------------------------------------------------------
##-----------------------------------------------------------------------------
#/Start Subroutine : _connect
#
# Purpose : send a message to someone over sctp
# i_sd : The socket descriptor of the client who is connecting
# i_port : The port to connect to
# sz_ip : The ip address to connect to
# b_inet6 : The version of ip we are using, true for v6 false for v4
int
_connect( i_sd, i_port, sz_ip, b_inet6 )
int i_sd
int i_port
char* sz_ip
bool b_inet6
PREINIT:
struct sockaddr_in servaddr;
CODE:
bzero( (void *)&servaddr, sizeof(struct sockaddr_in) );
// AF_INET for IPv4
// AF_INET6 for IPv6
servaddr.sin_family = ( (b_inet6) ? AF_INET6 : AF_INET );
servaddr.sin_port = htons(i_port);
servaddr.sin_addr.s_addr = inet_addr( sz_ip );
RETVAL=connect( i_sd, (struct sockaddr *)&servaddr, sizeof(struct sockaddr_in) );
if( RETVAL )
{
printf("After connect errno: %d\n", errno);
perror("Description: ");
}
OUTPUT:
RETVAL
##-----------------------------------------------------------------------------
#/Start Subroutine : _sctp_bindx
#
# Purpose : Bind the server ti multiple connections
# Returns : Success(0) or failure(-1)
# i_sd : The socket descriptor of the server
# i_port : The port of the server
# av_sz_ip : The array of ips to bind to
# av_b_inet6 : The array of ip versions created for the user in perl
# i_flags : 1 is add these addresses 2 is remove them
int
_sctp_bindx(i_sd, i_port, av_sz_ip, av_b_inet6, i_flags)
int i_sd
int i_port
SV* av_sz_ip
SV* av_b_inet6
int i_flags
PREINIT:
int i = 0;
int i_addr_cnt;
CODE:
AV* array_length = (AV *) SvRV (av_b_inet6);
i_addr_cnt = av_len(array_length);
struct sockaddr_in t_addrs[i_addr_cnt];
while(i <= i_addr_cnt)
{
SV** item2 = av_fetch(array_length, i, 0);
bool temp_int = (bool)SvIV(*item2);
AV* array = (AV *) SvRV (av_sz_ip);
##-----------------------------------------------------------------------------
#/Start Subroutine : _sctp_connectx
#
# Purpose : Attempts to connect to a server using multiple addresses
# Returns : Success(0) or failure(-1)
# i_sd : The socket descriptor of the client
# i_port : The port of the server
# av_sz_ip : The array of ips to connect to
# av_b_inet6 : The array of ip versions created for the user in perl
# i_id : The association id to give the association that is
# being set up
int
_sctp_connectx(i_sd, i_port, av_sz_ip, av_b_inet6, i_id = 0)
int i_sd
int i_port
SV* av_sz_ip
SV* av_b_inet6
int i_id;
PREINIT:
int i = 0;
int i_addr_cnt;
CODE:
AV* array_length = (AV *) SvRV (av_b_inet6);
i_addr_cnt = av_len(array_length);
struct sockaddr_in t_addrs[i_addr_cnt];
while(i <= i_addr_cnt)
{
SV** item2 = av_fetch(array_length, i, 0);
int temp_int = (int)SvIV(*item2);
##-----------------------------------------------------------------------------
#/Start Subroutine : _sctp_getpaddrs
#
# Purpose : Returns all peer addresses in an association
# Returns : Fills out the arrays passed with peer addresses
# i_sd : The socket descriptor of the client
# i_port : The port to be filled
# av_sz_ip : The array of ips to to be filled
# av_b_inet6 : The array of ip versions to be filled
# i_id : The association id to get the addresses from
# : Automatically calls sctp_freepaddrs
int
_sctp_getpaddrs(i_sd, i_id, av_sz_ip,av_i_port, av_b_inet6)
int i_sd
int i_id
SV* av_sz_ip
SV* av_i_port
SV* av_b_inet6
PREINIT:
struct sockaddr_in * t_addrs;
int i = 0;
AV* array_ip = (AV *) SvRV (av_sz_ip);
AV* array_port = (AV *) SvRV (av_i_port);
AV* array_inet6 = (AV *) SvRV (av_b_inet6);
CODE:
RETVAL = sctp_getladdrs(i_sd, i_id, (struct sockaddr **)&t_addrs);
while(i < RETVAL)
{
char* temp_c_ip = (char*)inet_ntoa(*(struct in_addr *)&t_addrs[i].sin_addr.s_addr);
SV* temp_ip = newSVpvn(temp_c_ip, strlen(temp_c_ip));
av_push(array_ip, temp_ip);
SV* temp_port = newSViv(t_addrs[i].sin_port);
av_push(array_port, temp_port);
SV* temp_family = newSViv(t_addrs[i].sin_family);
av_push(array_inet6, temp_family);
++i;
}
sctp_freepaddrs((struct sockaddr *)&t_addrs);
if( RETVAL < 0 )
{
printf("After getpaddrs errno: %d\n", errno);
perror("Description: ");
}
OUTPUT:
##-----------------------------------------------------------------------------
#/Start Subroutine : _sctp_getladdrs
#
# Purpose : Returns all local addresses in an association
# Returns : Fills out the arrays passed with local addresses
# i_sd : The socket descriptor of the client
# i_port : The port to be filled
# av_sz_ip : The array of ips to to be filled
# av_b_inet6 : The array of ip versions to be filled
# i_id : The association id to get the addresses from
# Automatically calls sctp_freeladdrs
int
_sctp_getladdrs(i_sd, i_id, av_sz_ip, av_i_port, av_b_inet6)
int i_sd
int i_id
SV* av_sz_ip
SV* av_i_port
SV* av_b_inet6
PREINIT:
struct sockaddr_in * t_addrs;
int i = 0;
AV* array_ip = (AV *) SvRV (av_sz_ip);
AV* array_port = (AV *) SvRV (av_i_port);
AV* array_inet6 = (AV *) SvRV (av_b_inet6);
CODE:
RETVAL = sctp_getladdrs(i_sd, i_id, (struct sockaddr **)&t_addrs);
while(i < RETVAL)
{
char* temp_c_ip = (char*)inet_ntoa(*(struct in_addr *)&t_addrs[i].sin_addr.s_addr);
SV* temp_ip = newSVpvn(temp_c_ip, strlen(temp_c_ip));
av_push(array_ip, temp_ip);
SV* temp_port = newSViv(t_addrs[i].sin_port);
av_push(array_port, temp_port);
SV* temp_family = newSViv(t_addrs[i].sin_family);
av_push(array_inet6, temp_family);
++i;
}
sctp_freeladdrs((struct sockaddr *)&t_addrs);
if( RETVAL < 0 )
{
printf("After getladdrs errno: %d\n", errno);
perror("Description: ");
}
OUTPUT:
##-----------------------------------------------------------------------------
## Not Supported Stuff:
#
# SCTP_SENDX
#
# i_ppid -- message_id so chunks can be put together (OPTIONAL)
# i_stream -- 0 = out | 1 = input | 2 = error
#int
#_sctp_sendx( i_sd, sz_msg, i_port, av_sz_ip, av_b_inet6, i_flags = 0)
# int i_sd
# char* sz_msg
# int i_port
# SV* av_sz_ip
# SV* av_b_inet6
# int i_flags
# PREINIT:
# int i_addr_cnt = 0;
# int i = 0;
# CODE:
# AV* array_length = (AV *) SvRV (av_b_inet6);
# i_addr_cnt = av_len(array_length);
# struct sockaddr_in t_addrs[i_addr_cnt];
#
#
# while(i <= i_addr_cnt)
# {
# SV** item2 = av_fetch(array_length, i, 0);
# bool temp_int = (bool)SvIV(*item2);
#
#
( run in 0.214 second using v1.01-cache-2.11-cpan-5f2e87ce722 )