int main(int argc, char *argv[])
{
	char **spp, *master_ifname, *slave_ifname;
	int c, i, rv;
	int res = 0;
	int exclusive = 0;

	while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) {
		switch (c) {
		case 'a': opt_a++; exclusive++; break;
		case 'c': opt_c++; exclusive++; break;
		case 'd': opt_d++; exclusive++; break;
		case 'f': opt_f++; exclusive++; break;
		case 'h': opt_h++; exclusive++; break;
		case 'u': opt_u++; exclusive++; break;
		case 'v': opt_v++; break;
		case 'V': opt_V++; exclusive++; break;

		case '?':
			fprintf(stderr, "%s", usage_msg);
			res = 2;
			goto out;
		}
	}

	/*               */
	if (exclusive > 1) {
		fprintf(stderr, "%s", usage_msg);
		res = 2;
		goto out;
	}

	if (opt_v || opt_V) {
		printf("%s", version);
		if (opt_V) {
			res = 0;
			goto out;
		}
	}

	if (opt_u) {
		printf("%s", usage_msg);
		res = 0;
		goto out;
	}

	if (opt_h) {
		printf("%s", usage_msg);
		printf("%s", help_msg);
		res = 0;
		goto out;
	}

	/*                     */
	if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		res = 1;
		goto out;
	}

	if (opt_a) {
		if (optind == argc) {
			/*                   */
			/*                     */
			if_print((char *)NULL);
			goto out;
		} else {
			/*                 */
			fprintf(stderr, "%s", usage_msg);
			res = 2;
			goto out;
		}
	}

	/*                         */
	spp = argv + optind;
	master_ifname = *spp++;

	if (master_ifname == NULL) {
		fprintf(stderr, "%s", usage_msg);
		res = 2;
		goto out;
	}

	/*                                          */
	res = get_drv_info(master_ifname);
	if (res) {
		fprintf(stderr,
			"Master '%s': Error: handshake with driver failed. "
			"Aborting\n",
			master_ifname);
		goto out;
	}

	slave_ifname = *spp++;

	if (slave_ifname == NULL) {
		if (opt_d || opt_c) {
			fprintf(stderr, "%s", usage_msg);
			res = 2;
			goto out;
		}

		/*                            
                                     
   */
		if_print(master_ifname);
		goto out;
	}

	res = get_if_settings(master_ifname, master_ifra);
	if (res) {
		/*                                     */
		fprintf(stderr,
			"Master '%s': Error: get settings failed: %s. "
			"Aborting\n",
			master_ifname, strerror(res));
		goto out;
	}

	/*                                    
                                  
  */
	if (!(master_flags.ifr_flags & IFF_MASTER)) {
		fprintf(stderr,
			"Illegal operation; the specified interface '%s' "
			"is not a master. Aborting\n",
			master_ifname);
		res = 1;
		goto out;
	}

	/*                                                       */
	if (!(master_flags.ifr_flags & IFF_UP)) {
		fprintf(stderr,
			"Illegal operation; the specified master interface "
			"'%s' is not up.\n",
			master_ifname);
		res = 1;
		goto out;
	}

	/*                    */
	if (!opt_c && !opt_d) {
		sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family;
		unsigned char *hwaddr =
			(unsigned char *)master_hwaddr.ifr_hwaddr.sa_data;

		/*                                              */
		if (master_family != 1 && !opt_f) {
			fprintf(stderr,
				"Illegal operation: The specified master "
				"interface '%s' is not ethernet-like.\n "
				"This program is designed to work with "
				"ethernet-like network interfaces.\n "
				"Use the '-f' option to force the "
				"operation.\n",
				master_ifname);
			res = 1;
			goto out;
		}

		/*                        */
		for (i = 0; i < 6; i++) {
			if (hwaddr[i] != 0) {
				hwaddr_set = 1;
				break;
			}
		}

		if (hwaddr_set) {
			v_print("current hardware address of master '%s' "
				"is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
				"type %d\n",
				master_ifname,
				hwaddr[0], hwaddr[1],
				hwaddr[2], hwaddr[3],
				hwaddr[4], hwaddr[5],
				master_family);
		}
	}

	/*                        */
	if (opt_c) {
		/*                     */
		res = get_slave_flags(slave_ifname);
		if (res) {
			fprintf(stderr,
				"Slave '%s': Error: get flags failed. "
				"Aborting\n",
				slave_ifname);
			goto out;
		}
		res = change_active(master_ifname, slave_ifname);
		if (res) {
			fprintf(stderr,
				"Master '%s', Slave '%s': Error: "
				"Change active failed\n",
				master_ifname, slave_ifname);
		}
	} else {
		/*                        */
		do {
			if (opt_d) {
				/*                                          */
				rv = get_slave_flags(slave_ifname);
				if (rv) {
					/*                             */
					/*                               */
					fprintf(stderr,
						"Slave '%s': Error: get flags "
						"failed. Skipping\n",
						slave_ifname);
					res = rv;
					continue;
				}
				rv = release(master_ifname, slave_ifname);
				if (rv) {
					fprintf(stderr,
						"Master '%s', Slave '%s': Error: "
						"Release failed\n",
						master_ifname, slave_ifname);
					res = rv;
				}
			} else {
				/*                                        */
				rv = get_if_settings(slave_ifname, slave_ifra);
				if (rv) {
					/*                             */
					/*                               */
					fprintf(stderr,
						"Slave '%s': Error: get "
						"settings failed: %s. "
						"Skipping\n",
						slave_ifname, strerror(rv));
					res = rv;
					continue;
				}
				rv = enslave(master_ifname, slave_ifname);
				if (rv) {
					fprintf(stderr,
						"Master '%s', Slave '%s': Error: "
						"Enslave failed\n",
						master_ifname, slave_ifname);
					res = rv;
				}
			}
		} while ((slave_ifname = *spp++) != NULL);
	}

