@@ 0,0 1,53 @@
+package main
+
+var excuses = []string{
+ "Android doesn't support DHCPv6",
+ "AWS doesn't support it",
+ "Azure doesn't support it",
+ "Can't we just buy more IPv4 addresses?",
+ "Did you mean IPTV?",
+ "End users don't care about IPv6",
+ "Github doesn't support IPv6",
+ "Hex is hard",
+ "I don't want to expose my MAC address",
+ "I don't want to lose the security provided by NAT",
+ "IPv6 addresses are too long to remember",
+ "IPv6 is a security risk",
+ "IPv6 is just a fad",
+ "IPv6 isn't an Internet Standard yet",
+ "IPv6 isn't supported by OVH Cloud",
+ "IPv6 is slower than IPv4",
+ "IPv6 just isn't a priority",
+ "It'll break our GeoIP",
+ "It'll make it easier for the government to track me",
+ "It's not mature enough",
+ "It's not supported by Google Compute",
+ "It's on our roadmap",
+ "It's too complicated",
+ "It's too hard to support",
+ "Larger headers are less efficient",
+ "My transit provider doesn't support IPv6",
+ "NAT444 is fine",
+ "None of our customers want it",
+ "Our business intelligence team can't even parse IPv4 logfiles",
+ "Our Dynamic DNS doesn't support it",
+ "Our Lawful Intercept doesn't support IPv6 yet",
+ "Our recursive DNS can't handle the extra load",
+ "Our vendor doesn't support it",
+ "There's no certification track",
+ "There's no ROI on deploying IPv6",
+ "Those stupid Privacy Extension addresses keep changing",
+ "Too many people have broken IPv6 stacks",
+ "Vendor bugs",
+ "We can use RFC6598",
+ "We don't have a lab to test it",
+ "We don't need that many addresses",
+ "We forgot to include IPv6 in our last RFP",
+ "We have IPv6, but we just want to keep things simple",
+ "We have no roadmap for native IPv6 as we rolled out 6RD.",
+ "We'll deploy IPv6 right after we deploy DNSSEC",
+ "We've still got plenty of IPv4",
+ "We would have to rewrite our entire application to support it",
+ "What do you mean I have to wrap an IP in square brackets?",
+ "What's IPv6?",
+}
@@ 0,0 1,80 @@
+package main
+
+import (
+ "flag"
+ "fmt"
+ "math/rand"
+ "net"
+ "time"
+)
+
+var (
+ header = "Today's excuse to not implement IPv6 is:"
+ footer = "Brought to you courtesy https://ipv6excuses.com/"
+ past time.Time
+)
+
+func pickExcuse() string {
+ index := rand.Intn(len(excuses))
+ excuse := excuses[index]
+ return fmt.Sprintf("%s\n\n%s\n\n%s\n", header, excuse, footer)
+}
+
+func listenUDP(address string) {
+ udpAddr, err := net.ResolveUDPAddr("udp", address)
+ if err != nil {
+ panic(err)
+ }
+ c, err := net.ListenUDP("udp", udpAddr)
+ if err != nil {
+ panic(err)
+ }
+
+ for {
+ _, ret, err := c.ReadFrom(nil)
+ if err != nil {
+ panic(err)
+ }
+ excuse := pickExcuse()
+ c.WriteTo([]byte(excuse), ret)
+ }
+}
+
+func listenTCP(address string) {
+ tcpAddr, err := net.ResolveTCPAddr("tcp", address)
+ if err != nil {
+ panic(err)
+ }
+
+ c, err := net.ListenTCP("tcp", tcpAddr)
+ if err != nil {
+ panic(err)
+ }
+ defer c.Close()
+
+ for {
+ conn, err := c.AcceptTCP()
+ if err != nil {
+ panic(err)
+ }
+ go func() {
+ excuse := pickExcuse()
+ conn.SetLinger(3)
+ conn.Write([]byte(excuse))
+ conn.SetReadDeadline(past)
+ conn.Close()
+ }()
+ }
+}
+
+func main() {
+ var address = flag.String("address", "0.0.0.0", "Address to listen on")
+ var port = flag.Int("port", 17, "Port to listen on")
+ flag.Parse()
+
+ addr := fmt.Sprintf("%s:%d", *address, *port)
+
+ go listenTCP(addr)
+ go listenUDP(addr)
+ select { }
+}