stunc.c 4.62 KB
Newer Older
Pekka Pessi's avatar
Pekka Pessi committed
1 2 3 4 5 6 7
/*
 * This file is part of the Sofia-SIP package
 *
 * Copyright (C) 2005 Nokia Corporation.
 *
 * Contact: Pekka Pessi <pekka.pessi@nokia.com>
 *
8
 * This library is free software; you can redistribute it and/or
Pekka Pessi's avatar
Pekka Pessi committed
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
 * modify it under the terms of the GNU Lesser General Public License
 * as published by the Free Software Foundation; either version 2.1 of
 * the License, or (at your option) any later version.
 *
 * This library is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
 * Lesser General Public License for more details.
 *
 * You should have received a copy of the GNU Lesser General Public
 * License along with this library; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA
 * 02110-1301 USA
 *
 */

/**
 * @file stunc.c STUN test client
 * 
 * @author Pekka Pessi <Pekka.Pessi@nokia.com>
 * 
 * @date Created: Thu Jul 24 17:21:00 2003 ppessi
 */

#include "config.h" 

#include <stdio.h>
#include <string.h>
#include <stdlib.h>

39 40 41 42
typedef struct stunc_s stunc_t;
#define SU_ROOT_MAGIC  stunc_t
#define STUN_MAGIC_T   stunc_t

Pekka Pessi's avatar
Pekka Pessi committed
43
#include "stun.h"
Martti Mela's avatar
Martti Mela committed
44
#include "stun_tag.h"
Martti Mela's avatar
Martti Mela committed
45 46 47 48 49 50 51
#include <su.h>

#ifndef SU_DEBUG
#define SU_DEBUG 3
#endif
#define SU_LOG (stun_log)
#include <su_debug.h>
Pekka Pessi's avatar
Pekka Pessi committed
52 53 54 55 56 57 58 59 60

char const *name = "stunc";

void usage(int exitcode)
{
  fprintf(stderr, "usage: %s server use_msgint\n", name);
  exit(exitcode);
}

61
struct stunc_s {
62
  int nothing; 
63 64 65
};


66
void stunc_callback(stunc_t *stunc, stun_handle_t *sh,
67
		    stun_request_t *req,
68 69
		    stun_discovery_t *sd,
		    stun_action_t action,
70
		    stun_state_t event)
71
{
Martti Mela's avatar
Martti Mela committed
72
  su_localinfo_t *li = NULL;
Martti Mela's avatar
Martti Mela committed
73
  char ipaddr[48];
74
  char const *nattype;
75
  int lifetime;
76

Martti Mela's avatar
Martti Mela committed
77
  SU_DEBUG_3(("%s: %s\n", __func__, stun_str_state(event)));
Martti Mela's avatar
Martti Mela committed
78

Martti Mela's avatar
Martti Mela committed
79 80
  switch (event) {
  case stun_tls_done:
81
    su_root_break(stun_handle_root(sh));
Martti Mela's avatar
Martti Mela committed
82 83
    break;

84
  case stun_discovery_done:
85 86 87 88 89 90 91 92 93 94
    if (action == stun_action_get_nattype) {
      nattype = stun_nattype(sd);
      SU_DEBUG_3(("%s: NAT type: %s\n", __func__, nattype));
    }
    else if (action == stun_action_get_lifetime) {
      lifetime = stun_lifetime(sd);
      SU_DEBUG_3(("%s: Life time is %d s.\n", __func__, lifetime));
    }
    
    su_root_break(stun_handle_root(sh));
95 96
    break;
    
Martti Mela's avatar
Martti Mela committed
97
  case stun_bind_done:
98
    li = stun_request_get_localinfo(req);
Martti Mela's avatar
Martti Mela committed
99
    inet_ntop(li->li_family, SU_ADDR(li->li_addr), ipaddr, sizeof(ipaddr)),
Martti Mela's avatar
Martti Mela committed
100 101
      SU_DEBUG_3(("%s: local address NATed as %s:%u\n", __func__,
		  ipaddr, (unsigned) ntohs(li->li_addr->su_port)));
102
    su_root_break(stun_handle_root(sh));
Martti Mela's avatar
Martti Mela committed
103 104 105
    break;

  case stun_bind_error:
Martti Mela's avatar
Martti Mela committed
106
    SU_DEBUG_3(("%s: no nat detected\n", __func__));
107
    su_root_break(stun_handle_root(sh));
Martti Mela's avatar
Martti Mela committed
108
    break;
Martti Mela's avatar
Martti Mela committed
109

Martti Mela's avatar
Martti Mela committed
110 111
  case stun_bind_timeout:
  case stun_tls_connection_failed:
Martti Mela's avatar
Martti Mela committed
112
  case stun_error:
113
    su_root_break(stun_handle_root(sh));
Martti Mela's avatar
Martti Mela committed
114

Martti Mela's avatar
Martti Mela committed
115 116 117
  default:
    break;
  }
Martti Mela's avatar
Martti Mela committed
118

119
  return;
120 121 122
}


