Beispiel #1
0
/**
 * Connects the given socket to the address.
 * @param sd        The socket handle to connect
 * @param addr      The address to connect to
 * @param addrlen   The length of the address details.
 * @return 0 on success.
 */
sock_result_t socket_connect(sock_handle_t sd, const sockaddr_t *addr, long addrlen)
{
    wiced_result_t result = WICED_INVALID_SOCKET;
    socket_t* socket = from_handle(sd);
    tcp_socket_t* tcp_socket = tcp(socket);
    if (tcp_socket) {
        std::lock_guard<socket_t> lk(*socket);
        result = wiced_tcp_bind(tcp_socket, WICED_ANY_PORT);
        if (result==WICED_SUCCESS) {
            // WICED callbacks are broken
            //wiced_tcp_register_callbacks(tcp(socket), socket_t::notify_connected, socket_t::notify_received, socket_t::notify_disconnected, (void*)socket);
            SOCKADDR_TO_PORT_AND_IPADDR(addr, addr_data, port, ip_addr);
            unsigned timeout = 5*1000;
            result = wiced_tcp_connect(tcp_socket, &ip_addr, port, timeout);
            if (result==WICED_SUCCESS) {
                tcp_socket->connected();
            } else {
              // Work around WICED bug that doesn't set connection handler to NULL after deleting
              // it, leading to deleting the same memory twice and a crash
              // WICED/network/LwIP/WICED/tcpip.c:920
              tcp_socket->conn_handler = NULL;
            }
        }
    }
    return as_sock_result(result);
}
Beispiel #2
0
static int parse_ipv6(void *data, uint64_t nh_off, void *data_end)
{
	struct ipv6hdr *ip6h;
	struct iphdr *iph;
	uint64_t ihl_len = sizeof(struct ipv6hdr);
	uint64_t nexthdr;

	ip6h = data + nh_off;
	if (ip6h + 1 > data_end)
		return 0;

	nexthdr = ip6h->nexthdr;

	if (nexthdr == IPPROTO_IPIP) {
		iph = data + nh_off + ihl_len;
		if (iph + 1 > data_end)
			return 0;
		ihl_len += iph->ihl * 4;
		nexthdr = iph->protocol;
	} else if (nexthdr == IPPROTO_IPV6) {
		ip6h = data + nh_off + ihl_len;
		if (ip6h + 1 > data_end)
			return 0;
		ihl_len += sizeof(struct ipv6hdr);
		nexthdr = ip6h->nexthdr;
	}

	if (nexthdr == IPPROTO_TCP)
		return tcp(data, nh_off + ihl_len, data_end);
	else if (nexthdr == IPPROTO_UDP)
		return udp(data, nh_off + ihl_len, data_end);
	return 0;
}
Beispiel #3
0
sock_result_t socket_send_ex(sock_handle_t sd, const void* buffer, socklen_t len, uint32_t flags, system_tick_t timeout, void* reserved)
{
    sock_result_t result = SOCKET_INVALID;
    socket_t* socket = from_handle(sd);

    uint16_t bytes_sent = 0;

    if (is_open(socket)) {
        std::lock_guard<socket_t> lk(*socket);
        wiced_result_t wiced_result = WICED_TCPIP_INVALID_SOCKET;
        if (is_tcp(socket)) {
            wiced_tcp_send_flags_t wiced_flags = timeout == 0 ? WICED_TCP_SEND_FLAG_NONBLOCK : WICED_TCP_SEND_FLAG_NONE;
            bytes_sent = (uint16_t)len;
            wiced_result = wiced_tcp_send_buffer_ex(tcp(socket), buffer, &bytes_sent, wiced_flags, timeout);
        }
        else if (is_client(socket)) {
            tcp_server_client_t* server_client = client(socket);
            size_t written = 0;
            wiced_result = server_client->write(buffer, len, &written, flags, timeout);
            bytes_sent = (uint16_t)written;
        }
        if (!wiced_result)
            DEBUG("Write %d bytes to socket %d result=%d", (int)len, (int)sd, wiced_result);
        result = wiced_result ? as_sock_result(wiced_result) : bytes_sent;
    }
    return result;
}
Beispiel #4
0
static int parse_ipv4(void *data, uint64_t nh_off, void *data_end)
{
	struct iphdr *iph;
	uint64_t ihl_len;

	iph = data + nh_off;
	if (iph + 1 > data_end)
		return 0;

	if (ip_is_fragment(iph))
		return 0;
	ihl_len = iph->ihl * 4;

	if (iph->protocol == IPPROTO_IPIP) {
		iph = data + nh_off + ihl_len;
		if (iph + 1 > data_end)
			return 0;
		ihl_len += iph->ihl * 4;
	}

	if (iph->protocol == IPPROTO_TCP)
		return tcp(data, nh_off + ihl_len, data_end);
	else if (iph->protocol == IPPROTO_UDP)
		return udp(data, nh_off + ihl_len, data_end);
	return 0;
}
Beispiel #5
0
/* -----------------------------------------------------------------------------------------------------------*/
void ip( int packet_lenght ,  char *buffer )
	{
		struct ETH_header *ETH_packet; 		// ETH_struct anlegen
		ETH_packet = (struct ETH_header *)&buffer[0];
		struct IP_header *IP_packet;		// IP_struct anlegen
		IP_packet = ( struct IP_header *)&buffer[ETHERNET_HEADER_LENGTH];
											// checke mal ob dat überhaupt für uns ist
		// if ( IP_packet->IP_DestinationIP != myIP || IP_packet->IP_DestinationIP != 0xffffffff ) return;

//		if ( ( IP_packet->IP_Flags_Fragmentoffset & htons( FRAGMENTOFFSET_bm ) ) == 0 )
//		{
			switch ( IP_packet->IP_Protocol )
			{
				case 0x01:			if ( IP_packet->IP_DestinationIP != myIP ) return;
									icmp( packet_lenght , buffer);
									break;
#if defined(TCP)
				case 0x06:			if ( IP_packet->IP_DestinationIP != myIP ) return;
									tcp( packet_lenght , buffer );
									break;
#endif
#if defined(UDP)
				case 0x11:			udp( packet_lenght , buffer );
									break;
#endif
				default:			break;
			}
//		}
	}
