C Program to find UP and DOWN machines.? - c++

Suppose I have a scenario like below :
There are about 225 Computers having the following range of IP addresses and hostnames:-
PC-LAB IP ADDRESS RANGE HOSTNAME RANGE
PC-LAB1 10.11.2.01 - 10.11.2.30 ccl1pc01 - ccl1pc30
PC-LAB2 10.11.3.01 - 10.11.3.30 ccl2pc01 - ccl2pc30
PC-LAB3 10.11.4.01 - 10.11.4.45 ccl3pc01 - ccl3pc45
PC-LAB4 10.11.5.01 - 10.11.5.50 ccl4pc01 - ccl4pc50
PC-LAB5 10.13.6.01 - 10.13.6.65 ccl5pc01 – ccl5pc65
I want to write a program (in C / C++) that will take the above IP address and hostname ranges as input and create two separate files, one with 225 entries of IP
addresses and another with 225 entries of hostnames..
Then the program will figure out which of these machines are up and which are down and then create two files one containing
hostname and IP addresses of the systems which are UP and another which are DOWN.
E.g.
FILE1.down
Hostname IP address
ccl1pc10 10.8.2.10
ccl5pc25 10.11.5.25
Note : If any ubuntu command simplifies this work..we can use that in the program for sure..!!

Look at fping
Run this command, sit back and relax:
fping ccl{1..6}pc{01..60}
this will print a list of
All hosts that have a DNS name/IP record and are up
All hosts that have a DNS name/IP record but are down
All hosts that are not in the DNS (I guess you can ignore these)
Regards

Check out Nmap. You might need to create a small wrapper to handle the input and output in the format you want, but it should do exactly what you need.

Is this homework, ie do you have to do it programmatically in C?
Otherwise there a dozen of already existing monitoring frameworks, with several already in Ubuntu: munin, nagios, zabbix, ...

Related

QtRO - class qremoteobjects - how can connect 2 and more remote peers beetwen TCP

I was build example simpleswitch with registry node in Qt5.9. It's work fine, but when i replace QUrl("local.registry") and QUrl("local.replica") in definition QRemoteObjectRegistryHost and QRemoteObjectHost to QUrl("tcp://localhost:9999") or "tcp://127.0.0.1:9999", or paste current host address to defniton... i have error after run app...
qt.remoteobjects: Listen failed for URL: QUrl("tcp://127.0.0.1:9999")
qt.remoteobjects: QAbstractSocket::AddressInUseError
qt.remoteobjects: Could not create ClientIoDevice for client. Invalid url/scheme provided? QUrl("")
The valid value, use instead of QUrl("local.registry"):
QUrl("tcp://192.168.0.3:-1");
The valid value, use instead of QUrl("local.replica"):
QUrl("tcp://192.168.0.3:9999");
The IP address 192.168.0.3 - used for example (it value valid for my workstation in our office network) in your case IP address can contain other digits.
If Qt is indicating that 'the address is in use' then that is likely the source of the problem, literally the socket at IP:PORT is being used. You may check your development environment to see if you have multiple processes running of the same app - this is often the case and it leads to a collision of address spaces. We see this error in our environment consistently, and the root cause is simply as stated: 'the address is in use'.

Start a service in a LAN; the unknow server address case

This questions are a new attempt to solve a previous question "How to get a list of all valid ip address in a local network using Javascript?" (see How to get a list of all valid ip address in a local network using Javascript? )
In order to avoid the need of test millions of addresses, I wonder if it would be possible following scenario (in this case, forget the JavaScriipt constraint of the initial post, and suppose a more general language, say C++ and a I/O library like Boost Asio):
a) A server "S" wakeup in a LAN to provide some service, say listening in port X, and get a random address (i.e A1 = 192.168.1.35).
b) A client "C", that need the service, wakeup in the same LAN, an get other random address (say A2 = 192.168.1.40).
"C" does not know the "S" address to get the service. So, two questions:
1.- Can "S" and "C" know for themselves its own addresses (A1 and A2)?
2.- Can "C" send a broadcast request to the LAN in the given port X? Some as "Here P2, some one in X?"
Obviously, if "S" is listening in the given port, and can get the message, them can in turn broadcast its own direction; so if "C" is listening, can get the server's address.
Related to my first question, after some digging, the answer is Yes.
See "Winsock Programer's FAQ".
If in Windows, as is my case for the server, there are a complete API named "IP Helper" http://msdn.microsoft.com/en-us/library/aa366073%28VS.85%29.aspx that can serve as well.
Related to the second question, I will try the quick and dirty method exposed, and hope be back with some result.

