Skip to content

Instantly share code, notes, and snippets.

@alekswn
Created April 22, 2022 08:07
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save alekswn/80eb0287d93deb9d449378041cf49445 to your computer and use it in GitHub Desktop.
Save alekswn/80eb0287d93deb9d449378041cf49445 to your computer and use it in GitHub Desktop.
#include <assert.h>
#include <sys/ioctl.h>
#include <errno.h>
#include <unistd.h>
#include <arpa/inet.h>
#include <sys/socket.h>
#include <sys/types.h>
#include <linux/errqueue.h>
#define max_mtu_size_bytes (1500)
#define header_length_bytes (28)
#define max_payload_size_bytes (max_mtu_size_bytes - header_length_bytes)
int main(int argc, char* argv[])
{
assert(argc == 2);
int s = socket(AF_INET, SOCK_DGRAM, 0);
assert(s > 0);
const int pmtu_option = IP_PMTUDISC_WANT;
assert(setsockopt(s, IPPROTO_IP, IP_MTU_DISCOVER, &pmtu_option, sizeof pmtu_option) == 0);
const int one = 1;
assert(ioctl(s, FIONBIO, &one) != -1);
struct in_addr ip_addr;
assert(inet_pton(AF_INET, argv[1], (void*)&ip_addr) == 1);
const unsigned short echo_port = 7;
struct sockaddr_in addr = {
.sin_family = AF_INET,
.sin_port = htons(echo_port),
.sin_addr = ip_addr,
};
assert(connect(s, (const struct sockaddr *)&addr, sizeof addr) == 0);
int i = 0;
for (i = 0; i < 100; i++)
{
size_t payload_size_bytes;
socklen_t option_len = sizeof payload_size_bytes;
assert(getsockopt(s, IPPROTO_IP, IP_MTU, &payload_size_bytes, &option_len) == 0);
payload_size_bytes -= header_length_bytes;
const char* payload[max_payload_size_bytes] = {0};
assert(send(s, payload, payload_size_bytes, 0) == payload_size_bytes);
}
return i;
}
~
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment