コード例 #1
0
ファイル: csp_io.c プロジェクト: janbre/NUTS
int csp_send(csp_conn_t * conn, csp_packet_t * packet, uint32_t timeout) {

    int ret;

    if ((conn == NULL) || (packet == NULL) || (conn->state != CONN_OPEN)) {
        csp_log_error("Invalid call to csp_send\r\n");
        return 0;
    }

#ifdef CSP_USE_RDP
    if (conn->idout.flags & CSP_FRDP) {
        if (csp_rdp_send(conn, packet, timeout) != CSP_ERR_NONE) {
            csp_route_t * ifout = csp_route_if(conn->idout.dst);
            if (ifout != NULL && ifout->interface != NULL)
                ifout->interface->tx_error++;
            csp_log_warn("RDP send failed\r\n!");
            return 0;
        }
    }
#endif

    ret = csp_send_direct(conn->idout, packet, timeout);

    return (ret == CSP_ERR_NONE) ? 1 : 0;

}
コード例 #2
0
/**
 * Send a packet on an already established connection
 * @param conn pointer to connection
 * @param packet pointer to packet,
 * @param timeout a timeout to wait for TX to complete. NOTE: not all underlying drivers supports flow-control.
 * @return returns 1 if successful and 0 otherwise. you MUST free the frame yourself if the transmission was not successful.
 */
