int xscope_ep_request_upload(int sockfd, unsigned int length, const unsigned char *data)
{
  char request = XSCOPE_SOCKET_MSG_EVENT_TARGET_DATA;
  char *requestBuffer = (char *)malloc(sizeof(char)+sizeof(int)+length);
  int requestBufIndex = 0;
  int n = 0;

  if (xscope_ep_upload_pending == 1)
    return XSCOPE_EP_FAILURE;

  requestBuffer[requestBufIndex] = request;
  requestBufIndex += 1;
  *(unsigned int *)&requestBuffer[requestBufIndex] = length;
  requestBufIndex += 4;
  memcpy(&requestBuffer[requestBufIndex], data, length);
  requestBufIndex += length;

  n = send(sockfd, requestBuffer, requestBufIndex, 0);
  if (n != requestBufIndex)
    print_and_exit("ERROR: Command send failed\n");

  xscope_ep_upload_pending = 1;
  free(requestBuffer);

  return XSCOPE_EP_SUCCESS;
}
Example #2
0
void mutex_create(mutex_t *mutex)
{
  *mutex = CreateMutex( 
      NULL,              // default security attributes
      FALSE,             // initially not owned
      NULL);             // unnamed mutex

  if (*mutex == NULL) 
    print_and_exit("ERROR: mutex init failed\n");
}
void *console_thread(void *arg)
#endif
{
  int sockfd = *(int *)arg;
  char buffer[LINE_LENGTH + 1];
  do {
    int i = 0;
    int c = 0;

    printf("%s", g_prompt);
    for (i = 0; (i < LINE_LENGTH) && ((c = getchar()) != EOF) && (c != '\n'); i++)
      buffer[i] = tolower(c);
    buffer[i] = '\0';

    if (buffer[0] == 'q') {
      print_and_exit("Done\n");

    } else if (buffer[0] == 'e') {
      tester_command_t cmd = AVB_TESTER_EXPECT_NORMAL;
      if (get_next_char(&buffer[1]) == 'o')
        cmd = AVB_TESTER_EXPECT_OVERSUBSCRIBED;
      xscope_ep_request_upload(sockfd, 4, (unsigned char *)&cmd);

    } else if (buffer[0] == 'x') {
      tester_command_t cmd = AVB_TESTER_XSCOPE_PACKETS_DISABLE;
      if (get_next_char(&buffer[1]) == 'e')
        cmd = AVB_TESTER_XSCOPE_PACKETS_ENABLE;
      xscope_ep_request_upload(sockfd, 4, (unsigned char *)&cmd);

    } else if ((buffer[0] == 'h') || (buffer[0] == '?')) {
      print_console_usage();

    } else {
      printf("Unrecognised command '%s'\n", buffer);
      print_console_usage();
    }
  } while (1);

#ifdef _WIN32
  return 0;
#else
  return NULL;
#endif
}
Example #4
0
static void manage_queue(socket_data_t *socket_data)
{
  int n = 0;
  upload_queue_entry_t *entry = socket_data->queue.head;

  // Can't start sending more data until outstanding data complete
  if (socket_data->upload_active)
    return;

  // No more data to send
  if (entry == NULL)
    return;

  // Send the head
  n = send(socket_data->sockfd, entry->data, entry->length, 0);
  if (n != entry->length)
    print_and_exit("ERROR: send failed on socket %d\n", socket_data->sockfd);

  socket_data->upload_active = 1;
}
/*
 * Library code
 */
int initialise_socket(char *ip_addr_str, char *port_str)
{
  int sockfd = 0;
  int n = 0;
  unsigned char command_buffer[1];
  struct sockaddr_in serv_addr;
  char *end_pointer = NULL;
  int port = 0;
  int connect_retries = 0;

  if (DEBUG)
    g_log = fopen("run.log", "w");

  signal(SIGINT, interrupt_handler);

#ifdef _WIN32
  {
    //Start up Winsock
    WSADATA wsadata;
    int retval = WSAStartup(0x0202, &wsadata);
    if (retval)
      print_and_exit("ERROR: WSAStartup failed with '%d'\n", retval);

    //Did we get the right Winsock version?
    if (wsadata.wVersion != 0x0202) {
      WSACleanup();
      print_and_exit("ERROR: WSAStartup version incorrect '%x'\n", wsadata.wVersion);
    }
  }
#endif // _WIN32

  // Need the fflush because there is no newline in the print
  printf("Connecting"); fflush(stdout);
  while (1) {
    if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
      print_and_exit("ERROR: Could not create socket\n");

    memset(&serv_addr, 0, sizeof(serv_addr));

    // Parse the port parameter
    end_pointer = (char*)port_str;
    port = strtol(port_str, &end_pointer, 10);
    if (end_pointer == port_str)
      print_and_exit("ERROR: Failed to parse port\n");

    serv_addr.sin_family = AF_INET;
    serv_addr.sin_port = htons(port);

    if (inet_pton(AF_INET, ip_addr_str, &serv_addr.sin_addr) <= 0)
      print_and_exit("ERROR: inet_pton error occured\n");

    if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0) {
      close(sockfd);

      if (connect_retries < MAX_NUM_CONNECT_RETRIES) {
        // Need the fflush because there is no newline in the print
        printf("."); fflush(stdout);
#ifdef _WIN32
        Sleep(1000);
#else
        sleep(1);
#endif
        connect_retries++;
      } else {
        print_and_exit("\nERROR: Connect failed on ip: %s, port: %s\n",ip_addr_str, port_str);
      }
    } else {
      break;
    }
  }

  // Send the command to request which event types to receive
  command_buffer[0] = XSCOPE_SOCKET_MSG_EVENT_DATA | XSCOPE_SOCKET_MSG_EVENT_PRINT;
  n = send(sockfd, command_buffer, 1, 0);
  if (n != 1)
    print_and_exit("\nERROR: Command send failed\n");

  printf(" - connected to ip: %s, port: %s\n",ip_addr_str, port_str);

  return sockfd;
}
/*
 * Function to handle all data being received on the socket. It handles the
 * fact that full messages may not be received together and therefore needs
 * to keep the remainder of any message that hasn't been processed yet.
 */
