e9974a8ee7eb65c7adb675ca7ee6939d243c4aea
2 Copyright (C) by Ronnie Sahlberg <ronniesahlberg@gmail.com> 2011
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 3 of the License, or
7 (at your option) any later version.
9 This program is distributed in the hope that it will be useful,
10 but WITHOUT ANY WARRANTY; without even the implied warranty of
11 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 GNU General Public License for more details.
14 You should have received a copy of the GNU General Public License
15 along with this program; if not, see <http://www.gnu.org/licenses/>.
18 /* Example program using the lowlevel raw broadcast interface.
25 #include "win32_compat.h"
50 #ifdef HAVE_SYS_IOCTL_H
51 #include <sys/ioctl.h>
54 #ifdef HAVE_SYS_SOCKET_H
55 #include <sys/socket.h>
58 #include "libnfs-zdr.h"
60 #include "libnfs-raw.h"
61 #include "libnfs-private.h"
62 #include "libnfs-raw-mount.h"
63 #include "libnfs-raw-portmap.h"
65 struct nfs_list_data
{
67 struct nfs_server_list
*srvrs
;
70 void free_nfs_srvr_list(struct nfs_server_list
*srv
)
73 struct nfs_server_list
*next
= srv
->next
;
81 void pm_cb(struct rpc_context
*rpc
, int status
, void *data _U_
, void *private_data
)
83 struct nfs_list_data
*srv_data
= private_data
;
86 struct nfs_server_list
*srvr
;
88 if (status
== RPC_STATUS_CANCEL
) {
92 srv_data
->status
= -1;
96 sin
= rpc_get_recv_sockaddr(rpc
);
98 rpc_set_error(rpc
, "failed to get sockaddr in CALLIT callback");
99 srv_data
->status
= -1;
103 if (getnameinfo(sin
, sizeof(struct sockaddr_in
), &hostdd
[0], sizeof(hostdd
), NULL
, 0, NI_NUMERICHOST
) < 0) {
104 rpc_set_error(rpc
, "getnameinfo failed in CALLIT callback");
105 srv_data
->status
= -1;
110 srvr
= malloc(sizeof(struct nfs_server_list
));
112 rpc_set_error(rpc
, "Malloc failed when allocating server structure");
113 srv_data
->status
= -1;
117 srvr
->addr
= strdup(hostdd
);
118 if (srvr
->addr
== NULL
) {
119 rpc_set_error(rpc
, "Strdup failed when allocating server structure");
121 srv_data
->status
= -1;
125 srvr
->next
= srv_data
->srvrs
;
126 srv_data
->srvrs
= srvr
;
129 int main(int argc _U_
, char *argv
[] _U_
)
131 struct rpc_context
*rpc
;
135 struct timeval tv_start
, tv_current
;
136 struct nfs_list_data data
= {0, NULL
};
137 struct nfs_server_list
*srvr
;
140 rpc
= rpc_init_udp_context();
142 printf("failed to init context\n");
146 if (rpc_bind_udp(rpc
, "0.0.0.0", 0) < 0) {
147 printf("failed to bind to udp %s\n", rpc_get_error(rpc
));
152 /* get list of all interfaces */
153 size
= sizeof(struct ifreq
);
157 while(ifc
.ifc_len
> (size
- sizeof(struct ifreq
))) {
162 ifc
.ifc_buf
= malloc(size
);
163 memset(ifc
.ifc_buf
, 0, size
);
164 if (ioctl(rpc_get_fd(rpc
), SIOCGIFCONF
, (caddr_t
)&ifc
) < 0) {
165 printf("ioctl SIOCGIFCONF failed\n");
170 for (ptr
=(char *)ifc
.ifc_buf
; ptr
< ((char *)ifc
.ifc_buf
) + ifc
.ifc_len
; ) {
174 ifr
= (struct ifreq
*)ptr
;
175 #ifdef HAVE_SOCKADDR_LEN
176 if (ifr
->ifr_addr
.sa_len
> sizeof(struct sockaddr
)) {
177 ptr
+= sizeof(ifr
->ifr_name
) + ifr
->ifr_addr
.sa_len
;
179 ptr
+= sizeof(ifr
->ifr_name
) + sizeof(struct sockaddr
);
182 ptr
+= sizeof(struct ifreq
);
185 if (ifr
->ifr_addr
.sa_family
!= AF_INET
) {
188 if (ioctl(rpc_get_fd(rpc
), SIOCGIFFLAGS
, ifr
) < 0) {
189 printf("ioctl DRBADDR failed\n");
192 if (!(ifr
->ifr_flags
& IFF_UP
)) {
195 if (ifr
->ifr_flags
& IFF_LOOPBACK
) {
198 if (!(ifr
->ifr_flags
& IFF_BROADCAST
)) {
201 if (ioctl(rpc_get_fd(rpc
), SIOCGIFBRDADDR
, ifr
) < 0) {
204 if (getnameinfo(&ifr
->ifr_broadaddr
, sizeof(struct sockaddr_in
), &bcdd
[0], sizeof(bcdd
), NULL
, 0, NI_NUMERICHOST
) < 0) {
207 if (rpc_set_udp_destination(rpc
, bcdd
, 111, 1) < 0) {
208 printf("failed to set udp destination %s\n", rpc_get_error(rpc
));
212 if (rpc_pmap_callit_async(rpc
, MOUNT_PROGRAM
, 2, 0, NULL
, 0, pm_cb
, &data
) < 0) {
213 printf("Failed to set up callit function\n");
219 gettimeofday(&tv_start
, NULL
);
223 pfd
.fd
= rpc_get_fd(rpc
);
224 pfd
.events
= rpc_which_events(rpc
);
226 gettimeofday(&tv_current
, NULL
);
228 - (tv_current
.tv_sec
*1000 + tv_current
.tv_usec
/ 1000)
229 + (tv_start
.tv_sec
*1000 + tv_start
.tv_usec
/ 1000);
231 if (poll(&pfd
, 1, mpt
) < 0) {
232 printf("Poll failed");
235 if (pfd
.revents
== 0) {
239 if (rpc_service(rpc
, pfd
.revents
) < 0) {
240 printf("rpc_service failed with %s\n", rpc_get_error(rpc
));
245 for (srvr
=data
.srvrs
; srvr
; srvr
= srvr
->next
) {
246 printf("NFS SERVER @ %s\n", srvr
->addr
);
248 free_nfs_srvr_list(data
.srvrs
);
250 rpc_destroy_context(rpc
);