aboutsummaryrefslogtreecommitdiffstats
path: root/src/vnet/map/examples/health_check.c
blob: 5f0d85fec0814283861a34a8804fc7e895ec1318 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <netinet/in.h>
#include <netinet/ip.h>
#include <netinet/ip_icmp.h>
#include <arpa/inet.h>
#include <net/if.h>
#include <stdbool.h>
#include <errno.h>

static void
usage (void) {
  fprintf(stderr,
	  "Usage: health_check"
	  " -d debug"
	  " -I interface"
	  "\n");
  exit(2);
}

int
main (int argc, char **argv)
{
  int sd, ch;
  uint8_t *opt, *pkt;
  struct ifreq ifr;
  char *interface = NULL;
  bool debug = false;

  while ((ch = getopt(argc, argv, "h?" "I:" "d")) != EOF) {
    switch(ch) {
    case 'I':
      interface = optarg;
      break;
    case 'd':
      debug = true;
      break;
    default:
      usage();
      break;
    }
  }

  argc -= optind;
  argv += optind;

  if (!interface)
    usage();

  /* Request a socket descriptor sd. */
  if ((sd = socket (AF_INET6, SOCK_RAW, IPPROTO_IPIP)) < 0) {
    perror ("Failed to get socket descriptor ");
    exit (EXIT_FAILURE);
  }

  memset(&ifr, 0, sizeof(ifr));
  snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", interface);

  /* Bind socket to interface of this node. */
  if (setsockopt (sd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr, sizeof (ifr)) < 0) {
    perror ("SO_BINDTODEVICE failed");
    exit (EXIT_FAILURE);
  }
  if (debug) printf("Binding to interface %s\n", interface);

  while (1) {
    struct sockaddr_in6 src_addr;
    socklen_t addrlen = sizeof(src_addr);
    char source[INET6_ADDRSTRLEN+1];
    int len;
    uint8_t inpack[IP_MAXPACKET];

    if ((len = recvfrom(sd, inpack, sizeof(inpack), 0, (struct sockaddr *)&src_addr, &addrlen)) < 0) {
      perror("recvfrom failed ");
    }
    if (inet_ntop(AF_INET6, &src_addr.sin6_addr, source, INET6_ADDRSTRLEN) == NULL) {
      perror("inet_ntop() failed.");
      exit(EXIT_FAILURE);
    }

    /* Reply */
    struct iphdr *ip = (struct iphdr *)inpack;
    uint32_t saddr;
    struct icmphdr *icmp;

    saddr = ip->saddr;
    ip->saddr = ip->daddr;
    ip->daddr = saddr;

    switch (ip->protocol) {
    case 1:
      if (debug) printf ("ICMP Echo request from %s\n", source);
      icmp = (struct icmphdr *)&ip[1];
      icmp->type = ICMP_ECHOREPLY;
      break;
    default:
      fprintf(stderr, "Unsupported protocol %d", ip->protocol);
    }
    if (len = sendto(sd, inpack, len, 0, (struct sockaddr *)&src_addr, addrlen) < 0) {
      perror("sendto failed ");
    }
  }

  close (sd);

  return (EXIT_SUCCESS);
}
clib_memcpy_fast (rw->data, data, data_bytes); clib_memset (rw->data + data_bytes, 0xfe, max_size - data_bytes); } #define vnet_rewrite_set_data(rw,data,data_bytes) \ vnet_rewrite_set_data_internal (&((rw).rewrite_header), \ sizeof ((rw).rewrite_data), \ (data), \ (data_bytes)) always_inline void * vnet_rewrite_get_data_internal (vnet_rewrite_header_t * rw, int max_size) { ASSERT (rw->data_bytes <= max_size); return rw->data; } #define vnet_rewrite_get_data(rw) \ vnet_rewrite_get_data_internal (&((rw).rewrite_header), sizeof ((rw).rewrite_data)) always_inline void _vnet_rewrite_one_header (vnet_rewrite_header_t * h0, void *packet0, int max_size, int most_likely_size) { /* 0xfefe => poisoned adjacency => crash */ ASSERT (h0->data_bytes != 0xfefe); if (PREDICT_TRUE (most_likely_size == h0->data_bytes)) { clib_memcpy_fast ((u8 *) packet0 - most_likely_size, h0->data, most_likely_size); } else { clib_memcpy_fast ((u8 *) packet0 - h0->data_bytes, h0->data, h0->data_bytes); } } always_inline void _vnet_rewrite_two_headers (vnet_rewrite_header_t * h0, vnet_rewrite_header_t * h1, void *packet0, void *packet1, int max_size, int most_likely_size) { /* 0xfefe => poisoned adjacency => crash */ ASSERT (h0->data_bytes != 0xfefe); ASSERT (h1->data_bytes != 0xfefe); if (PREDICT_TRUE (most_likely_size == h0->data_bytes && most_likely_size == h1->data_bytes)) { clib_memcpy_fast ((u8 *) packet0 - most_likely_size, h0->data, most_likely_size); clib_memcpy_fast ((u8 *) packet1 - most_likely_size, h1->data, most_likely_size); } else { clib_memcpy_fast ((u8 *) packet0 - h0->data_bytes, h0->data, h0->data_bytes); clib_memcpy_fast ((u8 *) packet1 - h1->data_bytes, h1->data, h1->data_bytes); } } #define vnet_rewrite_one_header(rw0,p0,most_likely_size) \ _vnet_rewrite_one_header (&((rw0).rewrite_header), (p0), \ sizeof ((rw0).rewrite_data), \ (most_likely_size)) #define vnet_rewrite_two_headers(rw0,rw1,p0,p1,most_likely_size) \ _vnet_rewrite_two_headers (&((rw0).rewrite_header), &((rw1).rewrite_header), \ (p0), (p1), \ sizeof ((rw0).rewrite_data), \ (most_likely_size)) always_inline void vnet_ip_mcast_fixup_header (u32 dst_mcast_mask, u32 dst_mcast_offset, u32 * addr, u8 * packet0) { if (PREDICT_TRUE (0 != dst_mcast_offset)) { /* location to write to in the packet */ u8 *p0 = packet0 - dst_mcast_offset; u32 *p1 = (u32 *) p0; *p1 |= (*addr & dst_mcast_mask); } } #define VNET_REWRITE_FOR_SW_INTERFACE_ADDRESS_BROADCAST ((void *) 0) /** Deprecated */ void vnet_rewrite_for_sw_interface (struct vnet_main_t *vnm, vnet_link_t packet_type, u32 sw_if_index, u32 node_index, void *dst_address, vnet_rewrite_header_t * rw, u32 max_rewrite_bytes); u32 vnet_tx_node_index_for_sw_interface (struct vnet_main_t *vnm, u32 sw_if_index); void vnet_rewrite_init (struct vnet_main_t *vnm, u32 sw_if_index, vnet_link_t linkt, u32 this_node, u32 next_node, vnet_rewrite_header_t * rw); void vnet_rewrite_update_mtu (struct vnet_main_t *vnm, vnet_link_t linkt, vnet_rewrite_header_t * rw); u8 *vnet_build_rewrite_for_sw_interface (struct vnet_main_t *vnm, u32 sw_if_index, vnet_link_t packet_type, const void *dst_address); void vnet_update_adjacency_for_sw_interface (struct vnet_main_t *vnm, u32 sw_if_index, u32 ai); format_function_t format_vnet_rewrite; serialize_function_t serialize_vnet_rewrite, unserialize_vnet_rewrite; #endif /* included_vnet_rewrite_h */ /* * fd.io coding-style-patch-verification: ON * * Local Variables: * eval: (c-set-style "gnu") * End: */