int csp_send(csp_conn_t * conn, csp_packet_t * packet, unsigned int timeout) {

	if ((conn == NULL) || (packet == NULL) || (conn->state != CONN_OPEN)) {
		csp_debug(CSP_ERROR, "Invalid call to csp_send\r\n");
		return 0;
	}

#if CSP_USE_RDP

	int result = 1;
	switch(conn->idout.protocol) {
	case CSP_RDP:
		result = csp_rdp_send(conn, packet, timeout);
		break;
	default:
		break;
	}
	if (result == 0) {
		csp_debug(CSP_WARN, "RPD send failed\r\n!");
		return 0;
	}

#endif

	return csp_send_direct(conn->idout, packet, timeout);

}
コード例 #3
0
ファイル: csp_io.c プロジェクト: janbre/NUTS
int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t * packet, uint32_t timeout) {

    packet->id.flags = 0;

    if (opts & CSP_O_RDP) {
        csp_log_error("Attempt to create RDP packet on connection-less socket\r\n");
        return CSP_ERR_INVAL;
    }

    /** SEQNR */
    if(opts & CSP_O_SEQNR) {
#ifdef CSP_USE_SEQNR
        packet->id.flags |= CSP_SEQNR;
#else
        csp_log_error("Attempt to create packet with SEQNR capabilities, but CSP was compiled without such support\r\n");
        return CSP_ERR_NOTSUP;
#endif
    }

    if (opts & CSP_O_HMAC) {
#ifdef CSP_USE_HMAC
        packet->id.flags |= CSP_FHMAC;
#else
        csp_log_error("Attempt to create HMAC authenticated packet, but CSP was compiled without HMAC support\r\n");
        return CSP_ERR_NOTSUP;
#endif
    }

    if (opts & CSP_O_XTEA) {
#ifdef CSP_USE_XTEA
        packet->id.flags |= CSP_FXTEA;
#else
        csp_log_error("Attempt to create XTEA encrypted packet, but CSP was compiled without XTEA support\r\n");
        return CSP_ERR_NOTSUP;
#endif
    }

    if (opts & CSP_O_CRC32) {
#ifdef CSP_USE_CRC32
        packet->id.flags |= CSP_FCRC32;
#else
        csp_log_error("Attempt to create CRC32 validated packet, but CSP was compiled without CRC32 support\r\n");
        return CSP_ERR_NOTSUP;
#endif
    }

    packet->id.dst = dest;
    packet->id.dport = dport;
    packet->id.src = my_address;
    packet->id.sport = src_port;
    packet->id.pri = prio;

    if (csp_send_direct(packet->id, packet, timeout) != CSP_ERR_NONE)
        return CSP_ERR_NOTSUP;

    return CSP_ERR_NONE;
}
コード例 #4
0
ファイル: csp_io.c プロジェクト: CatFreed/libcsp
int csp_sendto(uint8_t prio, uint8_t dest, uint8_t dport, uint8_t src_port, uint32_t opts, csp_packet_t * packet, uint32_t timeout) {

	packet->id.flags = 0;

	if (opts & CSP_O_RDP) {
		csp_log_error("Attempt to create RDP packet on connection-less socket");
		return CSP_ERR_INVAL;
	}

	if (opts & CSP_O_HMAC) {
#ifdef CSP_USE_HMAC
		packet->id.flags |= CSP_FHMAC;
#else
		csp_log_error("Attempt to create HMAC authenticated packet, but CSP was compiled without HMAC support");
		return CSP_ERR_NOTSUP;
#endif
	}

	if (opts & CSP_O_XTEA) {
#ifdef CSP_USE_XTEA
		packet->id.flags |= CSP_FXTEA;
#else
		csp_log_error("Attempt to create XTEA encrypted packet, but CSP was compiled without XTEA support");
		return CSP_ERR_NOTSUP;
#endif
	}

	if (opts & CSP_O_CRC32) {
#ifdef CSP_USE_CRC32
		packet->id.flags |= CSP_FCRC32;
#else
		csp_log_error("Attempt to create CRC32 validated packet, but CSP was compiled without CRC32 support");
		return CSP_ERR_NOTSUP;
#endif
	}

	packet->id.dst = dest;
	packet->id.dport = dport;
	packet->id.src = csp_get_address();
	packet->id.sport = src_port;
	packet->id.pri = prio;

	csp_iface_t * ifout = csp_rtable_find_iface(dest);
	if (csp_send_direct(packet->id, packet, ifout, timeout) != CSP_ERR_NONE)
		return CSP_ERR_NOTSUP;
	
	return CSP_ERR_NONE;

}
コード例 #5
0
ファイル: csp_route.c プロジェクト: GomSpace/libcsp
int csp_route_work(uint32_t timeout) {

	csp_qfifo_t input;
	csp_packet_t * packet;
	csp_conn_t * conn;
	csp_socket_t * socket;

#ifdef CSP_USE_RDP
	/* Check connection timeouts (currently only for RDP) */
	csp_conn_check_timeouts();
#endif

	/* Get next packet to route */
	if (csp_qfifo_read(&input) != CSP_ERR_NONE)
		return -1;

	packet = input.packet;

	csp_log_packet("INP: S %u, D %u, Dp %u, Sp %u, Pr %u, Fl 0x%02X, Sz %"PRIu16" VIA: %s",
			packet->id.src, packet->id.dst, packet->id.dport,
			packet->id.sport, packet->id.pri, packet->id.flags, packet->length, input.interface->name);

	/* Here there be promiscuous mode */
#ifdef CSP_USE_PROMISC
	csp_promisc_add(packet);
#endif

#ifdef CSP_USE_DEDUP
	/* Check for duplicates */
	if (csp_dedup_is_duplicate(packet)) {
		/* Discard packet */
		csp_log_packet("Duplicate packet discarded");
		csp_buffer_free(packet);
		return 0;
	}
#endif

	/* If the message is not to me, route the message to the correct interface */
	if ((packet->id.dst != csp_get_address()) && (packet->id.dst != CSP_BROADCAST_ADDR)) {

		/* Find the destination interface */
		csp_iface_t * dstif = csp_rtable_find_iface(packet->id.dst);

		/* If the message resolves to the input interface, don't loop it back out */
		if ((dstif == NULL) || ((dstif == input.interface) && (input.interface->split_horizon_off == 0))) {
			csp_buffer_free(packet);
			return 0;
		}

		/* Otherwise, actually send the message */
		if (csp_send_direct(packet->id, packet, dstif, 0) != CSP_ERR_NONE) {
			csp_log_warn("Router failed to send");
			csp_buffer_free(packet);
		}

		/* Next message, please */
		return 0;
	}

	/* Discard packets with unsupported options */
	if (csp_route_check_options(input.interface, packet) != CSP_ERR_NONE) {
		csp_buffer_free(packet);
		return 0;
	}

	/* The message is to me, search for incoming socket */
	socket = csp_port_get_socket(packet->id.dport);

	/* If the socket is connection-less, deliver now */
	if (socket && (socket->opts & CSP_SO_CONN_LESS)) {
		if (csp_route_security_check(socket->opts, input.interface, packet) < 0) {
			csp_buffer_free(packet);
			return 0;
		}
		if (csp_queue_enqueue(socket->socket, &packet, 0) != CSP_QUEUE_OK) {
			csp_log_error("Conn-less socket queue full");
			csp_buffer_free(packet);
			return 0;
		}
		return 0;
	}

	/* Search for an existing connection */
	conn = csp_conn_find(packet->id.ext, CSP_ID_CONN_MASK);

	/* If this is an incoming packet on a new connection */
	if (conn == NULL) {

		/* Reject packet if no matching socket is found */
		if (!socket) {
			csp_buffer_free(packet);
			return 0;
		}

		/* Run security check on incoming packet */
		if (csp_route_security_check(socket->opts, input.interface, packet) < 0) {
			csp_buffer_free(packet);
			return 0;
		}

		/* New incoming connection accepted */
		csp_id_t idout;
		idout.pri   = packet->id.pri;
		idout.src   = csp_get_address();

		idout.dst   = packet->id.src;
		idout.dport = packet->id.sport;
		idout.sport = packet->id.dport;
		idout.flags = packet->id.flags;

		/* Create connection */
		conn = csp_conn_new(packet->id, idout);

		if (!conn) {
			csp_log_error("No more connections available");
			csp_buffer_free(packet);
			return 0;
		}

		/* Store the socket queue and options */
		conn->socket = socket->socket;
		conn->opts = socket->opts;

	/* Packet to existing connection */
	} else {

		/* Run security check on incoming packet */
		if (csp_route_security_check(conn->opts, input.interface, packet) < 0) {
			csp_buffer_free(packet);
			return 0;
		}

	}

#ifdef CSP_USE_RDP
	/* Pass packet to RDP module */
	if (packet->id.flags & CSP_FRDP) {
		csp_rdp_new_packet(conn, packet);
		return 0;
	}
#endif

	/* Pass packet to UDP module */
	csp_udp_new_packet(conn, packet);
	return 0;
}