Пример #1
0
/* sent the retransmit buffer */
static void
tx_rtxpacket(void)
{
    assert(g_rtxseqnum != 0);
    IF_TRACED(TRC_PACKET)
	dbgprintf("packetio_recv_handler: retranmitting response with seqnum=%d\n", g_rtxseqnum);
    END_TRACE

    tx_write(g_re_txbuf, g_re_tx_len);    
}
Пример #2
0
void
packetio_tx_emitee(topo_emitee_desc_t *ed)
{
    topo_opcode_t        Opcode;
    size_t               nbytes;
    topo_ether_header_t *ehdr = (topo_ether_header_t*) g_txbuf;
    topo_base_header_t  *bhdr = (topo_base_header_t*)  (ehdr + 1);

    Opcode = (ed->ed_type == 0x00) ? Opcode_Train : Opcode_Probe;
    
    ehdr->eh_src = ed->ed_src;
    ehdr->eh_dst = ed->ed_dst;
    ehdr->eh_ethertype = TOPO_ETHERTYPE;
    
    bhdr->tbh_version = TOPO_VERSION;
    bhdr->tbh_tos = (uint8_t)ToS_TopologyDiscovery;
    bhdr->tbh_opcode = (uint8_t)Opcode;
    bhdr->tbh_realsrc = g_hwaddr;
    bhdr->tbh_realdst = ed->ed_dst;
    bhdr->tbh_seqnum = htons(0);

#ifdef  __DEBUG__
    IF_TRACED(TRC_PACKET)
        printf("tx_emitee: src=" ETHERADDR_FMT "\n", ETHERADDR_PRINT(&ehdr->eh_src));
        printf("tx_emitee: dst=" ETHERADDR_FMT "\n", ETHERADDR_PRINT(&ehdr->eh_dst));
        printf("tx_emitee: real-src=" ETHERADDR_FMT "\n", ETHERADDR_PRINT(&bhdr->tbh_realsrc));
        printf("tx_emitee: tos=%d g_opcode=%d seq=%d bcast=%s\n", bhdr->tbh_tos, Opcode, bhdr->tbh_seqnum, "false");
    END_TRACE
#endif

    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);

    tx_sendpacket(nbytes, 0);

#ifdef  __DEBUG__
    IF_TRACED(TRC_PACKET)
	dbgprintf("tx_emitee: %s " ETHERADDR_FMT " -> " ETHERADDR_FMT "\n",
		Topo_opcode_names[g_opcode],
		ETHERADDR_PRINT(&ed->ed_src), ETHERADDR_PRINT(&ed->ed_dst));
    END_TRACE
