1 #ifndef _SNMP_TRANSPORT_H
2 #define _SNMP_TRANSPORT_H
3 
4 /*
5  * Portions of this file are copyrighted by:
6  * Copyright (c) 2016 VMware, Inc. All rights reserved.
7  * Use is subject to license terms specified in the COPYING file
8  * distributed with the Net-SNMP package.
9  */
10 #include <sys/types.h>
11 
12 #if HAVE_SYS_SOCKET_H
13 #ifdef solaris2
14 #define _XPG4_2
15 #endif
16 
17 #if defined(aix4) || defined(aix5) || defined(aix6) || defined(aix7)
18 #define _LINUX_SOURCE_COMPAT
19 #endif
20 
21 #include <sys/socket.h>
22 
23 #ifdef solaris2
24 # ifndef CMSG_SPACE
25 #  define CMSG_SPACE(l) \
26             ((unsigned int)_CMSG_HDR_ALIGN(sizeof (struct cmsghdr) + (l)))
27 #  define CMSG_LEN(l)   (_CMSG_HDR_ALIGN(sizeof(struct cmsghdr)) + (l))
28 # endif
29 #endif
30 #endif /* HAVE_SYS_SOCKET_H */
31 
32 #ifdef HAVE_NETINET_IN_H
33 #include <netinet/in.h>
34 #endif
35 
36 #include <net-snmp/library/asn1.h>
37 
38 #ifdef __cplusplus
39 extern          "C" {
40 #endif
41 
42 /*  Some transport-type constants.  */
43 
44 #ifndef NETSNMP_STREAM_QUEUE_LEN
45 #define	NETSNMP_STREAM_QUEUE_LEN	5
46 #endif
47 
48 /*  Some transport-type flags.  */
49 
50 #define		NETSNMP_TRANSPORT_FLAG_STREAM	 0x01
51 #define		NETSNMP_TRANSPORT_FLAG_LISTEN	 0x02
52 #define		NETSNMP_TRANSPORT_FLAG_TUNNELED	 0x04
53 #define         NETSNMP_TRANSPORT_FLAG_TMSTATE   0x08  /* indicates opaque is a
54                                                           TSM tmStateReference */
55 #define		NETSNMP_TRANSPORT_FLAG_EMPTY_PKT 0x10
56 #define		NETSNMP_TRANSPORT_FLAG_OPENED	 0x20  /* f_open called */
57 #define		NETSNMP_TRANSPORT_FLAG_SHARED	 0x40
58 #define		NETSNMP_TRANSPORT_FLAG_HOSTNAME	 0x80  /* for fmtaddr hook */
59 
60 /*  The standard SNMP domains.  */
61 
62 NETSNMP_IMPORT oid      netsnmpUDPDomain[]; 	/*      = { 1, 3, 6, 1, 6, 1, 1 };  */
63 NETSNMP_IMPORT oid      netsnmpCLNSDomain[];    /*      = { 1, 3, 6, 1, 6, 1, 2 };  */
64 NETSNMP_IMPORT oid      netsnmpCONSDomain[];    /*      = { 1, 3, 6, 1, 6, 1, 3 };  */
65 NETSNMP_IMPORT oid      netsnmpDDPDomain[]; 	/*      = { 1, 3, 6, 1, 6, 1, 4 };  */
66 NETSNMP_IMPORT oid      netsnmpIPXDomain[]; 	/*      = { 1, 3, 6, 1, 6, 1, 5 };  */
67 NETSNMP_IMPORT size_t   netsnmpUDPDomain_len;
68 NETSNMP_IMPORT size_t   netsnmpCLNSDomain_len;
69 NETSNMP_IMPORT size_t   netsnmpCONSDomain_len;
70 NETSNMP_IMPORT size_t   netsnmpDDPDomain_len;
71 NETSNMP_IMPORT size_t   netsnmpIPXDomain_len;
72 
73 /* Structure which stores transport security model specific parameters */
74 /* isms-secshell-11 section 4.1 */
75 
76 /* contents documented in draft-ietf-isms-transport-security-model
77    Section 3.2 */
78 /* note: VACM only allows <= 32 so this is overkill till another ACM comes */
79 #define NETSNMP_TM_MAX_SECNAME 256
80 
81 typedef union netsnmp_sockaddr_storage_u {
82     struct sockaddr     sa;
83     struct sockaddr_in  sin;
84 #ifdef NETSNMP_ENABLE_IPV6
85     struct sockaddr_in6 sin6;
86 #endif
87 } netsnmp_sockaddr_storage;
88 
89 typedef struct netsnmp_addr_pair_s {
90    netsnmp_sockaddr_storage remote_addr;
91    netsnmp_sockaddr_storage local_addr;
92 } netsnmp_addr_pair;
93 
94 typedef struct netsnmp_indexed_addr_pair_s {
95    netsnmp_sockaddr_storage remote_addr;
96    netsnmp_sockaddr_storage local_addr;
97     int if_index;
98 } netsnmp_indexed_addr_pair;
99 
100 typedef struct netsnmp_tmStateReference_s {
101    oid    transportDomain[MAX_OID_LEN];
102    size_t transportDomainLen;
103    char   securityName[NETSNMP_TM_MAX_SECNAME];
104    size_t securityNameLen;
105    int    requestedSecurityLevel;
106    int    transportSecurityLevel;
107    char   sameSecurity;
108    char   sessionID[8];
109 
110    char   have_addresses;
111    netsnmp_indexed_addr_pair addresses;
112 
113    void *otherTransportOpaque; /* XXX: May have mem leak issues */
114 } netsnmp_tmStateReference;
115 
116 #define NETSNMP_TSPEC_LOCAL                     0x01 /* 1=server, 0=client */
117 
118 struct netsnmp_container_s; /* forward decl */
119 typedef struct netsnmp_tdomain_spec_s {
120     const char *application;             /* application name */
121     const char *target;                  /* target as string */
122     u_int       flags;
123     const char *default_domain;          /* default domain */
124     const char *default_target;          /* default target */
125     const char *source;                  /* source as string iff remote */
126     struct netsnmp_container_s *transport_config; /* extra config */
127 } netsnmp_tdomain_spec;
128 
129 /*  Structure which defines the transport-independent API.  */
130 
131 struct snmp_session;
132 
133 typedef struct netsnmp_transport_s {
134     /*  The transport domain object identifier.  */
135 
136     const oid      *domain;
137     int             domain_length;  /*  In sub-IDs, not octets.  */
138 
139     /*  Local transport address (in relevant SNMP-style encoding).  */
140 
141     void           *local;
142     int             local_length;   /*  In octets.  */
143 
144     /*  Remote transport address (in relevant SNMP-style encoding).  */
145 
146     void           *remote;
147     int             remote_length;  /*  In octets.  */
148 
149     /*  The actual socket.  */
150 
151     int             sock;
152 
153     /*  Flags (see #definitions above).  */
154 
155     unsigned int    flags;
156 
157     /*  Protocol-specific opaque data pointer.  */
158 
159     void           *data;
160     int             data_length;
161 
162     /*  Maximum size of PDU that can be sent/received by this transport.  */
163 
164     size_t          msgMaxSize;
165 
166 #ifdef FOR_STANDARDS_COMPLIANCE_OR_FUTURE_USE
167     /* TM state reference per ISMS WG solution */
168     netsnmp_tmStateReference *tmStateRef;
169 #endif
170 
171     /* tunneled transports */
172     struct netsnmp_transport_s * base_transport;
173 
174     /*  Callbacks.  Arguments are:
175      *
176      *              "this" pointer, fd, buf, size, *opaque, *opaque_length
177      */
178 
179     int             (*f_recv)   (struct netsnmp_transport_s *, void *,
180 				 int, void **, int *);
181     int             (*f_send)   (struct netsnmp_transport_s *, const void *,
182 				 int, void **, int *);
183     int             (*f_close)  (struct netsnmp_transport_s *);
184 
185     /* Optional: opening can occur during creation if more appropriate */
186    struct netsnmp_transport_s * (*f_open)   (struct netsnmp_transport_s *);
187 
188     /*  This callback is only necessary for stream-oriented transports.  */
189 
190     int             (*f_accept) (struct netsnmp_transport_s *);
191 
192     /*  Optional callback to format a transport address.  */
193 
194     char           *(*f_fmtaddr)(struct netsnmp_transport_s *, const void *,
195                                  int);
196 
197     /*  Optional callback to support extra configuration token/value pairs */
198     /*  return non-zero on error */
199     int            (*f_config)(struct netsnmp_transport_s *, const char *,
200                                const char *);
201 
202     /*  Optional callback that is called after the first transport is
203         cloned to the second */
204     int            (*f_copy)(const struct netsnmp_transport_s *,
205                              struct netsnmp_transport_s *);
206 
207     /*  Setup initial session config if special things are needed */
208    int             (*f_setup_session)(struct netsnmp_transport_s *,
209                                       struct snmp_session *);
210 
211     /* allocated host name identifier; used by configuration system
212        to load localhost.conf for host-specific configuration */
213     u_char         *identifier; /* udp:localhost:161 -> "localhost" */
214 
215     /* Duplicate the remote address in the format required by SNMP-TARGET-MIB */
216     void           (*f_get_taddr)(struct netsnmp_transport_s *t,
217                                   void **addr, size_t *addr_len);
218 
219 } netsnmp_transport;
220 
221 typedef struct netsnmp_transport_list_s {
222     netsnmp_transport *transport;
223     struct netsnmp_transport_list_s *next;
224 } netsnmp_transport_list;
225 
226 typedef struct netsnmp_tdomain_s {
227     const oid      *name;
228     size_t          name_length;
229     const char    **prefix;
230 
231     /*
232      * The f_create_from_tstring and f_create_from_tstring_new fields are
233      * deprecated, please do not use them for new code and try to migrate
234      * old code away from using them.
235      */
236     netsnmp_transport *(*f_create_from_tstring) (const char *, int);
237 
238     /* @o and @o_len define an address in the format used by SNMP-TARGET-MIB */
239     netsnmp_transport *(*f_create_from_ostring) (const void *o, size_t o_len,
240                                                  int local);
241 
242     struct netsnmp_tdomain_s *next;
243 
244     /** deprecated, please do not use it */
245     netsnmp_transport *(*f_create_from_tstring_new) (const char *, int,
246 						     const char*);
247     netsnmp_transport *(*f_create_from_tspec) (netsnmp_tdomain_spec *);
248 
249 } netsnmp_tdomain;
250 
251 void init_snmp_transport(void);
252 void shutdown_snmp_transport(void);
253 
254 /*  Some utility functions.  */
255 
256 char *netsnmp_transport_peer_string(netsnmp_transport *t, const void *data,
257                                     int len);
258 
259 int netsnmp_transport_send(netsnmp_transport *t, const void *data, int len,
260                            void **opaque, int *olength);
261 int netsnmp_transport_recv(netsnmp_transport *t, void *data, int len,
262                            void **opaque, int *olength);
263 
264 int netsnmp_transport_add_to_list(netsnmp_transport_list **transport_list,
265 				  netsnmp_transport *transport);
266 int netsnmp_transport_remove_from_list(netsnmp_transport_list **transport_list,
267 				       netsnmp_transport *transport);
268 int netsnmp_sockaddr_size(const struct sockaddr *sa);
269 
270 
271 /*
272  * Return an exact (deep) copy of t, or NULL if there is a memory allocation
273  * problem (for instance).
274  */
275 
276 netsnmp_transport *netsnmp_transport_copy(const netsnmp_transport *t);
277 
278 
279 /*  Free an netsnmp_transport.  */
280 
281 NETSNMP_IMPORT
282 void            netsnmp_transport_free(netsnmp_transport *t);
283 
284 #ifndef FEATURE_REMOVE_TRANSPORT_CACHE
285 
286 /**  transport cache support */
287 
288 NETSNMP_IMPORT
289 netsnmp_transport *netsnmp_transport_cache_get(int af, int type, int local,
290                                                const netsnmp_sockaddr_storage *bind_addr);
291 
292 NETSNMP_IMPORT
293 int                netsnmp_transport_cache_save(int af, int type, int local,
294                                                 const netsnmp_sockaddr_storage *addr,
295                                                 netsnmp_transport *t);
296 
297 NETSNMP_IMPORT
298 int                netsnmp_transport_cache_remove(netsnmp_transport *t);
299 
300 #endif /* FEATURE_REMOVE_TRANSPORT_CACHE */
301 
302 /*
303  * If the passed oid (in_oid, in_len) corresponds to a supported transport
304  * domain, return 1; if not return 0.  If out_oid is not NULL and out_len is
305  * not NULL, then the "internal" oid which should be used to identify this
306  * domain (e.g. in pdu->tDomain etc.) is written to *out_oid and its length to
307  * *out_len.
308  */
309 
310 NETSNMP_IMPORT
311 int             netsnmp_tdomain_support(const oid *in_oid, size_t in_len,
312 					const oid **out_oid, size_t *out_len);
313 
314 int             netsnmp_tdomain_register(netsnmp_tdomain *domain);
315 
316 int             netsnmp_tdomain_unregister(netsnmp_tdomain *domain);
317 
318 NETSNMP_IMPORT
319 void            netsnmp_clear_tdomain_list(void);
320 
321 void            netsnmp_tdomain_init(void);
322 
323 NETSNMP_IMPORT
324 netsnmp_transport *netsnmp_tdomain_transport(const char *str,
325 					     int local,
326 					     const char *default_domain);
327 
328 NETSNMP_IMPORT
329 netsnmp_transport *netsnmp_tdomain_transport_full(const char *application,
330 						  const char *str,
331 						  int local,
332 						  const char *default_domain,
333 						  const char *default_target);
334 
335 NETSNMP_IMPORT
336 netsnmp_transport *netsnmp_tdomain_transport_oid(const oid * dom,
337 						 size_t dom_len,
338 						 const u_char * o,
339 						 size_t o_len,
340 						 int local);
341 
342 NETSNMP_IMPORT
343 netsnmp_transport *netsnmp_tdomain_transport_tspec(netsnmp_tdomain_spec *tspec);
344 
345 NETSNMP_IMPORT
346 netsnmp_transport*
347 netsnmp_transport_open_client(const char* application, const char* str);
348 
349 NETSNMP_IMPORT
350 netsnmp_transport*
351 netsnmp_transport_open_server(const char* application, const char* str);
352 
353 netsnmp_transport*
354 netsnmp_transport_open(const char* application, const char* str, int local);
355 
356 typedef struct netsnmp_transport_config_s {
357    char *key;
358    char *value;
359 } netsnmp_transport_config;
360 
361 NETSNMP_IMPORT
362 int netsnmp_transport_config_compare(netsnmp_transport_config *left,
363                                      netsnmp_transport_config *right);
364 NETSNMP_IMPORT
365 netsnmp_transport_config *netsnmp_transport_create_config(const char *key,
366                                                           const char *value);
367 
368 #ifndef NETSNMP_FEATURE_REMOVE_FILTER_SOURCE
369 NETSNMP_IMPORT
370 void netsnmp_transport_parse_filterType(const char *word, char *cptr);
371 
372 NETSNMP_IMPORT
373 int netsnmp_transport_filter_add(const char *addrtxt);
374 
375 NETSNMP_IMPORT
376 int netsnmp_transport_filter_remove(const char *addrtxt);
377 
378 NETSNMP_IMPORT
379 int netsnmp_transport_filter_check(const char *addrtxt);
380 
381 NETSNMP_IMPORT
382 void netsnmp_transport_filter_cleanup(void);
383 
384 #endif /* NETSNMP_FEATURE_REMOVE_FILTER_SOURCE */
385 
386 #ifdef __cplusplus
387 }
388 #endif
389 #endif/*_SNMP_TRANSPORT_H*/
390