Next function is recv() and as we know is invoked whenever the routing agent receives a packet. Every Packet has a common header called hdr_cmn defined in common/packet.h. To access this header there is a macro like the one we defined before for our own packet type, and we use it at line 3. Line 4 does the same but in order to get IP header, hdr_ip, described in ip.h.
1: void
2: Protoname::recv(Packet* p, Handler* h) {
3: struct hdr_cmn* ch = HDR_CMN(p);
4: struct hdr_ip* ih = HDR_IP(p);
5:
6: if (ih->saddr() == ra_addr()) {
7: // If there exists a loop, must drop the packet
8: if (ch->num_forwards() > 0) {
9: drop(p, DROP_RTR_ROUTE_LOOP);
10: return;
11: }
12: // else if this is a packet I am originating, must add IP header
13: else if (ch->num_forwards() == 0)
14: ch->size() += IP_HDR_LEN;
15: }
16:
17: // If it is a protoname packet, must process it
18: if (ch->ptype() == PT_PROTONAME)
19: recv_protoname_pkt(p);
20: // Otherwise, must forward the packet (unless TTL has reached zero)
21: else {
22: ih->ttl_--;
23: if (ih->ttl_ == 0) {
24: drop(p, DROP_RTR_TTL);
25: return;
26: }
27: forward_data(p);
28: }
29: }
First thing we should do is to check we are not receiving a packet we sent ourselves. If that is the case we should drop the packet and return, as we do in lines 8-11. In addition, if the packet has been generated within the node (by upper layers of the node) we should add to packet's length the overhead that the routing protocol is adding (in bytes). We assume protoname works over IP, as it is shown in lines 13-14.
When the received packet is of type PT_PROTONAME then we will call recv_protoname_pkt() to process it (lines 18-19). If it is a data packet then we should forward it (if it is destined to other node) or to deliver it to upper layers (if it was a broadcast packet or was destined to ourself), unless TTL3 reached zero. Lines 21-28 do what we have just described making use of the forward_data() function.
You would have realized that the drop() function is used for dropping packets. Its aarguments are a pointer to the packet itself and a constant giving the reason for discarding it. There exist several of these constants. Uou can take a look at them in the file trace/cmu-trace.h.