#endif
}
Пример #3
0
void
packetio_send_reset(etheraddr_t* pDst)
{
    size_t			nbytes;

//             buf,    src-addr, dst-addr,      service-type,        g_opcode,   seq,  B'cast
    fmt_base(g_txbuf, &g_hwaddr, pDst,    ToS_TopologyDiscovery, Opcode_Reset,  0,   FALSE);
    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);

    tx_sendpacket(nbytes, 0);

    IF_TRACED(TRC_PACKET)
        dbgprintf("tx_reset: dst= " ETHERADDR_FMT "\n", ETHERADDR_PRINT(pDst));
    END_TRACE
}
Пример #4
0
void
packetio_send_charge(uint16_t thisSeqNum, etheraddr_t* pDst)
{
    size_t			nbytes;

//             buf,    src-addr, dst-addr,      service-type,        g_opcode,     seq,      B'cast
    fmt_base(g_txbuf, &g_hwaddr, pDst,    ToS_TopologyDiscovery, Opcode_Charge, thisSeqNum, FALSE);
    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);

    tx_sendpacket(nbytes, thisSeqNum);

    IF_TRACED(TRC_PACKET)
        dbgprintf("tx_charge: seqnum = %d, dst= " ETHERADDR_FMT "\n",
                   thisSeqNum, ETHERADDR_PRINT(pDst));
    END_TRACE
}
Пример #5
0
void
packetio_tx_ack(uint16_t thisSeqNum)
{
    size_t nbytes;

    fmt_base(g_txbuf, &g_hwaddr, &g_topo_session->ssn_mapper_real, ToS_TopologyDiscovery,
             Opcode_ACK, thisSeqNum, FALSE /*g_topo_session->ssn_use_broadcast*/);
    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);

    tx_sendpacket(nbytes, thisSeqNum);

    IF_TRACED(TRC_PACKET)
	dbgprintf("tx_ack: %d -> " ETHERADDR_FMT "\n",
		thisSeqNum, ETHERADDR_PRINT(&g_topo_session->ssn_mapper_real));
    END_TRACE
}
Пример #6
0
static uint
validate_queryltlv()
{
    if (g_rcvd_pkt_len < sizeof(topo_ether_header_t) + sizeof(topo_base_header_t) + sizeof(topo_qltlv_header_t))
    {
	warn("query-ltlv-rcvd: frame with truncated qltlv header (len=%d src="
	     ETHERADDR_FMT " dst=" ETHERADDR_FMT "); ignoring\n",
	     g_rcvd_pkt_len, ETHERADDR_PRINT(&g_ethernet_hdr->eh_src), ETHERADDR_PRINT(&g_ethernet_hdr->eh_dst));
        g_this_event.evtType =  evtInvalidPacket;
	return INVALID_PACKET;
    }

    IF_TRACED(TRC_PACKET)
	dbgprintf("query-ltlv-rcvd: tlv# %d  offset: %d\n", g_qltlv_hdr->qh_type, g_qltlv_hdr->qh_offset);
    END_TRACE

    g_this_event.evtType =  evtPacketRcvd;
    return VALID_PACKET;
}
Пример #7
0
static int
write_lg_icon_t(int number, void *data, uint8_t *buf, int bytes_free, bool_t isHello, bool_t isLarge, size_t offset)
{
    lg_icon_t* icon = (lg_icon_t*) data;
    int          num_read;
    off_t        curOffset;
    int          remaining;

#ifdef  __DEBUG__
    IF_TRACED(TRC_TLVINFO)
        printf("write-lg_icon: tlvnum:%d  isHello:%s  isLarge:%s  offset:" FMT_SIZET "\n",
               number, isHello==TRUE?"true":"false", isLarge==TRUE?"true":"false", offset);
    END_TRACE
#endif

    if (icon->fd_icon < 0)
    {
        DEBUG({printf("write-lg_icon: No icon FD, nothing written\n");})
	return 0;	// No jumbo icon was correctly declared.
Пример #8
0
static uint
validate_hello()
{
    if (g_rcvd_pkt_len < sizeof(topo_ether_header_t) + sizeof(topo_base_header_t) + sizeof(topo_hello_header_t) + 1)
    {
	warn("rx_hello: frame with truncated Hello header (len=%d src="
	     ETHERADDR_FMT " dst=" ETHERADDR_FMT "); ignoring\n",
	     g_rcvd_pkt_len, ETHERADDR_PRINT(&g_ethernet_hdr->eh_src), ETHERADDR_PRINT(&g_ethernet_hdr->eh_dst));
        g_this_event.evtType =  evtInvalidPacket;
	return INVALID_PACKET;
    }

    IF_TRACED(TRC_PACKET)
	uint16_t gen = ntohs(g_hello_hdr->hh_gen);

	dbgprintf("hello-rcvd: gen=%d mapper=" ETHERADDR_FMT "\n",
		gen, ETHERADDR_PRINT(&g_hello_hdr->hh_curmapraddr));
    END_TRACE

    g_this_event.evtType =  evtPacketRcvd;
    return VALID_PACKET;
}
Пример #9
0
void
packetio_tx_queryresp(void)
{
    topo_queryresp_header_t *qr;
    topo_recvee_desc_t *p;
    size_t nbytes, bytes_left;

    qr = fmt_base(g_txbuf, &g_hwaddr, &g_topo_session->ssn_mapper_real, ToS_TopologyDiscovery, Opcode_QueryResp,
		  g_sequencenum, FALSE /*g_topo_session->ssn_use_broadcast*/);

    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t) +
	sizeof(topo_queryresp_header_t);
    bytes_left = TOPO_MAX_FRAMESZ - nbytes;
    qr->qr_numdescs = 0;
    p = (topo_recvee_desc_t*)(qr + 1);

    while ((bytes_left >= sizeof(topo_recvee_desc_t)) &&
	   seeslist_dequeue(p))
    {
	p++;
	bytes_left -= sizeof(topo_recvee_desc_t);
	nbytes += sizeof(topo_recvee_desc_t);
	qr->qr_numdescs++;
    }

    /* any more to follow? */
    if (!seeslist_is_empty())
	qr->qr_numdescs |= 0x8000; /* set the M (more) bit */

    qr->qr_numdescs = htons(qr->qr_numdescs);

    tx_sendpacket(nbytes, g_sequencenum);

#ifdef  __DEBUG__
    IF_TRACED(TRC_PACKET)
	dbgprintf("tx_queryresp: -> " ETHERADDR_FMT "\n", ETHERADDR_PRINT(&g_topo_session->ssn_mapper_real));
    END_TRACE
#endif
}
Пример #10
0
static
enum sm_Status
smS_NascentHandler  ( protocol_event_t *evt )
{
    IF_TRACED(TRC_STATE)
        printf("smS (Nascent): Entered with event %s",smEvent_names[evt->evtType]);
        if (g_this_event.evtType==evtPacketRcvd)
        {
            printf(" (%s)\n",Topo_opcode_names[g_opcode]);
        } else {
            puts("");
        }
    END_TRACE

    switch (evt->evtType)
    {
      case evtDiscoverRcvd:
        /* The first Topo ssn is the definitive one */
/**/    DEBUG({printf("session's ToS is %s %d\n",Lld2_tos_names[evt->ssn->ssn_TypeOfSvc],evt->ssn->ssn_TypeOfSvc);})
        if ((evt->ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) &&
            ((g_topo_session == NULL) || (g_topo_session->ssn_is_valid==FALSE)))
        {
/**/        DEBUG({printf("noting new TOPO session @ %X\n",(uint)evt->ssn);})
Пример #11
0
void
packetio_send_emit(uint16_t thisSeqNum, etheraddr_t* pDst, uint16_t emiteeCnt)
{
    size_t			nbytes;
    topo_emit_header_t	       *emithdr;
    topo_emitee_desc_t	       *pEmitee;
    topo_emitee_desc_t		emitee;
    etheraddr_t			OUI_hwaddr = {{0x00,0x0d,0x3a,0xd7,0xf1,0x50}};

    uint	count = emiteeCnt;

#ifdef  __DEBUG__
    IF_TRACED(TRC_PACKET)
        dbgprintf("tx_emit: seqnum = %d, dst= " ETHERADDR_FMT ", numEmitees=%d\n",
                   thisSeqNum, ETHERADDR_PRINT(pDst), count);
    END_TRACE
#endif

//					    buf,    src-addr, dst,  service-type,        g_opcode,       seq,     B'cast
    emithdr = (topo_emit_header_t*)fmt_base(g_txbuf,&g_hwaddr,pDst,ToS_TopologyDiscovery,Opcode_Emit,thisSeqNum,FALSE);
    emithdr->eh_numdescs = htons(emiteeCnt);
    nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t) + sizeof(topo_emit_header_t);

    pEmitee = (topo_emitee_desc_t*)(emithdr+1);
    emitee.ed_type  = 0;
    emitee.ed_pause = 3;
    memcpy(&emitee.ed_src,&OUI_hwaddr,sizeof(etheraddr_t));
    memcpy(&emitee.ed_dst,&OUI_hwaddr,sizeof(etheraddr_t));

    for (; emiteeCnt>0; emiteeCnt--)
    {
        memcpy(pEmitee,&emitee,sizeof(topo_emitee_desc_t));
        pEmitee++;
        nbytes += sizeof(topo_emitee_desc_t);
    }
    tx_sendpacket(nbytes, thisSeqNum);
}
Пример #12
0
static
void
ChargeConsume(int pktlen)
{
    struct timeval now;

    if (g_ctc_packets)
        g_ctc_packets--;

    if (g_ctc_bytes)
        g_ctc_bytes -= pktlen;

    IF_TRACED(TRC_CHARGE)
	dbgprintf("ChargeConsume: CTC now has bytes=" FMT_UINT32 " & packets=" FMT_UINT32 "\n",
		g_ctc_bytes, g_ctc_packets);
    END_TRACE

    /* Reset charge timer */

    gettimeofday(&now, NULL);
    timeval_add_ms(&now, TOPO_CHARGE_TIMEOUT);
    CANCEL(g_charge_timer);
    g_charge_timer = event_add(&now, state_charge_timeout, /*state:*/NULL);
}
Пример #13
0
static uint
validate_emit()
{
    topo_emit_header_t      *emit;	/* pointer to emit header in g_rxbuf */
    topo_emitee_desc_t *ed, *first_desc, *limit;
    uint16_t numdescs;
    int      i;

    /* Parse the Emit */
    g_totalPause = 0;
    g_neededPackets = 0;
    g_neededBytes = 0;

    if (g_rcvd_pkt_len < sizeof(topo_ether_header_t) + sizeof(topo_base_header_t) + 
	sizeof(topo_emit_header_t))
    {
	warn("validate_emit: frame with truncated Emit header (len=%d src="
	     ETHERADDR_FMT " dst=" ETHERADDR_FMT "); ignoring\n",
	     g_rcvd_pkt_len, ETHERADDR_PRINT(&g_ethernet_hdr->eh_src), ETHERADDR_PRINT(&g_ethernet_hdr->eh_dst));
        g_this_event.evtType =  evtInvalidPacket;
	return INVALID_PACKET;
    }

    emit = (topo_emit_header_t*)(g_base_hdr + 1);	// base the emit header in g_rxbuf

    numdescs = ntohs(emit->eh_numdescs);
    limit = (topo_emitee_desc_t*)(((uint8_t*)g_ethernet_hdr) + g_rcvd_pkt_len);

    /* check the emitee_descs are asking for reasonable transmissions */
    first_desc = (topo_emitee_desc_t*)(emit + 1);

    IF_TRACED(TRC_PACKET)
	dbgprintf("numdescs=%d EmiteeDescs=[", numdescs);
    END_TRACE

    for (i=0, ed=first_desc; ed+1 <= limit && i < numdescs; ed++, i++)
    {
	IF_TRACED(TRC_PACKET)
	    dbgprintf("{%s: %dms " ETHERADDR_FMT " -> " ETHERADDR_FMT "} ",
		    ed_type2name(ed->ed_type), ed->ed_pause,
		    ETHERADDR_PRINT(&ed->ed_src), ETHERADDR_PRINT(&ed->ed_dst));
        END_TRACE

	g_totalPause += ed->ed_pause;

	if (ed->ed_type != 0x00 && ed->ed_type != 0x01)
	{
	    warn("validate_emit: emitee_desc from " ETHERADDR_FMT " with unknown type=%d; "
		 "ignoring whole Emit request\n",
		 ETHERADDR_PRINT(&g_ethernet_hdr->eh_src), ed->ed_type);
            g_this_event.evtType =  evtInvalidPacket;
	    return INVALID_PACKET;
	}
	
	if (!ETHERADDR_EQUALS(&ed->ed_src, &g_hwaddr) &&
	    !TOPO_ETHERADDR_OUI(&ed->ed_src))
	{
	    warn("validate_emit: emitee_desc with src=" ETHERADDR_FMT " is invalid; "
		 "ignoring whole Emit request\n",
		 ETHERADDR_PRINT(&ed->ed_src));
            g_this_event.evtType =  evtInvalidPacket;
	    return INVALID_PACKET;
	}
	
	if (ETHERADDR_IS_MCAST(&ed->ed_dst))
	{
	    warn("validate_emit: emitee_desc with dst=" ETHERADDR_FMT " is invalid; "
		 "ignoring whole Emit request\n",
		 ETHERADDR_PRINT(&ed->ed_dst));
            g_this_event.evtType =  evtInvalidPacket;
	    return INVALID_PACKET;
	}

	g_neededPackets++;
	g_neededBytes += sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);
    }

    IF_TRACED(TRC_PACKET)
	dbgprintf("]");
	if (i != numdescs)
	    dbgprintf(" (numdescs too big!)");
	dbgprintf("\n");
    END_TRACE

    if (g_totalPause > TOPO_TOTALPAUSE_MAX)
    {
	warn("validate_emit: Emit contains emitee_descs with total pausetime %ums > %ums; "
	     "ignoring whole Emit request\n",
	     g_totalPause, TOPO_TOTALPAUSE_MAX);
        g_this_event.evtType =  evtInvalidPacket;
	return INVALID_PACKET;
    }

    if (i != numdescs)
    {
	warn("validate_emit: numdescs=%d but only %d descs in frame\n", numdescs, i);
	numdescs = i;
    }

    /* will we need to send an ACK or Flat too? */
    if (g_sequencenum != 0)
    {
	g_neededPackets++;
	g_neededBytes += sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);
    }

    /* emitee_descs look ok; pass them up to state machine */

    g_this_event.numDescrs = numdescs;
    g_this_event.evtType =  evtEmitRcvd;
    return VALID_PACKET;
}
Пример #14
0
uint
state_process_packet()
{
    session_t           *this_session;
    enum sm_Status       smStatus;

#ifdef  __DEBUG__
    IF_TRACED((TRC_STATE|TRC_PACKET))
        printf("state_process_packet: Entered with event %s",smEvent_names[g_this_event.evtType]);
        if (g_this_event.evtType==evtPacketRcvd)
        {
            printf(" (%s)\n",Topo_opcode_names[g_opcode]);
        } else {
            puts("");
        }
    END_TRACE
#endif

    g_this_event.isInternalEvt = FALSE;	// It's a real event, not internally generated

    /* First, look this RealSrc up in the session table, to
     * locate any association with an established session.
     *
     * If there is no matching session, create a new one, iff the
     * packet is a valid Discover of either topo- or quick- TOS ... */

    g_this_event.isNewSession = FALSE;

    if ((this_session = find_session(&g_base_hdr->tbh_realsrc)) == NULL)
    {
        /* Not found: Check for a Discovery packet (validated in packetio.c) */
        if (g_opcode == Opcode_Discover)
        {
            /* Create a new session for this association */
            if ((this_session = new_session()) == NULL)
            {
                /* No room in the table: drop the packet and whine. */
                warn("state_process_packet: no room to create new session. Packet dropped.\n");
                return UINT_MAX;
            }
            g_this_event.isNewSession = TRUE;

            /* Fill in the newly valid session table entry with info from the packet */
            this_session->ssn_XID            = g_sequencenum;
            this_session->ssn_mapper_real    = g_base_hdr->tbh_realsrc;
            this_session->ssn_mapper_current = g_ethernet_hdr->eh_src;
            this_session->ssn_TypeOfSvc      = g_base_hdr->tbh_tos;
#ifdef  __DEBUG__
            IF_TRACED(TRC_STATE)
                printf("New Session:\n\tXID = %X\n\treal address: " ETHERADDR_FMT \
                       "\n",this_session->ssn_XID, \
                       ETHERADDR_PRINT(&this_session->ssn_mapper_real) );

                printf("\tcurrent address: " ETHERADDR_FMT "\n\tToS: %s\n",
                       ETHERADDR_PRINT(&this_session->ssn_mapper_current),
                       Lld2_tos_names[this_session->ssn_TypeOfSvc] );
            END_TRACE
#endif
            g_this_event.ssn = this_session;

        }   /*** end of if (g_opcode == Opcode_Discover) ***/

        /* Probes are forced to associate with the mapping session, if there is one. */
        if (g_opcode == Opcode_Probe)
        {
             if (g_topo_session != NULL  &&  g_topo_session->ssn_is_valid)
             {
                this_session = g_topo_session;
             }
        }

    }   /*** endo of if (find_session()==NULL) ***/

    /* We have associated whatever session that we can with this packet - pass to state machines */
    g_this_event.ssn = this_session;

    smStatus = smS_process_event( &g_this_event );

    if (smStatus != PROCESSING_ABORTED)
    {
        smStatus = smE_process_event( &g_this_event );
    }

    if (smStatus != PROCESSING_ABORTED)
    {
        smStatus = smT_process_event( &g_this_event );
    }

    /* Remove any "new-session" marking */
    g_this_event.isNewSession = FALSE;

#ifdef  __DEBUG__
    IF_TRACED(TRC_PACKET)
        printf("state_process_packet: Leaving - done with event %s\n",smEvent_names[g_this_event.evtType]);
    END_TRACE
#endif
    return 0;	/* Success! */
}