/**
 * Create a Diameter Response to a given Request. 
 * @param request - the request that this response is for
 * @returns the AAAMessage* or NULL on error
 */
AAAMessage *AAACreateResponse(AAAMessage *request)
{
	AAAMessage *msg;
	msg = AAANewMessage(request->commandCode,request->applicationId,request->sId,request);
		
	return msg;
}
Beispiel #2
0
AAAMessage *send_unknown_request_answer(AAAMessage *req)
{
        AAAMessage *ans=0;
        char x[4];
        AAA_AVP *avp;


        /* UAA header is created based on the UAR */
        ans = AAANewMessage(req->commandCode,req->applicationId,0,req);

        if (!ans) return 0;

        set_4bytes(x,(unsigned int) DIAMETER_UNABLE_TO_COMPLY);

        avp = AAACreateAVP(AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4,AVP_DUPLICATE_DATA);
        if (!avp) {
                LOG(L_ERR,"ERR: Failed creating avp for result code\n");
                AAAFreeMessage(&ans);
                return 0;
        }
        if (AAAAddAVPToMessage(ans,avp,ans->avpList.tail)!=AAA_ERR_SUCCESS) {
                LOG(L_ERR,"ERR: Failed adding avp to message\n");
                AAAFreeAVP(&avp);
                AAAFreeMessage(&ans);
                return 0;
        }
        return ans;
}
Beispiel #3
0
/**
 * Send a Capabilities Exchange Answer.
 * Checks whether there are common applications.
 * \note Must be called with a lock on the peer.
 * @param p - peer identification
 * @param cer - the CER message
 * @param result_code - the Result-Code to send
 * @param sock - socket to send through
 */
void Snd_CEA(peer *p,AAAMessage *cer,int result_code,int sock)
{
	AAAMessage *cea;
	unsigned int ip;
	struct sockaddr_in addr;
	socklen_t addrlen;
	char x[6];
	
	cea = AAANewMessage(Code_CE,0,0,cer);	
	if (!cea) goto done;
	
	addrlen = sizeof(struct sockaddr_in);
	if (getsockname(sock,(struct sockaddr*) &addr, &addrlen) == -1) { 
		LOG(L_ERR,"ERROR:Snd_CEA(): Error on finding local host address > %s\n",strerror(errno));
	}else{
		set_2bytes(x,1);
		ip = htonl(addr.sin_addr.s_addr);
		set_4bytes(x+2,ip);
		AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6);
	}

	set_4bytes(x,config->vendor_id);
	AAACreateAndAddAVPToMessage(cea,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4);
			
	AAACreateAndAddAVPToMessage(cea,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len);

	set_4bytes(x,result_code);
	AAACreateAndAddAVPToMessage(cea,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);

	Snd_CE_add_applications(cea,p);

	peer_send(p,sock,cea,1);
done:	
	AAAFreeMessage(&cer);
}
Beispiel #4
0
/**
 * Send a Capability Exchange Request.
 * \note Must be called with a lock on the peer.
 * @param p - the peer to send to
 */
void I_Snd_CER(peer *p)
{
	AAAMessage *cer=0;
//	AAA_AVP *avp;
	unsigned long ip;
	struct sockaddr_in addr;
	socklen_t addrlen;
	char x[6];
	
	cer = AAANewMessage(Code_CE,0,0,0);
	if (!cer) return;
	cer->hopbyhopId = next_hopbyhop();
	cer->endtoendId = next_endtoend();
	addrlen = sizeof(struct sockaddr_in);
	if (getsockname(p->I_sock,(struct sockaddr*) &addr, &addrlen) == -1) { 
		LOG(L_ERR,"ERROR:I_Snd_CER(): Error on finding local host address > %s\n",strerror(errno));
	}else{
		set_2bytes(x,1);
		ip = htonl(addr.sin_addr.s_addr);
		set_4bytes(x+2,ip);
		AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6);
	}

	set_4bytes(x,config->vendor_id);
	AAACreateAndAddAVPToMessage(cer,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4);
			
	AAACreateAndAddAVPToMessage(cer,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len);

	Snd_CE_add_applications(cer,p);
//	peer_send(p,p->I_sock,cer,1);
	peer_send_msg(p,cer);
}
Beispiel #5
0
/**
 * Sends a Disconnect Peer Answer.
 * \note Must be called with a lock on the peer.
 * @param p - the peer to send to
 * @param dpr - the DPR message
 * @param result_code - the Result-Code to attach to DPA
 * @param sock - socket to send on
 */
void Snd_DPA(peer *p,AAAMessage *dpr,int result_code,int sock)
{
	AAAMessage *dpa;

	dpa = AAANewMessage(Code_DP,0,0,dpr);	
	if (dpa) peer_send_msg(p,dpa);
	AAAFreeMessage(&dpr);
}
void Send_ASA(cdp_session_t* s, AAAMessage* msg)
{
	AAAMessage *asa;
	char x[4];
	AAA_AVP *avp;	
	LOG(L_INFO,"Send_ASA():  sending ASA\n");
	if (!s) {
	//send an ASA for UNKNOWN_SESSION_ID - use AAASendMessage()
	// msg is the ASR received
		asa = AAANewMessage(IMS_ASA,0,0,msg);
		if (!asa) return;	
	
		set_4bytes(x,AAA_SUCCESS);
		AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
	
		AAASendMessage(asa,0,0);
	}else{
		// send... many cases... maybe not needed.
		// for now we do the same
		asa = AAANewMessage(IMS_ASA,0,0,msg);
		if (!asa) return;	
	
		set_4bytes(x,AAA_SUCCESS);
		AAACreateAndAddAVPToMessage(asa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
				
		avp = AAAFindMatchingAVP(msg,0,AVP_Origin_Host,0,0);	
		if (avp) {
				// This is because AAASendMessage is not going to find a route to the 
				// the PCRF because TS 29.214 says no Destination-Host and no Auth-Application-Id
				// in the ASA
			LOG(L_INFO,"sending ASA to peer %.*s\n",avp->data.len,avp->data.s); 
			peer *p;
			p = get_peer_by_fqdn(&avp->data);
			if (!peer_send_msg(p,asa)) {
				if (asa) AAAFreeMessage(&asa);	//needed in frequency
			} else  
				LOG(L_INFO,"success sending ASA\n");
		}else if (!AAASendMessage(asa,0,0)) {
			LOG(L_ERR,"Send_ASA() : error sending ASA\n");
		}	
	}	
}
/**
 * Create a Diameter Request.
 * @param app_id - application id to be set
 * @param command_code - the command code for this message
 * @param flags - flags to be set
 * @param sessId - session id to be set
 * @returns the AAAMessage* or NULL on error
 */
AAAMessage *AAACreateRequest(AAAApplicationId app_id,
							AAACommandCode command_code,
							AAAMsgFlag flags,
							AAASessionId *sessId)
{
	AAAMessage *msg;
	msg = AAANewMessage(command_code,app_id,sessId,0);
	if (!msg) return 0;
	msg->hopbyhopId = next_hopbyhop();
	msg->endtoendId = next_endtoend();
	msg->flags |= flags;	
	return msg;
}
Beispiel #8
0
/**
 * Sends a Diameter Watch-dog Request.
 * The flag for waiting a DWA is set.
 * \note Must be called with a lock on the peer.
 * @param p - the peer that the DWR was received from
 */	
void Snd_DWR(peer *p)
{
	AAAMessage *dwr=0;
	
	dwr = AAANewMessage(Code_DW,0,0,0);
	if (!dwr) return;	
	dwr->hopbyhopId = next_hopbyhop();
	dwr->endtoendId = next_endtoend();
	if (p->state==I_Open)
		peer_send_msg(p,dwr);	
	else
		peer_send_msg(p,dwr);	
}
/**
 * Create a Diameter Request.
 * @param app_id - application id to be set
 * @param command_code - the command code for this message
 * @param flags - flags to be set
 * @param sessId - session id to be set
 * @returns the AAAMessage* or NULL on error
 */
AAAMessage *AAACreateRequest(AAAApplicationId app_id,
							AAACommandCode command_code,
							AAAMsgFlag flags,
							AAASession *session)
{
	AAAMessage *msg;
	AAA_AVP      *avp;

	msg = AAANewMessage(command_code,app_id,session,0);
	if (!msg) return 0;
	msg->hopbyhopId = next_hopbyhop();
	msg->endtoendId = next_endtoend();
	msg->flags |= flags;	

	if(session){
		/* add destination host and destination realm */
		if(session->dest_host.s){
			avp = AAACreateAVP(AVP_Destination_Host,AAA_AVP_FLAG_MANDATORY,0,
				session->dest_host.s,session->dest_host.len,AVP_DUPLICATE_DATA);
			if (!avp) {
				LOG(L_ERR,"ERR:AAACreateRequest: Failed creating Destination Host avp\n");
				goto error;
			}
			if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
				LOG(L_ERR,"ERR:AAACreateRequest: Failed adding Destination Host avp to message\n");
				AAAFreeAVP(&avp);
				goto error;
			}
		}

		if(session->dest_realm.s){
	
			avp = AAACreateAVP(AVP_Destination_Realm,AAA_AVP_FLAG_MANDATORY,0,
				session->dest_realm.s,session->dest_realm.len,AVP_DUPLICATE_DATA);
			if (!avp) {
				LOG(L_ERR,"ERR:AAACreateRequest: Failed creating Destination Realm avp\n");
				goto error;
			}
			if (AAAAddAVPToMessage(msg,avp,msg->avpList.tail)!=AAA_ERR_SUCCESS) {
				LOG(L_ERR,"ERR:AAACreateRequest: Failed adding Destination Realm avp to message\n");
				AAAFreeAVP(&avp);
				goto error;
			}		
		}
	}

	return msg;
error:
	AAAFreeMessage(&msg);
	return NULL;
}
Beispiel #10
0
/**
 * Send a Capabilities Exchange Answer.
 * Checks whether there are common applications.
 * \note Must be called with a lock on the peer.
 * @param p - peer identification
 * @param cer - the CER message
 * @param result_code - the Result-Code to send
 * @param sock - socket to send through
 */