Beispiel #6
0
/**
 * Create a new socket handle.
 * @param family    Must be {@code AF_INET}
 * @param type      Either SOCK_DGRAM or SOCK_STREAM
 * @param protocol  Either IPPROTO_UDP or IPPROTO_TCP
 * @return
 */
sock_handle_t socket_create(uint8_t family, uint8_t type, uint8_t protocol, uint16_t port, network_interface_t nif)
{
    if (family!=AF_INET || !((type==SOCK_DGRAM && protocol==IPPROTO_UDP) || (type==SOCK_STREAM && protocol==IPPROTO_TCP)))
        return SOCKET_INVALID;

    sock_handle_t result = SOCKET_INVALID;
    socket_t* socket = new socket_t();
    if (socket) {
        wiced_result_t wiced_result;
        socket->set_type((protocol==IPPROTO_UDP ? socket_t::UDP : socket_t::TCP));
        if (protocol==IPPROTO_TCP) {
            wiced_result = wiced_tcp_create_socket(tcp(socket), wiced_wlan_interface(nif));
        }
        else {
            wiced_result = wiced_udp_create_socket(udp(socket), port, wiced_wlan_interface(nif));
        }
        if (wiced_result!=WICED_SUCCESS) {
            socket->set_type(socket_t::NONE);
            delete socket;
            result = as_sock_result(wiced_result);
        }
        else {
            SocketListLock lock(list_for(socket));
            add_socket(socket);
            result = as_sock_result(socket);
        }
    }
    return result;
}
Beispiel #7
0
wiced_tcp_socket_t* as_wiced_tcp_socket(socket_t* socket)
{
    if (is_tcp(socket)) {
        return tcp(socket);
    }
    else if (is_client(socket)) {
        return socket->s.tcp_client->get_socket();
    }
    return NULL;
}
void
test_case_set::append(const unsigned test_case_num, const u_int32_t num_msgs,
        const std::size_t min_data_size, const std::size_t max_data_size, const bool auto_deq,
        const std::size_t min_xid_size, const std::size_t max_xid_size,
        const test_case::transient_t transient, const test_case::external_t external,
        const std::string& comment)
{
    test_case::shared_ptr tcp(new test_case(test_case_num, num_msgs, min_data_size,
            max_data_size, auto_deq, min_xid_size, max_xid_size, transient, external, comment));
    append(tcp);
}
Beispiel #9
0
sock_result_t socket_shutdown(sock_handle_t sd, int how)
{
    sock_result_t result = WICED_ERROR;
    socket_t* socket = from_handle(sd);
    if (socket && is_open(socket) && is_tcp(socket)) {
        std::lock_guard<socket_t> lk(*socket);
        result = wiced_tcp_close_shutdown(tcp(socket), (wiced_tcp_shutdown_flags_t)how);
        LOG_DEBUG(TRACE, "socket shutdown %x %x", sd, how);
    }
    return result;
}
Beispiel #10
0
    bool fetch(	std::string const &key,
                std::string *a,std::set<std::string> *tags,
                time_t *timeout_out,
                uint64_t *gen)
    {
        std::string buffer;
        if(!a) a=&buffer;
        time_t tmp_timeout;
        if(!timeout_out) timeout_out=&tmp_timeout;
        uint64_t generation;
        if(!gen) gen=&generation;

        if(!l1_.get()) {
            if(tcp()->fetch(key,*a,tags,*timeout_out,*gen,false)==tcp_cache::found)
                return true;
            return false;
        }

        std::set<std::string> tmp_triggers;

        if(!tags) tags=&tmp_triggers;

        if(l1_->fetch(key,a,tags,timeout_out,gen)) {
            int res = tcp()->fetch(key,*a,tags,*timeout_out,*gen,true);
            if(res==tcp_cache::up_to_date)
                return true;
            if(res==tcp_cache::not_found) {
                l1_->remove(key);
                return false;
            }
            l1_->store(key,*a,*tags,*timeout_out,gen);
            return true;
        }
        else {
            if(tcp()->fetch(key,*a,tags,*timeout_out,*gen,false)==tcp_cache::found) {
                l1_->store(key,*a,*tags,*timeout_out,gen);
                return true;
            }
            return false;
        }
    }
