Esempio n. 1
0
static inline int check_against_rule_list(struct ip_addr *ip, str *text,
					  unsigned short port,
					  unsigned short proto,
					  int i)
{
	struct bl_rule *p;
	int t_val;
	int ret = 0;

	LM_DBG("using list %.*s \n",
		blst_heads[i].name.len, blst_heads[i].name.s);

	if( !blst_heads[i].flags&BL_READONLY_LIST ) {
		/* get list for read */
		lock_get( blst_heads[i].lock );
		while(blst_heads[i].count_write) {
			lock_release( blst_heads[i].lock );
			sleep_us(5);
			lock_get( blst_heads[i].lock );
		}
		blst_heads[i].count_read++;
		lock_release(blst_heads[i].lock);
	}

	for(p = blst_heads[i].first ; p ; p = p->next) {
		t_val = (p->port==0 || p->port==port) &&
			(p->proto==PROTO_NONE || p->proto==proto) &&
			(matchnet(ip, &(p->ip_net)) == 1) &&
			(p->body.s==NULL || !fnmatch(p->body.s, text->s, 0));
		if(!!(p->flags & BLR_APPLY_CONTRARY) ^ !!(t_val)){
			ret = 1;
			LM_DBG("matched list %.*s \n",
				blst_heads[i].name.len,blst_heads[i].name.s);
			break;
		}
	}

	if( !blst_heads[i].flags&BL_READONLY_LIST ) {
		lock_get( blst_heads[i].lock );
		blst_heads[i].count_read--;
		lock_release(blst_heads[i].lock);
	}
	return ret;
}
Esempio n. 2
0
/*! \brief eval_elem helping function, returns an op param */
inline static int comp_ip(struct sip_msg *msg, int op, struct ip_addr* ip,
		operand_t *opd)
{
	struct hostent* he;
	char ** h;
	int ret;
	str tmp;

	ret=-1;
	switch(opd->type){
		case NET_ST:
			switch(op){
				case EQUAL_OP:
					ret=(matchnet(ip, (struct net*)opd->v.data)==1);
					break;
				case DIFF_OP:
					ret=(matchnet(ip, (struct net*)opd->v.data)!=1);
					break;
				default:
					goto error_op;
			}
			break;
		case STR_ST:
		case RE_ST:
			switch(op){
				case EQUAL_OP:
				case MATCH_OP:
					/* 1: compare with ip2str*/
					ret=comp_str(ip_addr2a(ip), opd->v.data, op, opd->type);
					if (ret==1) break;
					/* 2: resolve (name) & compare w/ all the ips */
					if (opd->type==STR_ST){
						he=resolvehost((char*)opd->v.data,0);
						if (he==0){
							LM_DBG("could not resolve %s\n",(char*)opd->v.data);
						}else if (he->h_addrtype==(int)ip->af){
							for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
								ret=(memcmp(ip->u.addr, *h, ip->len)==0);
							}
							if (ret==1) break;
						}
					}
					/* 3: (slow) rev dns the address
					* and compare with all the aliases
					* !!??!! review: remove this? */
					if(received_dns & DO_REV_DNS)
					{
						he=rev_resolvehost(ip);
						if (he==0){
							print_ip("comp_ip: could not rev_resolve ip"
									" address: ", ip, "\n");
						ret=0;
						}else{
							/*  compare with primary host name */
							ret=comp_str(he->h_name, opd->v.data, op,
									opd->type);
							/* compare with all the aliases */
							for(h=he->h_aliases; (ret!=1) && (*h); h++){
								ret=comp_str(*h, opd->v.data, op, opd->type);
							}
						}
					} else {
						return 0;
					}
					break;
				case DIFF_OP:
					ret=comp_ip(msg, op, ip, opd);
					if (ret>=0) ret=!ret;
					break;
				default:
					goto error_op;
			}
			break;
		case MYSELF_ST: /* check if it's one of our addresses*/
			tmp.s=ip_addr2a(ip);
			tmp.len=strlen(tmp.s);
			ret=check_self_op(op, &tmp, 0);
			break;
		default:
			LM_CRIT("invalid type for src_ip or dst_ip (%d)\n", opd->type);
			ret=-1;
	}
	return ret;
error_op:
	LM_CRIT("invalid operator %d\n", op);
	return -1;
	
}
Esempio n. 3
0
/* receive an ipv4 udp packet over a raw socket.
 * The packet is copied in *buf and *buf is advanced to point to the
 * payload.  Fills from and to.
 * @param rsock - raw socket
 * @param buf - the packet will be written to where *buf points intially and
 *              then *buf will be advanced to point to the udp payload.
 * @param len - buffer length (should be enough to hold at least the
 *               ip and udp headers + 1 byte).
 * @param from - result parameter, filled with source address and port of the
 *               packet.
 * @param from - result parameter, filled with destination (local) address and
 *               port of the packet.
 * @param rf   - filter used to decide whether or not the packet is
 *                accepted/processed. If null, all the packets are accepted.
 * @return packet len or  <0 on error (-1 and -2 on recv error @see recvpkt4,
 *         -3 if the headers are invalid and -4 if the packet doesn't
 *         match the  filter).
 */
