own ip change

All other questions regarding DCMTK

Moderator: Moderator Team

Post Reply
Message
Author
nagyjano
Posts: 3
Joined: Mon, 2006-10-16, 07:56

own ip change

#1 Post by nagyjano »

Hi!

I would like to know that if it has any way to change my own ip in a DICOM service. For example I have more than one ethereal card and due to I have more than one ip address. In this case how can I set that the DICOM service use a particular ip of mine's.

Thanks in advance.

Best regards,
Nagyjano

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1444
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#2 Post by Marco Eichelberg »

The relevant system call here is bind(2), which is only used in function initializeNetworkTCP() in dcmnet/libsrc/dul.cc. Here DCMTK currently always specifies INADDR_ANY as the interface from which connections are accepted, i.e. DCMTK will always accept associations from all interfaces present on the local machine as long as the port number is correct. One could modify this behaviour and explicitly specify the IP address of one specific interface at this point, but this would require some modifications to the source code. For further details, see the ip(7) man page.

nagyjano
Posts: 3
Joined: Mon, 2006-10-16, 07:56

#3 Post by nagyjano »

Hi!

Thanks for your fast responde :)

So this means that if I want to use a setting methode for this (new paramteres) then I have to modify some part of the code and recompile the libs and my apps. :(

So there are any chance in the future to make it configurable via functions?

Best regards,
Nagyjano

Marco Eichelberg
OFFIS DICOM Team
OFFIS DICOM Team
Posts: 1444
Joined: Tue, 2004-11-02, 17:22
Location: Oldenburg, Germany
Contact:

#4 Post by Marco Eichelberg »

I'll add an entry to our internal wish-list, but cannot promise anything for the next release. Restricting a service on a multi-homed host to a certain interface seems to be a rather rare wish.

nagyjano
Posts: 3
Joined: Mon, 2006-10-16, 07:56

#5 Post by nagyjano »

Hi!

Thanks.

Bye,
Nagyjano

Shaeto
Posts: 147
Joined: Tue, 2009-01-20, 17:50
Location: CA, USA
Contact:

#6 Post by Shaeto »

well, some necro posting :) 2009 requires new level of security.

there is small patch to add possibility to bind ACCEPTOR to specific local IP address/name or network interface (Unix).

tested under Linux (fc10) and Windows XP.

check for ASC_initializeSpecificNetwork for new parameter:
* @bindto "Socket name", NULL terminated string restricting
* the socket binding to one of local IPs or interfaces.
* Allowed types are:
* "node: HOSTNAME" where "HOSTNAME" is the server
* local host name or ip address
* "if: INTERFACE NAME" - bind socket to one of
* network interfaces, currently available only for Unix
* NULL to allow ADDR_ANY binding


================ PATCH HERE ===============
diff -ru dcmtk_patched/dcmnet/include/dcmtk/dcmnet/assoc.h dcmtk/dcmnet/include/dcmtk/dcmnet/assoc.h
--- dcmtk_patched/dcmnet/include/dcmtk/dcmnet/assoc.h 2009-03-03 18:32:44.000000000 +0300
+++ dcmtk/dcmnet/include/dcmtk/dcmnet/assoc.h 2009-03-23 02:14:13.000000000 +0300
@@ -261,6 +261,32 @@
T_ASC_Network ** network,
unsigned long options = 0);