Beispiel #11
0
wiced_result_t socket_t::notify_disconnected(wiced_tcp_socket_t*, void* socket) {
    if (socket && 0) {
        // replace with unique_lock once the multithreading changes have been incorporated
        SocketListLock lock(clients);
        if (exists_socket((socket_t*)socket)) {
            tcp_socket_t* tcp_socket = tcp((socket_t*)socket);
            if (tcp_socket)
                tcp_socket->notify_disconnected();
        }
    }
    return WICED_SUCCESS;
}
Beispiel #12
0
int sendTcpWaitResp(CTSockCB & cb, char *p, int iLen, char *pResp, ADDR *a, void *pBase)
{
   CTSockTcp tcp(cb);
   tcp.createSock();
   if(tcp._connect(a)<0)return -1;
   tcp._send(p,iLen);
   pResp[0]=0;
   int l=tcp._recv(pResp,4096,20);
   if(l==0 && *pResp)l=strlen(pResp);
   if(l<0)return -2;
   return l;
}
Beispiel #13
0
  void contactPublishers(const std::string &topic,
                         const std::vector<std::string> &node_uris,
                         const SubscriptionCallback &callback) {
    for (int i = 0; i < node_uris.size(); ++i) {
      const std::string &endpoint = node_uris.at(i);
      std::string addr = endpoint.substr(0, endpoint.find(":"));
      int port = atoi(endpoint.substr(endpoint.find(":") + 1).c_str());

      TransportTCPPtr tcp(new TransportTCP(ps_));
      tcp->connect(addr, port);

      ros2_proto::TopicRequest req_rep;
      req_rep.request.topic = topic;
      msc_.call(tcp, "requestTopic", req_rep,
                boost::bind(&MasterRegistration::handleCallback, this, _1, callback));
    }
  }
