Skip to content

Instantly share code, notes, and snippets.

@cheshirekow
Created February 21, 2019 17:07
Show Gist options
  • Save cheshirekow/43a700c79f342665722cd698d3137f50 to your computer and use it in GitHub Desktop.
Save cheshirekow/43a700c79f342665722cd698d3137f50 to your computer and use it in GitHub Desktop.
Post your IP addresses to slack. Useful to run on-boot.
// Copyright 2019 Josh Bialkowski <josh.bialkowski@gmail.com>
#include <fcntl.h>
#include <ifaddrs.h>
#include <net/if.h>
#include <netinet/in.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/ioctl.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <unistd.h>
#include <map>
#include <sstream>
#include <string>
#include <curl/curl.h>
#include <fmt/format.h>
#include <glog/logging.h>
struct ResultItem {
uint8_t ipv4[4];
uint16_t ipv6[8];
ResultItem() {
memset(ipv4, 0, 4);
memset(ipv6, 0, 16);
}
};
void post_to_slack(const std::map<std::string, ResultItem>& map) {
// override headers
struct curl_slist* headerlist = NULL;
headerlist = curl_slist_append(headerlist, "Expect:");
headerlist = curl_slist_append(headerlist, "Content-Type: application/json");
CURL* easy = curl_easy_init();
const char* webhook_uri = getenv("SLACK_URI");
if (!webhook_uri) {
LOG(WARNING) << "SLACK_URI missing from environment, can't continue";
}
std::string slack_url =
fmt::format("https://hooks.slack.com/services/{}", webhook_uri);
std::string hostname;
char* env_hostname = getenv("SLACK_POST_HOSTNAME");
if (env_hostname) {
hostname = env_hostname;
} else {
char buffer[32];
gethostname(buffer, sizeof(buffer));
hostname = buffer;
}
std::stringstream out;
out << "{\"text\": \"`";
out << hostname << "` has booted with addresses:```\\n";
for (auto& pair : map) {
out << pair.first << "\\n";
out << " ipv4: "
<< fmt::format("{:d}.{:d}.{:d}.{:d}", pair.second.ipv4[0],
pair.second.ipv4[1], pair.second.ipv4[2],
pair.second.ipv4[3])
<< "\\n";
out << " ipv6: "
<< fmt::format(
"{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}:{:04x}",
ntohs(pair.second.ipv6[0]), ntohs(pair.second.ipv6[1]),
ntohs(pair.second.ipv6[2]), ntohs(pair.second.ipv6[3]),
ntohs(pair.second.ipv6[4]), ntohs(pair.second.ipv6[5]),
ntohs(pair.second.ipv6[5]), ntohs(pair.second.ipv6[7]))
<< "\\n";
}
out << "```\"}";
std::string post_data = out.str();
curl_easy_setopt(easy, CURLOPT_URL, slack_url.c_str());
curl_easy_setopt(easy, CURLOPT_HTTPHEADER, headerlist);
curl_easy_setopt(easy, CURLOPT_POSTFIELDS, post_data.c_str());
curl_easy_setopt(easy, CURLOPT_VERBOSE, 0L);
curl_easy_setopt(easy, CURLOPT_LOW_SPEED_TIME, 3L);
curl_easy_setopt(easy, CURLOPT_LOW_SPEED_LIMIT, 10L);
curl_easy_perform(easy);
curl_easy_cleanup(easy);
}
std::map<std::string, ResultItem> get_addresses() {
int err = 0;
std::map<std::string, ResultItem> map;
struct ifaddrs* addrs = NULL;
err = getifaddrs(&addrs);
if (err != 0) {
return map;
}
for (struct ifaddrs* iter = addrs; iter != NULL; iter = iter->ifa_next) {
auto& item = map[iter->ifa_name];
if (!iter->ifa_addr) {
continue;
}
if (iter->ifa_addr->sa_family == AF_INET) {
uint8_t* addrbytes =
(uint8_t*)&((struct sockaddr_in*)(iter->ifa_addr))->sin_addr;
memcpy(item.ipv4, addrbytes, 4);
} else if (iter->ifa_addr->sa_family == AF_INET6) {
uint16_t* addrwords =
(uint16_t*)&((struct sockaddr_in6*)(iter->ifa_addr))->sin6_addr;
memcpy(item.ipv6, addrwords, 16);
}
}
freeifaddrs(addrs);
return map;
}
void print_map(const std::map<std::string, ResultItem>& map) {
for (auto pair : map) {
printf("%s: \n", pair.first.c_str());
printf(" %d.%d.%d.%d\n", pair.second.ipv4[0], pair.second.ipv4[1],
pair.second.ipv4[2], pair.second.ipv4[3]);
printf(" %04x:%04x:%04x:%04x:%04x:%04x:%04x:%04x\n",
ntohs(pair.second.ipv6[0]), ntohs(pair.second.ipv6[1]),
ntohs(pair.second.ipv6[2]), ntohs(pair.second.ipv6[3]),
ntohs(pair.second.ipv6[4]), ntohs(pair.second.ipv6[5]),
ntohs(pair.second.ipv6[6]), ntohs(pair.second.ipv6[7]));
}
}
int main(int argc, char** argv) {
curl_global_init(CURL_GLOBAL_ALL);
std::map<std::string, ResultItem> map = get_addresses();
// print_map(map);
post_to_slack(map);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment