Exemplo n.º 1
0
uint8_t OMMoCoNode::check() {



	uint8_t command = getPacket();

		// no packet available
	if( command == 0 )
		return(0);

		// command OM_SER_BASECOM is reserved for core protocol commands.
		// We handle these automatically for the node.

	if( ! isBroadcast() && command == OM_SER_BASECOM ) {
		_coreProtocol(this->buffer());
		return(0);
	}
	else {
		// we have a command code which is higher than 1,
		// send to the supplied handler.
		if( f_bcastHandler != 0 && isBroadcast() ) {
				// a callback is assigned, and this is a
				// broadcast command
			f_bcastHandler(command, this->buffer());
		}
		else if( f_cmdHandler != 0 && ! isBroadcast() ) {
				// a callback is assigned, call callback
				// with command code and payload
			f_cmdHandler(command, this->buffer());
		}
	}


	return(command);
}
Exemplo n.º 2
0
Socket::Error UDPTransmit::connect(const IPV4Broadcast &subnet, tpport_t  port)
{
	if(!isBroadcast())
		setBroadcast(true);

	return cConnect((IPV4Address)subnet,port);
}
Exemplo n.º 3
0
Socket::Error UDPTransmit::connect(const IPV4Host &ia, tpport_t port)
{
	if(isBroadcast())
		setBroadcast(false);

	return cConnect((IPV4Address)ia,port);
}
Exemplo n.º 4
0
bool ChannelData::canWrite() const {
	// Duplicated in Data::CanWriteValue().
	return amIn()
		&& (canPublish()
			|| (!isBroadcast()
				&& !restricted(Restriction::f_send_messages)));
}
Exemplo n.º 5
0
uint16_t Artnetnode::handleDMX(){
  if(isBroadcast()){
    return 0;
  }
  else{
    // Get universe
    uint16_t universe = artnetPacket[14] | artnetPacket[15] << 8;

    // Get DMX frame length
    uint16_t dmxDataLength = artnetPacket[17] | artnetPacket[16] << 8;


    for(int a = 0; a < DMX_MAX_OUTPUTS; a++){
      if(DMXOutputs[a][1] == universe){
        for (int i = 0 ; i < DMX_MAX_BUFFER ; i++){
          if(i < dmxDataLength){
            DMXBuffer[a][i] = artnetPacket[i+ARTNET_DMX_START_LOC];
          }
          else{
            DMXBuffer[a][i] = 0;
          }
        }
      }
    }

    return OpDmx;
  }
}
Exemplo n.º 6
0
uint16_t Artnetnode::handlePollRequest(){
  if(isBroadcast()){
    
    Udp.beginPacket(localBroadcast, ARTNET_PORT);
    Udp.write(PollReplyPacket.printPacket(), sizeof(PollReplyPacket.packet));
    Udp.endPacket();

    return OpPoll;
  }
  else{
    return 0;
  }
}
// get response with timeout -ignoring 
int OMMoCoMaster::_getResponse() {

		// if we sent a broadcast packet, do not look for a response
	if( isBroadcast() == true )
		return(1);
	
	unsigned long cur_tm = millis();

	// timeout if we don't get a response packet in
	// time

	uint8_t code = getPacket();
	while (code == 0) {
		if (millis() - cur_tm > OM_SER_MASTER_TIMEOUT)
			return -1;
		code = getPacket();
	}

	return code;
}
Exemplo n.º 8
0
bool Nequeo::Net::Sockets::IPAddress::isUnicast() const
{
	return !isWildcard() && !isBroadcast() && !isMulticast();
}
Exemplo n.º 9
0
bool IPAddress::isUnicast() const
{
	return !isWildcard() && !isBroadcast() && !isMulticast();
}
Exemplo n.º 10
0
void rxpacket(int sock) {
	Packet pkt;
	memset(&pkt, 0, sizeof(pkt));

	// using recvmsg
	int size;				  // size of the received data
	struct msghdr msg;
	memset(&msg,   0, sizeof(msg));
	struct sockaddr_in from;
	int fromlen=sizeof(from);
	msg.msg_name = &from;
	msg.msg_namelen = fromlen;

	char anciliary[2048];
	msg.msg_control = anciliary;
	msg.msg_controllen = sizeof(anciliary);

	struct iovec   iov[1];
	memset(iov,    0, sizeof(iov));
	iov[0].iov_base = &pkt.data;
	iov[0].iov_len  = sizeof(pkt.data);
	msg.msg_iov     = iov;
	msg.msg_iovlen  = 1;

	struct cmsghdr *cmsg;
	unsigned int ifindex;			  // interface index
	struct in_addr hdraddr;			  // destination IP address in IP header
	size = recvmsg(sock, &msg, 0);
	if (size == -1) {
		ASSERT(0);
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP,
			"cannot read data on socket, attempting recovery...");
		exit(1);
	}
	
	// verify packet size
	int sz = size - 4;
	if (sz<= 0 || (sz % sizeof(RipRoute)) != 0) {
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP,
			"Invalid RIP packet size");
		return;
	}
	int routes = sz / sizeof(RipRoute);
	
	int found = 0;
	for(cmsg = CMSG_FIRSTHDR(&msg); cmsg != NULL; cmsg = CMSG_NXTHDR(&msg, cmsg)) {
		if (cmsg->cmsg_level == IPPROTO_IP && cmsg->cmsg_type == IP_PKTINFO) {
			//    struct in_pktinfo {
			//        unsigned int   ipi_ifindex;  /* Interface index */
			//        struct in_addr ipi_spec_dst; /* Local address */
			//        struct in_addr ipi_addr;     /* Header Destination
			//                                        address */
			//    };
			hdraddr = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_addr;
			ifindex = ((struct in_pktinfo*)CMSG_DATA(cmsg))->ipi_ifindex;
			found = 1;
		}
	}
	if (!found)
		return;
		
	pkt.ip_source = ntohl(from.sin_addr.s_addr);
	pkt.ip_dest = ntohl(hdraddr.s_addr);
	pkt.if_index = ifindex;

	// is the source ip address one of our addresses?
	RcpInterface *rxif  = rcpFindInterface(shm, pkt.ip_source);
	if (rxif) {
		// on Linux, packets we send to the multicast group will be received back on the socket
		return;
	}

	char *cmd[] = {"", "request", "response"};
	rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP,
		"Receiving RIP packet of size %d, from %d.%d.%d.%d, destination %d.%d.%d.%d, RIP %s, protocol version %d",
		size,
		RCP_PRINT_IP(pkt.ip_source),
		RCP_PRINT_IP(pkt.ip_dest),
		cmd[(pkt.data.command <= 2) ? pkt.data.command: 0],
		pkt.data.version);


	// update neighbor list
	RipNeighbor *neigh = neighbors;
	while (neigh != NULL) {
		if (neigh->ip == pkt.ip_source) {
			neigh->rx_time = 0;
			break;
		}
		neigh = neigh->next;
	}
	if (neigh == NULL) {
		RipNeighbor *newneigh = malloc(sizeof(RipNeighbor));
		if (newneigh != NULL) {
			memset(newneigh, 0, sizeof(RipNeighbor));
			newneigh->ip = pkt.ip_source;
			newneigh->next = neighbors;
			neighbors = newneigh;
			neigh = newneigh;
		}
		else {
			ASSERT(0);
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_ERR, RLOG_FC_RIP,
				"cannot allocate memory, attempting recovery...");
			exit(1);
		}
	}

	// do we have a valid interface?
	rxif =rcpFindInterfaceByKIndex(shm, pkt.if_index);
	if (rxif == NULL) {
		neigh->errors++;
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid interface, dropping...");
		return;
	}


	// do we have a configured neighbor?
	RcpRipPartner *rxnetwork = NULL;
	RcpRipPartner *net;
	int i;
	for (i = 0, net = shm->config.rip_neighbor; i < RCP_RIP_NEIGHBOR_LIMIT; i++, net++) {
		if (!net->valid)
			continue;

		// matching both source and destination addresses
		if (net->ip == pkt.ip_source && rxif->ip == pkt.ip_dest) {
			rxnetwork = net;
			break;
		}
	}
	
	// if no configured neighbor was found, try to find a configured network
	if (rxnetwork == NULL)
		rxnetwork = find_network_for_interface(rxif);
			
	// no network or neighbor configured, just drop the packet
	if (rxnetwork == NULL) {
		neigh->errors++;
		// the network can get disabled while receiving packets
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid network or neighbor, dropping...");
		return;
	}

	
	// the source of the datagram must be on a directly-connected network
	if ((pkt.ip_source & rxif->mask) != (rxif->ip & rxif->mask)) {
		neigh->errors++;
		// interface ip addresses are changing dynamically via CLI
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid source IP address, dropping...");
		return;
	}
	
	// drop invalid command packets
	if (pkt.data.command > 2) {
		neigh->errors++;
		rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid RIP command, dropping...");
		return;
	}
	
	if (pkt.data.command == 1) {
		rxnetwork->req_rx++;
		// force a response in one second
		rxif->rip_timeout = 1;
		return;
	}
	else
		rxnetwork->resp_rx++;

	ASSERT(sizeof(RipAuthMd5) == sizeof(RipAuthSimple));
	ASSERT(sizeof(RipAuthSimple) == sizeof(RipRoute));

	RipRoute *ptr = &pkt.data.routes[0];
	int rt = 0;
	
	// if md5 auth configured, and the packet is missing the auth header, drop the packet
	if (rxif->rip_passwd[0] != '\0') {
		if (ptr->family != 0xffff ||  ntohs(ptr->tag) != 3) {
			neigh->md5_errors++;		
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   missing MD5 authentication header");
			return;
		}
	}
	
	// checking auth header and calculate md5
	if (ptr->family == 0xffff) {
		// we don't care about simple auth
		if (ntohs(ptr->tag) == 3 && rxif->rip_passwd[0] != '\0') {
			RipAuthMd5 *md5 = (RipAuthMd5 *) ptr;
			uint16_t offset = ntohs(md5->offset);
			uint32_t seq = ntohl(md5->seq);
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   MD5 auth offset %u, key id %d, auth_len %d, seq %u",
				offset,
				md5->key_id,
				md5->auth_len,
				ntohl(md5->seq));

			// check offset
			if ((offset + sizeof(RipRoute)) != size) {
				neigh->md5_errors++;		
				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid offset");
				return;
			}

			// check seq
			if (seq != 0 && seq < neigh->auth_seq) {
				neigh->md5_errors++;		
				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid sequence number");
				return;
			}
			neigh->auth_seq = seq;
			
			// calculate md5
			uint8_t secret[16];
			memset(secret, 0, 16);
			memcpy(secret, rxif->rip_passwd, strlen(rxif->rip_passwd));
			
			MD5_CTX context;
			uint8_t digest[16];
			MD5Init (&context);
			MD5Update (&context, (uint8_t *) &pkt, size - 16);
			MD5Update (&context, secret, 16);
			MD5Final (digest, &context);
#if 0
{
int i;		
uint8_t *p = digest;
printf("rx digest:\n");
for (i = 0; i < 16; i++,p++)
	printf("%02x ", *p);
printf("\n");
}
#endif
			// compare md5
			if (memcmp((uint8_t *) ptr + offset, digest, 16) != 0) {
				neigh->md5_errors++;		
				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid MD5 digest");
				return;
			}	
		}
		ptr++;
		rt++;
		routes--;	// the last route is the digest
	}		
	
	// parsing routes
	while (rt < routes) {
		uint32_t metric = ntohl(ptr->metric);
		uint32_t mask = ntohl(ptr->mask);
		uint32_t ip = ntohl(ptr->ip);
		uint32_t gw = ntohl(ptr->gw);
		
//		if (trace_prefix == 0 || 
//		      (trace_prefix != 0 && trace_prefix == ip)) {
//		      	if (gw == 0)
//				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP,
//					"   %d.%d.%d.%d/%d metric %u",
//					RCP_PRINT_IP(ip),
//					mask2bits(mask),
//					metric);
//			else
//				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP,
//					"   %d.%d.%d.%d/%d metric %u next hop %d.%d.%d.%d",
//					RCP_PRINT_IP(ip),
//					mask2bits(mask),
//					metric,
//					RCP_PRINT_IP(gw));
//		}
		
		// only AF_INET family is supported
		if (ntohs(ptr->family) != AF_INET) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid route family");
			goto next_element;
		}			

		// check destination for loopback addresses
		if (isLoopback(ip)) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid loopback route prefix");
			goto next_element;
		}			
		
		// check destination for broadcast addresses
		if (isBroadcast(ip)) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid broadcast route prefix");
			goto next_element;
		}			
		
		// check destination for multicast addresses
		if (isMulticast(ip)) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid multicast route prefix");
			goto next_element;
		}			
		
		

		// validate route metric
		else if (metric > 16 || metric == 0) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid metric");
			goto next_element;
		}		
		
		// validate route entry
		if (ip == 0 && mask == 0) {
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   received default route metric %d",
				metric);
		}
		else if (pkt.data.version == 2 && mask == 0) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid RIP route");
			goto next_element;
		}		
		else if (pkt.data.version == 1 && mask != 0) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid RIP route");
			goto next_element;
		}		
		
		// check if the mask is contiguous
		if (mask != 0 && !maskContiguous(mask)) {
			neigh->route_errors++;
			rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid mask");
			goto next_element;
		}		
		
		// validate next hop
		if (gw) {
			if (isLoopback(gw) || isMulticast(gw) || isBroadcast(gw)) {
				neigh->route_errors++;
				rcpLog(muxsock, RCP_PROC_RIP, RLOG_DEBUG, RLOG_FC_RIP, "   invalid next hop");
				goto next_element;
			}
		}		
		
		// manufacture mask for rip v1
		if (pkt.data.version == 1)
			mask = classMask(ip);
			
		// RFC metric = metric + interface cost
		// we assume a cost of 1 for each interface
		metric++;
		
		// add the route in the database
		if (metric < 16) {
//RFC
//- Setting the destination address to the destination address in the
//     RTE
//
//   - Setting the metric to the newly calculated metric (as described 
//     above)
//
//   - Set the next hop address to be the address of the router from which
//     the datagram came
//
//   - Initialize the timeout for the route.  If the garbage-collection
//     timer is running for this route, stop it (see section 3.6 for a
//     discussion of the timers)
//
//   - Set the route change flag
//
//   - Signal the output process to trigger an update (see section 3.8.1)

			// a next hop of 0 means send the packets to me
			if (gw == 0)
				gw = pkt.ip_source;
			ripdb_add(RCP_ROUTE_RIP, ip, mask, gw, metric, pkt.ip_source, rxif);
		}
		else {
			// a next hop of 0 means send the packets to me
			if (gw == 0)
				gw = pkt.ip_source;
			ripdb_delete(RCP_ROUTE_RIP, ip, mask, gw, pkt.ip_source);
		}
