Create a gist now

Instantly share code, notes, and snippets.

What would you like to do?
get route source address
#include <arpa/inet.h>
#include <netinet/in.h>
#include <stdio.h>
#include <string.h>
#include <sys/socket.h>
#include <string>
std::string get_src_addr_popen(const std::string& addr) {
// assemble command string
char command[64];
snprintf(command, 64, "ip route get %s", addr.c_str());
// execute command
FILE* fp = popen(command, "r");
if (fp == NULL) {
return ""; // error
}
// get stdout of command
char buffer[64];
if (fgets(buffer, 64, fp) == NULL) {
return ""; // error
}
buffer[strlen(buffer) - 1] = '\0'; // chomp '\n'
// get source address
char* pos = strstr(buffer, "src ");
if (pos == NULL) {
return ""; // error
}
pclose(fp); // close file pointer
return std::string(pos + 4);
}
std::string get_src_addr_socket(const std::string& addr) {
// create address structure
struct sockaddr_in sin;
socklen_t len = sizeof(sin);
// set address configurations
sin.sin_family = AF_INET;
inet_aton(addr.c_str(), &sin.sin_addr);
sin.sin_port = htons(0);
// create socket
int sockfd = socket(AF_INET, SOCK_DGRAM, 0);
if (sockfd == -1) {
return ""; // error
}
// connect socket
int rc_conn = connect(sockfd, (struct sockaddr*)&sin, sizeof(sin));
if (rc_conn == -1) {
return ""; // error
}
// get local address
int rc_get = getsockname(sockfd, (struct sockaddr*)&sin, &len);
if (rc_get == -1) {
return ""; // error
}
return std::string(inet_ntoa(sin.sin_addr));
}
#include <iostream>
int main(int argc, char** argv) {
std::cout << get_src_addr_popen(argv[1]) << std::endl;
std::cout << get_src_addr_socket(argv[1]) << std::endl;
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment