⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 demux.c

📁 This a good VPN source
💻 C
📖 第 1 页 / 共 5 页
字号:
		     */#ifdef NAT_TRAVERSAL		    if ((packet_len == 1) && (buffer[0] = 0xff)#ifdef DEBUG			&& ((cur_debugging & DBG_NATT) == 0)#endif			) {			    /* don't log NAT-T keepalive related errors unless NATT debug is			     * enabled			     */		    }		    else#endif		    openswan_log((sender != NULL) + "~"			"ERROR: asynchronous network error report on %s"			"%s"			", complainant %s"			": %s"			" [errno %lu, origin %s"			/* ", pad %d, info %ld" */			/* ", data %ld" */			"]"			, ifp->rname			, fromstr			, offstr			, strerror(ee->ee_errno)			, (unsigned long) ee->ee_errno			, orname			/* , ee->ee_pad, (unsigned long)ee->ee_info */			/* , (unsigned long)ee->ee_data */			);		    cur_state = old_state;		}	    }	    else	    {		/* .cmsg_len is a kernel_size_t(!), but the value		 * certainly ought to fit in an unsigned long.		 */		openswan_log("unknown cmsg: level %d, type %d, len %lu"		    , cm->cmsg_level, cm->cmsg_type		    , (unsigned long) cm->cmsg_len);	    }	}    }    return (pfd.revents & interest) != 0;}#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */bool#ifdef NAT_TRAVERSAL_send_packet(struct state *st, const char *where, bool verbose)#elsesend_packet(struct state *st, const char *where)#endif{    struct connection *c = st->st_connection;    int port_buf;    bool err;#ifdef NAT_TRAVERSAL    u_int8_t ike_pkt[MAX_OUTPUT_UDP_SIZE];    u_int8_t *ptr;    unsigned long len;    if ((c->interface->ike_float == TRUE) && (st->st_tpacket.len != 1)) {	if ((unsigned long) st->st_tpacket.len >	    (MAX_OUTPUT_UDP_SIZE-sizeof(u_int32_t))) {	    DBG_log("send_packet(): really too big");	    return FALSE;	}	ptr = ike_pkt;	/** Add Non-ESP marker **/	memset(ike_pkt, 0, sizeof(u_int32_t));	memcpy(ike_pkt + sizeof(u_int32_t), st->st_tpacket.ptr,	    (unsigned long)st->st_tpacket.len);	len = (unsigned long) st->st_tpacket.len + sizeof(u_int32_t);    }    else {	ptr = st->st_tpacket.ptr;	len = (unsigned long) st->st_tpacket.len;    }#endif    DBG(DBG_RAW,	{	    DBG_log("sending %lu bytes for %s through %s to %s:%u:"		, (unsigned long) st->st_tpacket.len		, where		, c->interface->rname 		, ip_str(&c->spd.that.host_addr)		, (unsigned)c->spd.that.host_port);	    DBG_dump_chunk(NULL, st->st_tpacket);	});    /* XXX: Not very clean.  We manipulate the port of the ip_address to     * have a port in the sockaddr*, but we retain the original port     * and restore it afterwards.     */    port_buf = portof(&c->spd.that.host_addr);    setportof(htons(c->spd.that.host_port), &c->spd.that.host_addr);#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)    (void) check_msg_errqueue(c->interface, POLLOUT);#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */#ifdef NAT_TRAVERSAL    err = sendto(c->interface->fd    	, ptr, len, 0    	, sockaddrof(&c->spd.that.host_addr)    	, sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)len;#else    err = sendto(c->interface->fd    	, st->st_tpacket.ptr, st->st_tpacket.len, 0    	, sockaddrof(&c->spd.that.host_addr)    	, sockaddrlenof(&c->spd.that.host_addr)) != (ssize_t)st->st_tpacket.len;#endif    /* restore port */    setportof(port_buf, &c->spd.that.host_addr);    if (err)    {#ifdef NAT_TRAVERSAL        /* do not log NAT-T Keep Alive packets */        if (!verbose)	    return FALSE; #endif	log_errno((e, "sendto on %s to %s:%u failed in %s"	    , c->interface->rname	    , ip_str(&c->spd.that.host_addr)	    , (unsigned)c->spd.that.host_port	    , where));	return FALSE;    }    else    {	return TRUE;    }}static stf_statusunexpected(struct msg_digest *md){    loglog(RC_LOG_SERIOUS, "unexpected message received in state %s"	, enum_name(&state_names, md->st->st_state));    return STF_IGNORE;}static stf_statusinformational(struct msg_digest *md){    struct payload_digest *const n_pld = md->chain[ISAKMP_NEXT_N];    /* If the Notification Payload is not null... */    if (n_pld != NULL)    {        pb_stream *const n_pbs = &n_pld->pbs;        struct isakmp_notification *const n = &n_pld->payload.notification;        int disp_len;        char disp_buf[200];	struct state *st = md->st;            /* may be NULL */        /* Switch on Notification Type (enum) */	/* note that we can get notification payloads unencrypted	 * once we are at least in R3/I4. 	 * and that the handler is expected to treat them suspiciously.	 */        switch (n->isan_type)        {        case R_U_THERE:            return dpd_inI_outR(st, n, n_pbs);        case R_U_THERE_ACK:            return dpd_inR(st, n, n_pbs);	case PAYLOAD_MALFORMED:	    if(st) {		st->hidden_variables.st_malformed_received++;		openswan_log("received %u malformed payload notifies"			     , st->hidden_variables.st_malformed_received);		if(st->hidden_variables.st_malformed_sent > MAXIMUM_MALFORMED_NOTIFY/2		   && ((st->hidden_variables.st_malformed_sent			+ st->hidden_variables.st_malformed_received)		       > MAXIMUM_MALFORMED_NOTIFY)) {		    openswan_log("too many malformed payloads (we sent %u and received %u"				 , st->hidden_variables.st_malformed_sent				 , st->hidden_variables.st_malformed_received);		    delete_state(st);		}	    }	    return STF_IGNORE;        default:            if (pbs_left(n_pbs) >= sizeof(disp_buf)-1)                disp_len = sizeof(disp_buf)-1;            else                disp_len = pbs_left(n_pbs);            memcpy(disp_buf, n_pbs->cur, disp_len);            disp_buf[disp_len] = '\0';            break;        }    }    loglog(RC_LOG_SERIOUS, "received and ignored informational message");    return STF_IGNORE;}/* message digest allocation and deallocation */static struct msg_digest *md_pool = NULL;/* free_md_pool is only used to avoid leak reports */voidfree_md_pool(void){    for (;;)    {	struct msg_digest *md = md_pool;	if (md == NULL)	    break;	md_pool = md->next;	pfree(md);    }}struct msg_digest *alloc_md(void){    struct msg_digest *md = md_pool;    /* convenient initializer:     * - all pointers NULL     * - .note = NOTHING_WRONG     * - .encrypted = FALSE     */    static const struct msg_digest blank_md;    if (md == NULL)	md = alloc_thing(struct msg_digest, "msg_digest");    else	md_pool = md->next;    *md = blank_md;    md->digest_roof = md->digest;    /* note: although there may be multiple msg_digests at once     * (due to suspended state transitions), there is a single     * global reply_buffer.  It will need to be saved and restored.     */    init_pbs(&md->reply, reply_buffer, sizeof(reply_buffer), "reply packet");    return md;}struct state *looking_for_state = NULL;struct msg_digest *looking_for_md = NULL;voidrelease_md(struct msg_digest *md){    passert(looking_for_md == NULL || md != looking_for_md);    passert(looking_for_state == NULL || md->st != looking_for_state);    freeanychunk(md->raw_packet);    pfreeany(md->packet_pbs.start);    md->packet_pbs.start = NULL;    md->next = md_pool;    md_pool = md;}/* wrapper for read_packet and process_packet * * The main purpose of this wrapper is to factor out teardown code * from the many return points in process_packet.  This amounts to * releasing the msg_digest and resetting global variables. * * When processing of a packet is suspended (STF_SUSPEND), * process_packet sets md to NULL to prevent the msg_digest being freed. * Someone else must ensure that msg_digest is freed eventually. * * read_packet is broken out to minimize the lifetime of the * enormous input packet buffer, an auto. */voidcomm_handle(const struct iface *ifp){    static struct msg_digest *md;#if defined(IP_RECVERR) && defined(MSG_ERRQUEUE)    /* Even though select(2) says that there is a message,     * it might only be a MSG_ERRQUEUE message.  At least     * sometimes that leads to a hanging recvfrom.  To avoid     * what appears to be a kernel bug, check_msg_errqueue     * uses poll(2) and tells us if there is anything for us     * to read.     *     * This is early enough that teardown isn't required:     * just return on failure.     */    if (!check_msg_errqueue(ifp, POLLIN))	return;	/* no normal message to read */#endif /* defined(IP_RECVERR) && defined(MSG_ERRQUEUE) */    md = alloc_md();    md->iface = ifp;    if (read_packet(md))	process_packet(&md);    if (md != NULL)	release_md(md);    cur_state = NULL;    reset_cur_connection();    cur_from = NULL;}/* read the message. * Since we don't know its size, we read it into * an overly large buffer and then copy it to a * new, properly sized buffer. */static boolread_packet(struct msg_digest *md){    const struct iface *ifp = md->iface;    int packet_len;    /* ??? this buffer seems *way* too big */    u_int8_t bigbuffer[MAX_INPUT_UDP_SIZE];#ifdef NAT_TRAVERSAL    u_int8_t *_buffer = bigbuffer;#endif    union    {	struct sockaddr sa;	struct sockaddr_in sa_in4;	struct sockaddr_in6 sa_in6;    } from;    int from_len = sizeof(from);    err_t from_ugh = NULL;    static const char undisclosed[] = "unknown source";    happy(anyaddr(addrtypeof(&ifp->addr), &md->sender));    zero(&from.sa);    packet_len = recvfrom(ifp->fd, bigbuffer, sizeof(bigbuffer), 0	, &from.sa, &from_len);    /* First: digest the from address.     * We presume that nothing here disturbs errno.     */    if (packet_len == -1    && from_len == sizeof(from)    && all_zero((const void *)&from.sa, sizeof(from)))    {	/* "from" is untouched -- not set by recvfrom */	from_ugh = undisclosed;    }    else if (from_len    < (int) (offsetof(struct sockaddr, sa_family) + sizeof(from.sa.sa_family)))    {	from_ugh = "truncated";    }    else    {	const struct af_info *afi = aftoinfo(from.sa.sa_family);	if (afi == NULL)	{	    from_ugh = "unexpected Address Family";	}	else if (from_len != (int)afi->sa_sz)	{	    from_ugh = "wrong length";	}	else	{	    switch (from.sa.sa_family)	    {	    case AF_INET:		from_ugh = initaddr((void *) &from.sa_in4.sin_addr		    , sizeof(from.sa_in4.sin_addr), AF_INET, &md->sender);		md->sender_port = ntohs(from.sa_in4.sin_port);		break;	    case AF_INET6:		from_ugh = initaddr((void *) &from.sa_in6.sin6_addr		    , sizeof(from.sa_in6.sin6_addr), AF_INET6, &md->sender);		md->sender_port = ntohs(from.sa_in6.sin6_port);		break;	    }	}    }    /* now we report any actual I/O error */    if (packet_len == -1)    {	if (from_ugh == undisclosed	&& errno == ECONNREFUSED)	{	    /* Tone down scary message for vague event:	     * We get "connection refused" in response to some	     * datagram we sent, but we cannot tell which one.	     */	    openswan_log("some IKE message we sent has been rejected with ECONNREFUSED (kernel supplied no details)");	}	else if (from_ugh != NULL)	{	    log_errno((e, "recvfrom on %s failed; Pluto cannot decode source sockaddr in rejection: %s"		, ifp->rname, from_ugh));	}	else	{	    log_errno((e, "recvfrom on %s from %s:%u failed"		, ifp->rname		, ip_str(&md->sender), (unsigned)md->sender_port));	}	return FALSE;    }    else if (from_ugh != NULL)    {	openswan_log("recvfrom on %s returned misformed source sockaddr: %s"	    , ifp->rname, from_ugh);	return FALSE;    }    cur_from = &md->sender;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -