changeset 419:9cc48cd22e67

Finished RTR on Diameter-SIP
author Alexandre Westfahl <awestfahl@freediameter.net>
date Mon, 12 Jul 2010 22:56:33 +0900
parents 1097c885c065
children c8a61dabea55
files extensions/app_sip/CMakeLists.txt extensions/app_sip/diamsip.c extensions/app_sip/diamsip.h extensions/app_sip/registrationtermination.c extensions/app_sip/rtrsipaor extensions/app_sip/rtrsipaor.c
diffstat 6 files changed, 559 insertions(+), 3 deletions(-) [+]
line wrap: on
line diff
--- a/extensions/app_sip/CMakeLists.txt	Thu Jul 08 18:17:18 2010 +0900
+++ b/extensions/app_sip/CMakeLists.txt	Mon Jul 12 22:56:33 2010 +0900
@@ -19,6 +19,7 @@
 	libdiamsip.c
 	md5.c
 	multimediaauth.c
+	registrationtermination.c
 )
 
 # Compile as a module
--- a/extensions/app_sip/diamsip.c	Thu Jul 08 18:17:18 2010 +0900
+++ b/extensions/app_sip/diamsip.c	Mon Jul 12 22:56:33 2010 +0900
@@ -89,6 +89,7 @@
 	
 	struct dict_object * app=NULL;
 	struct disp_when data;
+	pthread_t rtr_thread;
 	
 	/* Initialize configuration */
 	CHECK_FCT( as_conf_init() );
@@ -114,6 +115,8 @@
 	//We set usefull AVPs 
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Session-State", &sip_dict.Auth_Session_State, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Auth-Application-Id", &sip_dict.Auth_Application_Id, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Destination-Host", &sip_dict.Destination_Host, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Session-Id", &sip_dict.Session_Id, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Auth-Data-Item", &sip_dict.SIP_Auth_Data_Item, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authorization", &sip_dict.SIP_Authorization, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Authenticate", &sip_dict.SIP_Authenticate, ENOENT) );
@@ -123,6 +126,9 @@
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Server-URI", &sip_dict.SIP_Server_URI, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Method", &sip_dict.SIP_Method, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-AOR", &sip_dict.SIP_AOR, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Deregistration-Reason", &sip_dict.SIP_Deregistration_Reason, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Code", &sip_dict.SIP_Reason_Code, ENOENT) );
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "SIP-Reason-Info", &sip_dict.SIP_Reason_Info, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Realm", &sip_dict.Digest_Realm, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-URI", &sip_dict.Digest_URI, ENOENT) );
 	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_AVP, AVP_BY_NAME, "Digest-Nonce", &sip_dict.Digest_Nonce, ENOENT) );
@@ -163,6 +169,18 @@
 	
 	CHECK_FCT(fd_sess_handler_create(&ds_sess_hdl, free));
 	
+	//Creation of thread for Registration Termination	
+	if(pthread_create(&rtr_thread, NULL,rtr_socket, NULL))
+	{
+		TRACE_DEBUG(INFO,"Creation of thread failed, abort!");
+		return 1;
+	}
+		
+
+	
+	
+	
+	
 	return 0;
 }
 
--- a/extensions/app_sip/diamsip.h	Thu Jul 08 18:17:18 2010 +0900
+++ b/extensions/app_sip/diamsip.h	Mon Jul 12 22:56:33 2010 +0900
@@ -87,6 +87,22 @@
 
 int fd_avp_search_avp ( struct avp * groupedavp, struct dict_object * what, struct avp ** avp );
 
+//thread procedure
+void *rtr_socket(void *);
+
+struct rtrsipaor
+{
+	char username[200];
+	char sip_aor1[200];
+	char sip_aor2[200];
+	char sip_aor3[200];
+	char strreason[200];
+	char desthost[200];
+	int reason;
+};
+int diamsip_RTR_cb(struct rtrsipaor structure);
+#define PORT 666 //TODO:put in conf file
+
 int ds_entry();
 void fd_ext_fini(void);
 int diamsip_default_cb( struct msg ** msg, struct avp * avp, struct session * sess, enum disp_action * act);