void handle_sockets(int *sockfd, int no_of_sock)
{

  int total_bytes = 0;
  int num_remaining_bytes = 0;
  unsigned char recv_buffer[MAX_RECV_BYTES];
  int i = 0,max_sockfd=0,activity=0,sock_fd=0,n=0;
  
  // Keep track of whether a message should be printed at the start of the line
  // and when the prompt needs to be printed
  int new_line = 1;
  
  //set of socket descriptors
  fd_set readfds;
   
  while(1)
  { 
#if 1 
    // clear the socket set
    FD_ZERO(&readfds);
#endif
#if 1
    // add sockets to set
    for(i=0; i < no_of_sock; i++) {
      // if valid socket descriptor then add to read list
      if(sockfd[i] > 0)
        FD_SET(sockfd[i],&readfds);
      
      // highest file descriptor number, need it for the select function
      if(sockfd[i] > max_sockfd)
        max_sockfd = sockfd[i];
    }
#endif
    // wait for an activity on one of the sockets, timeout is NULL, so wait indefinitely
    activity = select(max_sockfd+1, &readfds, NULL, NULL, NULL);

    if( (activity < 0) && (errno != EINTR) ) 
      printf("select error\n");fflush(stdout);
      
    // If something happened on the socket
    for(i = 0; i< no_of_sock; i++) {
        
      sock_fd = sockfd[i];

      if(FD_ISSET(sock_fd, &readfds)) {
        // read the incoming message
#ifdef _WIN32
        if((n = recv(sock_fd, &recv_buffer[num_remaining_bytes],sizeof(recv_buffer) - num_remaining_bytes, MSG_PARTIAL)) > 0) {
#else               
        if((n = read(sock_fd, &recv_buffer[num_remaining_bytes],sizeof(recv_buffer) - num_remaining_bytes)) > 0) {
#endif          
          int i;
            
          if (DEBUG)
            fprintf(g_log, ">> Received %d", n);
            
          n += num_remaining_bytes;
          num_remaining_bytes = 0;
          if (DEBUG) {
            for (i = 0; i < n; i++) {
              if ((i % 16) == 0)
                fprintf(g_log, "\n");
              fprintf(g_log, "%02x ", recv_buffer[i]);
            }
            fprintf(g_log, "\n");
          }
            
          for (i = 0; i < n; ) {
            // Indicate when a block of data has been handled by the fact that the pointer can move on
            int increment = 0;

            if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_PRINT) {
              // Data to print to the screen has been received
              unsigned int string_len = 0;

              // Need one byte for type, then 8 bytes of time stamp and 4 bytes of length
              if ((i + PRINT_EVENT_BYTES) <= n) {
                unsigned int string_len = EXTRACT_UINT(recv_buffer, i + 9);

                int string_start = i + PRINT_EVENT_BYTES;
                int string_end = i + PRINT_EVENT_BYTES + string_len;

                // Ensure the buffer won't overflow (has to be after variable
                // declaration for Windows c89 compile)
                assert(string_len < MAX_RECV_BYTES);

                if (string_end <= n) {
                  // Ensure the string is null-terminated - but remember the data byte
                  // in order to be able to restore it.
                  unsigned char tmp = recv_buffer[string_end];
                  recv_buffer[string_end] = '\0';

                  if (new_line && (g_prompt != NULL)) {
                    // When starting to print a message, emit a carriage return in order
                    // to overwrite the prompt
                    printf("\r");
                    new_line = 0;
                  }

                  fwrite(&recv_buffer[string_start], sizeof(unsigned char), string_len, stdout);

                  if (recv_buffer[string_end - 1] == '\n') {
                    // When a string ends with a newline then print the prompt again
                    if (g_prompt != NULL)
                      printf("%s", g_prompt);

                    new_line = 1;
                  }

                  // Because there is no newline character at the end of the prompt and there
                  // may be none at the end of the string then we need to flush explicitly
                  fflush(stdout);

                  // Restore the end character
                  recv_buffer[string_end] = tmp;

                  increment = PRINT_EVENT_BYTES + string_len;
                }  //(string_end <= n)
              }    //((i + PRINT_EVENT_BYTES) <= n)

            } else if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_DATA) {
              // Data has been received, put it into the pcap file
              if ((i + DATA_EVENT_HEADER_BYTES) <= n) {
                int xscope_probe = recv_buffer[i+1];
                int packet_len = EXTRACT_UINT(recv_buffer, i + 4);

                // Fixed-length data packets are encoded with a length of 0
                // but actually carry 8 bytes of data
                if (packet_len == 0)
                  packet_len = 8;

                if ((i + packet_len + DATA_EVENT_BYTES) <= n) {
                  // Data starts after the message header
                  int data_start = i + DATA_EVENT_HEADER_BYTES;

                  // An entire packet has been received - write it to the file
                  total_bytes += packet_len;

                  hook_data_received(sock_fd,xscope_probe, &recv_buffer[data_start], packet_len);
                  increment = packet_len + DATA_EVENT_BYTES;
                }
              }

            } else if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_TARGET_DATA) {
                // The target acknowledges that it has received the message sent
                if ((i + TARGET_DATA_EVENT_BYTES) <= n) {
                  xscope_ep_upload_pending = 0;
                  increment = TARGET_DATA_EVENT_BYTES;
                }

            } else {
                print_and_exit("ERROR: Message format corrupted (received %u)\n", recv_buffer[i]);
            }

            if (increment) {
              i += increment;

            } else {
                // Only part of the packet received - store rest for next iteration
                num_remaining_bytes = n - i;
                memmove(recv_buffer, &recv_buffer[i], num_remaining_bytes);

                if (DEBUG)
                  fprintf(g_log, "%d remaining\n", num_remaining_bytes);

                break;
            }
          } 
        }
      }
    }  
  } //while(1)
}
int main(int argc, char *argv[])
{
#ifdef _WIN32
  HANDLE thread;
#else
  pthread_t tid;
#endif

  char *server_ip = DEFAULT_SERVER_IP;
  char *port_str = DEFAULT_PORT;
  char *filename = DEFAULT_FILE;
  int err = 0;
  int sockfd = 0;
  int c = 0;

  while ((c = getopt(argc, argv, "ls:p:")) != -1) {
    switch (c) {
      case 's':
        server_ip = optarg;
        break;
      case 'p':
        port_str = optarg;
        break;
      case 'l':
        g_libpcap_mode = 1;
        break;
      case ':': /* -f or -o without operand */
        fprintf(stderr, "Option -%c requires an operand\n", optopt);
        err++;
        break;
      case '?':
        fprintf(stderr, "Unrecognized option: '-%c'\n", optopt);
        err++;
    }
  }
  for ( ; optind < argc; optind++) {
    if (filename != DEFAULT_FILE)
      err++;
    filename = argv[optind];
    break;
  }

  if (err)
    usage(argv);

  sockfd = initialise_common(server_ip, port_str);
  g_pcap_fptr = fopen(filename, "wb");

  if (g_libpcap_mode) {
    // Emit libpcap common header
    emit_pcap_header(g_pcap_fptr);

  } else {
    // Emit common header and two interface descriptions as there are two on the tap
    emit_pcapng_section_header_block(g_pcap_fptr);
    emit_pcapng_interface_description_block(g_pcap_fptr);
    emit_pcapng_interface_description_block(g_pcap_fptr);
  }
  fflush(g_pcap_fptr);

  // Now start the console
#ifdef _WIN32
  thread = CreateThread(NULL, 0, console_thread, &sockfd, 0, NULL);
  if (thread == NULL)
    print_and_exit("ERROR: Failed to create console thread\n");
#else
  err = pthread_create(&tid, NULL, &console_thread, &sockfd);
  if (err != 0)
    print_and_exit("ERROR: Failed to create console thread\n");
#endif

  handle_socket(sockfd);

  return 0;
}
Example #8
0
void mutex_acquire(mutex_t *mutex)
{
  if (pthread_mutex_lock(mutex))
    print_and_exit("ERROR: mutex acquire failed\n");
}
Example #9
0
void mutex_release(mutex_t *mutex)
{
  if (pthread_mutex_unlock(mutex))
    print_and_exit("ERROR: mutex release failed\n");
}
Example #10
0
void mutex_create(mutex_t *mutex)
{
  if (pthread_mutex_init(mutex, NULL) != 0)
    print_and_exit("ERROR: mutex init failed\n");
}
Example #11
0
void mutex_release(mutex_t *mutex)
{
  if (! ReleaseMutex(*mutex))
    print_and_exit("ERROR: mutex release failed\n");
}
Example #12
0
void mutex_acquire(mutex_t *mutex)
{
  DWORD result = WaitForSingleObject(*mutex, INFINITE);
  if (result != WAIT_OBJECT_0)
    print_and_exit("ERROR: mutex acquire failed\n");
}
Example #13
0
int initialise_common(char *ip_addr_str, char *port_str)
{
  int sockfd = 0;
  int n = 0;
  unsigned char command_buffer[1];
  struct sockaddr_in serv_addr;
  char *end_pointer = NULL;
  int port = 0;

  if (DEBUG)
    g_log = fopen("run.log", "w");

  signal(SIGINT, interrupt_handler);

#ifdef _WIN32
  {
    //Start up Winsock
    WSADATA wsadata;
    int retval = WSAStartup(0x0202, &wsadata);
    if (retval)
      print_and_exit("ERROR: WSAStartup failed with '%d'\n", retval);

    //Did we get the right Winsock version?
    if (wsadata.wVersion != 0x0202) {
      WSACleanup();
      print_and_exit("ERROR: WSAStartup version incorrect '%x'\n", wsadata.wVersion);
    }
  }
#endif // _WIN32

  if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
    print_and_exit("ERROR: Could not create socket\n");

  memset(&serv_addr, 0, sizeof(serv_addr));

  // Parse the port parameter
  end_pointer = (char*)port_str;
  port = strtol(port_str, &end_pointer, 10);
  if (end_pointer == port_str)
    print_and_exit("ERROR: Failed to parse port\n");

  serv_addr.sin_family = AF_INET;
  serv_addr.sin_port = htons(port);

  if (inet_pton(AF_INET, ip_addr_str, &serv_addr.sin_addr) <= 0)
    print_and_exit("ERROR: inet_pton error occured\n");

  if (connect(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) < 0)
    print_and_exit("ERROR: Connect failed\n");

  // Send the command to request which event types to receive
  command_buffer[0] = XSCOPE_SOCKET_MSG_EVENT_DATA | XSCOPE_SOCKET_MSG_EVENT_PRINT;
  //command_buffer[0] = XSCOPE_SOCKET_MSG_EVENT_DATA;
  n = send(sockfd, command_buffer, 1, 0);
  if (n != 1)
    print_and_exit("ERROR: Command send failed\n");

  printf("Connected\n");

  return sockfd;
}
Example #14
0
/*
 * Function to handle all data being received on the socket. It handles the
 * fact that full messages may not be received together and therefore needs
 * to keep the remainder of any message that hasn't been processed yet.
 */
