1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146
|
/*
* ipmi_port.c
* Allocate the RMCP port (623.) with a bind so that port manager
* does not try to reuse it. Only needed for Linux.
*
* Note that the Intel dpcproxy service also uses port 623 to listen
* for incoming telnet/SOL clients, so we should not start ipmi_port
* if dpcproxy is running.
*
* Changes:
* 05/18/07 Andy Cress - created
*/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <fcntl.h>
#include <netinet/in.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <signal.h>
#ifdef TEST
#include "ipmicmd.h"
#endif
#define RMCP_PORT 623
static char * progver = "1.4"; /* program version */
static char *progname = "ipmi_port"; /* program name */
static int sockfd = 0;
static struct sockaddr_in _srcaddr;
static int interval = 20; /* num sec to wait, was 60 */
static char fdebug = 0;
static int mkdaemon(int fchdir, int fclose);
static int mkdaemon(int fchdir, int fclose)
{
int fdlimit = sysconf(_SC_OPEN_MAX); /*fdlimit usu = 1024.*/
int fd = 0;
int i;
fdlimit = fileno(stderr);
switch (fork()) {
case 0: break;
case -1: return -1;
default: _exit(0); /* exit the original process */
}
if (setsid() < 0) return -1; /* shouldn't fail */
switch (fork()) {
case 0: break;
case -1: return -1;
default: _exit(0);
}
if (fchdir) i = chdir("/");
if (fclose) {
/* Close stdin,stdout,stderr and replace them with /dev/null */
for (fd = 0; fd < fdlimit; fd++) close(fd);
fd = open("/dev/null",O_RDWR);
i = dup(0);
i = dup(0);
}
return 0;
}
static int open_rmcp_port(int port);
static int open_rmcp_port(int port)
{
int rv;
/* Open a socket binding to the RMCP port */
rv = socket(AF_INET, SOCK_DGRAM, 0);
if (rv < 0) return (rv);
else sockfd = rv;
memset(&_srcaddr, 0, sizeof(_srcaddr));
_srcaddr.sin_family = AF_INET;
_srcaddr.sin_port = htons(port);
_srcaddr.sin_addr.s_addr = htonl(INADDR_ANY);
rv = bind(sockfd, (struct sockaddr *)&_srcaddr, sizeof(_srcaddr));
if (rv < 0) {
printf("bind(%d,%d) error, rv = %d\n",port,INADDR_ANY,rv);
close(sockfd);
return (rv);
}
return(rv);
}
static void iport_cleanup(int sig)
{
if (sockfd != 0) close(sockfd);
exit(EXIT_SUCCESS);
}
/*int ipmi_port(int argc, char **argv) */
int main(int argc, char **argv)
{
int rv;
int c;
int background = 0;
struct sigaction sact;
while ((c = getopt(argc, argv, "bx?")) != EOF) {
switch (c) {
case 'x': fdebug = 1; break;
case 'b': background = 1; break;
default:
printf("Usage: %s [-xb] (-b means background)\n",progname);
exit(1);
}
}
if (!background)
printf("%s ver %s\n", progname,progver);
rv = open_rmcp_port(RMCP_PORT);
if (rv != 0) {
printf("open_rmcp_port(%d) failed, rv = %d\n",RMCP_PORT,rv);
exit(1);
} else if (!background)
printf("open_rmcp_port(%d) succeeded, sleeping\n",RMCP_PORT);
/* convert to a daemon if background */
if (background) {
rv = mkdaemon(1,1);
if (rv != 0) {
printf("%s: Cannot become daemon, rv = %d\n", progname,rv);
exit(1);
}
}
/* handle signals for cleanup */
sact.sa_handler = iport_cleanup;
sact.sa_flags = 0;
sigemptyset(&sact.sa_mask);
sigaction(SIGINT, &sact, NULL);
sigaction(SIGQUIT, &sact, NULL);
sigaction(SIGTERM, &sact, NULL);
if (rv == 0) while(1)
{
sleep(interval); /*wait 60 seconds*/
}
if (sockfd != 0) close(sockfd);
return(rv);
}
/*end ipmi_port.c */
|