Net-SCTP

 view release on metacpan or  search on metacpan

SCTP.xs  view on Meta::CPAN

#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: ");
    }

SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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 )

SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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: ");

SCTP.xs  view on Meta::CPAN

##-----------------------------------------------------------------------------


##-----------------------------------------------------------------------------
#/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

SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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);

SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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);


SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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:

SCTP.xs  view on Meta::CPAN



##-----------------------------------------------------------------------------
#/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:

SCTP.xs  view on Meta::CPAN

##-----------------------------------------------------------------------------


## 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 )