void handle_socket(int sockfd)
{
  int total_bytes = 0;
  int num_remaining_bytes = 0;
  unsigned char recv_buffer[MAX_RECV_BYTES];
  int n = 0;

  // Keep track of whether a message should be printed at the start of the line
  // and when the prompt needs to be printed
  int new_line = 1;

#ifdef _WIN32
  while ((n = recv(sockfd, &recv_buffer[num_remaining_bytes], sizeof(recv_buffer) - num_remaining_bytes, MSG_PARTIAL)) > 0) {
#else
  while ((n = read(sockfd, &recv_buffer[num_remaining_bytes], sizeof(recv_buffer) - num_remaining_bytes)) > 0) {
#endif
    int i;

    if (DEBUG)
      fprintf(g_log, ">> Received %d", n);

    n += num_remaining_bytes;
    num_remaining_bytes = 0;
    if (DEBUG) {
      for (i = 0; i < n; i++) {
        if ((i % 16) == 0)
          fprintf(g_log, "\n");
        fprintf(g_log, "%02x ", recv_buffer[i]);
      }
      fprintf(g_log, "\n");
    }

    for (i = 0; i < n; ) {
      // Indicate when a block of data has been handled by the fact that the pointer can move on
      int increment = 0;

      if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_PRINT) {
        // Data to print to the screen has been received
        unsigned int string_len = 0;

        // Need one byte for type, then 8 bytes of time stamp and 4 bytes of length
        if ((i + PRINT_EVENT_BYTES) <= n) {
          unsigned int string_len = EXTRACT_UINT(recv_buffer, i + 9);

          int string_start = i + PRINT_EVENT_BYTES;
          int string_end = i + PRINT_EVENT_BYTES + string_len;

          // Ensure the buffer won't overflow (has to be after variable
          // declaration for Windows c89 compile)
          assert(string_len < MAX_RECV_BYTES);

          if (string_end <= n) {
            // Ensure the string is null-terminated - but remember the data byte
            // in order to be able to restore it.
            unsigned char tmp = recv_buffer[string_end];
            recv_buffer[string_end] = '\0';

            if (new_line && (g_prompt != NULL)) {
              // When starting to print a message, emit a carriage return in order
              // to overwrite the prompt
              printf("\r");
              new_line = 0;
            }

            fwrite(&recv_buffer[string_start], sizeof(unsigned char), string_len, stdout);

            if (recv_buffer[string_end - 1] == '\n') {
              // When a string ends with a newline then print the prompt again
              if (g_prompt != NULL)
                printf("%s", g_prompt);

              // Because there is no newline character we need to explictly flush
              fflush(stdout);
              new_line = 1;
            }

            // Restore the end character
            recv_buffer[string_end] = tmp;

            increment = PRINT_EVENT_BYTES + string_len;
          }
        }

      } else if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_DATA) {
        // Data has been received, put it into the pcap file
        if ((i + DATA_EVENT_HEADER_BYTES) <= n) {
          int packet_len = EXTRACT_UINT(recv_buffer, i + 4);

          if ((i + packet_len + DATA_EVENT_BYTES) <= n) {
            // Data starts after the message header
            int data_start = i + DATA_EVENT_HEADER_BYTES;

            // An entire packet has been received - write it to the file
            total_bytes += packet_len;

            hook_data_received(&recv_buffer[data_start], packet_len);
            increment = packet_len + DATA_EVENT_BYTES;
          }
        }

      } else if (recv_buffer[i] == XSCOPE_SOCKET_MSG_EVENT_TARGET_DATA) {
        // The target acknowledges that it has received the message sent
        if ((i + TARGET_DATA_EVENT_BYTES) <= n) {
		  assert(xscope_ep_upload_pending > 0);
          xscope_ep_upload_pending--;
          increment = TARGET_DATA_EVENT_BYTES;
        }

      } else {
        print_and_exit("ERROR: Message format corrupted (received %u)\n", recv_buffer[0]);
      }

      if (increment) {
        i += increment;

      } else {
        // Only part of the packet received - store rest for next iteration
        num_remaining_bytes = n - i;
        memmove(recv_buffer, &recv_buffer[i], num_remaining_bytes);

        if (DEBUG)
          fprintf(g_log, "%d remaining\n", num_remaining_bytes);

        break;
      }
    }
  }
}

void emit_pcap_header(FILE *f)
{
  pcap_hdr_t header = {
    0xA1B2C3D4,             // Byte-Order Magic
    0x2,                    // Major Version
    0x4,                    // Minor Version
    0x0,                    // Time zone (GMT)
    0x0,                    // Accuracy - simply set 0
    CAPTURE_LENGTH,         // Snaplength
    DATA_LINK_ETHERNET,     // Data link type
  };
  fwrite(&header, sizeof(header), 1, f);
}