1 /* ----------------------------- MNI Header -----------------------------------
2 @NAME       : open_connection.c
3 @DESCRIPTION: File containing routines to open a decnet connection.
4 @GLOBALS    :
5 @CREATED    : November 22, 1993 (Peter Neelin)
6 @MODIFIED   :
7  * $Log: open_connection.c,v $
8  * Revision 1.1  2003-08-15 19:52:55  leili
9  * Initial revision
10  *
11  * Revision 1.1.1.1  2000/11/30 02:13:15  rhoge
12  * imported sources to CVS repository on amoeba
13  *
14  * Revision 6.1  1999/10/29 17:51:56  neelin
15  * Fixed Log keyword
16  *
17  * Revision 6.0  1997/09/12 13:24:27  neelin
18  * Release of minc version 0.6
19  *
20  * Revision 5.0  1997/08/21  13:25:26  neelin
21  * Release of minc version 0.5
22  *
23  * Revision 4.0  1997/05/07  20:06:20  neelin
24  * Release of minc version 0.4
25  *
26  * Revision 1.1  1997/03/04  20:56:47  neelin
27  * Initial revision
28  *
29  * Revision 3.0  1995/05/15  19:31:44  neelin
30  * Release of minc version 0.3
31  *
32  * Revision 2.5  1995/02/14  18:12:26  neelin
33  * Added project names and defaults files (using volume name).
34  * Added process id to log file name.
35  * Moved temporary files to subdirectory.
36  *
37  * Revision 2.4  1995/02/09  13:51:26  neelin
38  * Mods for irix 5 lint.
39  *
40  * Revision 2.3  1995/02/08  19:31:47  neelin
41  * Moved ARGSUSED statements for irix 5 lint.
42  *
43  * Revision 2.2  1994/12/07  09:45:59  neelin
44  * Fixed called to ioctl to get rid of type mismatch warning messages.
45  *
46  * Revision 2.1  94/12/07  08:20:10  neelin
47  * Added support for irix 5 decnet.
48  *
49  * Revision 2.0  94/09/28  10:35:32  neelin
50  * Release of minc version 0.2
51  *
52  * Revision 1.5  94/09/28  10:34:50  neelin
53  * Pre-release
54  *
55  * Revision 1.4  94/01/18  14:23:41  neelin
56  * Changed bzero to memset.
57  *
58  * Revision 1.3  93/11/30  14:42:13  neelin
59  * Copies to minc format.
60  *
61  * Revision 1.2  93/11/25  13:26:55  neelin
62  * Working version.
63  *
64  * Revision 1.1  93/11/23  14:11:54  neelin
65  * Initial revision
66  *
67 @COPYRIGHT  :
68               Copyright 1993 Peter Neelin, McConnell Brain Imaging Centre,
69               Montreal Neurological Institute, McGill University.
70               Permission to use, copy, modify, and distribute this
71               software and its documentation for any purpose and without
72               fee is hereby granted, provided that the above copyright
73               notice appear in all copies.  The author and McGill University
74               make no representations about the suitability of this
75               software for any purpose.  It is provided "as is" without
76               express or implied warranty.
77 ---------------------------------------------------------------------------- */
78 
79 #include <stdlib.h>
80 #include <stdio.h>
81 #include <sys/types.h>
82 #include <sys/socket.h>
83 #include <netinet/in.h>
84 #include <arpa/inet.h>
85 #include <errno.h>
86 #include <signal.h>
87 #include <dicomserver.h>
88 
89 /* ----------------------------- MNI Header -----------------------------------
90 @NAME       : connection_okay
91 @INPUT      : sockfd - input file descriptor which might be a socket
92 @OUTPUT     : (none)
93 @RETURNS    : TRUE if connection is okay, FALSE otherwise
94 @DESCRIPTION: Checks whether the connection is allowed. Looks at sockfd
95               to find out if remote host is allowed to connect. If sockfd
96               is a file and not a socket, then the connection is allowed.
97 @METHOD     :
98 @GLOBALS    :
99 @CALLS      :
100 @CREATED    : February 20, 1997 (Peter Neelin)
101 @MODIFIED   :
102 ---------------------------------------------------------------------------- */
connection_okay(int sockfd)103 private int connection_okay(int sockfd)
104 {
105    struct sockaddr_in us, them;
106    int status;
107    int namelen;
108    extern int Do_logging;
109 
110    /* Get our own id. If sockfd is a file, then its okay. Check that we
111       have an internet connection. */
112    namelen = sizeof(us);
113    if (getsockname(sockfd, &us, &namelen) != 0) {
114       if (errno == ENOTSOCK)
115          return TRUE;
116       else {
117          (void) fprintf(stderr, "Unable to get our own host address.\n");
118          return FALSE;
119       }
120    }
121    else if (us.sin_family != AF_INET) {
122       (void) fprintf(stderr, "Connection is not from network.\n");
123       return FALSE;
124    }
125 
126    /* Try to get id of host at other end of connection */
127    namelen = sizeof(us);
128    status = getpeername(sockfd, &them, &namelen);
129    if (status != 0) {
130       (void) fprintf(stderr, "Unable to check connection source.\n");
131       return FALSE;
132    }
133 
134    /* */
135    if (Do_logging >= LOW_LOGGING) {
136       (void) fprintf(stderr, "Connection from %s ", inet_ntoa(them.sin_addr));
137    }
138 
139    /* modified by rhoge to relax network restriction from class C to B */
140 
141    /* Compare the addresses. Make sure that we have the same IP domain
142       assuming class B structure. */
143    if ((us.sin_addr.s_addr & IN_CLASSB_NET) !=
144        (them.sin_addr.s_addr & IN_CLASSB_NET)) {
145       if (Do_logging >= LOW_LOGGING) {
146 	(void) fprintf(stderr,"Request not from same IP domain (class B)\n");
147 	(void) fprintf(stderr,"Our   ip address:  %d\n",us.sin_addr.s_addr);
148 	(void) fprintf(stderr,"Their ip address:  %d\n",them.sin_addr.s_addr);
149 	(void) fprintf(stderr,"CLASSB mask:       %d\n",IN_CLASSB_NET);
150 	(void) fprintf(stderr,
151 		       "Connection from %s ", inet_ntoa(them.sin_addr));
152 	(void) fprintf(stderr, "refused.\n");
153       }
154       /*      return FALSE; */
155    }
156 
157    /* Log a warning if hosts not from same class C network */
158    if ((us.sin_addr.s_addr & IN_CLASSC_NET) !=
159        (them.sin_addr.s_addr & IN_CLASSC_NET)) {
160       if (Do_logging >= LOW_LOGGING) {
161           (void) fprintf(stderr,"Request not from same IP domain (class C)\n");
162 	  (void) fprintf(stderr,
163 			 "Connection from %s ", inet_ntoa(them.sin_addr));
164       }
165    }
166 
167    if (Do_logging >= LOW_LOGGING) {
168       (void) fprintf(stderr, "accepted.\n");
169    }
170 
171    return TRUE;
172 }
173 
174 /* ----------------------------- MNI Header -----------------------------------
175 @NAME       : open_connection
176 @INPUT      : argc - number of command-line arguments
177               argv - array of command-line arguments
178 @OUTPUT     : afpin - Acr file pointer for input
179               afpout - Acr file pointer for output
180 @RETURNS    : (nothing)
181 @DESCRIPTION: Opens the connection for reading writing dicom messages.
182 @METHOD     :
183 @GLOBALS    :
184 @CALLS      :
185 @CREATED    : November 22, 1993 (Peter Neelin)
186 @MODIFIED   :
187 ---------------------------------------------------------------------------- */
188 /* ARGSUSED */
open_connection(int argc,char * argv[],Acr_File ** afpin,Acr_File ** afpout)189 public void open_connection(int argc, char *argv[],
190                             Acr_File **afpin, Acr_File **afpout)
191 {
192    /* Set default file pointers */
193    *afpin = *afpout = NULL;
194 
195    /* Check for a valid connection */
196    if (!connection_okay(fileno(stdin))) return;
197 
198    /* Open the connection */
199    *afpin=acr_initialize_dicom_input(stdin, 0, acr_stdio_read);
200    *afpout=acr_initialize_dicom_output(stdout, 0, acr_stdio_write);
201 
202    /* Ignore SIGPIPE errors in case connection gets closed when we are
203       doing output */
204    (void) signal(SIGPIPE, SIG_IGN);
205 }
206 
207