void Snd_CEA(peer *p,AAAMessage *cer,int result_code,int sock)
{
	AAAMessage *cea;
	unsigned int ip;
	union {
		struct sockaddr addr;
		struct sockaddr_in in;
		struct sockaddr_in6 in6;
	} addr_u ;
	socklen_t addrlen;
	char x[18];
	
	cea = AAANewMessage(Code_CE,0,0,cer);	
	if (!cea) goto done;
	
	addrlen = sizeof(addr_u);
	if (getsockname(sock, &(addr_u.addr), &addrlen) == -1) { 
		LM_ERR("Snd_CEA(): Error on finding local host address > %s\n",strerror(errno));
	}else{
		switch(addr_u.addr.sa_family){
			case AF_INET:
				set_2bytes(x,1);
				ip = htonl(addr_u.in.sin_addr.s_addr);
				set_4bytes(x+2,ip);
				AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6);
				break;
			case AF_INET6:
				set_2bytes(x,2);
				memcpy(x+2,addr_u.in6.sin6_addr.s6_addr,16);
				AAACreateAndAddAVPToMessage(cea,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,18);
				break;
			default:
				LM_ERR("Snd_CEA(): unknown address type with family %d\n",addr_u.addr.sa_family);
		}
	}

	set_4bytes(x,config->vendor_id);
	AAACreateAndAddAVPToMessage(cea,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4);
			
	AAACreateAndAddAVPToMessage(cea,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len);

	set_4bytes(x,result_code);
	AAACreateAndAddAVPToMessage(cea,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);

	Snd_CE_add_applications(cea,p);

	peer_send(p,sock,cea,1);
