Coverage Report

Created: 2024-02-25 06:37

/src/ntopng/third-party/snmp/net.c
Line
Count
Source (jump to first uncovered line)
1
2
#include <stdio.h>
3
#include <string.h>
4
#include <stdlib.h>
5
#ifndef WIN32
6
#include <arpa/inet.h>
7
#include <netinet/in.h>
8
#include <sys/types.h>
9
#include <sys/socket.h>
10
#include <netdb.h>
11
#include <errno.h>
12
#endif
13
14
#ifndef __USE_GNU
15
#define __USE_GNU
16
#endif
17
18
#ifdef WIN32
19
#define gethostbyname2(a, b) gethostbyname(a)
20
#else
21
#include <unistd.h>
22
#endif
23
24
0
#define BUFLEN 65535
25
26
void diep(char *s)
27
0
{
28
0
  perror(s);
29
0
  exit(1);
30
0
}
31
32
int split_host_port(char *input, int default_port, char **host, int *port)
33
0
{
34
0
  char *p;
35
    
36
0
  *host = strdup(input);
37
    
38
0
  if ((p = strchr(*host, ':')))
39
0
    {
40
0
      *port = strtol(p+1, NULL, 0);
41
0
      *p = 0;
42
0
    }
43
0
  else
44
0
    {
45
0
      *port = default_port;
46
0
    }
47
    
48
0
  return 1;
49
0
}
50
51
int open_udp_socket(int port)
52
0
{
53
0
  struct sockaddr_in si_me;
54
0
  int s;
55
0
  int reuse = 1;
56
    
57
0
  if ((s = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
58
0
    return(-1); // diep("socket");
59
60
0
  if (setsockopt(s, SOL_SOCKET, SO_REUSEADDR, (const char*)&reuse, sizeof(reuse)) != 0)
61
0
    return(-1); //diep("setsockaopt");
62
63
0
  memset((char *) &si_me, 0, sizeof(si_me));
64
0
  si_me.sin_family = AF_INET;
65
0
  si_me.sin_port = htons(port);
66
0
  si_me.sin_addr.s_addr = htonl(INADDR_ANY);
67
0
  if (::bind(s, (struct sockaddr *) &si_me, sizeof(si_me)) != 0)
68
0
    return(-1); //diep("bind");
69
    
70
0
  return s;
71
0
}
72
73
void send_udp_datagram(void *buf, int len, int socket, char *target_host, int target_port)
74
0
{
75
0
  struct sockaddr_in target_si;
76
77
0
  struct addrinfo hints, *res = NULL, *p;
78
0
  int errcode;
79
80
0
  memset(&target_si, 0, sizeof(target_si));
81
0
  memset(&hints, 0, sizeof(hints));
82
0
  hints.ai_family = AF_INET; /* IPv4 */
83
  //  hints.ai_socktype = SOCK_STREAM;
84
  //  hints.ai_flags |= AI_CANONNAME;
85
86
0
  if((errcode = getaddrinfo(target_host, NULL, &hints, &res))
87
0
     || !res)
88
0
    return;
89
90
0
  for (p = res; p != NULL; p = p->ai_next) {
91
0
    memcpy(&target_si, res->ai_addr, res->ai_addrlen);
92
0
    break;
93
0
  }
94
95
0
  freeaddrinfo(res);
96
97
0
  target_si.sin_port = htons(target_port);
98
    
99
0
  if (sendto(socket, (const char*)buf, len, 0, (struct sockaddr *) &target_si, sizeof(target_si)) == -1)
100
0
    return; //diep("sendto");
101
0
}    
102
103
int receive_udp_datagram(void *buf, int max, int socket, char **sender_host, int *sender_port)
104
0
{
105
0
  struct sockaddr_in sender_si;
106
0
  int slen = sizeof(sender_si);
107
0
  int nr;
108
    
109
0
  nr = recvfrom(socket, (char*)buf, BUFLEN, 
110
#ifdef WIN32
111
    0,
112
#else
113
0
    MSG_DONTWAIT, // TODO: add select() to avoid waiting forever
114
0
#endif
115
0
    (struct sockaddr *) &sender_si, (socklen_t*)&slen);
116
0
  if (nr == -1)
117
0
    {
118
0
      if (errno == EAGAIN || errno == EWOULDBLOCK)
119
0
  return 0;
120
        
121
0
      return(-1); //diep("recvfrom");
122
0
    }
123
    
124
0
  if (sender_host)
125
0
    *sender_host = inet_ntoa(sender_si.sin_addr);
126
    
127
0
  if (sender_port)
128
0
    *sender_port = ntohs(sender_si.sin_port);
129
    
130
0
  return nr;
131
0
}
132
133
/* Borrowed from the GNU libc manual. */
134
int input_timeout(int filedes, unsigned int seconds)
135
0
{
136
0
  fd_set set;
137
0
  struct timeval timeout;
138
139
  /* Initialize the file descriptor set. */
140
0
  FD_ZERO(&set);
141
0
  FD_SET(filedes, &set);
142
143
  /* Initialize the timeout data structure. */
144
0
  timeout.tv_sec = seconds;
145
0
  timeout.tv_usec = 0;
146
147
  /* `select' returns 0 if timeout, 1 if input available, -1 if error. */
148
0
  return /* TEMP_FAILURE_RETRY*/(select(FD_SETSIZE,
149
0
          &set, NULL, NULL,
150
0
          &timeout));
151
0
}