access class by ip

I'm currently working on a UDP server.
I want to redirect all incoming packets to the connected clients by using the ip address and port.
My current way of doing it looks like this:
class Connection;
typedef std::map<unsigned short, Connection*> PortMap;
typedef std::map<unsigned int, PortMap> AddressMap;
So I'm basically using two maps. The second one contains a map of all the ports using an ipv4 address(unsigned int) as a key. The PortMap uses the port as the key and it contains a pointer to the Connection class(the clients).
I speed tested it by accessing 64 clients using randomly generated ips and ports and it took ~ (EDIT : 0.4 milliseconds) to access 64 different clients 64 times.
I don't know really if it's slow or not. Of course it depends on the system I'm running the test on.
Here's how I'm accessing the client using the address:
Client * GetClient(Address address)
{
AddressMap::iterator ipIt;
PortMap::iterator portIt;
unsigned int ip = address.GetAddress();
unsigned short port = address.GetPort();
/// Does the ip exist?
if((ipIt = clientAddresses.find(ip)) == clientAddresses.end())
{
return NULL;
}
/// Does the port exist?
if(clientAddresses[ip].find(port) == clientAddresses[ip].end())
{
return NULL;
}
return clientAddresses[ip][port];
}
Does anyone know another faster way of doing it?
Maybe it'll be better to combine IP and Port..
Port < 65535. You can get key: IP * 65535 + Port, it'll be unique for all ports and IPs.
About speed: for example we have N Ip's, each IP has M ports.
Searching into map has efficient N log(N), so your search take N*M*log(N)*log(M).
If you combine IP and port into one key, efficient will be N*M*log(N*M).
log(N*M) = log(N)+log(M) < log(N)*log(M), for big N, M..
So, I think it'll be better.
64 accesses into a map taking 400ms sounds horrifically slow... check your measurements. Your map should probably be based on a combination of IP and port (not separate), since a NAT can combine clients under a specific IP.

Embedding Mongoose Web Server in C++

I just embedded the Mongoose Web Server into my C++ dll (just a single header and recommended in most of the stack overflow threads) and I have it up and running properly with the very minimal example code.
However, I am having a rough time finding any sort of tutorials, examples, etc. on configuring the very basic necessities of a web server. I need to figure out the following...
1) How to allow directory browsing
2 Is it possible to restrict download speeds on the files?
3) Is it possible to have a dynamic list of IPs addresses allowed to download files?
4) How to allow the download of specific file extensions (.bz2 in this case) ANSWERED
5) How to bind to a specific IP Address ANSWERED
Most of the information I have found is in regards to using the pre-compiled binary release, so I am a bit stumped right now. Any help would be fantastic!
1) "enable_directory_listing" option
2) Not built into Mongoose (at least not the version I have, which is about 6 months old). [EDIT:] Newer versions of Mongoose support throttling download speed. From the manual...
Limit download speed for clients. throttle is a comma-separated list
of key=value pairs, where key could be:
* limit speed for all connections
x.x.x.x/mask limit speed for specified subnet
uri_prefix_pattern limit speed for given URIs
The value is a floating-point number of bytes per second, optionally
followed by a k or m character, meaning kilobytes and megabytes
respectively. A limit of 0 means unlimited rate. The last matching
rule wins. Examples:
*=1k,10.0.0.0/8=0 limit all accesses to 1 kilobyte per second,
but give connections from 10.0.0.0/8 subnet
unlimited speed
/downloads/=5k limit accesses to all URIs in `/downloads/` to
5 kilobytes per secods. All other accesses are unlimited
3) "access_control_list" option. In the code accept_new_connection calls check_acl that compares the client's IP to a list of IPs to accept and/or ignore. From the manual...
Specify access control list (ACL). ACL is a comma separated list of IP
subnets, each subnet is prepended by '-' or '+' sign. Plus means
allow, minus means deny. If subnet mask is omitted, like "-1.2.3.4",
then it means single IP address. Mask may vary from 0 to 32 inclusive.
On each request, full list is traversed, and last match wins. Default
setting is to allow all. For example, to allow only 192.168/16 subnet
to connect, run "mongoose
-0.0.0.0/0,+192.168/16". Default: ""
http://code.google.com/p/mongoose/wiki/MongooseManual
Of course as soon as I give up and post, I find most of the answers were right in front of my face. Here is the options for them...
const char *options[] =
{
"document_root", "C:/",
"listening_ports", "127.0.0.1:8080",
"extra_mime_types", ".bz2=plain/text",
NULL
};
However, I am still not sure how to make enable directory browsing. Right now, my callback function is just the basic one out of the example (as seen below). What would I need to do to get it so the files are listed?
static void *callback(enum mg_event event, struct mg_connection *conn, const struct mg_request_info *request_info)
{
if (event == MG_NEW_REQUEST)
{
// Echo requested URI back to the client
mg_printf(conn, "HTTP/1.1 200 OK\r\n"
"Content-Type: text/plain\r\n\r\n"
"%s", request_info->uri);
return ""; // Mark as processed
}
else
{
return NULL;
}
}

Is ->h_addr_list[0] the address I need?

I am working on implementing UpNP on C++, and I need to get the local internal IP address assigned by the router to make the sockets works. The address I need is the one that appears on routers where it shows the computers connected to the router and the local IP assigned to each computer. I am using this:
PHOSTENT Addr = NULL;
char Host[MAX_PATH];
if( gethostname(Host, sizeof(Host)) == 0 )
{
Address = gethostbyname( Host );
if( Address != NULL )
{
//*(struct in_addr *)Address->h_addr_list[0]) <- this is my address
}
}
This works fine on the computer I am testing, but that computer has only one network card, so I was wondering if maybe when a computer has more than one card or network device, Address->h_addr_list[0] may not be the one I need and it could be in another index of that array.
Will [0] always retrieve the IP assigned by the router?
(Assuming winsock here, as per previous question)
You shouldn't assume that the first address is the correct one (as there may be multiple interfaces, and more than one may be active)
I'd recommend enumerating addresses using either getaddrinfo with an empty pNodeName argument, or GetAdaptersAddresses.
Both of these return a linked lists with your system's registered addresses
... get the local internal IP address assigned by the router ...
Note that in some cases, the machine's IP address will be manually assigned, but the user will still want to use UPnP.
On Linux, it is suggested to use getaddrinfo(3) instead of gethostbyname(3), perhaps Winsocks has made a similar transition?
On Linux, it is common for /etc/hosts to have loopback entries also accessible by hostname; /etc/gai.conf can be used to configure the sort order of returned addresses, and possibly a loopback address will be returned. Does Winsock make it that easy for sysadmins to change the order of returned addresses?
Don't forget that a system may legitimately have multiple upstream routers: a laptop with an EV-DO or EDGE or similar cellular data connection and a wireless or wired Ethernet will have multiple IPs, multiple upstream routers, and the routing table will be consulted to figure out which one should be used to send each packet.
Can you use either (a) the address used by clients to contact you? (getsockname(2) will return the local address used on a specific socket.) (b) ask the user to select among the list of IP addresses, if there are several? Binding to N of M interfaces would be nice, so users can select which networks get the services and which networks are left alone.