1 /* -*- mode: c; c-basic-offset: 8; indent-tabs-mode: nil; -*-
2 * vim:expandtab:shiftwidth=8:tabstop=8:
6 #include <sys/socket.h>
7 #include <netinet/tcp.h>
12 #include <sys/ioctl.h>
17 #include <arpa/inet.h>
18 #include <netinet/in.h>
22 #include <portals/api-support.h>
23 #include <portals/list.h>
24 #include <portals/lib-types.h>
25 #include <portals/socknal.h>
27 /* should get this from autoconf somehow */
29 #define PIDFILE_DIR "/var/run"
32 #define PROGNAME "acceptor"
35 /* needed because libwrap declares these as externs */
36 int allow_severity = LOG_INFO;
37 int deny_severity = LOG_WARNING;
40 void create_pidfile(char *name, int port)
45 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
46 PIDFILE_DIR, name, port);
48 if ((fp = fopen(pidfile, "w"))) {
49 fprintf(fp, "%d\n", getpid());
52 syslog(LOG_ERR, "%s: %s\n", pidfile,
57 int pidfile_exists(char *name, int port)
61 snprintf(pidfile, sizeof(pidfile), "%s/%s-%d.pid",
62 PIDFILE_DIR, name, port);
64 if (!access(pidfile, F_OK)) {
65 fprintf(stderr, "%s: exists, acceptor already running.\n",
73 show_connection (int fd, __u32 net_ip)
75 struct hostent *h = gethostbyaddr ((char *)&net_ip, sizeof net_ip, AF_INET);
76 __u32 host_ip = ntohl (net_ip);
81 snprintf (host, sizeof(host), "%d.%d.%d.%d", (host_ip >> 24) & 0xff,
82 (host_ip >> 16) & 0xff, (host_ip >> 8) & 0xff, host_ip & 0xff);
84 snprintf (host, sizeof(host), "%s", h->h_name);
86 syslog (LOG_INFO, "Accepted host: %s\n", host);
93 "Usage: %s [-N nal_id] [-p] [-l] port\n\n"
94 " -l\tKeep stdin/stdout open\n"
95 " -p\tAllow connections from non-privileged ports\n",
100 int main(int argc, char **argv)
102 int o, fd, rc, port, pfd;
103 struct sockaddr_in srvaddr;
108 int require_privports = 1;
110 while ((c = getopt (argc, argv, "N:lp")) != -1) {
113 if (sscanf(optarg, "%d", &nal) != 1 ||
114 nal < 0 || nal > NAL_MAX_NR)
121 require_privports = 0;
132 port = atol(argv[optind++]);
134 if (pidfile_exists(PROGNAME, port))
137 memset(&srvaddr, 0, sizeof(srvaddr));
138 srvaddr.sin_family = AF_INET;
139 srvaddr.sin_port = htons(port);
140 srvaddr.sin_addr.s_addr = INADDR_ANY;
142 fd = socket(PF_INET, SOCK_STREAM, 0);
144 perror("opening socket");
149 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &o, sizeof(o))) {
150 perror("Cannot set REUSEADDR socket opt");
154 rc = bind(fd, (struct sockaddr *)&srvaddr, sizeof(srvaddr));
160 if (listen(fd, 127)) {
164 fprintf(stderr, "listening on port %d\n", port);
166 pfd = open("/dev/portals", O_RDWR);
168 perror("opening portals device");
172 rc = daemon(0, noclose);
174 perror("daemon(): ");
178 openlog(PROGNAME, LOG_PID, LOG_DAEMON);
179 syslog(LOG_INFO, "started, listening on port %d\n", port);
180 create_pidfile(PROGNAME, port);
183 struct sockaddr_in clntaddr;
184 int len = sizeof(clntaddr);
186 struct portal_ioctl_data data;
187 struct portals_cfg pcfg;
189 struct request_info request;
191 char addrstr[INET_ADDRSTRLEN];
193 cfd = accept(fd, (struct sockaddr *)&clntaddr, &len);
201 /* libwrap access control */
202 request_init(&request, RQ_DAEMON, "lustre", RQ_FILE, cfd, 0);
204 if (!hosts_access(&request)) {
205 inet_ntop(AF_INET, &clntaddr.sin_addr,
206 addrstr, INET_ADDRSTRLEN);
207 syslog(LOG_WARNING, "Unauthorized access from %s:%hd\n",
208 addrstr, ntohs(clntaddr.sin_port));
214 if (require_privports && ntohs(clntaddr.sin_port) >= IPPORT_RESERVED) {
215 inet_ntop(AF_INET, &clntaddr.sin_addr,
216 addrstr, INET_ADDRSTRLEN);
217 syslog(LOG_ERR, "Closing non-privileged connection from %s:%d\n",
218 addrstr, ntohs(clntaddr.sin_port));
221 perror ("close un-privileged client failed");
225 show_connection (cfd, clntaddr.sin_addr.s_addr);
227 PCFG_INIT(pcfg, NAL_CMD_REGISTER_PEER_FD);
230 pcfg.pcfg_misc = SOCKNAL_CONN_NONE; /* == incoming connection */
232 PORTAL_IOC_INIT(data);
233 data.ioc_pbuf1 = (char*)&pcfg;
234 data.ioc_plen1 = sizeof(pcfg);
236 if (ioctl(pfd, IOC_PORTAL_NAL_CMD, &data) < 0) {
237 perror("ioctl failed");
239 printf("client registered\n");
243 perror ("close failed");