done:	
	AAAFreeMessage(&cer);
}
Beispiel #11
0
/**
 * Sends a Diameter Watch-dog Answer.
 * \note Must be called with a lock on the peer.
 * @param p - the peer that the DWR was received from
 * @param dwr - the DWR message
 * @param result_code - the Result-Code to attach to DWA
 * @param sock - socket to send on
 */	
void Snd_DWA(peer *p,AAAMessage *dwr,int result_code,int sock)
{
	AAAMessage *dwa;
	char x[4];	

	dwa = AAANewMessage(Code_DW,0,0,dwr);
	if (!dwa) goto done;	

	set_4bytes(x,result_code);
	AAACreateAndAddAVPToMessage(dwa,AVP_Result_Code,AAA_AVP_FLAG_MANDATORY,0,x,4);
	
	peer_send_msg(p,dwa);
done:	
	AAAFreeMessage(&dwr);
}
Beispiel #12
0
/**
 * Send a Capability Exchange Request.
 * \note Must be called with a lock on the peer.
 * @param p - the peer to send to
 */
void I_Snd_CER(peer *p)
{
	AAAMessage *cer=0;
//	AAA_AVP *avp;
	unsigned long ip;
	union {
		struct sockaddr addr;
		struct sockaddr_in in;
		struct sockaddr_in6 in6;
	} addr_u ;
	socklen_t addrlen;
	char x[18];
	
	cer = AAANewMessage(Code_CE,0,0,0);
	if (!cer) return;
	cer->hopbyhopId = next_hopbyhop();
	cer->endtoendId = next_endtoend();
	addrlen = sizeof(addr_u);
	if (getsockname(p->I_sock,&(addr_u.addr), &addrlen) == -1) { 
		LM_ERR("I_Snd_CER(): Error on finding local host address > %s\n",strerror(errno));
	}else{
		switch(addr_u.addr.sa_family){
			case AF_INET:
				set_2bytes(x,1);
				ip = htonl(addr_u.in.sin_addr.s_addr);
				set_4bytes(x+2,ip);
				AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,6);
				break;
			case AF_INET6:
				set_2bytes(x,2);
				memcpy(x+2,addr_u.in6.sin6_addr.s6_addr,16);
				AAACreateAndAddAVPToMessage(cer,AVP_Host_IP_Address,AAA_AVP_FLAG_MANDATORY,0,x,18);
				break;
			default:
				LM_ERR("I_Snd_CER(): unknown address type with family %d\n",addr_u.addr.sa_family);
		}
	}

	set_4bytes(x,config->vendor_id);
	AAACreateAndAddAVPToMessage(cer,AVP_Vendor_Id,AAA_AVP_FLAG_MANDATORY,0,x,4);
			
	AAACreateAndAddAVPToMessage(cer,AVP_Product_Name,AAA_AVP_FLAG_MANDATORY,0,config->product_name.s,config->product_name.len);

	Snd_CE_add_applications(cer,p);
//	peer_send(p,p->I_sock,cer,1);
	peer_send_msg(p,cer);
}
Beispiel #13
0
/**
 * Sends a Disconnect Peer Request.
 * \note Must be called with a lock on the peer.
 * @param p - the peer to send to
 */
void Snd_DPR(peer *p)
{
	AAAMessage *dpr=0;
	char x[4];
	
	dpr = AAANewMessage(Code_DP,0,0,0);	
	if (!dpr) return;
	dpr->hopbyhopId = next_hopbyhop();
	dpr->endtoendId = next_endtoend();

	set_4bytes(x,0/*busy*/);
	AAACreateAndAddAVPToMessage(dpr,AVP_Disconnect_Cause,AAA_AVP_FLAG_MANDATORY,0,x,4);

	if (p->state==I_Open)
		peer_send_msg(p,dpr);	
	else
		peer_send_msg(p,dpr);	
}