Snippets:IPv6 link local connect hack

/* connect2ll.c -- License: public domain / CC0 */
#include <sys/socket.h>
#include <fcntl.h>
#include <unistd.h>
#include <netinet/ip6.h>
#include <syscall.h>
#include <string.h>
#include <errno.h>
volatile static int data_fd = -1;
int connect(int fd, const struct sockaddr *addr, socklen_t length) {
        if (length != sizeof(struct sockaddr_in6)) goto do_real_connect;
        struct sockaddr_in6 addr_in6 = {0};
        memcpy(&addr_in6, addr, sizeof(struct sockaddr_in6));
        if (addr_in6.sin6_family != AF_INET6) goto do_real_connect;
        if (addr_in6.sin6_addr.s6_addr32[0] != *(uint32_t *) "\376\220\0\0") goto do_real_connect;
        if (addr_in6.sin6_scope_id) goto do_real_connect;
        addr_in6.sin6_scope_id = ntohl(addr_in6.sin6_addr.s6_addr32[1]);
        addr_in6.sin6_addr.s6_addr32[0] = *(uint32_t *) "\376\200\0\0";
        addr_in6.sin6_addr.s6_addr32[1] = 0;
        return syscall(SYS_connect, fd, &addr_in6, sizeof(addr_in6));
        return syscall(SYS_connect, fd, addr, length);
gcc -shared -o connect2ll connect2ll.c -Wall
LD_PRELOAD=./connect2ll firefox

Write the binary contents of a struct sockaddr_in6 into a file called connect_data in the current working directory. Only sin6_addr and sin6_scope_id will be used. Enter [febf::] in the URL bar.

Requires GCC atomic builtin support.

Characterized to be async signal safe and thread safe but not fully tested in those scenarios

This program is an LD_PRELOAD library. If you connect to fe90:0:[scope id]:[IP address], it will connect to fe80::[IP address]%scope_id even if the program which uses it is unaware of it.

For example, if you use this LD_PRELOAD library on an app and make a connection to fe90:0:0:3:0:0:1234:5678, then it will be equivalent to fe80::1234:5678%3.

For a much better version of this, check out Socket Enhancer.