next_element:
		ptr++;
		rt++;
	}
}
Exemplo n.º 11
0
bool IPEndpoint::V4::isPublic () const
{
    return !isPrivate() && !isBroadcast() && !isMulticast();
}
Exemplo n.º 12
0
RoutingDecision_e routePacket(MacInfo_t *info)
{
    MosAddr *dst = &info->originalDst;

    // PRINTF("route: dst address=0x%04x, nexthop=0x%04x\n", dst->shortAddr, info->immedDst.shortAddr);
    // PRINTF("  localAddress=0x%04x\n", localAddress);

    if (IS_LOCAL(info)) {
        // fix root address if we are sending it to the root
        if (dst->shortAddr == MOS_ADDR_ROOT) {
            intToAddr(info->originalDst, rootAddress);
            // info->hoplimit = hopCountToRoot;
            info->hoplimit = MAX_HOP_COUNT;
        }
    } else {
//        PRINTF("route packet, addr=0x%04x port=%02x\n", dst->shortAddr, info->dstPort);
        uint8_t index = markAsSeen(info->immedSrc.shortAddr, false);
        if (index != 0xff) {
            uint32_t expectedTimeStart = 4000ul + MOTE_TIME_FULL * index + MOTE_TIME
                    + (IS_ODD_COLLECTOR ? MOTE_TIME_FULL * MAX_MOTES : 0);
            uint32_t expectedTimeEnd = expectedTimeStart + MOTE_TIME;
            uint32_t now = timeSinceFrameStart();
            if (now < expectedTimeStart || now > expectedTimeEnd) {
                TPRINTF("*** mote %#04x sends out of its time: expected at %lu (+0-512 ms), now %lu!\n",
                        motes[index].address, expectedTimeStart, now);
            }
        } else {
            if (timeSinceFrameStart() > 4000) {
                TPRINTF("*** unregistered sender!\n");
            }
        }
    }

    if (isLocalAddress(dst)) {
        INC_NETSTAT(NETSTAT_PACKETS_RECV, info->originalSrc.shortAddr);
        return RD_LOCAL;
    }
    if (isBroadcast(dst)) {
        fillLocalAddress(&info->immedSrc); // XXX
        if (!IS_LOCAL(info)){
            INC_NETSTAT(NETSTAT_PACKETS_RECV, info->originalSrc.shortAddr);
        }
        // don't forward broadcast packets
        return IS_LOCAL(info) ? RD_BROADCAST : RD_LOCAL;
    }

    // check if hop limit allows the packet to be forwarded
    if (!checkHoplimit(info)) {
        PRINTF("hoplimit reached!\n");
        return RD_DROP;
    }

    // fill address: may forward it
    fillLocalAddress(&info->immedSrc);

    if (dst->shortAddr == rootAddress) {
        if (isRoutingInfoValid()) {
            //PRINTF("using 0x%04x as nexthop to root\n", nexthopToRoot);
            if (!IS_LOCAL(info)) {
#if PRECONFIGURED_NH_TO_ROOT
                if (info->immedDst.shortAddr != localAddress) {
                    TPRINTF("Dropping, I'm not a nexthop for sender %#04x\n",
                            info->originalSrc.shortAddr);
                    INC_NETSTAT(NETSTAT_PACKETS_DROPPED_RX, EMPTY_ADDR);
                    return RD_DROP;
                }
#endif
                // if (info->hoplimit < hopCountToRoot){
                //     PRINTF("Dropping, can't reach host with left hopCounts\n");
                //     return RD_DROP;
                // } 
                TPRINTF("****** Forwarding a packet to root for %#04x!\n",
                        info->originalSrc.shortAddr);
                INC_NETSTAT(NETSTAT_PACKETS_FWD, nexthopToRoot);
                // delay a bit
                info->timeWhenSend = getSyncTimeMs() + randomNumberBounded(150);
            } else{
                //INC_NETSTAT(NETSTAT_PACKETS_SENT, nexthopToRoot);     // Done @ comm.c
            }
            info->immedDst.shortAddr = nexthopToRoot;
            return RD_UNICAST;
        } else {
            // PRINTF("root routing info not present or expired!\n");
            TPRINTF("DROP\n");
            return RD_DROP;
        }
    }

    if (IS_LOCAL(info)) {
        //INC_NETSTAT(NETSTAT_PACKETS_SENT, dst->shortAddr);        // Done @ comm.c
        // send out even with an unknown nexthop, makes sense?
        return RD_UNICAST;
    }
    return RD_DROP;
}