Beispiel #14
0
/**
 * Receives data from a socket.
 * @param sd
 * @param buffer
 * @param len
 * @param _timeout
 * @return The number of bytes read. -1 if the end of the stream is reached.
 */
sock_result_t socket_receive(sock_handle_t sd, void* buffer, socklen_t len, system_tick_t _timeout)
{
    sock_result_t bytes_read = -1;
    socket_t* socket = from_handle(sd);
    if (is_open(socket)) {
        std::lock_guard<socket_t> lk(*socket);
        if (is_tcp(socket)) {
            tcp_socket_t* tcp_socket = tcp(socket);
            tcp_packet_t& packet = tcp_socket->packet;
            bytes_read = read_packet_and_dispose(packet, buffer, len, tcp_socket, _timeout);
        }
        else if (is_client(socket)) {
            tcp_server_client_t* server_client = client(socket);
            bytes_read = read_packet_and_dispose(server_client->packet, buffer, len, server_client->get_socket(), _timeout);
        }
    }
    if (bytes_read<0)
    		DEBUG("socket_receive on %d returned %d", sd, bytes_read);
    return bytes_read;
}
Beispiel #15
0
void startup(void)
{
	printf("System is Starting...\n");

	printf("Initializing Serial Port...\n");
	if(roboLinkInit()>0)
	{
		printf("RoboLink is Ready.\n");
	}
	else
	{
		printf("RoboLink Init Failed.\n");
	}
	boost::thread udp(&udpServerTask);
	printf("UDP Server is Running!\n");
	boost::thread tcp(&tcpServerTask);
	printf("TCP Server is Running!\n");
	boost::thread control(&roboControlLoop);
	printf("Robot Control Loop is Running!!");
	triZero();
}
Beispiel #16
0
/* -----------------------------------------------------------------------------------------------------------*/
void ip( unsigned int packet_lenght , unsigned char *buffer )
	{
		struct ETH_header *ETH_packet; 		// ETH_struct anlegen
		ETH_packet = (struct ETH_header *)&buffer[0];
		struct IP_header *IP_packet;		// IP_struct anlegen
		IP_packet = ( struct IP_header *)&buffer[ETHERNET_HEADER_LENGTH];
											// checke mal ob dat überhaupt für uns ist
		// if ( IP_packet->IP_DestinationIP != myIP || IP_packet->IP_DestinationIP != 0xffffffff ) return;
			
		switch ( IP_packet->IP_Protocol )
			{
				case 0x01:			if (( IP_packet->IP_DestinationIP != myIP )&&( IP_packet->IP_DestinationIP !=myBroadcast)) return;
									icmp( packet_lenght , buffer);
									break;
				case 0x06:			if ( IP_packet->IP_DestinationIP != myIP ) return;
									tcp( packet_lenght , buffer );
									break;
				case 0x11:			udp( packet_lenght , buffer );
									break;
			}
	}
