Exemple #1
0
void check_notification(int sock_fd, char *recvline, int rd_len)
{
	union sctp_notification *snp;
	struct sctp_assoc_change *sac;
	struct sockaddr_storage *sa1, *sar;
	int	num_rem, num_loc;

	snp = (union sctp_notification *)recvline;
	if (snp->sn_header.sn_type == SCTP_ASSOC_CHANGE) {
		sac = &snp->sn_assoc_change;
		if ((sac->sac_state == SCTP_ASSOC_CHANGE) ||
				(sac->sac_state == SCTP_RESTART)) {
			num_rem = sctp_getpaddrs(sock_fd, sac->sac_assoc_id,
					&sar);
			printf("There are %d remote addresses and they"
			       " are: \n", num_rem);
			sctp_print_addresses(sar, num_rem);
			sctp_freepaddrs(sar);

			num_loc = sctp_getladdrs(sock_fd, sac->sac_assoc_id,
					&sal);
			printf("There are %d local addresses and they are: \n",
					num_loc);
			sctp_print_addresses(sal, num_loc);
			sctp_freepaddrs(sal);
		}
	}
}
Exemple #2
0
/* Test peer addresses for association. */
int test_peer_addr(int sk, sctp_assoc_t asoc, sockaddr_storage_t * peers,
		   int count)
{
	struct sockaddr *addrs;
	int error, i, j;
	struct sockaddr *sa_addr;
	socklen_t addrs_size = 0;
	void *addrbuf;
	char *found = (char *)malloc(count);
	memset(found, 0, count);

	error = sctp_getpaddrs(sk, asoc, &addrs);
	if (-1 == error) {
		tst_brkm(TBROK, NULL, "sctp_getpaddrs: %s", strerror(errno));
		return error;
	}
	if (error != count) {
		sctp_freepaddrs(addrs);
		tst_brkm(TBROK, NULL, "peer count %d mismatch, expected %d",
			 error, count);
	}
	addrbuf = addrs;
	for (i = 0; i < count; i++) {
		sa_addr = (struct sockaddr *)addrbuf;
		switch (sa_addr->sa_family) {
		case AF_INET:
			addrs_size += sizeof(struct sockaddr_in);
			addrbuf += sizeof(struct sockaddr_in);
			break;
		case AF_INET6:
			addrs_size += sizeof(struct sockaddr_in6);
			addrbuf += sizeof(struct sockaddr_in6);
			break;
		default:
			errno = EINVAL;
			sctp_freepaddrs(addrs);
			tst_brkm(TBROK, NULL, "sctp_getpaddrs: %s",
				 strerror(errno));
			return -1;
		}
		for (j = 0; j < count; j++) {
			if (cmp_addr((sockaddr_storage_t *) sa_addr,
				     &peers[j]) == 0) {
				found[j] = 1;
			}
		}
	}
	for (j = 0; j < count; j++) {
		if (found[j] == 0) {
			tst_brkm(TBROK, NULL, "peer address %d not found", j);
		}
	}
	sctp_freepaddrs(addrs);
	return 0;
}
static void printPeerAddresses(int socket)
{
  struct sockaddr* addresses;
  int retVal;
  if ((retVal = sctp_getpaddrs(socket, 0, &addresses)) < 0)
  {
    printf("printPeerAddresses sctp_getladdrs error\n");
  }
  else
  {
    int i;
    for (i = 0; i < retVal; ++i)
    {
      struct AddrPortStrings addrPortStrings;
      socklen_t addressSize = 0;
      if (addresses[i].sa_family == AF_INET)
      {
        addressSize = sizeof(struct sockaddr_in);
      }
      else if (addresses[i].sa_family == AF_INET6)
      {
        addressSize = sizeof(struct sockaddr_in6);
      }
      if (addressToNameAndPort(&addresses[i], addressSize, &addrPortStrings) == 0)
      {
        printf("peer address %d %s:%s\n", i, addrPortStrings.addrString, addrPortStrings.portString);
      }
    }
    sctp_freepaddrs(addresses);
  }
}
Exemple #4
0
static PyObject* getpaddrs(PyObject* dummy, PyObject* args)
{
	PyObject* ret = 0;
	int fd;
	int assoc_id;
	struct sockaddr* saddrs;
	int count;
	int x;
	char addr[256];

	if (! PyArg_ParseTuple(args, "ii", &fd, &assoc_id)) {
		return ret;
	}

	count = sctp_getpaddrs(fd, assoc_id, &saddrs);

	if (count < 0) {
		PyErr_SetFromErrno(PyExc_IOError);
	} else {
		if (count == 0) {
			saddrs = 0;
		}
		
		ret = PyTuple_New(count);
		char *p = (char*) saddrs;

		for(x = 0; x < count; ++x) {
			int len;
			int family;
			int port;
			PyObject* oaddr;

			if (from_sockaddr((struct sockaddr*) p, &family, &len, &port, 
										addr, sizeof(addr))) {
				oaddr = PyTuple_New(2);
				PyTuple_SetItem(oaddr, 0, PyString_FromString(addr));
				PyTuple_SetItem(oaddr, 1, PyInt_FromLong(port));
				PyTuple_SetItem(ret, x, oaddr);
			} else {
				// something's wrong; not safe to continue
				break;
			}
			
			p += len;
		}

		sctp_freepaddrs(saddrs);

		// If something went wrong, the remaining expected addresses will be set to None.
		for(; x < count; ++x) {
			PyTuple_SetItem(ret, x, Py_None);
			Py_INCREF(Py_None);

		}
	}

	return ret;
}
Exemple #5
0
int SctpSocket::getpaddrs(sctp_assoc_t id,std::list<std::string>& vec)
{
	struct sockaddr *p = NULL;
	int n = sctp_getpaddrs(GetSocket(), id, &p);
	if (!n || n == -1)
	{
		Handler().LogError(this, "SctpSocket", -1, "sctp_getpaddrs failed", LOG_LEVEL_WARNING);
		return n;
	}
	for (int i = 0; i < n; i++)
	{
		vec.push_back(Utility::Sa2String(&p[i]));
	}
	sctp_freepaddrs(p);
	return n;
}
void DrtaMW2 :: SctpRefreshRemoteIP( int socket )
{

	struct sockaddr *addr_list;
	struct sockaddr_in *in;

	peer_addr_lst . clear();

	// TODO: assoc_id ignore in one-one
	int sock_num = sctp_getpaddrs(socket , 0 , &addr_list );

	lb_recv_mtr -> clear();

	if( sock_num > 0 ){
		int assid = SctpSocketHandler::SctpGetAssocID( transmitter -> getSocketFd() );
		QString prim_str = SctpSocketHandler::SctpGetPrim( transmitter -> getSocketFd(), assid );

		for(int i = 0 ; i < sock_num ; i ++ ){
			in = (struct sockaddr_in*)& addr_list[i];

			char *ip = inet_ntoa( in->sin_addr );
			QString ip_from(ip);

			lb_recv_mtr -> insertItem( ip_from );

			if(prim_str == ip_from)
				peer_addr_lst . append( new PEER_ADDR(ip_from , true) );
			else
				peer_addr_lst . append( new PEER_ADDR(ip_from , false) );
		}

		sctp_freepaddrs( addr_list );
	}else{

	}

}
int
ACE_SOCK_SEQPACK_Association::get_remote_addrs (ACE_INET_Addr *addrs, size_t &size) const
{
  ACE_TRACE ("ACE_SOCK_SEQPACK_Association::get_remote_addrs");
#if defined (ACE_HAS_LKSCTP)
  /*
    The size of ACE_INET_Addr must be large enough to hold the number of
    remotes addresses in the association.  If the array is too small, the
    function will only return the number of addresses that will fit.  If the
    array is too large, the 'size' parameter will be modified to indicate
    the number of addrs.

    We will call sctp_getpaddrs() which accepts 3 parameters
    1. a socket fd
    2. a sctp association_id which will be ignored since we are using
       tcp sockets
    3. a pointer to a sockaddr

    lksctp/draft will allocate memory and we are responsible for freeing
    it by calling sctp_freepaddrs().
  */

  sockaddr_in *si = 0;
  sockaddr *paddrs = 0;
  int err = 0;
  size_t len = 0;

#ifndef ACE_HAS_VOID_PTR_SCTP_GETPADDRS
  err = sctp_getpaddrs(this->get_handle(), 0, &paddrs);
#else
  err = sctp_getpaddrs(this->get_handle(), 0, reinterpret_cast<void**>(&paddrs));
#endif /* ACE_HAS_VOID_PTR_SCTP_GETPADDRS */

  if (err > 0)
  {
    len = err;
    // check to see if we have more addresses than we have
    // space in our ACE_INET_Addr array
    if (len > size)
    {
      // since our array is too small, we will only copy the first
      // few that fit
      len = size;
    }

    for (size_t i = 0; i < len; i++)
    {
      // first we cast the sockaddr to sockaddr_in
      // since we only support ipv4 at this time.
      si = (sockaddr_in *) (&(paddrs[i]));

      // now we fillup the ace_inet_addr array
      addrs[i].set_addr(si, sizeof(sockaddr_in));
      addrs[i].set_type(si->sin_family);
      addrs[i].set_size(sizeof(sockaddr_in));
    }
  }
  else /* err < 0 */
  {
    // sctp_getpaddrs will return -1 on error
    return -1;
  }

  // indicate the num of addrs returned to the calling function
  size = len;

  // make sure we free the struct using the system function
  sctp_freepaddrs(paddrs);

#else

  /*
    We will be calling ACE_OS::getpeername, which accepts (and
    potentially modifies) two reference parameters:

    1.  a sockaddr_in* that points to a buffer
    2.  an int* that points to the size of this buffer

    The OpenSS7 implementation of SCTP copies an array of ipv4
    sockaddr_in into the buffer.  Then, if the size of the buffer is
    greater than the size used, the size parameter is reduced
    accordingly.

  */

  // The array of sockaddr_in will be stored in an ACE_Auto_Array_Ptr,
  // which causes dynamically-allocated memory to be released as soon
  // as the ACE_Auto_Array_Ptr goes out of scope.
  ACE_Auto_Array_Ptr<sockaddr_in> addr_structs;

  // Allocate memory for this array.  Return -1 if the memory cannot
  // be allocated.  (This activity requires a temporary variable---a
  // bare sockaddr_in* --- because ACE_NEW_RETURN cannot act directory on
  // an ACE_Auto_Array_Ptr.)
  {
    sockaddr_in *addr_structs_bootstrap = 0;
#if defined (ACE_HAS_ALLOC_HOOKS)
    ACE_ALLOCATOR_RETURN (addr_structs_bootstrap, static_cast<sockaddr_in*>(ACE_Allocator::instance()->malloc(sizeof(sockaddr_in) * (size))), -1);
#else
    ACE_NEW_RETURN (addr_structs_bootstrap, sockaddr_in[size], -1);
#endif
    addr_structs.reset(addr_structs_bootstrap);
  }

  // Physical size of this array is its logical size multiplied by
  // the physical size of one of its elements.
  size_t physical_size = size * sizeof(sockaddr_in);

  /* Clear the array */
  ACE_OS::memset(addr_structs.get(),
                 0,
                 physical_size);

  /*
  ** Populate the array with real values from the getpeername system
  ** call.  addr_structs is modified, and name_size is modified to contain
  ** the number of bytes written to addr_structs.
  ** Use name_size to get the data types right across the call.
  */
  int name_size = static_cast<int> (physical_size);
  if (ACE_OS::getpeername (this->get_handle (),
                           reinterpret_cast<sockaddr *> (addr_structs.get()),
                           &name_size) == -1)
    return -1;

  /* Calculate the NEW physical size of the array */
  name_size /= sizeof (sockaddr_in);
  size = static_cast<size_t> (name_size);

  /* Copy each sockaddr_in to the address structure of an ACE_Addr from
     the passed-in array */
  const int addrlen (static_cast<int> (sizeof (sockaddr_in)));
  for (int i = 0; i < name_size; ++i)
    {
      addrs[i].set_addr (&(addr_structs[i]), addrlen);
      addrs[i].set_type (addr_structs[i].sin_family);
      addrs[i].set_size (addrlen);
    }
#endif /* ACE_HAS_LKSCTP */
  return 0;
}
Exemple #8
0
int main(int argc, char **argv) 
{
   int fd, n, addr_len, len, msg_flags, close_time, i;
   size_t buffer_size;
   fd_set rset;
   char buffer[1000];
   struct sctp_event_subscribe evnts;
   struct sctp_sndrcvinfo sri;
   struct sockaddr_in local_addr, remote_addr;
    struct sctp_setprim set_prim;
    
   i = 0;
   if (argc < 4) {
      printf("Usage: client2 local_port remote_addr remote_port [autoclose]\n");
      exit(-1);
   }
   
   if ((fd = ext_socket(AF_INET, SOCK_SEQPACKET, IPPROTO_SCTP)) < 0)
      perror("socket");
      
   bzero(&evnts, sizeof(evnts));
   evnts.sctp_data_io_event = 1;
   evnts.sctp_association_event = 1;
   evnts.sctp_address_event = 1;
   evnts.sctp_send_failure_event = 1;
   evnts.sctp_peer_error_event = 1;
   evnts.sctp_shutdown_event = 1;
   evnts.sctp_partial_delivery_event = 1;
   evnts.sctp_adaption_layer_event = 1;

   if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_EVENTS, &evnts, sizeof(evnts)) < 0)
      perror("setsockopt");
      
   if (argc > 4) {
      close_time = atoi(argv[4]);
      if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_AUTOCLOSE, &close_time, sizeof(close_time)) < 0)
         perror("setsockopt");
   }
   
   bzero(&local_addr, sizeof(struct sockaddr_in));
   local_addr.sin_family      = AF_INET;
