static int ras_help(struct sk_buff *skb, unsigned int protoff, struct nf_conn *ct, enum ip_conntrack_info ctinfo) { static RasMessage ras; unsigned char *data; int datalen = 0; int ret; pr_debug("nf_ct_ras: skblen = %u\n", skb->len); spin_lock_bh(&nf_h323_lock); data = get_udp_data(skb, protoff, &datalen); if (data == NULL) goto accept; pr_debug("nf_ct_ras: RAS message len=%d ", datalen); nf_ct_dump_tuple(&ct->tuplehash[CTINFO2DIR(ctinfo)].tuple); ret = DecodeRasMessage(data, datalen, &ras); if (ret < 0) { pr_debug("nf_ct_ras: decoding error: %s\n", ret == H323_ERROR_BOUND ? "out of bound" : "out of range"); goto accept; } if (process_ras(skb, ct, ctinfo, &data, &ras) < 0) goto drop; accept: spin_unlock_bh(&nf_h323_lock); return NF_ACCEPT; drop: spin_unlock_bh(&nf_h323_lock); if (net_ratelimit()) pr_info("nf_ct_ras: packet dropped\n"); return NF_DROP; }
tree_cell * nasl_recv(lex_ctxt * lexic) { char * data; int len = get_int_local_var_by_name(lexic, "length", -1); int min_len = get_int_local_var_by_name(lexic, "min", -1); int soc = get_int_local_var_by_name(lexic, "socket", 0); int to = get_int_local_var_by_name(lexic, "timeout", lexic->recv_timeout); fd_set rd; struct timeval tv; int new_len = 0; tree_cell * retc; int type = -1, opt_len = sizeof(type); int e; if(len <= 0 || soc <= 0) return NULL; if (to <= 0) to = 5; tv.tv_sec = to; tv.tv_usec = 0; data = emalloc(len); if ( !fd_is_stream(soc) ) e = getsockopt(soc, SOL_SOCKET, SO_TYPE, &type, &opt_len); else e = -1; if(e == 0 && type == SOCK_DGRAM) { /* * As UDP packets may be lost, we retry up to 5 times */ int retries = 5; int i; tv.tv_sec = to / retries; tv.tv_usec = (to % retries) * 100000; for(i=0;i<retries;i++) { FD_ZERO(&rd); FD_SET(soc, &rd); if(!to || select(soc+1, &rd, NULL, NULL, &tv)>0) { int e; e = recv(soc, data+new_len, len-new_len, 0); if(e <= 0) { if(!new_len) { efree(&data); return NULL; } else break; } else new_len+=e; if(new_len >= len)break; break; /* UDP data is never fragmented */ } else { /* * The packet may have been lost en route - we resend it */ char * data; int len; data = get_udp_data(lexic->script_infos, soc, &len); if(data != NULL)send(soc, data, len, 0); tv.tv_sec = to / retries; tv.tv_usec = ( to % retries) * 100000; } } } else { int old = stream_set_timeout(soc, tv.tv_sec); new_len = read_stream_connection_min(soc, data, min_len, len); stream_set_timeout(soc, old); } if(new_len > 0) { retc = alloc_tree_cell(0, NULL); retc->type = CONST_DATA; retc->x.str_val = nasl_strndup(data, new_len); retc->size = new_len; efree(&data); return retc; } else { efree(&data); return NULL; } }