@@ -120,7 +136,9 @@
 struct diamsip_dict{
 	struct dict_object * Auth_Session_State;
 	struct dict_object * Auth_Application_Id;
+	struct dict_object * Destination_Host;
 	struct dict_object * User_Name;
+	struct dict_object * Session_Id;
 	struct dict_object * SIP_Auth_Data_Item;
 	struct dict_object * SIP_Authorization;
 	struct dict_object * SIP_Authenticate;
@@ -130,6 +148,9 @@
 	struct dict_object * SIP_Server_URI;
 	struct dict_object * SIP_Method;
 	struct dict_object * SIP_AOR;
+	struct dict_object * SIP_Deregistration_Reason;
+	struct dict_object * SIP_Reason_Code;
+	struct dict_object * SIP_Reason_Info;
 	struct dict_object * Digest_URI;		
 	struct dict_object * Digest_Nonce;
 	struct dict_object * Digest_Nonce_Count;
--- a/extensions/app_sip/registrationtermination.c	Thu Jul 08 18:17:18 2010 +0900
+++ b/extensions/app_sip/registrationtermination.c	Mon Jul 12 22:56:33 2010 +0900
@@ -34,10 +34,235 @@
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
 *********************************************************************************************************/
 #include "diamsip.h"
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
 
+//Procedure which always wait for data on socket 
+void *rtr_socket(void *arg)
+{
+	SOCKET sock;
+    SOCKADDR_IN sin, csin;
+    struct rtrsipaor rtrsip;
+    int rcvbytes=0;
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(PORT);
+    socklen_t sinsize = sizeof(csin);
+	int accepted=0;
 
+    TRACE_DEBUG(INFO,"############********************THREAD OPEN \n********************\n********************\n");
+    
+	if(!bind(sock, (SOCKADDR*)&sin, sizeof(sin)))
+	{
+		if(listen(sock,1))
+		{
+			TRACE_DEBUG(INFO,"ERROR on listen!");
+		}
+		
+		while(1)
+		{
+			accepted=accept(sock, (struct sockaddr *)&csin,&sinsize);
+			if(accepted>-1)
+			{
+				rcvbytes=recv(accepted, &rtrsip, sizeof(struct rtrsipaor),0);
+	
+				
+				if(rcvbytes>-1)
+				{
+					diamsip_RTR_cb(rtrsip);
+					
+					
+				}
+			}
+		}
+		
+		
+	}
+	else
+		TRACE_DEBUG(INFO,"Can't create socket!");
+
+	
+	
+	
+	
+	TRACE_DEBUG(INFO,"############********************THREAD CLOSED \n********************\n********************\n");
+	pthread_exit(NULL);
+	
+}
+//Called to send a RTR
+int diamsip_RTR_cb(struct rtrsipaor structure)
+{
+	TRACE_ENTRY("%p", structure);
+	
+	int got_username=0;
+	int got_streason=0;
+	int num_aor=0;//How many SIP-AOR?
+	struct dict_object * rtr_model=NULL;
+	struct msg * message=NULL;
+	struct avp *groupedavp=NULL, *avp=NULL;
+	struct session *sess=NULL;
+	union avp_value value;
+	
+	//We must check that we have all needed value in structure
+	if(structure.username[0]!='\0')
+		got_username=1;
+	
+	if(structure.sip_aor1[0]!='\0')
+	{	
+		num_aor++;
+		if(structure.sip_aor2[0]!='\0')
+		{
+			num_aor++;
+			if(structure.sip_aor3[0]!='\0')
+				num_aor++;
+		}
+	}
+	
+	if(structure.strreason!='\0')
+		got_streason=1;
+	
+	
+	TRACE_DEBUG(INFO,"We have %d SIP_AOR",num_aor);
+	
+	if((got_username + num_aor)==0)
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"Can not proceed because there is no SIP_AOR or Username");
+		return EINVAL;
+	}
+	if(structure.reason<0)
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"Incorrect Reason-Code");
+		return EINVAL;
+	}
+	
+	if(structure.desthost[0]=='\0')
+	{
+		//We must have a least a SIP_AOR or a Username
+		TRACE_DEBUG(INFO,"No Destination_Host was provided!");
+		return EINVAL;
+	}
+	//Create the base message for an RTR
+	CHECK_FCT( fd_dict_search( fd_g_config->cnf_dict, DICT_COMMAND, CMD_BY_NAME, "Registration-Termination-Request", &rtr_model, ENOENT) );
+	CHECK_FCT( fd_msg_new (rtr_model, 0, &message));
+	
+	// Create a new session 
+	{
+		CHECK_FCT( fd_sess_new( &sess, fd_g_config->cnf_diamid, "app_sip", 7 ));
+		char * sid;
+		CHECK_FCT( fd_sess_getsid ( sess, &sid ));
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Session_Id, 0, &avp ));
+		value.os.data = (uint8_t *)sid;
+		value.os.len  = strlen(sid);
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ));
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_FIRST_CHILD, avp ));
+	}
+	
+	
+	//Auth_Session_State
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Auth_Session_State, 0, &avp ) );
+		value.i32=1;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	//Origin_Host & Origin_Realm
+	CHECK_FCT( fd_msg_add_origin ( message, 0 ));
+	
+	//Destination_Host
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.Destination_Host, 0, &avp ) );
+		value.os.data=(unsigned char *)structure.desthost;
+		value.os.len=(size_t)strlen(structure.desthost);
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+	}
+	
+	
+	//SIP Deregistration Reason (Grouped AVP)
+	{
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Deregistration_Reason, 0, &groupedavp ) );
+		
+		//Reason Code
+		CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Code, 0, &avp ) );
+		value.i32=structure.reason;
+		CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+		CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+		
+		if(got_streason)
+		{
+			//Reason Info
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_Reason_Info, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.strreason;
+			value.os.len=(size_t)strlen(structure.strreason);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( groupedavp, MSG_BRW_LAST_CHILD, avp ) );
+		}
+		
+		//We add the grouped AVP to the message
+		CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, groupedavp ) );
+	}
+	
+	//Username
+	{
+		if(got_username)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.User_Name, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.username;
+			value.os.len=(size_t)strlen(structure.username);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+		}
+	}
+	
+	//SIP_AOR
+	{
+		if(num_aor>0)
+		{
+			CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+			value.os.data=(unsigned char *)structure.sip_aor1;
+			value.os.len=(size_t)strlen(structure.sip_aor1);
+			CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+			CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+			if(num_aor>1)
+			{
+				CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+				value.os.data=(unsigned char *)structure.sip_aor2;
+				value.os.len=(size_t)strlen(structure.sip_aor2);
+				CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+				CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+				if(num_aor>2)
+				{
+					CHECK_FCT( fd_msg_avp_new ( sip_dict.SIP_AOR, 0, &avp ) );
+					value.os.data=(unsigned char *)structure.sip_aor3;
+					value.os.len=(size_t)strlen(structure.sip_aor3);
+					CHECK_FCT( fd_msg_avp_setvalue( avp, &value ) );
+					CHECK_FCT( fd_msg_avp_add( message, MSG_BRW_LAST_CHILD, avp ) );
+				}
+			}
+		}
+	}
+	
+	fd_msg_dump_walk(INFO,message);
+	CHECK_FCT( fd_msg_send( &message, NULL, NULL ));
+	
+	return 0;
+}
+
+//Called when an RTA arrive
 int diamsip_RTA_cb( struct msg ** msg, struct avp * paramavp, struct session * sess, enum disp_action * act)
 {
+	//TODO: RTA reception
+/*
 	//TODO:remove unused variables
 	struct msg *ans, *qry;
 	struct avp *avp, *a2, *authdataitem;
@@ -60,13 +285,13 @@
 		return EINVAL;
 	
 	
-	/* Create answer header */
+	// Create answer header 
 	qry = *msg;
 	CHECK_FCT( fd_msg_new_answer_from_req ( fd_g_config->cnf_dict, msg, 0 ) );
 	ans = *msg;	
 	
 	
-	/* Add the Auth-Session-State AVP */
+	// Add the Auth-Session-State AVP 
 	{
 		
 		CHECK_FCT( fd_msg_search_avp ( qry, sip_dict.Auth_Session_State, &avp) );
@@ -92,7 +317,8 @@
 	
 	
 	
+	*/
+	return 0;
 	
-	return 0;
 }
 
Binary file extensions/app_sip/rtrsipaor has changed
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/extensions/app_sip/rtrsipaor.c	Mon Jul 12 22:56:33 2010 +0900
@@ -0,0 +1,290 @@
+/*********************************************************************************************************
+* Software License Agreement (BSD License)                                                               *
+* Author: Alexandre Westfahl <awestfahl@freediameter.net>						 *
+*													 *
+* Copyright (c) 2010, Alexandre Westfahl, Teraoka Laboratory (Keio University), and the WIDE Project. 	 *		
+*													 *
+* All rights reserved.											 *
+* 													 *
+* Redistribution and use of this software in source and binary forms, with or without modification, are  *
+* permitted provided that the following conditions are met:						 *
+* 													 *
+* * Redistributions of source code must retain the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer.										 *
+*    													 *
+* * Redistributions in binary form must reproduce the above 						 *
+*   copyright notice, this list of conditions and the 							 *
+*   following disclaimer in the documentation and/or other						 *
+*   materials provided with the distribution.								 *
+* 													 *
+* * Neither the name of the Teraoka Laboratory nor the 							 *
+*   names of its contributors may be used to endorse or 						 *
+*   promote products derived from this software without 						 *
+*   specific prior written permission of Teraoka Laboratory 						 *
+*   													 *
+* 													 *
+* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED *
+* WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A *
+* PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR *
+* ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 	 *
+* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 	 *
+* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR *
+* TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF   *
+* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.								 *
+*********************************************************************************************************/
+
+
+// This file is separated from the source code because it is a separate command which will call registration termination function in Diameter-SIP
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <unistd.h>
+typedef int SOCKET;
+typedef struct sockaddr_in SOCKADDR_IN;
+typedef struct sockaddr SOCKADDR;
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#define PORT 666
+#include <errno.h>
+
+struct rtrsipaor
+{
+	char username[200];
+	char sip_aor1[200];
+	char sip_aor2[200];
+	char sip_aor3[200];
+	char strreason[200];
+	char desthost[200];
+	int reason;
+};
+
+int main (int argc, char **argv)
+{
+	SOCKET sock;
+    SOCKADDR_IN sin;
+    struct rtrsipaor rtrsip;
+    int numaor=0,i=0;
+    
+	sock = socket(AF_INET, SOCK_STREAM, 0);
+	sin.sin_addr.s_addr = inet_addr("127.0.0.1");
+    sin.sin_family = AF_INET;
+    sin.sin_port = htons(PORT);
+    
+    //We initialize the structure
+    rtrsip.username[0]='\0';
+    rtrsip.sip_aor1[0]='\0';
+    rtrsip.sip_aor2[0]='\0';
+    rtrsip.sip_aor3[0]='\0';
+    rtrsip.strreason[0]='\0';
+    rtrsip.desthost[0]='\0';
+    rtrsip.reason=-1;
+    
+    
+	//Start of arguments check
+	if(argc<3)
+	{
+		fprintf(stderr,"Missing arguments! You must at least provide a username.\n");
+		return 1;
+	}
+	
+	
+	for (i=1;i<argc;i++)
+	{
+		//We must check if it is a value or the name
+		if(strncmp(argv[i],"-",1)==0)
+		{
+			if(strcmp(argv[i],"-u")==0)
+			{
+				//Username
+				if(strlen(argv[i+1])<199)
+				{
+					strcpy(rtrsip.username,argv[i+1]);
+					//We must not check the value
+					i++;
+				}
+				else
+				{
+					fprintf(stderr,"Username is too long!\n");
+				}
+			}
+			else if(strcmp(argv[i],"-a")==0)
+			{
+				i++;
+				int j=i;
+			
+				for(j=i;j<argc;j++)
+				{
+					
+					if(strncmp(argv[i],"-",1)!=0)
+					{
+						if(strlen(argv[i])>199)
+						{
+							fprintf(stderr,"SIP-AOR is too long!\n");
+						}
+						else if(strncmp(argv[i],"sip",3)!=0)
+						{
+							//Bad format of SIP-AOR
+							fprintf(stderr,"A SIP-AOR must start by 'sip:' or 'sips:'. Aborting...\n");
+							return 1;
+						}
+						else
+						{
+							if(numaor<3)
+							{
+								switch(numaor)
+								{
+									case 0:
+										strcpy(rtrsip.sip_aor1,argv[i]);
+									break;
+									case 1:
+										strcpy(rtrsip.sip_aor2,argv[i]);
+									break;
+									case 2:
+										strcpy(rtrsip.sip_aor3,argv[i]);
+									break;
+								}
+								numaor++;
+							}
+							else
+							{
+								fprintf(stderr,"You can not provide more than 3 SIP-AOR at the same time!\n");
+								break;
+							}
+						}
+						i=j+1;
+					}
+					else
+					{
+						//We have a new argument
+						i--;
+						break;
+					}
+				}
+			}
+			else if(strcmp(argv[i],"-r")==0)
+			{
+				
+				if(strlen(argv[i+1])>199)
+				{
+					fprintf(stderr,"Deregistration reason is too long!\n");
+				}
+				else
+				{
+					strcpy(rtrsip.strreason,argv[i+1]);
+				}
+				i++;
+			}
+			else if(strcmp(argv[i],"-h")==0)
+			{
+				//Remote SIP Server
+				if(strlen(argv[i+1])>199)
+				{
+					fprintf(stderr,"Host is too long!\n");
+				}
+				else if(strlen(argv[i+1])<5)
+				{
+					fprintf(stderr,"Host is too short!\n");
+				}
+				else
+				{
+					strcpy(rtrsip.desthost,argv[i+1]);
+				}
+				i++;
+			}
+			else if(strcmp(argv[i],"-pt")==0)
+			{
+				//Permanent Termination
+				rtrsip.reason=0;
+			}
+			else if(strcmp(argv[i],"-nssa")==0)
+			{
+				//New SIP Server Assigned
+				rtrsip.reason=1;
+			}
+			else if(strcmp(argv[i],"-ssc")==0)
+			{
+				//SIP Server Change
+				rtrsip.reason=2;
+			}
+			else if(strcmp(argv[i],"-rss")==0)
+			{
+				//Remote SIP Server
+				rtrsip.reason=3;
+			}
+			else
+			{
+				fprintf(stderr,"Unknown argument: %s\n",argv[i]);
+			}
+		}
+		else
+		{
+			fprintf(stderr,"Unknown argument: %s\n",argv[i]);
+			i++;
+		}
+			
+	}
+	
+	//If no SIP-AOR provided, we remove all
+	if(numaor<1)
+	{
+		fprintf(stderr,"All SIP-AOR of %s will be deregistrated.\n",rtrsip.username);
+	}
+	
+	//We want a username
+	if(strlen(rtrsip.username)==0)
+	{
+		fprintf(stderr,"You must provide a username!\n");
+		return 1;
+	}
+	
+	if(rtrsip.desthost[0]=='\0')
+	{
+		fprintf(stderr,"You must provide the hostname of SIP-Server!\n");
+		return 1;
+	}
+    
+    
+   
+    
+    /*
+    fprintf(stderr,"*%s*\n",rtrsip.username);
+	fprintf(stderr,"*%s*\n",rtrsip.sip_aor1);
+	fprintf(stderr,"*%s*\n",rtrsip.sip_aor2);
+	fprintf(stderr,"*%s*\n",rtrsip.sip_aor3);
+	fprintf(stderr,"*%d*\n",rtrsip.reason);
+	fprintf(stderr,"*%s*\n",rtrsip.strreason);
+	
+	//return 0;
+	*/
+	
+	
+	//TODO: check args
+	if(!connect(sock, (SOCKADDR*)&sin, sizeof(sin)))
+    {
+       fprintf(stderr,"Connexion succeed!\n");
+        
+ 
+        if(send(sock, &rtrsip, sizeof(struct rtrsipaor), 0))
+			fprintf(stderr,"sent OK!\n");
+		else
+			fprintf(stderr,"not sent\n");
+        
+    }
+    else
+    {
+        fprintf(stderr,"Unable to connect\n");
+    }
+ 
+    close(sock);
+
+	return 0;
+}
+
+
+
+
+
+
"Welcome to our mercurial repository"