nmsg  0.9.0
sock.c
1 /*
2  * Copyright (c) 2010, 2012 by Farsight Security, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 /* Import. */
18 
19 #include <arpa/inet.h>
20 
21 #include "private.h"
22 
23 /* Export. */
24 
26 nmsg_sock_parse(int af, const char *addr, unsigned port,
27  struct sockaddr_in *sai,
28  struct sockaddr_in6 *sai6,
29  struct sockaddr **sa,
30  socklen_t *salen)
31 {
32  switch (af) {
33 
34  case AF_INET:
35  if (!inet_pton(AF_INET, addr, &sai->sin_addr))
36  return (nmsg_res_parse_error);
37 
38  sai->sin_family = AF_INET;
39  sai->sin_port = htons(port);
40 #ifdef HAVE_SA_LEN
41  sai->sin_len = sizeof(struct sockaddr_in);
42 #endif
43  *sa = (struct sockaddr *) sai;
44  *salen = sizeof(struct sockaddr_in);
45  break;
46 
47  case AF_INET6:
48  if (!inet_pton(AF_INET6, addr, &sai6->sin6_addr))
49  return (nmsg_res_parse_error);
50 
51  sai6->sin6_family = AF_INET6;
52  sai6->sin6_port = htons(port);
53 #ifdef HAVE_SA_LEN
54  sai6->sin6_len = sizeof(struct sockaddr_in6);
55 #endif
56  *sa = (struct sockaddr *) sai6;
57  *salen = sizeof(struct sockaddr_in6);
58  break;
59 
60  default:
61  assert(af != AF_INET && af != AF_INET6);
62  }
63 
64  return (nmsg_res_success);
65 }
66 
68 nmsg_sock_parse_sockspec(const char *sockspec, int *af, char **addr,
69  unsigned *port_start, unsigned *port_end)
70 {
71  char *sock = NULL;
72  char *sock_addr = NULL;
73  char *t;
75  int n;
76  uint8_t buf[16];
77 
78  sock = strdup(sockspec);
79  assert(sock != NULL);
80 
81  /* tokenize socket address */
82  sock_addr = calloc(1, INET6_ADDRSTRLEN);
83  assert(sock_addr != NULL);
84  t = strchr(sockspec, '/');
85  if (t == NULL)
86  goto out;
87  memcpy(sock_addr, sockspec, t - sockspec);
88  sock_addr[t - sockspec] = '\x00';
89 
90  /* parse socket address */
91  if (inet_pton(AF_INET6, sock_addr, buf)) {
92  *af = AF_INET6;
93  *addr = strdup(sock_addr);
94  if (*addr == NULL)
95  goto out;
96  } else if (inet_pton(AF_INET, sock_addr, buf)) {
97  *af = AF_INET;
98  *addr = strdup(sock_addr);
99  if (*addr == NULL)
100  goto out;
101  }
102 
103  n = sscanf(t + 1, "%d..%d", port_start, port_end);
104  if (n == 1)
105  *port_end = *port_start;
106  else if (n <= 0)
107  goto out;
108 
109  /* parsed successfully */
110  res = nmsg_res_success;
111 
112 out:
113  free(sock);
114  free(sock_addr);
115  return (res);
116 }
nmsg_res nmsg_sock_parse(int af, const char *addr, unsigned port, struct sockaddr_in *sai, struct sockaddr_in6 *sai6, struct sockaddr **sa, socklen_t *salen)
Parse an IP address and port number into a sockaddr.
Definition: sock.c:26
nmsg_res
nmsg result code
Definition: res.h:25
success
Definition: res.h:26
nmsg_res nmsg_sock_parse_sockspec(const char *sockspec, int *af, char **addr, unsigned *port_start, unsigned *port_end)
Parse a "socket spec" string.
Definition: sock.c:68
generic failure
Definition: res.h:27
unable to parse input
Definition: res.h:36