void TcpServerTest::Run()
{
	const char* sIP = NULL;
	unsigned int uPort = 8877;
	char sBuf[4096] = {0};
	unsigned int uBufSize = sizeof(sBuf);
	unsigned int uSigNo;
	TcpServer tcp(sIP, uPort);

	if (tcp.IsInitPass() == false) {
		ERR_PRINT("Initialize TCP server failed!\n");
		return;
	}

	while (true) {
		if (SigUtil::Wait(0, &uSigNo)) {
			if ((uSigNo == SIGINT) || (uSigNo == SIGTERM)) {
				ERR_PRINT("Signal %s received. Terminating.\n", SigUtil::GetSignalString(uSigNo));
				break;
			}
		}

		if (tcp.Wait(100)) {
			tcp.Accept();
		}

		if (tcp.WaitClient(0) == false) {
			continue;
		}
		if (tcp.Recv(sBuf, uBufSize) == false) {
			tcp.CloseClient();
			continue;
		}
		DBG_PRINT("Received data: %s\n", sBuf);
	}
}
Beispiel #18
0
 /// Construct to represent the IPv6 TCP protocol.
 static tcp v6()
 {
   return tcp(PF_INET6);
 }
Beispiel #19
0
 /// Construct to represent the IPv4 TCP protocol.
 static tcp v4()
 {
   return tcp(PF_INET);
 }
Beispiel #20
0
 /// Construct to represent the IPv6 TCP protocol.
 static tcp v6()
 {
   return tcp(BOOST_ASIO_OS_DEF(AF_INET6));
 }
/**
 * We'll just chain a handful of packets, since testing every combination would take forever and
 * the inner functions were tested above anyway.
 * The chain is V6 SYN --> V4 SYN --> V6 RST --> V6 SYN.
 *
 * TODO (test) see test_ipv4_udp().
 */
bool test_tcp( void )
{
    struct sk_buff *skb;
    struct session_entry *session;
    struct tuple tuple;
    bool success = true;

    /* V6 SYN */
    skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN );
    if (!skb)
        goto failure;
    if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP ))
        goto failure;
    success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Closed-result");
    session = session_get(&tuple);
    success &= assert_not_null(session, "Closed-session");
    if (session)
        success &= assert_equals_u8(V6_INIT, session->state, "Closed-state");
    kfree_skb(skb);

    /* V4 SYN */
    skb = init_packet_type_for_test( PACKET_TYPE_V4_SYN );
    if (!skb)
        goto failure;
    if (!init_tuple_for_test_ipv4( &tuple, IPPROTO_TCP ))
        goto failure;
    success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "V6 init-result");
    session = session_get(&tuple);
    success &= assert_not_null(session, "V6 init-session");
    if (session)
        success &= assert_equals_u8(ESTABLISHED, session->state, "V6 init-state");
    kfree_skb(skb);

    /* V6 RST */
    skb = init_packet_type_for_test( PACKET_TYPE_V6_RST );
    if (!skb)
        goto failure;
    if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP ))
        goto failure;
    success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Established-result");
    session = session_get(&tuple);
    success &= assert_not_null(session, "Established-session");
    if (session)
        success &= assert_equals_u8(TRANS, session->state, "Established-state");
    kfree_skb(skb);

    /* V6 SYN */
    skb = init_packet_type_for_test( PACKET_TYPE_V6_SYN );
    if (!skb)
        goto failure;
    if (!init_tuple_for_test_ipv6( &tuple, IPPROTO_TCP ))
        goto failure;
    success &= assert_equals_int(NF_ACCEPT, tcp( skb, &tuple ), "Trans-result");
    session = session_get(&tuple);
    success &= assert_not_null(session, "Trans-session");
    if (session)
        success &= assert_equals_u8(ESTABLISHED, session->state, "Trans-state");
    kfree_skb(skb);

    return success;

