packet_t* recv_packet_native(int from) { int size; char *data = malloc(MAX_PACKET_SIZE); size = read(from, data, MAX_PACKET_SIZE); if (size < 0) { return NULL; } return alloc_packet(size, data); }
void client::on_data() { unsigned char data[16384]; int size = recv( my_socket, (char*)data, 16384, 0 ); if( size == 0 ) { // REMOTE SIDE DISCONNECTED } unsigned char *read = data; while( size > 0 ) { if( buffer_write_pos == 0 ) { packet_buffer = alloc_packet(); packet_buffer->data_size = *read++; size--; buffer_write_pos++; } else if( buffer_write_pos == 1 ) { packet_buffer->data_size |= (*read++) << 8; size--; buffer_write_pos++; // TODO: VERIFY DATA SIZE //packet_buffer->data = new unsigned char[packet_buffer->data_size]; remaining_bytes = packet_buffer->data_size; } else { while( (size > 0) && (remaining_bytes > 0) ) { packet_buffer->data[buffer_write_pos-2] = *read++; size--; remaining_bytes--; buffer_write_pos++; } if( remaining_bytes == 0 ) { packet_buffer->link = 0; if( !fifo ) { fifo = packet_buffer; fifo_end = packet_buffer; } else { fifo_end->link = packet_buffer; fifo_end = packet_buffer; } buffer_write_pos = 0; } } } }
static buffer * setup_dummy_ether_packet( size_t length ) { buffer *ether_buffer = alloc_buffer_with_length( length ); alloc_packet( ether_buffer ); append_back_buffer( ether_buffer, length ); packet_info( ether_buffer )->l2_data.eth = ether_buffer->data; memcpy( ( char * ) packet_info( ether_buffer )->l2_data.eth->macda, macda, ETH_ADDRLEN ); memcpy( ( char * ) packet_info( ether_buffer )->l2_data.eth->macsa, macsa, ETH_ADDRLEN ); packet_info( ether_buffer )->l2_data.eth->type = htons( ETH_ETHTYPE_ARP ); return ether_buffer; }
void handle_packet(const uchar *data, ushort size) { uchar *buf; int *bufsize; ushort psize; packet_t *pkt; if (_fromsv) { buf = _svbuf; bufsize = &_svbufsize; } else { buf = _clbuf; bufsize = &_clbufsize; } if (size+*bufsize >= BUFSIZE) { log_msg("dbg", "warning: buffer size exceeded in handle_packet.\r\n"); return; } memcpy(buf+*bufsize, data, size); *bufsize += size; psize = *(ushort *)buf; if (psize < 3) { log_msg("dbg", "warning: malformed packet (%.2X) incorrect size: %hu.\r\n", *(ushort *)data, psize); return; } if (*bufsize >= psize) { do { pkt = alloc_packet(buf, psize); if (decrypt_packet(pkt, _fromsv, &_isfirst) != 0) { log_msg("dbg", "error: decryption failed, missed key packet?\r\n"); } else { if (_fromsv) { handle_sv_packet(pkt); } else { handle_cl_packet(pkt); } } free(pkt); *bufsize -= psize; memcpy(buf, buf+psize, *bufsize); psize = *(ushort *)buf; } while (*bufsize >= psize && *bufsize > 0); } }
static buffer * setup_dummy_ether_packet( size_t length, uint16_t type ) { buffer *buf = alloc_buffer_with_length( length ); alloc_packet( buf ); append_back_buffer( buf, length ); packet_info( buf )->l2_data.eth = buf->data; packet_info( buf )->ethtype = type; ether_header_t *ether = packet_info( buf )->l2_data.eth; ether->type = htons( type ); memcpy( ( char * ) ether->macda, macda, ETH_ADDRLEN ); memcpy( ( char * ) ether->macsa, macsa, ETH_ADDRLEN ); packet_info( buf )->l3_data.l3 = ( char * ) packet_info( buf )->l2_data.l2 + sizeof( ether_header_t ); vlantag_header_t *vtag = ( vlantag_header_t * ) ( ( void * ) ( ether + 1 ) ); packet_info( buf )->vtag = vtag; return buf; }
packet_t* recv_packet(int from) { int size; char *data; int err; err = read(from, &size, sizeof(size)); if (err < 0) { return NULL; } data = malloc(size); err = read(from, data, size); if (err < 0) { return NULL; } return alloc_packet(size, data); }
int alloc_free_queue(nic_t *nic, size_t num_of_packets) { int i; pthread_mutex_lock(&nic->free_packet_queue_mutex); for (i = 0; i < num_of_packets; i++) { packet_t *pkt; pkt = alloc_packet(STD_MTU_SIZE, STD_MTU_SIZE); if (pkt == NULL) { goto done; } reset_packet(pkt); pkt->next = nic->free_packet_queue; nic->free_packet_queue = pkt; } done: pthread_mutex_unlock(&nic->free_packet_queue_mutex); return i; }
packet_t* recv_packet(int from) { int size; char *data; int err; err = read(from, &size, sizeof(size)); if (err < 0) { return NULL; } data = malloc(size); err = read(from, data, size); if (err < 0) { return NULL; } if (size > MAX_PACKET_SIZE) { printf("Packet to big!\n"); size = MAX_PACKET_SIZE; } return alloc_packet(size, data); }
/* 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; }
/* 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; }
int main(int argc, const char * argv[]) { struct { int verbose, _1_, keepalive, _2_, timeout, _3_; char * hostname, * port, * source_type, * source_name; } cfg; struct config_var vars[] = { // {"name", {0, f, r, n}, '-', "ENV_NAME", DEFAULT_VALUE, &my_variable}, {"verbose", {0, 1, 0, 0}, 'v', NULL, (void *)1, &cfg.verbose}, {"quiet", {0, 1, 0, 0}, 'q', NULL, (void *)-1, &cfg.verbose}, {"hostname", {0, 0, 1, 0}, 'h', "HOSTNAME", "localhost", &cfg.hostname}, {"port", {0, 0, 1, 0}, 'p', "PORT", SERVER_PORT, &cfg.port}, {"source-type", {0, 0, 1, 0}, 't', "SOURCE_TYPE", "file", &cfg.source_type}, {"source-name", {0, 0, 1, 0}, 's', "SOURCE_NAME", NULL, &cfg.source_name}, {"keepalive-int", {0, 0, 1, 1}, 'k', "KEEPALIVE_INTERVAL", (void *)300, &cfg.keepalive}, {"packet-timeout", {0, 0, 1, 1}, 't', "PACKET_TIMEOUT", (void *)DEFAULT_TIMEOUT, &cfg.timeout} }; int sockfd = 0; ssize_t retv = 0; char buf[256]; pk_keepalive_t * pk = (pk_keepalive_t *)buf; pk_advertize_t * ad; pid_t keepalive_pid = 0; struct keepalive_param kp = {&sockfd, &cfg.keepalive}; config(argc, argv, sizeof(vars)/sizeof(struct config_var), vars); ad = (pk_advertize_t *)alloc_packet(PACKET_SIZE_MAX); if ((retv = !ad)) goto exit; printf("Connecting to %s:%s\n", cfg.hostname, cfg.port); if ((retv = connect_socket(cfg.hostname, cfg.port, &sockfd))) { fprintf(stderr, "Connection failed\n"); goto free; } if ((retv = send_handshake(sockfd, cfg.timeout))) { fprintf(stderr, "Bad handshake\n"); goto free; } _fork(&keepalive_pid, &do_keepalive, &kp); if (!strcasecmp("file", cfg.source_type)) { FILE * file = fopen(cfg.source_name, "r"); if ((retv = !file)) { perror("fopen"); goto free; } // states: // 0 - whitespace before name // 1 - name // 2 - whitespace between name and port // 3 - port // 4 - whitespace after port char state = 0, name[220], port[7]; for (int c = 0, i = 0, j = 0; (c = fgetc(file)) > 0;) switch (state) { case 0: // whitespace before name if (c == '#') { state = 4; break; } else if (c <= 0x20 || 0x7F <= c) break; state = 1; i = 0; case 1: // name if ((retv = i >= sizeof(name))) { fprintf(stderr, "Names cannot be more than %lu characters\n", sizeof(name) - 1); goto fclose; } else if (j == 0 && 0x30 <= c && c <= 0x39) { // if the first character is a number, interpret it as a port port[j++] = c; state = 3; break; } if (0x20 < c && c < 0x7F) { name[i++] = c; break; } state = 2; case 2: // whitespace between name and port if (c <= 0x20 || 0x7F <= c) break; state = 3; j = 0; case 3: // port if ((retv = j >= sizeof(port))) { fprintf(stderr, "Port number cannot be greater than 65535\n"); goto fclose; } else if (0x30 <= c && c <= 0x39) { port[j++] = c; state = 3; break; } else if (0x20 < c && c < 0x7F && c != '#') { fprintf(stderr, "Port numbers must be numeric\n"); goto fclose; } state = 4; case 4: // whitespace after port if (c == '\n' || c == '\r') { name[i] = 0; port[j] = 0; if (i == 0 && j == 0) { state = 0; break; } int portnum = atoi(port); if ((retv = portnum > USHRT_MAX)) { fprintf(stderr, "Port number cannot be greater than 65535\n"); goto fclose; } init_pk_advertize(ad, portnum, name); if (!*name) ad->name.data[0] = '+'; retv = pk_send(sockfd, (pk_keepalive_t *)ad, 0); if ((retv = retv < 0)) goto free; state = 0; } break; default: fprintf(stderr, "Internal error\n"); retv = 1; goto fclose; break; } fclose: fclose(file); } else if (!strcasecmp("sqlite", cfg.source_type)) { fprintf(stderr, "Using SQLite as a source is currently unsupported\n"); retv = 1; goto free; } else { fprintf(stderr, "Bad source type %s\n", cfg.source_type); retv = 1; goto free; } free: free_packet((pk_keepalive_t *)ad); while (!retv) { retv = pk_recv(sockfd, buf, cfg.timeout, 0); if (retv <= 0) break; retv = check_version(pk); } //close: if (sockfd) close(sockfd); kill(keepalive_pid, SIGTERM); exit: return (int)retv; }
static struct packet *add_to_queue(struct ts *ts) { queue_add(ts->packet_queue, ts->current_packet); ts->current_packet = alloc_packet(ts); return ts->current_packet; }
/* Main function launches all T50 modules */ int main(int argc, char *argv[]) { struct config_options *co; /* Pointer to options. */ struct cidr *cidr_ptr; /* Pointer to cidr host id and 1st ip address. */ modules_table_t *ptbl; /* Pointer to modules table */ uint8_t proto; /* Used on main loop. */ initialize(); /* Configuring command line interface options. */ co = getConfigOptions(argc, argv); /* This is a requirement of t50. User must be root to use it. Previously on checkConfigOptions(). */ if (getuid()) { ERROR("User must have root priviledge to run."); return EXIT_FAILURE; } /* Validating command line interface options. */ if (!checkConfigOptions(co)) return EXIT_FAILURE; /* Setting socket file descriptor. */ /* NOTE: createSocket() handles its own errors before returning. */ createSocket(); /* Setup random seed using current date/time timestamp. */ /* NOTE: Random seed don't need to be so precise! */ srandom(time(NULL)); #ifdef __HAVE_TURBO__ /* Entering in TURBO. */ if (co->turbo) { /* Decides if it's necessary to fork a new process. */ if ((co->ip.protocol == IPPROTO_T50 && co->threshold > (threshold_t)getNumberOfRegisteredModules()) || (co->ip.protocol != IPPROTO_T50 && co->threshold > 1)) { threshold_t new_threshold; if ((pid = fork()) == -1) { perror("Error creating child process. Exiting..."); return EXIT_FAILURE; } /* Setting the priority to both parent and child process to highly favorable scheduling value. */ /* FIXME: Why not setup this value when t50 runs as a single process? */ if (setpriority(PRIO_PROCESS, PRIO_PROCESS, -15) == -1) { perror("Error setting process priority. Exiting..."); return EXIT_FAILURE; } /* Divide the process iterations in main loop between processes. */ new_threshold = co->threshold / 2; /* FIX: Ooops! Parent process get the extra packet, if given threshold is odd. */ if ((co->threshold % 2) && !IS_CHILD_PID(pid)) new_threshold++; co->threshold = new_threshold; } } #endif /* __HAVE_TURBO__ */ /* Calculates CIDR for destination address. */ cidr_ptr = config_cidr(co->bits, co->ip.daddr); /* Show launch info only for parent process. */ if (!IS_CHILD_PID(pid)) { time_t lt; struct tm *tm; /* Getting the local time. */ lt = time(NULL); tm = localtime(<); printf("\b\n%s %s successfully launched at %s %2d%s %d %.02d:%.02d:%.02d\n", PACKAGE, VERSION, getMonth(tm->tm_mon), tm->tm_mday, getOrdinalSuffix(tm->tm_mday), (tm->tm_year + 1900), tm->tm_hour, tm->tm_min, tm->tm_sec); } /* Selects the initial protocol to use. */ proto = co->ip.protocol; ptbl = mod_table; if (proto != IPPROTO_T50) ptbl += co->ip.protoname; co->ip.daddr = htonl(cidr_ptr->__1st_addr); /* Preallocate packet buffer. */ alloc_packet(INITIAL_PACKET_SIZE); /* Execute if flood or while threshold greater than 0. */ while (co->flood || (co->threshold-- > 0)) { /* Holds the actual packet size after module function call. */ size_t size; /* Set the destination IP address to RANDOM IP address. */ if (cidr_ptr->hostid) co->ip.daddr = htonl(cidr_ptr->__1st_addr + (random() % cidr_ptr->hostid)); /* Calls the 'module' function and sends the packet. */ co->ip.protocol = ptbl->protocol_id; ptbl->func(co, &size); sendPacket(packet, size, co); /* If protocol if 'T50', then get the next true protocol. */ if (proto == IPPROTO_T50) if ((++ptbl)->func == NULL) ptbl = mod_table; } /* Show termination message only for parent process. */ if (!IS_CHILD_PID(pid)) { time_t lt; struct tm *tm; /* FIX: We need to wait() for child processes only if we forked one! */ #ifdef __HAVE_TURBO__ int status; /* Wait 5 seconds for child process, then ungracefully closes the program. */ alarm(5); wait(&status); #endif /* FIX: To graciously end the program, only the parent process can close the socket. NOTE: I realize that closing descriptors are reference counted. Kept the logic just in case! */ closeSocket(); /* Getting the local time. */ lt = time(NULL); tm = localtime(<); printf("\b\n%s %s successfully finished at %s %2d%s %d %.02d:%.02d:%.02d\n", PACKAGE, VERSION, getMonth(tm->tm_mon), tm->tm_mday, getOrdinalSuffix(tm->tm_mday), (tm->tm_year + 1900), tm->tm_hour, tm->tm_min, tm->tm_sec); } return 0; }