+/** network instance creation function (constructor)
+ * @param role association acceptor, requestor or both
+ * @bindto "Socket name", NULL terminated string restricting
+ * the socket binding to one of local IPs or interfaces.
+ * Allowed types are:
+ * "node: HOSTNAME" where "HOSTNAME" is the server
+ * local host name or ip address
+ * "if: INTERFACE NAME" - bind socket to one of
+ * network interfaces, currently available only for Unix
+ * NULL to allow ADDR_ANY binding
+ * @param acceptorPort acceptor port for incoming connections.
+ * For association requestors, zero should be passed here.
+ * @param timeout timeout for network operations, in seconds
+ * @param network T_ASC_Network will be allocated and returned in this parameter
+ * @param options network options. Only DUL_FULLDOMAINNAME is currently defined
+ * as a possible option.
+ * @return EC_Normal if successful, an error code otherwise
+ */
+OFCondition
+ASC_initializeSpecificNetwork(T_ASC_NetworkRole role,
+ const char *bindto,
+ int acceptorPort,
+ int timeout,
+ T_ASC_Network ** network,
+ unsigned long options = 0);
+
/** network instance destruction function (destructor)
* @param network T_ASC_Network will be freed by this routine
* @return EC_Normal if successful, an error code otherwise
diff -ru dcmtk_patched/dcmnet/include/dcmtk/dcmnet/dul.h dcmtk/dcmnet/include/dcmtk/dcmnet/dul.h
--- dcmtk_patched/dcmnet/include/dcmtk/dcmnet/dul.h 2009-03-03 18:32:44.000000000 +0300
+++ dcmtk/dcmnet/include/dcmtk/dcmnet/dul.h 2009-03-23 00:21:11.000000000 +0300
@@ -352,6 +352,7 @@
DUL_InitializeNetwork(
const char *mode,
void *param,
+ const char *bindto,
int timeout,
unsigned long
options,
diff -ru dcmtk_patched/dcmnet/libsrc/assoc.cc dcmtk/dcmnet/libsrc/assoc.cc
--- dcmtk_patched/dcmnet/libsrc/assoc.cc 2009-03-03 18:32:44.000000000 +0300
+++ dcmtk/dcmnet/libsrc/assoc.cc 2009-03-23 02:04:10.000000000 +0300
@@ -233,7 +233,52 @@
break;
}

- OFCondition cond = DUL_InitializeNetwork(mode, &acceptorPort, timeout, DUL_ORDERBIGENDIAN | options, &netkey);
+ OFCondition cond = DUL_InitializeNetwork(mode, &acceptorPort, NULL, timeout, DUL_ORDERBIGENDIAN | options, &netkey);
+ if (cond.bad()) return cond;
+
+ *network = (T_ASC_Network *) malloc(sizeof(T_ASC_Network));
+ if (*network == NULL) return EC_MemoryExhausted;
+ (*network)->role = role;
+ (*network)->acceptorPort = acceptorPort;
+ (*network)->network = netkey;
+
+ return EC_Normal;
+}
+
+/*
+ * Network creation/distroy wrappers.
+ * The T_ASC_Network structure will be allocated/freed by
+ * these routines.
+ */
+
+OFCondition
+ASC_initializeSpecificNetwork(T_ASC_NetworkRole role,
+ const char *bindto,
+ int acceptorPort,
+ int timeout,
+ T_ASC_Network ** network,
+ unsigned long options)
+{
+ const char *mode;
+
+ DUL_NETWORKKEY * netkey;
+
+ switch (role) {
+ case NET_ACCEPTOR:
+ mode = DUL_AEACCEPTOR;
+ break;
+ case NET_REQUESTOR:
+ mode = DUL_AEREQUESTOR;
+ break;
+ case NET_ACCEPTORREQUESTOR:
+ mode = DUL_AEBOTH;
+ break;
+ default:
+ mode = "unknown";
+ break;
+ }
+
+ OFCondition cond = DUL_InitializeNetwork(mode, &acceptorPort, bindto, timeout, DUL_ORDERBIGENDIAN | options, &netkey);
if (cond.bad()) return cond;

*network = (T_ASC_Network *) malloc(sizeof(T_ASC_Network));
diff -ru dcmtk_patched/dcmnet/libsrc/dul.cc dcmtk/dcmnet/libsrc/dul.cc
--- dcmtk_patched/dcmnet/libsrc/dul.cc 2009-03-03 18:32:44.000000000 +0300
+++ dcmtk/dcmnet/libsrc/dul.cc 2009-03-23 02:04:10.000000000 +0300
@@ -155,7 +155,7 @@
createAssociationKey(PRIVATE_NETWORKKEY ** net, const char *node,
unsigned long maxPDU,
PRIVATE_ASSOCIATIONKEY ** assoc);
-static OFCondition initializeNetworkTCP(PRIVATE_NETWORKKEY ** k, void *p);
+static OFCondition initializeNetworkTCP(PRIVATE_NETWORKKEY ** k, void *p, const char *bindto = NULL);
static OFCondition
receiveTransportConnection(PRIVATE_NETWORKKEY ** network,
DUL_BLOCKOPTIONS block,
@@ -295,6 +295,8 @@
** cation as a requestor or acceptor.
** networkParameter A parameter which is specific to the network
** type, which may be needed to initialize the n/w
+** bindto NULL terminated string restricting the socket
+** binding (see ASC_initializeSpecificNetwork)
** timeout Length of time in seconds for TIMER timeout.
** If 0, the function will use a default value.
** opt Bitmask which describes options to be used
@@ -311,7 +313,8 @@

OFCondition
DUL_InitializeNetwork(const char *mode,
- void *networkParameter, int timeout, unsigned long opt,
+ void *networkParameter, const char *bindto,
+ int timeout, unsigned long opt,
DUL_NETWORKKEY ** networkKey)
{
// default return value if something goes wrong
@@ -336,7 +339,7 @@
OFCondition cond = createNetworkKey(mode, timeout, opt, &key);

// initialize network
- if (cond.good()) cond = initializeNetworkTCP(&key, networkParameter);
+ if (cond.good()) cond = initializeNetworkTCP(&key, networkParameter, bindto);

if (cond.good())
{
@@ -2039,6 +2042,14 @@
** Parameter Dictionary:
** key Handle to the network environment
** parameter port number on which to listen for connection
+** bindto "Socket name", NULL terminated string restricting
+** socket binding to one of local IPs or interfaces.
+** Allowed types are:
+** "node: HOSTNAME" where "HOSTNAME" is the server
+** local host name or ip address
+** "if: INTERFACE NAME" - bind socket to one of
+** network interfaces, currently available only
+** for Unix
**
** Return Values:
**
@@ -2049,7 +2060,7 @@
** Description of the algorithm (optional) and any other notes.
*/
static OFCondition
-initializeNetworkTCP(PRIVATE_NETWORKKEY ** key, void *parameter)
+initializeNetworkTCP(PRIVATE_NETWORKKEY ** key, void *parameter, const char *bindto)
{
struct linger
sockarg;
@@ -2103,10 +2114,48 @@
sprintf(buf2, "TCP Initialization Error: %s", strerror(errno));
return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, buf2);
}
+#ifndef HAVE_WINDOWS_H
+ if (bindto) {
+ if (strncmp(bindto, "if:", 3) == 0) {
+ // bind socket to specific network interface (eth0...)
+ bindto+=3; while (*bindto && *bindto==' ') bindto++;
+ }
+ if (setsockopt((*key)->networkSpecific.TCP.listenSocket,
+ SOL_SOCKET, SO_BINDTODEVICE, bindto, strlen(bindto)) < 0)
+ {
+ char buf2[256];
+ sprintf(buf2, "TCP Initialization Error: %s", strerror(errno));
+ return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, buf2);
+ }
+ }
+#endif
#endif
/* Name socket using wildcards */
server.sin_family = AF_INET;
server.sin_addr.s_addr = INADDR_ANY;
+ if (bindto) {
+ OFBool canusebindto = OFFalse;
+ if (strncmp(bindto, "node:", 5) == 0) {
+ // bind socket to specific ip name
+ bindto+=5; while (*bindto && *bindto==' ') bindto++;
+ canusebindto = OFTrue;
+ } else {
+ // raise exception
+ char buf2[4095];
+ sprintf(buf2, "TCP Initialization Error: unknown addr '%s'", bindto);
+ return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, buf2);
+ }
+ if (canusebindto) {
+ struct hostent *hp = gethostbyname(bindto);
+ if (hp == NULL)
+ {
+ char buf2[4095]; // node could be a long string
+ sprintf(buf2, "Attempt to bind to unknown addr: %s", bindto);
+ return makeDcmnetCondition(DULC_TCPINITERROR, OF_error, buf2);
+ }
+ (void) memcpy(&server.sin_addr, hp->h_addr, (size_t) hp->h_length);
+ }
+ }
server.sin_port = (unsigned short) htons((*key)->networkSpecific.TCP.port);
if (bind((*key)->networkSpecific.TCP.listenSocket,
(struct sockaddr *) & server, sizeof(server)))

Jörg Riesmeier
ICSMED DICOM Services
ICSMED DICOM Services
Posts: 2217
Joined: Fri, 2004-10-29, 21:38
Location: Oldenburg, Germany

#7 Post by Jörg Riesmeier »

Thank you for your contribution. I've added this to our to-do list ...

Post Reply

Who is online

Users browsing this forum: Ahrefs [Bot] and 1 guest