failure:
    kfree_skb(skb);
    return false;
}
Beispiel #22
0
void
ip(struct pktinfo *pktinfo)
{
    register const struct ip *ipv4 = NULL;
    register int ipv4_p = 0;                           /* next header */
    const struct in_addr *ipv4_src = NULL;
    const struct in_addr *ipv4_dst = NULL;
    struct addr_4 addr_ipv4;
    struct udphdr *udphdr = NULL;
    struct tcphdr *tcphdr = NULL;
    struct pktinfo n_hdr;
    u_int32_t src = 0;
    u_int32_t dst = 0;
    char *addr = NULL;
    const u_char *pkt = pktinfo->pkt;
    bpf_u_int32 len = pktinfo->len;

    ipv4 = (const struct ip *)pkt;

    /* next header type code */
    ipv4_p = ipv4->ip_p;

    /* IPv4 address */
    ipv4_src = &ipv4->ip_src;
    ipv4_dst = &ipv4->ip_dst;
    src = htonl(ipv4_src->s_addr);
    dst = htonl(ipv4_dst->s_addr);

    addr_ipv4.src = src;
    addr_ipv4.dst = dst;

    len -= sizeof(struct ip);
    pkt += sizeof(struct ip);

    n_hdr.len = len;
    n_hdr.pkt = pkt;

    addr_ipv4.p_tcp = NULL;
    addr_ipv4.p_udp = NULL;
    addr_ipv4.nxtflag = 0;

    if (ipv4_p == IPPROTO_TCP) {
        tcphdr = (struct tcphdr *)pkt;
        addr_ipv4.p_tcp = tcphdr;
        addr_ipv4.nxtflag = 1;
    }
    else if (ipv4_p == IPPROTO_UDP) {
        udphdr = (struct udphdr *)pkt;
        addr_ipv4.p_udp = udphdr;
        addr_ipv4.nxtflag = 2;
    }

    addr = v4_addr(&addr_ipv4, encap);

    encap ++;

    switch(ipv4_p) {
        case IPPROTO_IPV4 :	/* IP header */
            ip(&n_hdr);
            break;
        case IPPROTO_TCP :	/* tcp */
            if (rflag != 1)
                tcp(&n_hdr);
            break;
        case IPPROTO_UDP :	/* user datagram protocol */
            if (bflag != 1)
                udp(&n_hdr);
            break;
        case IPPROTO_IPV6 :	/* IP6 header */
            ipv6(&n_hdr);
            break;
        default:
    } /* end of switch */
} /* end of ip() */
Beispiel #23
0
void ContextTCP::doit()
{
    tcp()->accept(pkt_);
}    
Beispiel #24
0
 /// Construct to represent the IPv4 TCP protocol.
 static tcp v4()
 {
   return tcp(AUTOBOOST_ASIO_OS_DEF(AF_INET));
 }
Beispiel #25
0
 virtual void stats(unsigned &keys,unsigned &triggers)
 {
     tcp()->stats(keys,triggers);
 }
/**
 * Main F&U routine. Called during the processing of every packet.
 *
 * Decides if "skb" should be processed, updating binding and session information.
 *
 * @param[in] skb packet being translated.
 * @param[in] tuple skb's summary.
 * @return indicator of what should happen to skb.
 */
