Radcli library 2.0.0
A simple radius library -- legacy API reference
Loading...
Searching...
No Matches
ip_util.c
1/*
2 * Copyright (C) 1995,1996,1997 Lars Fenneberg
3 *
4 * Copyright 1992 Livingston Enterprises, Inc.
5 *
6 * Copyright 1992,1993, 1994,1995 The Regents of the University of Michigan
7 * and Merit Network, Inc. All Rights Reserved
8 *
9 * See the file COPYRIGHT for the respective terms and conditions.
10 * If the file is missing contact me at lf@elemental.net
11 * and I'll send you a copy.
12 *
13 */
14
15#include <config.h>
16#include <includes.h>
17#include <radcli/radcli.h>
18#include "options.h"
19#include "util.h"
20
21#define HOSTBUF_SIZE 1024
22
23/*- Returns a struct addrinfo from a host name or address in textual notation.
24 *
25 * @param host the name of the host
26 * @param flags should be a combination of PW_AI flags
27 * @return address which should be deallocated using freeaddrinfo() or NULL on failure
28 -*/
29struct addrinfo *rc_getaddrinfo (char const *host, unsigned flags)
30{
31 struct addrinfo hints, *res;
32 int err;
33 const char *service = NULL;
34
35 memset(&hints, 0, sizeof(hints));
36 hints.ai_socktype = SOCK_DGRAM;
37 if (flags & PW_AI_PASSIVE)
38 hints.ai_flags = AI_PASSIVE;
39
40 if (flags & PW_AI_AUTH)
41 service = "radius";
42 else if (flags & PW_AI_ACCT)
43 service = "radius-acct";
44
45 err = getaddrinfo(host, service, &hints, &res);
46 if (err != 0) {
47 rc_log(LOG_ERR, "rc_getaddrinfo: %s: %s", host ? host : "(null)", gai_strerror(err));
48 return NULL;
49 }
50
51 return res;
52}
53
54/*- Find the local source address the system would use to reach ria.
55 *
56 * @param lia set to the local address on success.
57 * @param ria the remote address to probe a route towards.
58 * @return OK_RC on success; NETUNREACH_RC if there is no route to ria;
59 * ERROR_RC for any other failure.
60 -*/
61int radcli2_priv_get_srcaddr(struct sockaddr *lia, const struct sockaddr *ria)
62{
63 int temp_sock;
64 socklen_t namelen;
65
66 temp_sock = socket(ria->sa_family, SOCK_DGRAM, 0);
67 if (temp_sock == -1) {
68 rc_log(LOG_ERR, "radcli2_priv_get_srcaddr: socket: %s", strerror(errno));
69 return ERROR_RC;
70 }
71
72 if (connect(temp_sock, ria, SA_LEN(ria)) != 0) {
73 int rc = errno == ENETUNREACH ? NETUNREACH_RC : ERROR_RC;
74 rc_log(LOG_ERR, "radcli2_priv_get_srcaddr: connect: %s",
75 strerror(errno));
76 close(temp_sock);
77 return rc;
78 }
79
80 namelen = SA_LEN(ria);
81 if (getsockname(temp_sock, lia, &namelen) != 0) {
82 rc_log(LOG_ERR, "radcli2_priv_get_srcaddr: getsockname: %s",
83 strerror(errno));
84 close(temp_sock);
85 return ERROR_RC;
86 }
87
88 close(temp_sock);
89 return OK_RC;
90}
91
92/*- Determine the local address to bind as a source for outgoing requests.
93 *
94 * @param rh a handle to parsed configuration.
95 * @param lia set to the resolved local bind address.
96 -*/
97void rc_own_bind_addr(rc_handle *rh, struct sockaddr_storage *lia)
98{
99 char *txtaddr = rc_conf_str_id(rh, OPT_BINDADDR);
100 struct addrinfo *info;
101
102 if (rh->own_bind_addr_set) {
103 memcpy(lia, &rh->own_bind_addr, SS_LEN(&rh->own_bind_addr));
104 return;
105 }
106
107 memset(lia, 0, sizeof(*lia));
108 if (txtaddr == NULL || txtaddr[0] == '*') {
109 ((struct sockaddr_in*)lia)->sin_family = AF_INET;
110 ((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY;
111 } else {
112 info = rc_getaddrinfo (txtaddr, PW_AI_PASSIVE);
113 if (info == NULL) {
114 rc_log(LOG_ERR, "rc_own_ipaddress: couldn't get IP address from bindaddr");
115 ((struct sockaddr_in*)lia)->sin_family = AF_INET;
116 ((struct sockaddr_in*)lia)->sin_addr.s_addr = INADDR_ANY;
117 return;
118 }
119
120 memcpy(lia, info->ai_addr, info->ai_addrlen);
121 }
122
123 return;
124}