static bool_t is_conflicting_ssn( session_t *ssn ) { if ((g_topo_session) && (g_topo_session->ssn_is_valid==TRUE) && /* if there already IS a topo-session, */ (ssn != g_topo_session) && /* and this is not the same session, */ (ssn->ssn_TypeOfSvc == ToS_TopologyDiscovery) && /* and this IS a topo-ssn Discover, */ /* and the real-addresses don't match, */ !(ETHERADDR_EQUALS(&ssn->ssn_mapper_real, &g_topo_session->ssn_mapper_real))) { /* then this is a conflicting Discover */ return TRUE; } return FALSE; }
/* This function locates an existing session that is associated with the passed-in address */ static session_t * find_session(etheraddr_t *this_addr) { session_t *ssn = &g_sessions[0]; int i; for (i=0; i < MAX_NUM_SESSIONS; ssn++, i++) { if ( (ssn->ssn_is_valid) && (ETHERADDR_EQUALS(&ssn->ssn_mapper_real, this_addr)) ) { DEBUG({printf("find_session returning session %d @ %X\n",i,(uint)ssn);}) return ssn; }
static bool_t is_acking_me(void) { etheraddr_t *p = (etheraddr_t*)(g_discover_hdr + 1); etheraddr_t *limit = (etheraddr_t*)(((char*)g_ethernet_hdr) + g_rcvd_pkt_len); uint16_t gen = ntohs(g_discover_hdr->mh_gen); uint16_t numstations = ntohs(g_discover_hdr->mh_numstations); bool_t acking = FALSE; int i; if (g_this_event.isAckingMe == TRUE) return TRUE; IF_TRACED(TRC_PACKET) dbgprintf("gen=%d, numsta=%d, stations=[", gen, numstations); END_TRACE /* parse seenlist, and decide if we are acked in this frame */ for (i=0; p+1 <= limit && i<numstations; i++, p++) { IF_TRACED(TRC_PACKET) dbgprintf(ETHERADDR_FMT " ", ETHERADDR_PRINT(p)); END_TRACE if (ETHERADDR_EQUALS(p, &g_hwaddr)) { acking = TRUE; /* we could break out early, but we also want to test the * numstations count is accurate so we loop over all the * acked addresses */ } } IF_TRACED(TRC_PACKET) dbgprintf("]\n"); END_TRACE if (i != numstations) warn("rx_discover: truncated frame: ended at station %d, " "but numstations claimed %d\n", i, numstations); return acking; }
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; }