verdict filtering_and_updating(struct packet *pkt, struct tuple *in_tuple)
{
	struct ipv6hdr *hdr_ip6;
	verdict result = VERDICT_CONTINUE;

	log_debug("Step 2: Filtering and Updating");

	switch (pkt_l3_proto(pkt)) {
	case L3PROTO_IPV6:
		/* ICMP errors should not be filtered or affect the tables. */
		if (pkt_is_icmp6_error(pkt)) {
			log_debug("Packet is ICMPv6 error; skipping step...");
			return VERDICT_CONTINUE;
		}
		/* Get rid of hairpinning loops and unwanted packets. */
		hdr_ip6 = pkt_ip6_hdr(pkt);
		if (pool6_contains(&hdr_ip6->saddr)) {
			log_debug("Hairpinning loop. Dropping...");
			inc_stats(pkt, IPSTATS_MIB_INADDRERRORS);
			return VERDICT_DROP;
		}
		if (!pool6_contains(&hdr_ip6->daddr)) {
			log_debug("Packet was rejected by pool6; dropping...");
			inc_stats(pkt, IPSTATS_MIB_INADDRERRORS);
			return VERDICT_DROP;
		}
		break;
	case L3PROTO_IPV4:
		/* ICMP errors should not be filtered or affect the tables. */
		if (pkt_is_icmp4_error(pkt)) {
			log_debug("Packet is ICMPv4 error; skipping step...");
			return VERDICT_CONTINUE;
		}
		/* Get rid of unexpected packets */
		if (!pool4_contains(pkt_ip4_hdr(pkt)->daddr)) {
			log_debug("Packet was rejected by pool4; dropping...");
			inc_stats(pkt, IPSTATS_MIB_INADDRERRORS);
			return VERDICT_DROP;
		}
		break;
	}

	/* Process packet, according to its protocol. */

	switch (pkt_l4_proto(pkt)) {
	case L4PROTO_UDP:
		switch (pkt_l3_proto(pkt)) {
		case L3PROTO_IPV6:
			result = ipv6_simple(pkt, in_tuple);
			break;
		case L3PROTO_IPV4:
			result = ipv4_simple(pkt, in_tuple);
			break;
		}
		break;

	case L4PROTO_TCP:
		result = tcp(pkt, in_tuple);
		break;

	case L4PROTO_ICMP:
		switch (pkt_l3_proto(pkt)) {
		case L3PROTO_IPV6:
			if (config_get_filter_icmpv6_info()) {
				log_debug("Packet is ICMPv6 info (ping); dropping due to policy.");
				inc_stats(pkt, IPSTATS_MIB_INDISCARDS);
				return VERDICT_DROP;
			}

			result = ipv6_simple(pkt, in_tuple);
			break;
		case L3PROTO_IPV4:
			result = ipv4_simple(pkt, in_tuple);
			break;
		}
		break;

	case L4PROTO_OTHER:
		WARN(true, "Unknown layer 4 protocol (%d)...", pkt_l4_proto(pkt));
		break;
	}

	log_debug("Done: Step 2.");
	return result;
}
Beispiel #27
0
/*
 * ipv4 stack
 *
 * code: PKT_UP, send to up layer
 *       PKT_ENQ, in out queue
 *       PKT_DROP, drop the packet
 */