Pekka Pessi's avatar
Pekka Pessi committed
123 124
int main(int argc, char *argv[])
{
125
  int s, lifetime;
Martti Mela's avatar
Martti Mela committed
126
  int msg_integrity;
127 128
  stunc_t stunc[1]; 
  su_root_t *root = su_root_create(stunc);
Martti Mela's avatar
Martti Mela committed
129
  stun_handle_t *se;
130
  
Pekka Pessi's avatar
Pekka Pessi committed
131 132 133 134

  if (argc != 3)
    usage(1);

Martti Mela's avatar
Martti Mela committed
135 136
  msg_integrity = atoi(argv[2]);

Pekka Pessi's avatar
Pekka Pessi committed
137
  /* Running this test requires a local STUN server on default port */
Martti Mela's avatar
Martti Mela committed
138 139 140 141 142 143
  se = stun_handle_tcreate(stunc,
			   root,
			   stunc_callback,
			   STUNTAG_SERVER(argv[1]), 
			   STUNTAG_INTEGRITY(msg_integrity),
			   TAG_NULL()); 
Martti Mela's avatar
Martti Mela committed
144 145

  if (!se) {
Martti Mela's avatar
Martti Mela committed
146
    SU_DEBUG_3(("%s: %s failed\n", __func__, "stun_handle_tcreate()"));
Martti Mela's avatar
Martti Mela committed
147 148
    return -1;
  }
Pekka Pessi's avatar
Pekka Pessi committed
149

Martti Mela's avatar
Martti Mela committed
150
  if (msg_integrity == 1 && stun_handle_request_shared_secret(se) < 0) {
Martti Mela's avatar
Martti Mela committed
151 152 153 154 155
    SU_DEBUG_3(("%s: %s failed\n", __func__, "stun_connect_start()"));
    return -1;
  }
 else if (msg_integrity == 1)
   su_root_run(root);
Pekka Pessi's avatar
Pekka Pessi committed
156

Martti Mela's avatar
Martti Mela committed
157
  s = su_socket(AF_INET, SOCK_DGRAM, 0); 
Pekka Pessi's avatar
Pekka Pessi committed
158
  
Martti Mela's avatar
Martti Mela committed
159 160 161 162
  if (s == -1) {
    SU_DEBUG_3(("%s: %s  failed: %s\n", __func__, "stun_socket_create()", su_gli_strerror(errno)));
    return -1;
  }
Pekka Pessi's avatar
Pekka Pessi committed
163

Martti Mela's avatar
Martti Mela committed
164
  
165
#if 0  
Martti Mela's avatar
Martti Mela committed
166 167
  if (stun_handle_set_bind_socket(se, s) < 0) {
    SU_DEBUG_3(("%s: %s  failed\n", __func__, "stun_handle_set_bind_socket()"));
Martti Mela's avatar
Martti Mela committed
168 169
    return -1;
  }
170
#endif  
Pekka Pessi's avatar
Pekka Pessi committed
171 172
  lifetime = 0;

173
  if (stun_handle_bind(se, &lifetime, STUNTAG_SOCKET(s), TAG_NULL()) < 0) {
Martti Mela's avatar
Martti Mela committed
174
    SU_DEBUG_3(("%s: %s  failed\n", __func__, "stun_handle_bind()"));
Martti Mela's avatar
Martti Mela committed
175 176
    return -1;
  }
177 178 179

  su_root_run(root);

180
  if (stun_handle_get_nattype(se, /* STUNTAG_SOCKET(s), */ TAG_NULL()) < 0) {
181 182 183 184 185 186
    SU_DEBUG_3(("%s: %s  failed\n", __func__, "stun_handle_get_nattype()"));
    return -1;
  }

  su_root_run(root);

187 188 189 190 191 192 193
  if (stun_handle_get_lifetime(se, /* STUNTAG_SOCKET(s), */ TAG_NULL()) < 0) {
    SU_DEBUG_3(("%s: %s  failed\n", __func__, "stun_handle_get_lifetime()"));
    return -1;
  }

  su_root_run(root);

Martti Mela's avatar
Martti Mela committed
194
  stun_handle_destroy(se);
Pekka Pessi's avatar
Pekka Pessi committed
195 196 197

  return 0;
}