I have lots of Drytek > Vigor 2700,2800 routers on the public net. I manage this networks and since this type of routers has Log support I write an application on my linux box to collect those logs.
The routers are sending UDP datagrams to a configurable address and port. Each datagram has one status message. My program collects each datagram from several routers and put them into log files.
The message datagrams has a three digit code on the beginning of the stream. Each code belongs to a different type of status info.

My program is running and the logs are ok. I just want to put it on the production server and before I do so I want to make my code comply with the basic rules of programming.

I am not experienced programmer so I know that in my code there can be lots of mistakes. This is why I need a help and comments of experienced programmers.

I simplify my code to be as short as possible.

char buf1[128];
	char buf2[128];
	char buf3[128];

int DisplayUpdate()	{
		// Creating the file streams for different kind of log types
		// There are 3 major data types for output: adsl status, local user 
                // connections and other
		// adsl status - sends periodically info about the up and download 
                // speeds and the technical parameters of the ADSL link
		// local user - notifies each activity from the local network to the public
		// There are other types of data which are not interesting for me now   
                // Like: PPOE, VPN, Router Config Access, Rebooting of router...
		// Each data type has its three digit code at the stream beginning, based 
                // upon this number I separate the logs

		ofstream adslstatus1("ADSL_status1.log", ios::app);
		ofstream adslstatus2 ...
		ofstream localuser1("Local_user1.log", ios::app);
		ofstream localuser2 ...
		ofstream other1("other1.log", ios::app);
		ofstream other2 ...

		// ADSL status
		for(int readline1=1; readline1<5; readline1++)	
			if(buf1[readline1]=='1')   {
                // The three digit code 174 is for ADSL status
				if(buf1[readline1+1]=='7') {
					if(buf1[readline1+2]=='4') {
						adslstatus1 << "router 1: "; 	
                // We don't show the ADSL status on the screen for now
		// therefor each cout is commented out, maybe later it will be 
	        // choosable option to show different info on the screen
//						cout << "router 1: ";
	                                        for(int printline1=5; printline1<20; printline1++)	{
               // Writes the date into the Log.
							adslstatus1 << buf1[printline1];
//							cout << buf1[printline1];
						adslstatus1 << " > ";
//						cout << " > ";
						for(int printline1=41; printline1<128; printline1++)	{
                // Writes the status data into the Log
						adslstatus1 << buf1[printline1];
//						cout << buf1[printline1];
					adslstatus1 << endl;
//					cout << endl;

		// Each router has its own Log. For now it supports 3 routers. I have now 
                // upto 10 routers outside which I want to Log.
		// ADSL Status roter 2

// This loop is repeated for router 2 and 3
// And same kind of loop for type codes 150 - localuser connection info
// 150 for router 2 and 3
// 166 - PPOE and VPN and same loop type for router 2 and 3

		for(int readline1=1; readline1<5; readline1++)

// Exiting Display update function
return 1;

[B]MAIN Function[/B]

[B]int main(int argc, char *argv[])

	// Creating the log collectors address structs - my_addr1,2,3 for 3
        // routers and the client address structs their_addr1,2,3.
	// We create the polling struct for each listening socket - ufds.

[B]struct sockaddr_in my_addr1, my_addr2, my_addr3;
struct sockaddr_in their_addr1, their_addr2, their_addr3;
struct pollfd ufds[3];[/B]

	// Creating variables for the address size.

[B]socklen_t sin_size1, sin_size2, sin_size3, fromlen1, fromlen2, fromlen3;
int byte_count1, byte_count2, byte_count3;[/B]

[B]int sockfd1, sockfd2, sockfd3, new_fd1, new_fd2, new_fd3;[/B]

	// Setting the address values in addresse structures. The ports   
        // where the server listens for incoming log datagrams for each 
	// router different and the IP address of our own socket

[B]my_addr1.sin_family = AF_INET;
my_addr1.sin_port = htons(11111);
my_addr1.sin_addr.s_addr = inet_addr("");
memset(my_addr1.sin_zero, '\0', sizeof my_addr1.sin_zero);[/B]

        // Same for router 2 and 3
[B]my_addr2.sin_family = AF_INET; 
my_addr2.sin_port = htons(11112);
my_addr2.sin_addr.s_addr = inet_addr("");
memset(my_addr2.sin_zero, '\0', sizeof my_addr2.sin_zero);[/B]

[B]my_addr3.sin_family = AF_INET;[/B]
	// Creating sockets
[B]sockfd1 = socket(PF_INET, SOCK_DGRAM, 0);
sockfd2 and 3 ...[/B]

	// Binding the sockets to addresses

[B]bind(sockfd1, (struct sockaddr *)&my_addr1, sizeof my_addr1);
bind(sockfd2, 3 ...
	// Setting them to listen and poll with the queue of 10 waiting  
        // connections for each socket, router

[B]listen(sockfd1, 10);
listen(sockfd2 ...[/B]
        // Size of each address struct
sin_size1 = sizeof  their_addr1;
sin_size2 ...[/B]
       // accepting connections

[B]new_fd1 = accept(sockfd1, (struct sockaddr *)&their_addr1, &sin_size1);
new_fd2 ...[/B]
	// Ok, each datagram is going into the main log file, so we create
        // the file stream for them

[B]ofstream log("router.log", ios::app);[/B]

	// As we are listening on more sockets and the received data are 
        // randomly arriving we need to poll for activity on them. 
	// The rv is the temporrary returnvalue which is tested and based on
        // the status the poll function returns which connection has news
	// for us We set the fd socket descriptor for each polling ufds structure.

[B]int rv;
ufds[0].fd = sockfd1;
ufds[0].events = POLLIN;
ufds[1].fd [/B] ... // Same for 2 and 3

[B]for(int b=0;b<2;b++)	// Eternal loop for receiving datagrams
	// We clear the buffers where we will store the received data. Three 
        // 128 char big buffers will be good for now.
[B]	for(int c=0;c<128;c++) {
		buf1[c] = ' ';
		buf2[c] = ' ';
			buf3[c] = ' ';
        // And so we call the poll function which returnes the rv descriptor 
        // to let us know which shocket gets data.
        // The poll function has 3 sockets for checking and one second - 
        // 1000 ms - to timeout for each socket. This can be later less.
[B]rv = poll(ufds, 3, 1000);
if (rv == -1) {[/B]
[B]} else if(rv == 0) {[/B]
	//  printf("... router timeout occured ...\n");
[B]} else {[/B]
        // We are intrested for POLLIN signal on each socket so when 
        // the .revents member gets POLLIN the socket has data for us
        // After this we can call the recvfrom function for the particular
	//  socket We put the data into the actual buffer buf1,2,3, and imediatelly
        //  write it into the main log file.
[B]if (ufds[0].revents & POLLIN) {
byte_count1 = recvfrom(sockfd1, buf1, 128, MSG_OOB, (struct sockaddr *)&their_addr1, &fromlen1);
	log << "router 1: ";
	for(int a=0;a<128;a++) {
		log  << buf1[a];
	log << endl;
if (ufds[1].revents & POLLIN) [/B] .... // same for 2 and 3

         // We fill the logical status values, b=0 for the main loop, 

	// And call the DisplayUpdate function to print the received data to 
        // the screen and process them into separate Log files
	// now separating them to groups of kind.


// End of Main function

I know there should be a lots of error checks but please remind me each of them and I will put them in.
It is possible that I will redesigne the whole code because of:
Put the possibilitie of configuration the ports, addresses the number of routers
And for displaying data on the screen choose a summary display and each router separately.

Thanks for ANY suggestion...

Sorry for the unclear design of code, I run out of 30 mins when it is possible to edit the post...

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.