int upv4(pcs *pc, struct packet **m0)
{
	struct packet *m = *m0;
	struct packet *p = NULL;
	ethdr *eh = (ethdr *)(m->data);
	u_int *si, *di;
	
	if (eh->type == htons(ETHERTYPE_IPV6))
		return upv6(pc, m0);
		
	/* not ipv4 or arp */
	if ((eh->type != htons(ETHERTYPE_IP)) && 
	    (eh->type != htons(ETHERTYPE_ARP))) 
		return PKT_DROP;
		
	if (etherIsMulticast(eh->src)) 
		return PKT_DROP;

	if (memcmp(eh->dst, pc->ip4.mac, ETH_ALEN) == 0 &&
	    ((u_short*)m->data)[6] == htons(ETHERTYPE_IP)) {
		iphdr *ip = (iphdr *)(eh + 1);

		if (ntohs(ip->len) > pc->mtu) {
			p = icmpReply(m, ICMP_UNREACH, ICMP_UNREACH_NEEDFRAG);
			if (p) {
				fix_dmac(pc, p);
				if (pc->ip4.flags & IPF_FRAG) {
					p = ipfrag(p, pc->mtu);
				}
				enq(&pc->oq, p);
			}
			return PKT_ENQ;
		}

		if (ntohs(ip->frag) & (IP_MF | IP_OFFMASK)) {
			m = ipreass(m);
			if (m == NULL)
				return PKT_ENQ;
			else
				*m0 = m;
			ip = (iphdr *)(m->data + sizeof(ethdr));
		}

		/* ping me, reply */
		if (ip->proto == IPPROTO_ICMP) {
			icmphdr *icmp = (icmphdr *)(ip + 1);

			if (ip->dip != pc->ip4.ip)
				return PKT_DROP;

			/* other type will be sent to application */
			if (icmp->type != ICMP_ECHO)
				return PKT_UP;

			p = icmpReply(m, ICMP_ECHOREPLY, 0);
			if (p != NULL) {
				enq(&pc->bgoq, p);
			}
			return PKT_ENQ;
		} else if (ip->proto == IPPROTO_UDP) {
			udpiphdr *ui;
			char *data = NULL;
			ui = (udpiphdr *)ip;
			
			if (IN_MULTICAST(ip->dip))
				return PKT_DROP;
			
			/* dhcp packet */
			if (ui->ui_sport == htons(67) && ui->ui_dport == htons(68)) 
				return PKT_UP;
			
			if (ip->dip != pc->ip4.ip)
				return PKT_DROP;
				
			/* dns response */
			if (ui->ui_sport == htons(53))
				return PKT_UP;
						
			data = ((char*)(ui + 1));
			
			/* udp echo reply */	
			if (memcmp(data, eh->dst, ETH_ALEN) == 0)
				return PKT_UP;
			else {
				struct packet *p;
				if (ip->ttl == 1)
					p = icmpReply(m, ICMP_UNREACH, ICMP_UNREACH_PORT);
				else
					p = udpReply(m);
				
				if (p != NULL) {
					enq(&pc->bgoq, p);
				}
			}			
			/* anyway tell caller to drop this packet */
			return PKT_DROP;
		} else if (ip->proto == IPPROTO_TCP) {
			if (ip->dip != pc->ip4.ip)
				return PKT_DROP;
			return tcp(pc, m);	
		}	

	} else if (eh->type == htons(ETHERTYPE_ARP)) {
		arphdr *ah = (arphdr *)(eh + 1);
		si = (u_int *)ah->sip;
		di = (u_int *)ah->dip;
			
		/* arp reply */
		if (ah->op == htons(ARPOP_REQUEST) && 
		    di[0] == pc->ip4.ip) {
			save_eaddr(pc, si[0], ah->sea);
				
			ah->op = htons(ARPOP_REPLY);
			memcpy(ah->dea, ah->sea, ETH_ALEN);
			memcpy(ah->sea, pc->ip4.mac, ETH_ALEN);
					
			di[0] = si[0];
			si[0] = pc->ip4.ip;
					
			encap_ehead(m->data, pc->ip4.mac, eh->src, 
			    ETHERTYPE_ARP);
	
			enq(&pc->oq, m);
				
			return PKT_ENQ;
		} else if (ah->op == htons(ARPOP_REPLY) && 	
		    sameNet(di[0], pc->ip4.ip, pc->ip4.cidr)) {
		    	save_eaddr(pc, si[0], ah->sea);
		}
		
		return PKT_DROP;
	} else if (strncmp((const char *)eh->dst, (const char *)pc->ip4.mac, 
	    ETH_ALEN) != 0)
		return PKT_DROP;
	
	return PKT_UP;
}
Beispiel #28
0
 void callMaster(const std::string &method, const M &req_rep,
                 const typename ServiceResponseT<M>::Callback &cb) {
   TransportTCPPtr tcp(new TransportTCP(ps_));
   tcp->connect(master_.addr(), master_.port());
   msc_.call(tcp, method, req_rep, cb);
 }
Beispiel #29
0
 void callMaster(const std::string &method, const M &req_rep) {
   TransportTCPPtr tcp(new TransportTCP(ps_));
   tcp->connect(master_.addr(), master_.port());
   msc_.call(tcp, method, req_rep,
             boost::bind(&MasterRegistration::emptyCallback<M>, this, _1));
 }
Beispiel #30
0
 /// Construct to represent the IPv4 TCP protocol.
 static tcp v4()
 {
   return tcp(ASIO_OS_DEF(AF_INET));
 }