int raw_udp4_recv(int rsock, char** buf, int len, union sockaddr_union* from,
					union sockaddr_union* to, struct raw_filter* rf)
{
	int n;
	unsigned short dst_port;
	unsigned short src_port;
	struct ip_addr dst_ip;
	char* end;
	char* udph_start;
	char* udp_payload;
	struct ip iph;
	struct udphdr udph;
	unsigned short udp_len;

	n=recvpkt4(rsock, *buf, len, from, to);
	if (unlikely(n<0)) goto error;
	
	end=*buf+n;
	if (unlikely(n<((sizeof(struct ip) * raw_ipip ? 2 : 1)+sizeof(struct udphdr)))) {
		n=-3;
		goto error;
	}
	
	if(raw_ipip) 
        	*buf = *buf + sizeof(struct ip);
	
	/* FIXME: if initial buffer is aligned, one could skip the memcpy
	   and directly cast ip and udphdr pointer to the memory */
	memcpy(&iph, *buf, sizeof(struct ip));
	udph_start=*buf+iph.ip_hl*4;
	udp_payload=udph_start+sizeof(struct udphdr);
	if (unlikely(udp_payload>end)){
		n=-3;
		goto error;
	}
	memcpy(&udph, udph_start, sizeof(struct udphdr));
	udp_len=ntohs(udph.uh_ulen);
	if (unlikely((udph_start+udp_len)!=end)){
		if ((udph_start+udp_len)>end){
			n=-3;
			goto error;
		}else{
			ERR("udp length too small: %d/%d\n",
					(int)udp_len, (int)(end-udph_start));
			n=-3;
			goto error;
		}
	}
	/* advance buf */
	*buf=udp_payload;
	n=(int)(end-*buf);
	/* fill ip from the packet (needed if no PKT_INFO is used) */
	dst_ip.af=AF_INET;
	dst_ip.len=4;
	dst_ip.u.addr32[0]=iph.ip_dst.s_addr;
	/* fill dst_port */
	dst_port=ntohs(udph.uh_dport);
	ip_addr2su(to, &dst_ip, dst_port);
	/* fill src_port */
	src_port=ntohs(udph.uh_sport);
	su_setport(from, src_port);
	if (likely(rf)) {
		su2ip_addr(&dst_ip, to);
		if ( (dst_port && rf->port1 && ((dst_port<rf->port1) ||
										(dst_port>rf->port2)) ) ||
			(matchnet(&dst_ip, &rf->dst)!=1) ){
			/* no match */
			n=-4;
			goto error;
		}
	}
	
error:
	return n;
}
Esempio n. 4
0
/* eval_elem helping function, returns an op param */
inline static int comp_ip(struct ip_addr* ip, void* param, int op, int subtype)
{
	struct hostent* he;
	char ** h;
	int ret;
	str tmp;

	ret=-1;
	switch(subtype){
		case NET_ST:
			switch(op){
				case EQUAL_OP:
					ret=(matchnet(ip, (struct net*) param)==1);
					break;
				case DIFF_OP:
					ret=(matchnet(ip, (struct net*) param)!=1);
					break;
				default:
					goto error_op;
			}
			break;
		case STRING_ST:
		case RE_ST:
			switch(op){
				case EQUAL_OP:
				case MATCH_OP:
					/* 1: compare with ip2str*/
					ret=comp_str(ip_addr2a(ip), param, op, subtype);
					if (ret==1) break;
					/* 2: resolve (name) & compare w/ all the ips */
					if (subtype==STRING_ST){
						he=resolvehost((char*)param);
						if (he==0){
							DBG("comp_ip: could not resolve %s\n",
									(char*)param);
						}else if (he->h_addrtype==ip->af){
							for(h=he->h_addr_list;(ret!=1)&& (*h); h++){
								ret=(memcmp(ip->u.addr, *h, ip->len)==0);
							}
							if (ret==1) break;
						}
					}
					/* 3: (slow) rev dns the address
					* and compare with all the aliases
					* !!??!! review: remove this? */
					he=rev_resolvehost(ip);
					if (he==0){
						print_ip( "comp_ip: could not rev_resolve ip address:"
									" ", ip, "\n");
					ret=0;
					}else{
						/*  compare with primary host name */
						ret=comp_str(he->h_name, param, op, subtype);
						/* compare with all the aliases */
						for(h=he->h_aliases; (ret!=1) && (*h); h++){
							ret=comp_str(*h, param, op, subtype);
						}
					}
					break;
				case DIFF_OP:
					ret=comp_ip(ip, param, EQUAL_OP, subtype);
					if (ret>=0) ret=!ret;
					break;
				default:
					goto error_op;
			}
			break;
		case MYSELF_ST: /* check if it's one of our addresses*/
			tmp.s=ip_addr2a(ip);
			tmp.len=strlen(tmp.s);
			ret=check_self_op(op, &tmp, 0);
			break;
		default:
			LOG(L_CRIT, "BUG: comp_ip: invalid type for "
						" src_ip or dst_ip (%d)\n", subtype);
			ret=-1;
	}
	return ret;
error_op:
	LOG(L_CRIT, "BUG: comp_ip: invalid operator %d\n", op);
	return -1;
	
}