Exemplo n.º 1
0
Arquivo: packet.c Projeto: lkl/lkl-net
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);
}
Exemplo n.º 2
0
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;
			}

		}
	}
}
Exemplo n.º 3
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;
}
Exemplo n.º 4
0
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);
	}
}
Exemplo n.º 5
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;
}
Exemplo n.º 6
0
Arquivo: packet.c Projeto: lkl/lkl-net
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);
}
Exemplo n.º 7
0
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;
}
Exemplo n.º 8
0
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);
}
Exemplo n.º 9
0
/* 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;
}
Exemplo n.º 10
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;
}
Exemplo n.º 11
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;
}
Exemplo n.º 12
0
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;
}
Exemplo n.º 13
0
Arquivo: t50.c Projeto: gisti/t50
/* 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(&lt);

    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(&lt);

    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;
}