📄 ctpacketio.c
字号:
printf("tx_emitee: tos=%d g_opcode=%d seq=%d bcast=%s\n", bhdr->tbh_tos, Opcode, bhdr->tbh_seqnum, "false");
END_TRACE
nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);
tx_sendpacket(nbytes, 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
}
void
packetio_tx_qltlvResp(uint16_t thisSeqNum, tlv_desc_t *tlvDescr, size_t LtlvOffset)
{
}
/************************** C - T M E S S A G E S E N D E R **************************/
extern etheraddr_t uutMAC;
void
packetio_send_discover(uint16_t thisSeqNum, bool_t sendAck)
{
size_t nbytes;
topo_discover_header_t* dhdr;
// buf, src-addr, dst-addr, service-type, g_opcode, seq, B'cast
dhdr = fmt_base(g_txbuf, &g_hwaddr, &Etheraddr_broadcast, ToS_TopologyDiscovery, Opcode_Discover, thisSeqNum, TRUE);
nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);
dhdr->mh_gen = 0;
if (sendAck)
{
dhdr->mh_numstations = htons(1);
memcpy((void*)(dhdr+1),&uutMAC,sizeof(etheraddr_t));
nbytes += sizeof(etheraddr_t);
} else {
dhdr->mh_numstations = 0;
}
nbytes += sizeof(topo_discover_header_t);
tx_sendpacket(nbytes, thisSeqNum);
IF_TRACED(TRC_PACKET)
dbgprintf("tx_discover: seqnum = %d\n", thisSeqNum);
END_TRACE
}
void
packetio_send_query(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_Query, thisSeqNum, FALSE);
nbytes = sizeof(topo_ether_header_t) + sizeof(topo_base_header_t);
tx_sendpacket(nbytes, thisSeqNum);
IF_TRACED(TRC_PACKET)
dbgprintf("tx_query: seqnum = %d, dst= " ETHERADDR_FMT "\n",
thisSeqNum, ETHERADDR_PRINT(pDst));
END_TRACE
}
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;
IF_TRACED(TRC_PACKET)
dbgprintf("tx_emit: seqnum = %d, dst= " ETHERADDR_FMT ", numEmitees=%d\n",
thisSeqNum, ETHERADDR_PRINT(pDst), count);
END_TRACE
// 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);
}
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
}
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
}
/************************** M E S S A G E R E C E I V E R **************************/
/* Upcalled by event.c when receive ready condition on the socket.
* Validates the ether and base headers, and g_opcode types. */
void
packetio_recv_handler(int fd, void *state)
{
uint16_t thisSeqnum;
/* Read into the global g_rxbuf, and save the length in a global */
g_rcvd_pkt_len = osl_read(fd, g_rxbuf, RXBUFSZ);
if (g_rcvd_pkt_len <= 0)
die("packetio_recv_handler: error on read: %s\n", strerror(errno));
if (g_rcvd_pkt_len < sizeof(topo_ether_header_t))
{
warn("packetio_recv_handler: runt frame (%d bytes < %d); ignoring\n",
g_rcvd_pkt_len, sizeof(topo_ether_header_t));
return;
}
/* We set up all the (macro-ized) global header pointers here.
* Actually, this could be done once, at process init time... */
g_ethernet_hdr = (topo_ether_header_t*)(g_rxbuf);
g_base_hdr = (topo_base_header_t*)(g_ethernet_hdr + 1);
g_discover_hdr = (topo_discover_header_t*)(g_base_hdr + 1);
g_hello_hdr = (topo_hello_header_t*)(g_base_hdr + 1);
g_qltlv_hdr = (topo_qltlv_header_t*)(g_base_hdr + 1);
DEBUG({printf("packetio: received a packet; len=%d ",g_rcvd_pkt_len);})
/* check Ethernet header */
if (g_ethernet_hdr->eh_ethertype != TOPO_ETHERTYPE)
return;
/* It's a Topology protocol packet */
/* check Base header */
if (g_rcvd_pkt_len < sizeof(topo_ether_header_t) + sizeof(topo_base_header_t))
{
warn("packetio_recv_handler: frame with truncated Base 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));
return;
}
/* is this the right version for us? */
if (g_base_hdr->tbh_version != TOPO_VERSION)
{
warn("packetio_recv_handler: got version %d protocol frame; ignoring\n",
g_base_hdr->tbh_version);
return;
}
/* set global g_opcode */
g_opcode = (topo_opcode_t) g_base_hdr->tbh_opcode;
if (g_opcode < 0 || g_opcode >= Opcode_INVALID)
{
warn("packetio_recv_handler: g_opcode=%d is out of range; ignoring\n", g_opcode);
return;
}
thisSeqnum = ntohs(g_base_hdr->tbh_seqnum);
IF_DEBUG
printf("rcvd seqnum=%X\n",g_base_hdr->tbh_seqnum);
END_DEBUG
/* Is this frame intended for us?
* We want to receive frames with realdst == (our addr || bcast)
* or with g_opcode == Probe (to record them)
* or with g_opcode == Hello (to run the BAND load control) */
if (g_opcode != Opcode_Probe &&
g_opcode != Opcode_Hello &&
!ETHERADDR_EQUALS(&g_base_hdr->tbh_realdst, &g_hwaddr) &&
!ETHERADDR_IS_BCAST(&g_base_hdr->tbh_realdst))
return;
/* print the frame */
IF_TRACED(TRC_PACKET)
dbgprintf(ETHERADDR_FMT " " ETHERADDR_FMT " %s (seq=%d)\n",
ETHERADDR_PRINT(&g_ethernet_hdr->eh_src), ETHERADDR_PRINT(&g_ethernet_hdr->eh_dst),
Topo_opcode_names[g_opcode], thisSeqnum);
END_TRACE
/* check for illegal or malformed packets */
/* 1) destination must not be broadcast or multicast, unless this is
* a broadcast-valid g_opcode. */
if (ETHERADDR_IS_MCAST(&g_base_hdr->tbh_realdst) && !BCAST_VALID(g_opcode))
{
warn("packetio_recv_handler: broadcast of g_opcode %d (from realsrc=" ETHERADDR_FMT
") is illegal; dropping\n",
g_opcode, ETHERADDR_PRINT(&g_base_hdr->tbh_realdst));
return;
}
/* 2) only frames allowed sequence numbers should have them;
* and some must have them. */
if (thisSeqnum != 0 && !SEQNUM_VALID(g_opcode))
{
warn("packetio_recv_handler: g_opcode %d with seq=%u (from realsrc=" ETHERADDR_FMT
") is illegal; dropping\n",
g_opcode, thisSeqnum, ETHERADDR_PRINT(&g_base_hdr->tbh_realsrc));
return;
}
if (thisSeqnum == 0 && SEQNUM_REQUIRED(g_opcode))
{
warn("packetio_recv_handler: g_opcode %d (from realsrc=" ETHERADDR_FMT
"must have seqnum\n",
g_opcode, ETHERADDR_PRINT(&g_base_hdr->tbh_realsrc));
return;
}
/* Does this frame have a sequence number?
* If so, check it and maybe do retransmission. */
/* Of course, sequence numbers are XIDs in Discover packets,
* so it's not a retry-request.... save it as XID (in rx_discover), but otherwise ignore it */
if (/*thisSeqnum !=*/ 0)
{
if (g_opcode != Opcode_Discover)
{
/* does it match the one in our retransmission buffer? */
if (thisSeqnum == g_rtxseqnum)
{
tx_rtxpacket();
return;
}
/* do we expect any particular sequence number? */
if (g_rtxseqnum != 0)
{
if (thisSeqnum != SEQNUM_NEXT(g_rtxseqnum))
{
warn("packetio_recv_handler: mis-matched sequence number: "
"got %d, expecting %d; ignoring\n",
thisSeqnum, SEQNUM_NEXT(g_rtxseqnum));
return;
}
}
}
/* update our sequence number */
/* (actually, we leave this to the state machine since
* we want to ignore packets while in the Emitting state, without
* consuming their sequence numbers.)
*/
}
/* By this time, we are pretty sure the sequence number is valid, so save a global copy... */
g_sequencenum = thisSeqnum;
g_rtxseqnum = g_re_tx_len = 0;
/* Initialize a protocol-event to the default: evtPacketRcvd
* later validation routines might refine the event type to a
* particular packet type. */
g_this_event.evtType = evtPacketRcvd;
g_this_event.ssn = NULL;
g_this_event.isNewSession = FALSE;
g_this_event.isAckingMe = FALSE;
g_this_event.isInternalEvt = FALSE;
g_this_event.numDescrs = 0;
enum packet_verification_results pktValidity;
/* Otherwise, perform per-g_opcode validation */
switch (g_opcode)
{
case Opcode_Discover:
pktValidity = validate_discover();
break;
case Opcode_Hello:
pktValidity = validate_hello();
break;
case Opcode_Emit:
pktValidity = validate_emit();
break;
case Opcode_QueryLargeTlv:
pktValidity = validate_queryltlv();
break;
case Opcode_Reset:
pktValidity = VALID_PACKET;
g_this_event.evtType = evtResetRcvd;
break;
case Opcode_Probe:
case Opcode_ACK:
case Opcode_Query:
case Opcode_QueryResp:
case Opcode_Charge:
case Opcode_Flat:
case Opcode_QueryLargeTlvResp:
pktValidity = VALID_PACKET;
break;
case Opcode_Train: /* Ignore TRAIN packets completely (they are only for switches) */
case Opcode_INVALID:
default:
pktValidity = INVALID_PACKET;
break;
}
/* and run the packet up to the protocol state machines for processing. */
if (pktValidity == VALID_PACKET)
{
state_process_packet();
}
/* (invalid packets are ignored completely) */
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -