FD.io VPP  v19.04.4-rc0-5-ge88582fac
Vector Packet Processing
health_check.c
Go to the documentation of this file.
1 #include <stdio.h>
2 #include <stdlib.h>
3 #include <unistd.h>
4 #include <string.h>
5 #include <netinet/in.h>
6 #include <netinet/ip.h>
7 #include <netinet/ip_icmp.h>
8 #include <arpa/inet.h>
9 #include <net/if.h>
10 #include <stdbool.h>
11 #include <errno.h>
12 
13 static void
14 usage (void) {
15  fprintf(stderr,
16  "Usage: health_check"
17  " -d debug"
18  " -I interface"
19  "\n");
20  exit(2);
21 }
22 
23 int
24 main (int argc, char **argv)
25 {
26  int sd, ch;
27  uint8_t *opt, *pkt;
28  struct ifreq ifr;
29  char *interface = NULL;
30  bool debug = false;
31 
32  while ((ch = getopt(argc, argv, "h?" "I:" "d")) != EOF) {
33  switch(ch) {
34  case 'I':
35  interface = optarg;
36  break;
37  case 'd':
38  debug = true;
39  break;
40  default:
41  usage();
42  break;
43  }
44  }
45 
46  argc -= optind;
47  argv += optind;
48 
49  if (!interface)
50  usage();
51 
52  /* Request a socket descriptor sd. */
53  if ((sd = socket (AF_INET6, SOCK_RAW, IPPROTO_IPIP)) < 0) {
54  perror ("Failed to get socket descriptor ");
55  exit (EXIT_FAILURE);
56  }
57 
58  clib_memset(&ifr, 0, sizeof(ifr));
59  snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s", interface);
60 
61  /* Bind socket to interface of this node. */
62  if (setsockopt (sd, SOL_SOCKET, SO_BINDTODEVICE, (void *) &ifr, sizeof (ifr)) < 0) {
63  perror ("SO_BINDTODEVICE failed");
64  exit (EXIT_FAILURE);
65  }
66  if (debug) printf("Binding to interface %s\n", interface);
67 
68  while (1) {
69  struct sockaddr_in6 src_addr;
70  socklen_t addrlen = sizeof(src_addr);
71  char source[INET6_ADDRSTRLEN+1];
72  int len;
73  uint8_t inpack[IP_MAXPACKET];
74 
75  if ((len = recvfrom(sd, inpack, sizeof(inpack), 0, (struct sockaddr *)&src_addr, &addrlen)) < 0) {
76  perror("recvfrom failed ");
77  }
78  if (inet_ntop(AF_INET6, &src_addr.sin6_addr, source, INET6_ADDRSTRLEN) == NULL) {
79  perror("inet_ntop() failed.");
80  exit(EXIT_FAILURE);
81  }
82 
83  /* Reply */
84  struct iphdr *ip = (struct iphdr *)inpack;
85  uint32_t saddr;
86  struct icmphdr *icmp;
87 
88  saddr = ip->saddr;
89  ip->saddr = ip->daddr;
90  ip->daddr = saddr;
91 
92  switch (ip->protocol) {
93  case 1:
94  if (debug) printf ("ICMP Echo request from %s\n", source);
95  icmp = (struct icmphdr *)&ip[1];
96  icmp->type = ICMP_ECHOREPLY;
97  break;
98  default:
99  fprintf(stderr, "Unsupported protocol %d", ip->protocol);
100  }
101  if (len = sendto(sd, inpack, len, 0, (struct sockaddr *)&src_addr, addrlen) < 0) {
102  perror("sendto failed ");
103  }
104  }
105 
106  close (sd);
107 
108  return (EXIT_SUCCESS);
109 }
Optimized string handling code, including c11-compliant "safe C library" variants.
#define NULL
Definition: clib.h:58
clib_memset(h->entries, 0, sizeof(h->entries[0]) *entries)
static void usage(void)
Definition: health_check.c:14
u8 len
Definition: ip_types.api:49
int main(int argc, char **argv)
Definition: health_check.c:24