/*
* Copyright ©2026 Soham Pardeshi. All rights reserved.
* Permission is hereby granted to students registered for University of
* Washington CSE 333 for use solely during Summer Quarter 2026 for
* purposes of the course. No other use, copying, distribution, or
* modification is permitted without prior written consent. Copyrights
* for third-party components of this work must be honored. Instructors
* interested in reusing these course materials should contact the author.
*/
#include <arpa/inet.h>
#include <netinet/in.h>
#include <sys/socket.h>
#include <cstdlib>
#include <cstring>
#include <iostream>
// Addresses in the sockets API are BINARY, inside a struct, in network
// byte order -- not strings. This program converts between the two forms:
//
// inet_pton "presentation" (text) -> network (binary, in the struct)
// inet_ntop network (binary) -> presentation (text)
//
// Note that IPv4 and IPv6 use different structs (sockaddr_in vs.
// sockaddr_in6) of different sizes, which is why generic code passes
// around a struct sockaddr* plus a length, and why sockaddr_storage
// exists (it is big enough for either family).
int main(int argc, char** argv) {
struct sockaddr_in sa; // IPv4
struct sockaddr_in6 sa6; // IPv6
memset(&sa, 0, sizeof(sa));
memset(&sa6, 0, sizeof(sa6));
sa.sin_family = AF_INET;
sa6.sin6_family = AF_INET6;
// Text -> binary, written directly into the address field of the struct.
inet_pton(AF_INET, "128.95.4.1", &(sa.sin_addr));
inet_pton(AF_INET6, "2001:db8:63b3:1::3490", &(sa6.sin6_addr));
// Ports are also in the struct, and also in network (big-endian) order:
// htons() converts from host order. Forgetting this is a classic bug.
sa.sin_port = htons(80);
// Binary -> text. The caller supplies the buffer and its size; the
// INET*_ADDRSTRLEN constants are the required sizes.
char v4[INET_ADDRSTRLEN];
char v6[INET6_ADDRSTRLEN];
inet_ntop(AF_INET, &(sa.sin_addr), v4, INET_ADDRSTRLEN);
inet_ntop(AF_INET6, &(sa6.sin6_addr), v6, INET6_ADDRSTRLEN);
std::cout << "IPv4: " << v4 << " port " << ntohs(sa.sin_port) << std::endl;
std::cout << "IPv6: " << v6 << std::endl;
std::cout << "sizeof(sockaddr_in) = " << sizeof(sa) << std::endl;
std::cout << "sizeof(sockaddr_in6) = " << sizeof(sa6) << std::endl;
std::cout << "sizeof(sockaddr_storage) = "
<< sizeof(struct sockaddr_storage) << std::endl;
return EXIT_SUCCESS;
}