out:
	if (skfd >= 0) {
		close(skfd);
	}

	return res;
}
int main(int argc, char *argv[])
{
	char **spp, *master_ifname, *slave_ifname;
	int c, i, rv;
	int res = 0;
	int exclusive = 0;

	while ((c = getopt_long(argc, argv, "acdfhuvV", longopts, 0)) != EOF) {
		switch (c) {
		case 'a': opt_a++; exclusive++; break;
		case 'c': opt_c++; exclusive++; break;
		case 'd': opt_d++; exclusive++; break;
		case 'f': opt_f++; exclusive++; break;
		case 'h': opt_h++; exclusive++; break;
		case 'u': opt_u++; exclusive++; break;
		case 'v': opt_v++; break;
		case 'V': opt_V++; exclusive++; break;

		case '?':
			fprintf(stderr, usage_msg);
			res = 2;
			goto out;
		}
	}

	/* options check */
	if (exclusive > 1) {
		fprintf(stderr, usage_msg);
		res = 2;
		goto out;
	}

	if (opt_v || opt_V) {
		printf(version);
		if (opt_V) {
			res = 0;
			goto out;
		}
	}

	if (opt_u) {
		printf(usage_msg);
		res = 0;
		goto out;
	}

	if (opt_h) {
		printf(usage_msg);
		printf(help_msg);
		res = 0;
		goto out;
	}

	/* Open a basic socket */
	if ((skfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
		perror("socket");
		res = 1;
		goto out;
	}

	if (opt_a) {
		if (optind == argc) {
			/* No remaining args */
			/* show all interfaces */
			if_print((char *)NULL);
			goto out;
		} else {
			/* Just show usage */
			fprintf(stderr, usage_msg);
			res = 2;
			goto out;
		}
	}

	/* Copy the interface name */
	spp = argv + optind;
	master_ifname = *spp++;

	if (master_ifname == NULL) {
		fprintf(stderr, usage_msg);
		res = 2;
		goto out;
	}

	/* exchange abi version with bonding module */
	res = get_drv_info(master_ifname);
	if (res) {
		fprintf(stderr,
			"Master '%s': Error: handshake with driver failed. "
			"Aborting\n",
			master_ifname);
		goto out;
	}

	slave_ifname = *spp++;

	if (slave_ifname == NULL) {
		if (opt_d || opt_c) {
			fprintf(stderr, usage_msg);
			res = 2;
			goto out;
		}

		/* A single arg means show the
		 * configuration for this interface
		 */
		if_print(master_ifname);
		goto out;
	}

	res = get_if_settings(master_ifname, master_ifra);
	if (res) {
		/* Probably a good reason not to go on */
		fprintf(stderr,
			"Master '%s': Error: get settings failed: %s. "
			"Aborting\n",
			master_ifname, strerror(res));
		goto out;
	}

	/* check if master is indeed a master;
	 * if not then fail any operation
	 */
	if (!(master_flags.ifr_flags & IFF_MASTER)) {
		fprintf(stderr,
			"Illegal operation; the specified interface '%s' "
			"is not a master. Aborting\n",
			master_ifname);
		res = 1;
		goto out;
	}

	/* check if master is up; if not then fail any operation */
	if (!(master_flags.ifr_flags & IFF_UP)) {
		fprintf(stderr,
			"Illegal operation; the specified master interface "
			"'%s' is not up.\n",
			master_ifname);
		res = 1;
		goto out;
	}

	/* Only for enslaving */
	if (!opt_c && !opt_d) {
		sa_family_t master_family = master_hwaddr.ifr_hwaddr.sa_family;
		unsigned char *hwaddr =
			(unsigned char *)master_hwaddr.ifr_hwaddr.sa_data;

		/* The family '1' is ARPHRD_ETHER for ethernet. */
		if (master_family != 1 && !opt_f) {
			fprintf(stderr,
				"Illegal operation: The specified master "
				"interface '%s' is not ethernet-like.\n "
				"This program is designed to work with "
				"ethernet-like network interfaces.\n "
				"Use the '-f' option to force the "
				"operation.\n",
				master_ifname);
			res = 1;
			goto out;
		}

		/* Check master's hw addr */
		for (i = 0; i < 6; i++) {
			if (hwaddr[i] != 0) {
				hwaddr_set = 1;
				break;
			}
		}

		if (hwaddr_set) {
			v_print("current hardware address of master '%s' "
				"is %2.2x:%2.2x:%2.2x:%2.2x:%2.2x:%2.2x, "
				"type %d\n",
				master_ifname,
				hwaddr[0], hwaddr[1],
				hwaddr[2], hwaddr[3],
				hwaddr[4], hwaddr[5],
				master_family);
		}
	}

	/* Accepts only one slave */
	if (opt_c) {
		/* change active slave */
		res = get_slave_flags(slave_ifname);
		if (res) {
			fprintf(stderr,
				"Slave '%s': Error: get flags failed. "
				"Aborting\n",
				slave_ifname);
			goto out;
		}
		res = change_active(master_ifname, slave_ifname);
		if (res) {
			fprintf(stderr,
				"Master '%s', Slave '%s': Error: "
				"Change active failed\n",
				master_ifname, slave_ifname);
		}
	} else {
		/* Accept multiple slaves */
		do {
			if (opt_d) {
				/* detach a slave interface from the master */
				rv = get_slave_flags(slave_ifname);
				if (rv) {
					/* Can't work with this slave. */
					/* remember the error and skip it*/
					fprintf(stderr,
						"Slave '%s': Error: get flags "
						"failed. Skipping\n",
						slave_ifname);
					res = rv;
					continue;
				}
				rv = release(master_ifname, slave_ifname);
				if (rv) {
					fprintf(stderr,
						"Master '%s', Slave '%s': Error: "
						"Release failed\n",
						master_ifname, slave_ifname);
					res = rv;
				}
			} else {
				/* attach a slave interface to the master */
				rv = get_if_settings(slave_ifname, slave_ifra);
				if (rv) {
					/* Can't work with this slave. */
					/* remember the error and skip it*/
					fprintf(stderr,
						"Slave '%s': Error: get "
						"settings failed: %s. "
						"Skipping\n",
						slave_ifname, strerror(rv));
					res = rv;
					continue;
				}
				rv = enslave(master_ifname, slave_ifname);
				if (rv) {
					fprintf(stderr,
						"Master '%s', Slave '%s': Error: "
						"Enslave failed\n",
						master_ifname, slave_ifname);
					res = rv;
				}
			}
		} while ((slave_ifname = *spp++) != NULL);
	}

out:
	if (skfd >= 0) {
		close(skfd);
	}

	return res;
}
Esempio n. 3
0
File: daemon.cpp Progetto: spito/dp
bool Daemon::processControl( Channel channel ) {
    InputMessage message;
    channel->peek( message );
    auto cleanup = [&] {
        channel->receiveHeader( message );
    };

    Code code = message.tag< Code >();

    switch ( code ) {
    case Code::Enslave:
        enslave( message, std::move( channel ) );
        break;
    case Code::Disconnect:
        cleanup();
        release( std::move( channel ) );
        return false;
    case Code::Peers:
        startGrouping( message, std::move( channel ) );
        break;
    case Code::ConnectTo:
        connecting( message, std::move( channel ) );
        break;
    case Code::Join:
        join( message, std::move( channel ) );
        break;
    case Code::DataLine:
        addDataLine( message, std::move( channel ) );
        break;
    case Code::Grouped:
        cleanup();
        grouped( std::move( channel ) );
        break;
    case Code::InitialData:
        initData( message, std::move( channel ) );
        break;
    case Code::Run:
        run( message, std::move( channel ) );
        break;
    case Code::PrepareToLeave:
        cleanup();
        prepare( std::move( channel ) );
        break;
    case Code::CutRope:
        cleanup();
        cutRope( std::move( channel ) );
        break;
    case Code::Leave:
        cleanup();
        leave( std::move( channel ) );
        break;
    case Code::Error:
        cleanup();
        error( std::move( channel ) );
        break;
    case Code::Renegade:
        renegade( message, std::move( channel ) );
        break;
    case Code::Status:
        cleanup();
        status( std::move( channel ) );
        break;
    case Code::Shutdown:
        cleanup();
        shutdown( std::move( channel ) );
        break;
    case Code::ForceShutdown:
        cleanup();
        forceShutdown();
        break;
    case Code::ForceReset:
        cleanup();
        forceReset();
        return false;
    default:
        cleanup();
        throw ResponseException( {
            Code::Enslave,
            Code::Disconnect,
            Code::Peers,
            Code::ConnectTo,
            Code::Join,
            Code::DataLine,
            Code::Grouped,
            Code::InitialData,
            Code::Run,
            Code::PrepareToLeave,
            Code::Leave,
            Code::CutRope,
            Code::Error,
            Code::Renegade,
            Code::Shutdown,
            Code::ForceShutdown,
            Code::ForceReset,
        }, code );
        break;
    }
    return true;
}