#ifdef HAVE_SIN_LEN
   local_addr.sin_len         = sizeof(struct sockaddr_in);
#endif
   local_addr.sin_addr.s_addr = htonl(INADDR_ANY);
   local_addr.sin_port        = htons(atoi(argv[1]));
   if (ext_bind(fd, (struct sockaddr *) &local_addr, sizeof(local_addr)) != 0)
      perror("bind");
      
   remote_addr.sin_family      = AF_INET;
   remote_addr.sin_port        = htons(atoi(argv[3]));
#ifdef HAVE_SIN_LEN
   remote_addr.sin_len         = sizeof(struct sockaddr_in);
#endif
   remote_addr.sin_addr.s_addr = inet_addr(argv[2]);

   FD_ZERO(&rset);
   
   while (1) {
      FD_SET(fd, &rset);
      FD_SET(0,  &rset);
      
      n = ext_select(fd + 1, &rset, NULL, NULL, NULL);
      
      if (n == 0) {
         printf("Timer was runnig off.\n");
      }
      
      if (FD_ISSET(0, &rset)) {
         printf("Reading from stdin.\n");
         len = ext_read(0, (void *) buffer, sizeof(buffer));
         if (len == 0) 
            break;
         if (num_rem > 0) {
            i = (i + 1) % num_rem;
            set_prim.ssp_assoc_id = assoc_id;
            memcpy(&set_prim.ssp_addr, sar + i, sizeof(struct sockaddr_in));
            memcpy(&remote_addr, sar + i, sizeof(struct sockaddr_in));
            if (ext_setsockopt(fd, IPPROTO_SCTP, SCTP_PRIMARY_ADDR, (void *) &set_prim, sizeof(set_prim)) < 0)
               perror("setprim");
         }
         if (ext_sendto(fd, (const void *)buffer, len, 0, (const struct sockaddr *)&remote_addr, sizeof(remote_addr)) != len)
            perror("sendto");
         else
            printf("Message of length %d sent to %s:%u: %.*s", len, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), len, buffer);

      }
            
      if (FD_ISSET(fd, &rset)) {
         printf("Reading from network.\n");
         addr_len = sizeof(struct sockaddr_in);
         buffer_size = sizeof(buffer);
         if ((len = sctp_recvmsg(fd, (void *) buffer, buffer_size , (struct sockaddr *)&remote_addr, &addr_len, &sri,&msg_flags)) < 0)
            perror("recvfrom");
         else {
            if(msg_flags & MSG_NOTIFICATION) {
               process_notification(fd, buffer);
               continue;
            } else {
               printf("Message of length %d received from %s:%u: %.*s", len, inet_ntoa(remote_addr.sin_addr), ntohs(remote_addr.sin_port), len, buffer);
            }
         }
      }
   }
   sctp_freepaddrs(sar);
   if (ext_close(fd) < 0)
      perror("close");
   sleep(2);
   return 0;
}
Exemple #9
0
int
main(int argc, char *argv[])
{
        int error;
	socklen_t len;
	int sk,lstn_sk,clnt_sk,acpt_sk,pf_class,sk1;
	struct msghdr outmessage;
        struct msghdr inmessage;
        char *message = "hello, world!\n";
        struct iovec iov;
        struct iovec iov_rcv;
        struct sctp_sndrcvinfo *sinfo;
        int msg_count;
        char outcmsg[CMSG_SPACE(sizeof(struct sctp_sndrcvinfo))];
        struct cmsghdr *cmsg;
        struct iovec out_iov;
        char * buffer_snd;
        char * buffer_rcv;
	char incmsg[CMSG_SPACE(sizeof(sctp_cmsg_data_t))];
	struct sockaddr *laddrs, *paddrs;

        struct sockaddr_in conn_addr,lstn_addr,acpt_addr;
	struct sockaddr_in *addr;

	/* Rather than fflush() throughout the code, set stdout to
         * be unbuffered.
         */
        setvbuf(stdout, NULL, _IONBF, 0);
        setvbuf(stderr, NULL, _IONBF, 0);

        pf_class = PF_INET;

        sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);

	/*Creating a regular socket*/
	clnt_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);

	/*Creating a listen socket*/
        lstn_sk = test_socket(pf_class, SOCK_STREAM, IPPROTO_SCTP);

	conn_addr.sin_family = AF_INET;
        conn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
        conn_addr.sin_port = htons(SCTP_TESTPORT_1);

	lstn_addr.sin_family = AF_INET;
        lstn_addr.sin_addr.s_addr = SCTP_IP_LOOPBACK;
        lstn_addr.sin_port = htons(SCTP_TESTPORT_1);

	/*Binding the listen socket*/
	test_bind(lstn_sk, (struct sockaddr *) &lstn_addr, sizeof(lstn_addr));

	/*Listening many sockets as we are calling too many connect here*/
	test_listen(lstn_sk, 1);

	len = sizeof(struct sockaddr_in);

	test_connect(clnt_sk, (struct sockaddr *) &conn_addr, len);

	acpt_sk = test_accept(lstn_sk, (struct sockaddr *) &acpt_addr, &len);

	memset(&inmessage, 0, sizeof(inmessage));
        buffer_rcv = malloc(REALLY_BIG);

        iov_rcv.iov_base = buffer_rcv;
        iov_rcv.iov_len = REALLY_BIG;
        inmessage.msg_iov = &iov_rcv;
        inmessage.msg_iovlen = 1;
        inmessage.msg_control = incmsg;
        inmessage.msg_controllen = sizeof(incmsg);

        msg_count = strlen(message) + 1;

	memset(&outmessage, 0, sizeof(outmessage));
        buffer_snd = malloc(REALLY_BIG);

        outmessage.msg_name = &lstn_addr;
        outmessage.msg_namelen = sizeof(lstn_addr);
        outmessage.msg_iov = &out_iov;
        outmessage.msg_iovlen = 1;
        outmessage.msg_control = outcmsg;
        outmessage.msg_controllen = sizeof(outcmsg);
        outmessage.msg_flags = 0;

        cmsg = CMSG_FIRSTHDR(&outmessage);
        cmsg->cmsg_level = IPPROTO_SCTP;
        cmsg->cmsg_type = SCTP_SNDRCV;
        cmsg->cmsg_len = CMSG_LEN(sizeof(struct sctp_sndrcvinfo));
        outmessage.msg_controllen = cmsg->cmsg_len;
        sinfo = (struct sctp_sndrcvinfo *)CMSG_DATA(cmsg);
        memset(sinfo, 0x00, sizeof(struct sctp_sndrcvinfo));

        iov.iov_base = buffer_snd;
	iov.iov_len = REALLY_BIG;
        outmessage.msg_iov->iov_base = message;

        outmessage.msg_iov->iov_len = msg_count;
	test_sendmsg(clnt_sk, &outmessage, MSG_NOSIGNAL, msg_count);

	test_recvmsg(acpt_sk, &inmessage, MSG_NOSIGNAL);

	/*sctp_getladdrs() TEST1: Bad socket descriptor, EBADF Expected error*/
	error = sctp_getladdrs(-1, 0, &laddrs);
	if (error != -1 || errno != EBADF)
		tst_brkm(TBROK, NULL, "sctp_getladdrs with a bad socket "
			 "descriptor error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getladdrs() with a bad socket descriptor - "
		 "EBADF");

	/*sctp_getladdrs() TEST2: Invalid socket, ENOTSOCK Expected error*/
	error = sctp_getladdrs(0, 0, &laddrs);
	if (error != -1 || errno != ENOTSOCK)
		tst_brkm(TBROK, NULL, "sctp_getladdrs with invalid socket "
			 "error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getladdrs() with invalid socket - ENOTSOCK");

	/*sctp_getladdrs() TEST3: socket of different protocol
	EOPNOTSUPP Expected error*/
        sk1 = socket(pf_class, SOCK_STREAM, IPPROTO_IP);
	error = sctp_getladdrs(sk1, 0, &laddrs);
	if (error != -1 || errno != EOPNOTSUPP)
		tst_brkm(TBROK, NULL, "sctp_getladdrs with socket of "
			 "different protocol error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getladdrs() with socket of different protocol - "
		 "EOPNOTSUPP");

	/*sctp_getladdrs() TEST4: Getting the local addresses*/
	error = sctp_getladdrs(lstn_sk, 0, &laddrs);
	if (error < 0)
		tst_brkm(TBROK, NULL, "sctp_getladdrs with valid socket "
			 "error:%d, errno:%d", error, errno);

	addr = (struct sockaddr_in *)laddrs;
	if (addr->sin_port != lstn_addr.sin_port ||
	    addr->sin_family != lstn_addr.sin_family ||
	    addr->sin_addr.s_addr != lstn_addr.sin_addr.s_addr)
		tst_brkm(TBROK, NULL, "sctp_getladdrs comparision failed");

	tst_resm(TPASS, "sctp_getladdrs() - SUCCESS");

	/*sctp_freealddrs() TEST5: freeing the local address*/
	if ((sctp_freeladdrs(laddrs)) < 0)
		tst_brkm(TBROK, NULL, "sctp_freeladdrs "
			 "error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_freeladdrs() - SUCCESS");

	/*sctp_getpaddrs() TEST6: Bad socket descriptor, EBADF Expected error*/
	error = sctp_getpaddrs(-1, 0, &paddrs);
	if (error != -1 || errno != EBADF)
		tst_brkm(TBROK, NULL, "sctp_getpaddrs with a bad socket "
			 "descriptor error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getpaddrs() with a bad socket descriptor - "
		 "EBADF");

	/*sctp_getpaddrs() TEST7: Invalid socket, ENOTSOCK Expected error*/
	error = sctp_getpaddrs(0, 0, &paddrs);
	if (error != -1 || errno != ENOTSOCK)
		tst_brkm(TBROK, NULL, "sctp_getpaddrs with invalid socket "
			 "error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getpaddrs() with invalid socket - ENOTSOCK");

	/*sctp_getpaddrs() TEST8: socket of different protocol
	EOPNOTSUPP Expected error*/
	error = sctp_getpaddrs(sk1, 0, &laddrs);
	if (error != -1 || errno != EOPNOTSUPP)
		tst_brkm(TBROK, NULL, "sctp_getpaddrs with socket of "
			 "different protocol error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_getpaddrs() with socket of different protocol - "
		 "EOPNOTSUPP");

	/*sctp_getpaddrs() TEST9: Getting the peer addresses*/
	error = sctp_getpaddrs(acpt_sk, 0, &paddrs);
	if (error < 0)
		tst_brkm(TBROK, NULL, "sctp_getpaddrs with valid socket "
			 "error:%d, errno:%d", error, errno);

	addr = (struct sockaddr_in *)paddrs;
	if (addr->sin_port != acpt_addr.sin_port ||
            addr->sin_family != acpt_addr.sin_family ||
            addr->sin_addr.s_addr != acpt_addr.sin_addr.s_addr)
		tst_brkm(TBROK, NULL, "sctp_getpaddrs comparision failed");

	tst_resm(TPASS, "sctp_getpaddrs() - SUCCESS");

	/*sctp_freeapddrs() TEST10: freeing the peer address*/
	if ((sctp_freepaddrs(paddrs)) < 0)
		tst_brkm(TBROK, NULL, "sctp_freepaddrs "
			 "error:%d, errno:%d", error, errno);

	tst_resm(TPASS, "sctp_freepaddrs() - SUCCESS");

	close(clnt_sk);

	tst_exit();
}
Exemple #10
0
int main(int argc,char **argv)
{
	int echo_to_all = 0;

	int ret_value;
	int sock_fd;
	int msg_flags;	// 記錄要傳送訊息時的相關設定
	char readbuf[BUFFERSIZE];
	struct sockaddr_in servaddr,cliaddr;
	struct sctp_sndrcvinfo sri;	// 記錄send, recv, association的相關資訊
	struct sctp_event_subscribe evnts;
	int stream_increment = 1;
	socklen_t len;
	size_t rd_sz;	// size_t指的就是unsigned long:rd_sz表示recv,send-size
	struct sockaddr *addrs;
	int addrcnt;
	int temp_step;

	if (argc == 2) {
		// 把字串轉換成數字
		stream_increment = atoi(argv[1]);
	}

	// 建立socket的型態為SCTP的one-to-many的型態
	sock_fd = socket(AF_INET,SOCK_SEQPACKET,IPPROTO_SCTP);
	if (sock_fd == -1) {
		printf("socket error\n");
		exit(-1);
	}
	// 初始化server address的設定
	memset(&servaddr,0,sizeof(servaddr));
	servaddr.sin_family = AF_INET;
	servaddr.sin_addr.s_addr = htonl(INADDR_ANY);
	servaddr.sin_port = htons(SERV_PORT);
	
	// 把socket與所建立的address綁在一起
	ret_value = bind(sock_fd,(struct sockaddr *) &servaddr,sizeof(servaddr));
	if (ret_value == -1) {
		printf("bind error\n");
		exit(-1);
	}

	// Set up for notifications of internet
	bzero(&evnts,sizeof(evnts));
	evnts.sctp_data_io_event = 1;	// 使得sctp_sndrcvinfo可以伴隨資料傳送過來
	ret_value = setsockopt(sock_fd,IPPROTO_SCTP,SCTP_EVENTS,&evnts,sizeof(evnts));
	if (ret_value == -1) {
		printf("setsockopt error\n");
		exit(-1);
	}

	// 設定等待多少個client端連線
	ret_value = listen(sock_fd,LISTENQ);
	if (ret_value == -1) {
		printf("listen error\n");
		exit(-1);
	}
	printf("start wait...\n");

	for (;;) {
		len = sizeof(struct sockaddr_in);
		// 等待client端連線
		rd_sz = sctp_recvmsg(sock_fd,readbuf,sizeof(readbuf),(struct sockaddr *) &cliaddr,&len,&sri,&msg_flags);

		// 分別印出local與peer端的address - start
		if ((addrcnt = sctp_getladdrs(sock_fd,sri.sinfo_assoc_id,&addrs))==-1) {
			printf("sctp_getladdrs error\n");
			exit(-1);
		}
		printf("the local has %d address(es)\n",addrcnt);
		for (temp_step=0;temp_step<addrcnt;temp_step++) {
			printf("the address is %s\n",inet_ntoa(((struct sockaddr_in *) addrs+temp_step)->sin_addr));
		}
		sctp_freeladdrs(addrs);
		if ((addrcnt = sctp_getpaddrs(sock_fd,sri.sinfo_assoc_id,&addrs))==-1) {
			printf("sctp_getpaddrs error\n");
			exit(-1);
		}
		printf("the peer has %d address(es)\n",addrcnt);
		for (temp_step=0;temp_step<addrcnt;temp_step++) {
			printf("the address is %s\n",inet_ntoa(((struct sockaddr_in *) addrs+temp_step)->sin_addr));
		}
		sctp_freepaddrs(addrs);
		// 分別印出local與peer端的address - start

		if (stream_increment) {
			sri.sinfo_stream++;
			if (sri.sinfo_stream >= 100) {
				sri.sinfo_stream = 0;
			}
		}
		// 把接收到的資料回送給client
		ret_value = sctp_sendmsg(sock_fd,readbuf,rd_sz,(struct sockaddr *) &cliaddr,len,sri.sinfo_ppid,sri.sinfo_flags,sri.sinfo_stream,0,0);
		if (ret_value == -1) {
			printf("sctp_sendmsg error\n");
			exit(-1);
		}
	}
	return 0;
}