/* Function Name: EIGRP packet header configuration. Description: This function configures and sends the EIGRP packet header. Targets: N/A */ int eigrp(const socket_t fd, const struct config_options *o) { size_t greoptlen, /* GRE options size. */ eigrp_tlv_len, /* EIGRP TLV size. */ packet_size, offset, counter; in_addr_t dest; /* EIGRP Destination address */ uint32_t prefix; /* EIGRP Prefix */ /* Packet and Checksum. */ mptr_t buffer; /* Socket address and IP header. */ struct sockaddr_in sin; struct iphdr * ip; /* EIGRP header. */ struct eigrp_hdr * eigrp; assert(o != NULL); greoptlen = gre_opt_len(o->gre.options, o->encapsulated); prefix = __RND(o->eigrp.prefix); eigrp_tlv_len = eigrp_hdr_len(o->eigrp.opcode, o->eigrp.type, prefix, o->eigrp.auth); packet_size = sizeof(struct iphdr) + greoptlen + sizeof(struct eigrp_hdr) + eigrp_tlv_len; /* Try to reallocate packet, if necessary */ alloc_packet(packet_size); /* IP Header structure making a pointer to Packet. */ ip = ip_header(packet, packet_size, o); /* GRE Encapsulation takes place. */ gre_encapsulation(packet, o, sizeof(struct iphdr) + sizeof(struct eigrp_hdr) + eigrp_tlv_len); /* * Please, be advised that there is no deep information about EIGRP, no * other than EIGRP PCAP files public available. Due to that I have done * a deep analysis using live EIGRP PCAP files to build the EIGRP Packet. * * There are some really good resources, such as: * http://www.protocolbase.net/protocols/protocol_EIGRP.php * http://packetlife.net/captures/category/cisco-proprietary/ * http://oreilly.com/catalog/iprouting/chapter/ch04.html * * EIGRP Header structure. */ eigrp = (struct eigrp_hdr *)((void *)ip + sizeof(struct iphdr) + greoptlen); eigrp->version = o->eigrp.ver_minor ? o->eigrp.ver_minor : EIGRPVERSION; eigrp->opcode = __RND(o->eigrp.opcode); eigrp->flags = htonl(__RND(o->eigrp.flags)); eigrp->sequence = htonl(__RND(o->eigrp.sequence)); eigrp->acknowledge = o->eigrp.type == EIGRP_TYPE_SEQUENCE ? htonl(__RND(o->eigrp.acknowledge)) : 0; eigrp->as = htonl(__RND(o->eigrp.as)); eigrp->check = 0; offset = sizeof(struct eigrp_hdr); buffer.ptr = (void *)eigrp + offset; /* * Every live EIGRP PCAP file brings Authentication Data TLV first. * * The Authentication Data TVL must be used only in some cases: * 1. IP Internal or External Routes TLV for Update * 2. Software Version with Parameter TLVs for Hello * 3. Next Multicast Sequence TLV for Hello */ if (o->eigrp.auth) { if (o->eigrp.opcode == EIGRP_OPCODE_UPDATE || (o->eigrp.opcode == EIGRP_OPCODE_HELLO && (o->eigrp.type == EIGRP_TYPE_MULTICAST || o->eigrp.type == EIGRP_TYPE_SOFTWARE))) { /* NOTE: stemp used to avoid multiple comparisons on loop below */ size_t stemp; stemp = auth_hmac_md5_len(o->eigrp.auth); /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * Authentication Data TLV (EIGRP Type = 0x0002) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | Authentication Method | Authentication Key Size | * +---------------------------------------------------------------+ * | Authentication Key ID | * +---------------------------------------------------------------+ * | | * + + * | Padding (?) | * + + * | | * +---------------------------------------------------------------+ * | | * + + * | Authentication Key Block | * + (MD5 Digest) + * | | * + + * | | * +---------------------------------------------------------------+ */ *buffer.word_ptr++ = htons(EIGRP_TYPE_AUTH); *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : EIGRP_TLEN_AUTH); *buffer.word_ptr++ = htons(AUTH_TYPE_HMACMD5); *buffer.word_ptr++ = htons(stemp); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.key_id)); for (counter = 0; counter < EIGRP_PADDING_BLOCK; counter++) *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; /* * The Authentication key uses HMAC-MD5 or HMAC-SHA-1 digest. */ for (counter = 0; counter < stemp; counter++) *buffer.byte_ptr++ = random(); /* FIXME: Is this correct?! The code, above seems to use a variable size for digest (stemp) and length (if o->eigrp_length != 0). */ offset += EIGRP_TLEN_AUTH; } } /* * AFAIK, there are differences when building the EIGRP packet for * Update, Request, Query and Reply. Any EIGRP PCAP file I saw does * not carry Paremeter, Software Version and/or Multicast Sequence, * instead, it carries Authentication Data, IP Internal and External * Routes or nothing (depends on the EIGRP Type). */ if (o->eigrp.opcode == EIGRP_OPCODE_UPDATE || o->eigrp.opcode == EIGRP_OPCODE_REQUEST || o->eigrp.opcode == EIGRP_OPCODE_QUERY || o->eigrp.opcode == EIGRP_OPCODE_REPLY) { if (o->eigrp.type == EIGRP_TYPE_INTERNAL || o->eigrp.type == EIGRP_TYPE_EXTERNAL) { /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * IP Internal Routes TLV (EIGRP Type = 0x0102) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | Next Hop Address | * +---------------------------------------------------------------+ * | Delay | * +---------------------------------------------------------------+ * | Bandwidth | * +---------------------------------------------------------------+ * | Maximum Transmission Unit (MTU) | Hop Count | * +---------------------------------------------------------------+ * | Reliability | Load | Reserved | * +---------------------------------------------------------------+ * | Prefix // * +---------------+ * * +---------------------------------------------------------------+ * // Destination IP Address(es) (1-4 octets) | * +---------------------------------------------------------------+ * * IP External Routes TLV (EIGRP Type = 0x0103) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | Next Hop Address | * +---------------------------------------------------------------+ * | Originating Router | * +---------------------------------------------------------------+ * | Originating Autonomous System | * +---------------------------------------------------------------+ * | Arbitrary TAG | * +---------------------------------------------------------------+ * | External Protocol Metric | * +---------------------------------------------------------------+ * | Reserved1 | Ext. Proto ID | Flags | * +---------------------------------------------------------------+ * | Delay | * +---------------------------------------------------------------+ * | Bandwidth | * +---------------------------------------------------------------+ * | Maximum Transmission Unit (MTU) | Hop Count | * +---------------------------------------------------------------+ * | Reliability | Load | Reserved2 | * +---------------------------------------------------------------+ * | Prefix // * +---------------+ * * +---------------------------------------------------------------+ * // Destination IP Address(es) (1-4 octets) | * +---------------------------------------------------------------+ * * The only difference between Internal and External Routes TLVs is 20 * octets. */ *buffer.word_ptr++ = htons(o->eigrp.type == EIGRP_TYPE_INTERNAL ? EIGRP_TYPE_INTERNAL : EIGRP_TYPE_EXTERNAL); /* * For both Internal and External Routes TLV the code must perform * an additional step to compute the EIGRP header length, because * it depends on the the EIGRP Prefix, and it can be 1-4 octets. */ *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : (o->eigrp.type == EIGRP_TYPE_INTERNAL ? EIGRP_TLEN_INTERNAL : EIGRP_TLEN_EXTERNAL) + EIGRP_DADDR_LENGTH(prefix)); *buffer.inaddr_ptr++ = INADDR_RND(o->eigrp.next_hop); /* * The only difference between Internal and External Routes TLVs is 20 * octets. Building 20 extra octets for IP External Routes TLV. */ if (o->eigrp.type == EIGRP_TYPE_EXTERNAL) { *buffer.inaddr_ptr++ = INADDR_RND(o->eigrp.src_router); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.src_as)); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.tag)); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.proto_metric)); *buffer.word_ptr++ = o->eigrp.opcode == EIGRP_OPCODE_UPDATE ? FIELD_MUST_BE_ZERO : htons(0x0004); *buffer.byte_ptr++ = __RND(o->eigrp.proto_id); *buffer.byte_ptr++ = __RND(o->eigrp.ext_flags); } dest = INADDR_RND(o->eigrp.dest); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.delay)); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.bandwidth)); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.mtu) << 8); *buffer.byte_ptr++ = __RND(o->eigrp.hop_count); *buffer.byte_ptr++ = __RND(o->eigrp.reliability); *buffer.byte_ptr++ = __RND(o->eigrp.load); *buffer.word_ptr++ = o->eigrp.opcode == EIGRP_OPCODE_UPDATE ? FIELD_MUST_BE_ZERO : htons(0x0004); *buffer.byte_ptr++ = prefix; *buffer.inaddr_ptr++ = EIGRP_DADDR_BUILD(dest, prefix); buffer.ptr += EIGRP_DADDR_LENGTH(prefix); offset += (o->eigrp.type == EIGRP_TYPE_INTERNAL ? EIGRP_TLEN_INTERNAL : EIGRP_TLEN_EXTERNAL) + EIGRP_DADDR_LENGTH(prefix); } /* * In the other hand, EIGRP Packet for Hello can carry Paremeter, * Software Version, Multicast Sequence or nothing (Acknowledge). */ } else if (o->eigrp.opcode == EIGRP_OPCODE_HELLO) { /* * AFAIK, EIGRP TLVs must follow a predefined sequence in order to * be built. I am not sure whether any TLV's precedence will impact * in the routers' processing of EIGRP Packet, so I am following * exactly what I saw on live EIGRP PCAP files. Read the code and * you will understand what I am talking about. */ switch (o->eigrp.type) { case EIGRP_TYPE_PARAMETER: case EIGRP_TYPE_SOFTWARE: case EIGRP_TYPE_MULTICAST: /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * General Parameter TLV (EIGRP Type = 0x0001) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | K1 | K2 | K3 | K4 | * +---------------------------------------------------------------+ * | K5 | Reserved | Hold Time | * +---------------------------------------------------------------+ */ *buffer.word_ptr++ = htons(EIGRP_TYPE_PARAMETER); *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : EIGRP_TLEN_PARAMETER); *buffer.byte_ptr++ = TEST_BITS(o->eigrp.values, EIGRP_KVALUE_K1) ? __RND(o->eigrp.k1) : o->eigrp.k1; *buffer.byte_ptr++ = TEST_BITS(o->eigrp.values, EIGRP_KVALUE_K2) ? __RND(o->eigrp.k2) : o->eigrp.k2; *buffer.byte_ptr++ = TEST_BITS(o->eigrp.values, EIGRP_KVALUE_K3) ? __RND(o->eigrp.k3) : o->eigrp.k3; *buffer.byte_ptr++ = TEST_BITS(o->eigrp.values, EIGRP_KVALUE_K4) ? __RND(o->eigrp.k4) : o->eigrp.k4; *buffer.byte_ptr++ = TEST_BITS(o->eigrp.values, EIGRP_KVALUE_K5) ? __RND(o->eigrp.k5) : o->eigrp.k5; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(o->eigrp.hold); offset += EIGRP_TLEN_PARAMETER; /* Going to the next TLV, if it needs to do so-> */ if (o->eigrp.type == EIGRP_TYPE_SOFTWARE || o->eigrp.type == EIGRP_TYPE_MULTICAST) { /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * Software Version TLV (EIGRP Type = 0x0004) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | IOS Major | IOS Minor | EIGRP Major | EIGRP Minor | * +---------------------------------------------------------------+ */ *buffer.word_ptr++ = htons(EIGRP_TYPE_SOFTWARE); *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : EIGRP_TLEN_SOFTWARE); *buffer.byte_ptr++ = __RND(o->eigrp.ios_major); *buffer.byte_ptr++ = __RND(o->eigrp.ios_minor); *buffer.byte_ptr++ = __RND(o->eigrp.ver_major); *buffer.byte_ptr++ = __RND(o->eigrp.ver_minor); offset += EIGRP_TLEN_SOFTWARE; /* Going to the next TLV, if it needs to do so-> */ if (o->eigrp.type == EIGRP_TYPE_MULTICAST) { /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * Sequence TLV (EIGRP Type = 0x0003) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | Addr Length // * +---------------+ * * +---------------------------------------------------------------+ * // IP Address | * +---------------------------------------------------------------+ */ *buffer.word_ptr++ = htons(EIGRP_TYPE_SEQUENCE); *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : EIGRP_TLEN_SEQUENCE); *buffer.byte_ptr++ = sizeof(o->eigrp.address); *buffer.inaddr_ptr++ = INADDR_RND(o->eigrp.address); /* * Enhanced Interior Gateway Routing Protocol (EIGRP) * * Next Multicast Sequence TLV (EIGRP Type = 0x0005) * * 0 1 2 3 3 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | Type | Length | * +---------------------------------------------------------------+ * | Next Multicast Sequence | * +---------------------------------------------------------------+ */ *buffer.word_ptr++ = htons(EIGRP_TYPE_MULTICAST); *buffer.word_ptr++ = htons(o->eigrp.length ? o->eigrp.length : EIGRP_TLEN_MULTICAST); *buffer.dword_ptr++ = htonl(__RND(o->eigrp.multicast)); offset += EIGRP_TLEN_MULTICAST + EIGRP_TLEN_SEQUENCE; } } } } /* Computing the checksum. */ eigrp->check = o->bogus_csum ? random() : cksum(eigrp, offset); /* GRE Encapsulation takes place. */ gre_checksum(packet, o, packet_size); /* Setting SOCKADDR structure. */ sin.sin_family = AF_INET; sin.sin_port = htons(IPPORT_RND(o->dest)); sin.sin_addr.s_addr = o->ip.daddr; /* Sending packet. */ if (sendto(fd, packet, packet_size, MSG_NOSIGNAL, (struct sockaddr *) &sin, sizeof(struct sockaddr)) == -1 && errno != EPERM) return 1; return 0; }
size_t greoptlen, /* GRE options size. */ esp_data, /* IPSec ESP Data Encrypted (RANDOM). */ counter; /* Packet. */ memptr_t buffer; struct iphdr *ip; /* IPSec AH header and IPSec ESP Header. */ struct ip_auth_hdr *ip_auth; struct ip_esp_hdr *ip_esp; assert(co != NULL); greoptlen = gre_opt_len(co); esp_data = auth_hmac_md5_len(1); *size = sizeof(struct iphdr) + sizeof(struct ip_auth_hdr) + sizeof(struct ip_esp_hdr) + greoptlen + IP_AH_ICV + esp_data; /* Try to reallocate packet, if necessary */ alloc_packet(*size); ip = ip_header(packet, *size, co); /* GRE Encapsulation takes place. */ gre_encapsulation(packet, co,
/* Function Name: RSVP packet header configuration. Description: This function configures and sends the RSVP packet header. Targets: N/A */ int rsvp(const socket_t fd, const struct config_options *o) { size_t greoptlen, /* GRE options size. */ objects_length, /* RSVP objects length. */ packet_size, offset, counter; /* Packet and Checksum. */ mptr_t buffer; /* Socket address and IP header. */ struct sockaddr_in sin; struct iphdr * ip; /* RSVP Common header. */ struct rsvp_common_hdr * rsvp; assert(o != NULL); greoptlen = gre_opt_len(o->gre.options, o->encapsulated); objects_length = rsvp_objects_len(o->rsvp.type, o->rsvp.scope, o->rsvp.adspec, o->rsvp.tspec); packet_size = sizeof(struct iphdr) + sizeof(struct rsvp_common_hdr) + greoptlen + objects_length; /* Try to reallocate the packet, if necessary */ alloc_packet(packet_size); /* IP Header structure making a pointer to Packet. */ ip = ip_header(packet, packet_size, o); /* GRE Encapsulation takes place. */ gre_encapsulation(packet, o, sizeof(struct iphdr) + sizeof(struct rsvp_common_hdr) + objects_length); /* RSVP Header structure making a pointer to IP Header structure. */ rsvp = (struct rsvp_common_hdr *)((void *)ip + sizeof(struct iphdr) + greoptlen); rsvp->flags = __RND(o->rsvp.flags); rsvp->version = RSVPVERSION; rsvp->type = o->rsvp.type; rsvp->ttl = __RND(o->rsvp.ttl); rsvp->length = htons(sizeof(struct rsvp_common_hdr) + objects_length); rsvp->reserved = FIELD_MUST_BE_ZERO; rsvp->check = 0; offset = sizeof(struct rsvp_common_hdr); buffer.ptr = (void *)rsvp + offset; /* * The SESSION Object Class is present for all RSVP Messages. * * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.1 SESSION Class * * SESSION Class = 1. * * o IPv4/UDP SESSION object: Class = 1, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | IPv4 DestAddress (4 bytes) | * +-------------+-------------+-------------+-------------+ * | Protocol Id | Flags | DstPort | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_SESSION); *buffer.byte_ptr++ = RSVP_OBJECT_SESSION; *buffer.byte_ptr++ = 1; *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.session_addr); *buffer.byte_ptr++ = __RND(o->rsvp.session_proto); *buffer.byte_ptr++ = __RND(o->rsvp.session_flags); *buffer.word_ptr++ = htons(__RND(o->rsvp.session_port)); offset += RSVP_LENGTH_SESSION; /* * The RESV_HOP Object Class is present for the following: * 3.1.3 Path Messages * 3.1.4 Resv Messages * 3.1.5 Path Teardown Messages * 3.1.6 Resv Teardown Messages * 3.1.8 Resv Error Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_PATH || o->rsvp.type == RSVP_MESSAGE_TYPE_RESV || o->rsvp.type == RSVP_MESSAGE_TYPE_PATHTEAR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVTEAR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVERR) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.2 RSVP_HOP Class * * RSVP_HOP class = 3. * * o IPv4 RSVP_HOP object: Class = 3, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | IPv4 Next/Previous Hop Address | * +-------------+-------------+-------------+-------------+ * | Logical Interface Handle | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_RESV_HOP); *buffer.byte_ptr++ = RSVP_OBJECT_RESV_HOP; *buffer.byte_ptr++ = 1; *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.hop_addr); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.hop_iface)); offset += RSVP_LENGTH_RESV_HOP; } /* * The TIME_VALUES Object Class is present for the following: * 3.1.3 Path Messages * 3.1.4 Resv Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_PATH || o->rsvp.type == RSVP_MESSAGE_TYPE_RESV) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.4 TIME_VALUES Class * * TIME_VALUES class = 5. * * o TIME_VALUES Object: Class = 5, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | Refresh Period R | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_TIME_VALUES); *buffer.byte_ptr++ = RSVP_OBJECT_TIME_VALUES; *buffer.byte_ptr++ = 1; *buffer.dword_ptr++ = htonl(__RND(o->rsvp.time_refresh)); offset += RSVP_LENGTH_TIME_VALUES; } /* * The ERROR_SPEC Object Class is present for the following: * 3.1.5 Path Teardown Messages * 3.1.8 Resv Error Messages * 3.1.9 Confirmation Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_PATHERR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVERR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVCONF) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.5 ERROR_SPEC Class * * ERROR_SPEC class = 6. * * o IPv4 ERROR_SPEC object: Class = 6, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | IPv4 Error Node Address (4 bytes) | * +-------------+-------------+-------------+-------------+ * | Flags | Error Code | Error Value | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_ERROR_SPEC); *buffer.byte_ptr++ = RSVP_OBJECT_ERROR_SPEC; *buffer.byte_ptr++ = 1; *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.error_addr); *buffer.byte_ptr++ = __RND(o->rsvp.error_flags); *buffer.byte_ptr++ = __RND(o->rsvp.error_code); *buffer.word_ptr++ = htons(__RND(o->rsvp.error_value)); offset += RSVP_LENGTH_ERROR_SPEC; } /* * The SENDER_TEMPLATE, SENDER_TSPEC and ADSPEC Object Classes are * present for the following: * 3.1.3 Path Messages * 3.1.5 Path Teardown Messages * 3.1.7 Path Error Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_PATH || o->rsvp.type == RSVP_MESSAGE_TYPE_PATHTEAR || o->rsvp.type == RSVP_MESSAGE_TYPE_PATHERR) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.10 SENDER_TEMPLATE Class * * SENDER_TEMPLATE class = 11. * * o IPv4 SENDER_TEMPLATE object: Class = 11, C-Type = 1 * * Definition same as IPv4/UDP FILTER_SPEC object. * * RSVP Extensions for IPSEC (RFC 2207) * * 3.3 SENDER_TEMPLATE Class * * SENDER_TEMPLATE class = 11. * * o IPv4/GPI SENDER_TEMPLATE object: Class = 11, C-Type = 4 * * Definition same as IPv4/GPI FILTER_SPEC object. */ *buffer.word_ptr++ = htons(RSVP_LENGTH_SENDER_TEMPLATE); *buffer.byte_ptr++ = RSVP_OBJECT_SENDER_TEMPLATE; *buffer.byte_ptr++ = 1; *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.sender_addr); *buffer.word_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(__RND(o->rsvp.sender_port)); offset += RSVP_LENGTH_SENDER_TEMPLATE; /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.11 SENDER_TSPEC Class * * SENDER_TSPEC class = 12. * * o Intserv SENDER_TSPEC object: Class = 12, C-Type = 2 * * The contents and encoding rules for this object are specified * in documents prepared by the int-serv working group. */ *buffer.word_ptr++ = htons(RSVP_LENGTH_SENDER_TSPEC + TSPEC_SERVICES(o->rsvp.tspec)); *buffer.byte_ptr++ = RSVP_OBJECT_SENDER_TSPEC; *buffer.byte_ptr++ = 2; /* * The Use of RSVP with IETF Integrated Services (RFC 2210) * * 3.1. RSVP SENDER_TSPEC Object * * 31 24 23 16 15 8 7 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 1 | 0 (a) | reserved | 7 (b) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 2 | 1 (c) |0| reserved | 6 (d) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 3 | 127 (e) | 0 (f) | 5 (g) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 4 | Token Bucket Rate [r] (32-bit IEEE floating point number) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 5 | Token Bucket Size [b] (32-bit IEEE floating point number) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 6 | Peak Data Rate [p] (32-bit IEEE floating point number) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 7 | Minimum Policed Unit [m] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 8 | Maximum Packet Size [M] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ *buffer.word_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons((TSPEC_SERVICES(o->rsvp.tspec) - RSVP_LENGTH_SENDER_TSPEC)/4); *buffer.byte_ptr++ = o->rsvp.tspec; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(TSPEC_SERVICES(o->rsvp.tspec)/4); /* Identifying the RSVP TSPEC and building it. */ switch (o->rsvp.tspec) { case TSPEC_TRAFFIC_SERVICE: case TSPEC_GUARANTEED_SERVICE: *buffer.byte_ptr++ = TSPECT_TOKEN_BUCKET_SERVICE; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons((TSPEC_SERVICES(o->rsvp.tspec) - TSPEC_MESSAGE_HEADER)/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.tspec_r)); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.tspec_b)); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.tspec_p)); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.tspec_m)); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.tspec_M)); break; } offset += RSVP_LENGTH_SENDER_TSPEC + TSPEC_SERVICES(o->rsvp.tspec); /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.12 ADSPEC Class * * ADSPEC class = 13. * * o Intserv ADSPEC object: Class = 13, C-Type = 2 * * The contents and format for this object are specified in * documents prepared by the int-serv working group. */ *buffer.word_ptr++ = htons(RSVP_LENGTH_ADSPEC + ADSPEC_SERVICES(o->rsvp.adspec)); *buffer.byte_ptr++ = RSVP_OBJECT_ADSPEC; *buffer.byte_ptr++ = 2; /* * The Use of RSVP with IETF Integrated Services (RFC 2210) * * 3.3.1. RSVP ADSPEC format * * 31 24 23 16 15 8 7 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | 0 (a) | reserved | Msg length - 1 (b) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | Default General Parameters fragment (Service 1) (c) | * | (Always Present) | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | Guaranteed Service Fragment (Service 2) (d) | * | (Present if application might use Guaranteed Service) | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * | | * | Controlled-Load Service Fragment (Service 5) (e) | * | (Present if application might use Controlled-Load Service) | * | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ *buffer.word_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons((ADSPEC_SERVICES(o->rsvp.adspec) - ADSPEC_MESSAGE_HEADER)/4); offset += RSVP_LENGTH_ADSPEC; /* * The Use of RSVP with IETF Integrated Services (RFC 2210) * * 3.3.2. Default General Characterization Parameters ADSPEC data fragment * * 31 24 23 16 15 8 7 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 1 | 1 (c) |x| reserved | 8 (d) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 2 | 4 (e) | (f) | 1 (g) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 3 | IS hop cnt (32-bit unsigned integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 4 | 6 (h) | (i) | 1 (j) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 5 | Path b/w estimate (32-bit IEEE floating point number) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 6 | 8 (k) | (l) | 1 (m) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 7 | Minimum path latency (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 8 | 10 (n) | (o) | 1 (p) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 9 | Composed MTU (32-bit unsigned integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ *buffer.byte_ptr++ = ADSPEC_PARAMETER_SERVICE; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons((ADSPEC_PARAMETER_LENGTH - ADSPEC_MESSAGE_HEADER)/4); *buffer.byte_ptr++ = ADSPEC_PARAMETER_ISHOPCNT; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_hop)); *buffer.byte_ptr++ = ADSPEC_PARAMETER_BANDWIDTH; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_path)); *buffer.byte_ptr++ = ADSPEC_PARAMETER_LATENCY; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_minimum)); *buffer.byte_ptr++ = ADSPEC_PARAMETER_COMPMTU; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_mtu)); offset += ADSPEC_PARAMETER_LENGTH; /* Identifying the ADSPEC and building it. */ switch (o->rsvp.adspec) { case ADSPEC_GUARANTEED_SERVICE: case ADSPEC_CONTROLLED_SERVICE: /* * The Use of RSVP with IETF Integrated Services (RFC 2210) * * 3.3.3. Guaranteed Service ADSPEC data fragment * * 31 24 23 16 15 8 7 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 1 | 2 (a) |x| reserved | N-1 (b) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 2 | 133 (c) | 0 (d) | 1 (e) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 3 | End-to-end composed value for C [Ctot] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 4 | 134 (f) | (g) | 1 (h) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 5 | End-to-end composed value for D [Dtot] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 6 | 135 (i) | (j) | 1 (k) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 7 | Since-last-reshaping point composed C [Csum] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 8 | 136 (l) | (m) | 1 (n) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 9 | Since-last-reshaping point composed D [Dsum] (32-bit integer) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 10 | Service-specific general parameter headers/values, if present | * . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . * N | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ *buffer.byte_ptr++ = ADSPEC_GUARANTEED_SERVICE; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons((ADSPEC_GUARANTEED_LENGTH - ADSPEC_MESSAGE_HEADER)/4); *buffer.byte_ptr++ = 133; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_Ctot)); *buffer.byte_ptr++ = 134; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_Dtot)); *buffer.byte_ptr++ = 135; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_Csum)); *buffer.byte_ptr++ = 136; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_SERVDATA_HEADER/4); *buffer.dword_ptr++ = htonl(__RND(o->rsvp.adspec_Dsum)); offset += ADSPEC_GUARANTEED_LENGTH; /* Going to the next ADSPEC, if it needs to do so-> */ if (o->rsvp.adspec == ADSPEC_CONTROLLED_SERVICE) { /* * The Use of RSVP with IETF Integrated Services (RFC 2210) * * 3.3.4. Controlled-Load Service ADSPEC data fragment * * 31 24 23 16 15 8 7 0 * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 1 | 5 (a) |x| (b) | N-1 (c) | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * 2 | Service-specific general parameter headers/values, if present | * . +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ * . * N | | * +-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+-+ */ *buffer.byte_ptr++ = ADSPEC_CONTROLLED_SERVICE; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.word_ptr++ = htons(ADSPEC_CONTROLLED_LENGTH - ADSPEC_MESSAGE_HEADER); offset += ADSPEC_CONTROLLED_LENGTH; } break; } } /* * The RESV_CONFIRM Object Class is present for the following: * 3.1.4 Resv Messages * 3.1.9 Confirmation Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_RESV || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVCONF) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.14 Resv_CONFIRM Class * * RESV_CONFIRM class = 15. * * o IPv4 RESV_CONFIRM object: Class = 15, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | IPv4 Receiver Address (4 bytes) | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_RESV_CONFIRM); *buffer.byte_ptr++ = RSVP_OBJECT_RESV_CONFIRM; *buffer.byte_ptr++ = 1; *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.confirm_addr); offset += RSVP_LENGTH_RESV_CONFIRM; } /* * The STYLE Object Classes is present for the following: * 3.1.4 Resv Messages * 3.1.6 Resv Teardown Messages * 3.1.8 Resv Error Messages * 3.1.9 Confirmation Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_RESV || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVTEAR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVERR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVCONF) { /* * The SCOPE Object Classes is present for the following: * 3.1.4 Resv Messages * 3.1.6 Resv Teardown Messages * 3.1.8 Resv Error Messages */ if (o->rsvp.type == RSVP_MESSAGE_TYPE_RESV || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVTEAR || o->rsvp.type == RSVP_MESSAGE_TYPE_RESVERR) { /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.6 SCOPE Class * * SCOPE class = 7. * * o IPv4 SCOPE List object: Class = 7, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | IPv4 Src Address (4 bytes) | * +-------------+-------------+-------------+-------------+ * // // * +-------------+-------------+-------------+-------------+ * | IPv4 Src Address (4 bytes) | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_SCOPE(o->rsvp.scope)); *buffer.byte_ptr++ = RSVP_OBJECT_SCOPE; *buffer.byte_ptr++ = 1; /* Dealing with scope address(es). */ for(counter = 0; counter < o->rsvp.scope ; counter ++) *buffer.inaddr_ptr++ = INADDR_RND(o->rsvp.address[counter]); offset += RSVP_LENGTH_SCOPE(o->rsvp.scope); } /* * Resource ReSerVation Protocol (RSVP) (RFC 2205) * * A.7 STYLE Class * * STYLE class = 8. * * o STYLE object: Class = 8, C-Type = 1 * * +-------------+-------------+-------------+-------------+ * | Flags | Option Vector | * +-------------+-------------+-------------+-------------+ */ *buffer.word_ptr++ = htons(RSVP_LENGTH_STYLE); *buffer.byte_ptr++ = RSVP_OBJECT_STYLE; *buffer.byte_ptr++ = 1; *buffer.byte_ptr++ = FIELD_MUST_BE_ZERO; *buffer.dword_ptr++ = htonl(__RND(o->rsvp.style_opt) << 8); offset += RSVP_LENGTH_STYLE; } /* Computing the checksum. */ rsvp->check = o->bogus_csum ? random() : cksum(rsvp, offset); /* GRE Encapsulation takes place. */ gre_checksum(packet, o, packet_size); /* Setting SOCKADDR structure. */ sin.sin_family = AF_INET; sin.sin_port = htons(IPPORT_RND(o->dest)); sin.sin_addr.s_addr = o->ip.daddr; /* Sending packet. */ if (sendto(fd, packet, packet_size, MSG_NOSIGNAL, (struct sockaddr *)&sin, sizeof(struct sockaddr)) == -1 && errno != EPERM) return 1; return 0; }
void udp(const struct config_options * const __restrict__ co, size_t *size) { size_t greoptlen; /* GRE options size. */ struct iphdr *ip; /* GRE Encapsulated IP Header. */ struct iphdr *gre_ip; /* UDP header and PSEUDO header. */ struct udphdr *udp; struct psdhdr *pseudo; assert(co != NULL); greoptlen = gre_opt_len(co->gre.options, co->encapsulated); *size = sizeof(struct iphdr) + greoptlen + sizeof(struct udphdr) + sizeof(struct psdhdr); /* Try to reallocate packet, if necessary */ alloc_packet(*size); /* Fill IP header. */ ip = ip_header(packet, *size, co); gre_ip = gre_encapsulation(packet, co, sizeof(struct iphdr) + sizeof(struct udphdr)); /* UDP Header structure making a pointer to IP Header structure. */ udp = (struct udphdr *)((void *)ip + sizeof(struct iphdr) + greoptlen); udp->source = htons(IPPORT_RND(co->source)); udp->dest = htons(IPPORT_RND(co->dest));