Created
February 21, 2019 17:07
-
-
Save cheshirekow/43a700c79f342665722cd698d3137f50 to your computer and use it in GitHub Desktop.
Post your IP addresses to slack. Useful to run on-boot.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Copyright 2019 Josh Bialkowski <[email protected]> | |
#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