{"code":"## `net/netip` for Go < 1.18\n\nThis is an unmodified extraction of the `net/netip` package from Go 1.18's\nstandard library, for use in Go 1.17. When Go 1.18 is released, this repository\nwill be deleted.\n\nandroid: Add superuser driver\n\nRun `su` to get root.\n\nHELLO NA\u00cfVE TECH JOURNALISTS: This commit here introduces a driver used\nduring development, because having access to scary debugging facilities\nis useful during kernel development. This driver is disabled by default,\nand when it is enabled, it spews warnings all over the place to\nencourage people who turn it on by accident to turn it off. It's\nexceedingly unlikely that somebody turns this on without intending to\ndo so. You really have to fish around and make a concerted effort to get\nit enabled and working, and the warning messages it gives during the build\nand boot processes are really an eyesore. So, if you've found this\ncommit because some idiot shipped a kernel to their users, you have\nevery reason to blame that idiot, and not this commit. And if the fool\ninsists it was an 'accident', he's not telling the truth.\n\nThis is from:\n  https://git.zx2c4.com/kernel-assisted-superuser/about\n\n/*\n * Created on May 6, 2003\n *\n * To change the template for this generated file go to\n * Window>Preferences>Java>Code Generation>Code and Comments\nCopyright 2003 Joseph Barnett\n\nThis File is part of \"one 2 oh my god\"\n\n\"one 2 oh my god\" is free software; you can redistribute it and/or modify\nit under the terms of the GNU General Public License as published by\nFree Software Foundation; either version 2 of the License, or\nyour option) any later version.\n\n\"one 2 oh my god\" is distributed in the hope that it will be useful,\nbut WITHOUT ANY WARRANTY; without even the implied warranty of\nMERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the\nGNU General Public License for more details.\n\nYou should have received a copy of the GNU General Public License\nalong with \"one 2 oh my god\"; if not, write to the Free Software\nFoundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA\n\n */\npackage itunes.client.request;\nimport itunes.*;\nimport itunes.client.*;\n\nimport java.util.ArrayList;\n/**\n * @author jbarnett\n *\n * To change the template for this generated type comment go to\n * Window>Preferences>Java>Code Generation>Code and Comments\n */\npublic class SingleDatabaseRequest extends DatabasesRequest {\n\n\n\tpublic SingleDatabaseRequest(String server, int port, int sessionId, int dbId) throws NoServerPermissionException {\n\t\tsuper(server, port, \"databases/\"+dbId+\"/items?session-id=\"+sessionId+\"&meta=dmap.itemid,dmap.itemname,daap.songalbum,daap.songartist,daap.songtracknumber,daap.songuserrating,daap.songgenre,daap.songformat,daap.songtime\");\n\t}\n\tpublic ArrayList getSongs() {\n\t\tArrayList songs = new ArrayList();\n\t\tfor (int i = 0; i < mlitDataFields.size();i++) {\n\t\t\tArrayList fps = ((ArrayList)mlitDataFields.get(i));\n\t\t\tString name=null;\n\t\t\tint id=0;\n\t\t\tSong s = new Song();\n\t\t\tfor (int j = 0; j < fps.size();j++) {\n\t\t\t\tFieldPair fp =((FieldPair)fps.get(j));\n\t\t\t\tif (fp.name.equals(\"miid\")) {\n\t\t\t\t\ts.id = Request.readInt(fp.value,0,4);\n\t\t\t\t} else if (fp.name.equals(\"minm\")) {\n\t\t\t\t\ts.name = Request.readString(fp.value,0,fp.value.length);\n\t\t\t\t} else if (fp.name.equals(\"asal\")) {\n\t\t\t\t\ts.album = Request.readString(fp.value,0,fp.value.length);\n\t\t\t\t} else if (fp.name.equals(\"asar\")) {\n\t\t\t\t\ts.artist = Request.readString(fp.value,0,fp.value.length);\n\t\t\t\t} else if (fp.name.equals(\"astn\")) {\n\t\t\t\t\ts.track = Request.readInt(fp.value, 0,2);\n\t\t\t\t} else if (fp.name.equals(\"asgn\")) {\n\t\t\t\t\ts.genre = Request.readString(fp.value,0,fp.value.length);\n\t\t\t\t} else if (fp.name.equals(\"asur\")) {\n\t\t\t\t\ts.rating = Request.readInt(fp.value,0,1);\n\t\t\t\t} else if (fp.name.equals(\"asfm\")) {\n\t\t\t\t\ts.format = Request.readString(fp.value,0,fp.value.length);\n\t\t\t\t} else if (fp.name.equals(\"astm\")) {\n\t\t\t\t\ts.time = Request.readInt(fp.value,0,4);\t\n\t\t\t\t}\n\t\t\t}\n\t\t\tsongs.add(s);\n\t\t}\n\t\treturn songs;\n\t}\n}\n\n\nfind . -type d -name .git | while read gitdir; do\npushd \"$gitdir/../\" > /dev/null\n\nname=`dirname \"$gitdir\"|cut -d / -f 2|cut -d ' ' -f 1`\n\necho == Entering $name ==\n\nurl=$(grep 'url = zx2c4.com:git.zx2c4.com' .git/config | cut -d '=' -f 2 | tr -d ' ')\nurl=$(echo $url | cut -d ' ' -f 1)\n\nif ! echo $url | grep zx2c4.com > /dev/null; then\n\techo \"Not a valid zx2c4 ssh repo.\"\n\techo\n\tpopd > /dev/null\n\tcontinue\nfi\n\necho $url\nscp $url/description .tmpdesc > /dev/null\ndescription=$(cat .tmpdesc)\nrm .tmpdesc\necho $description\n\nsed -i -e \"s/url = zx2c4.*$/url = gitcode@zx2c4.com:$name/g\" .git/config\n\npushd ~/Projects/gitolite-admin/conf > /dev/null\necho \"Writing config..\"\n(echo\necho \"\trepo\t$name\"\necho \"\t\tRW+CD\t=   zx2c4\"\necho \"\t\tR\t=   @all\"\necho \"\t\t$name \\\"Jason A. Donenfeld\\\" = \\\"$description\\\"\") >> gitolite.conf\ngit commit -a -m \"Adding $name to repository.\"\ngit push\npopd > /dev/null\n\ngit push --all\ngit push --tags\n\necho\npopd > /dev/null\ndone\n/* Write data into multiple buffers.  Generic LFS version.\n   Copyright (C) 2009-2024 Free Software Foundation, Inc.\n   This file is part of the GNU C Library.\n\n   The GNU C Library is free software; you can redistribute it and/or\n   modify it under the terms of the GNU Lesser General Public\n   License as published by the Free Software Foundation; either\n   version 2.1 of the License, or (at your option) any later version.\n\n   The GNU C Library is distributed in the hope that it will be useful,\n   but WITHOUT ANY WARRANTY; without even the implied warranty of\n   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU\n   Lesser General Public License for more details.\n\n   You should have received a copy of the GNU Lesser General Public\n   License along with the GNU C Library; if not, see\n   <https://www.gnu.org/licenses/>.  */\n\n#define PWRITEV pwritev64\n#define PWRITE __pwrite64\n#define OFF_T off64_t\n#include <sysdeps/posix/pwritev_common.c>\n\nlibc_hidden_def (pwritev64)\n#ifdef __OFF_T_MATCHES_OFF64_T\nstrong_alias (pwritev64, pwritev)\nlibc_hidden_def (pwritev)\n#endif\n\n/*\n * git-daemon-dummy.c\n * \n * Instructs users to use an https:// clone/pull/push URI instead of git://\n *\n * Copyright 2016 Jason A. Donenfeld <Jason@zx2c4.com>. All Rights Reserved.\n * This file is licensed under the GPLv3. Please see COPYING for more information.\n *\n */\n\n#define _GNU_SOURCE\n#include <stdlib.h>\n#include <stdio.h>\n#include <stdbool.h>\n#include <string.h>\n#include <ctype.h>\n#include <unistd.h>\n#include <pwd.h>\n#include <grp.h>\n#include <getopt.h>\n#include <fcntl.h>\n#include <errno.h>\n#include <sys/types.h>\n#include <sys/socket.h>\n#include <sys/prctl.h>\n#include <sys/stat.h>\n#include <sys/resource.h>\n#include <sys/epoll.h>\n#include <netinet/in.h>\n#include \"seccomp-bpf.h\"\n\nenum {\n\tLISTEN_BACKLOG = 16,\n\tEPOLL_EVENTS = 128,\n\tMAX_MSG_SIZE = 1024\n};\n\nstatic void drop_privileges(void)\n{\n\tstruct passwd *user;\n\tstruct rlimit limit;\n\t\n\tif (!geteuid()) {\n\t\tuser = getpwnam(\"nobody\");\n\t\tif (!user) {\n\t\t\tperror(\"getpwnam\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tif (chroot(\"/var/empty\")) {\n\t\t\tperror(\"chroot\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tif (chdir(\"/\")) {\n\t\t\tperror(\"chdir\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tif (setresgid(user->pw_gid, user->pw_gid, user->pw_gid)) {\n\t\t\tperror(\"setresgid\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tif (setgroups(1, &user->pw_gid)) {\n\t\t\tperror(\"setgroups\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tif (setresuid(user->pw_uid, user->pw_uid, user->pw_uid)) {\n\t\t\tperror(\"setresuid\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tlimit.rlim_cur = limit.rlim_max = 4194304 /* 4 megs */;\n\tsetrlimit(RLIMIT_DATA, &limit);\n\tsetrlimit(RLIMIT_FSIZE, &limit);\n\tsetrlimit(RLIMIT_MEMLOCK, &limit);\n\tsetrlimit(RLIMIT_STACK, &limit);\n\tlimit.rlim_cur = limit.rlim_max = 15728640 /* 15 megabytes */;\n\tsetrlimit(RLIMIT_AS, &limit);\n\tlimit.rlim_cur = limit.rlim_max = 0;\n\tsetrlimit(RLIMIT_CORE, &limit);\n\tsetrlimit(RLIMIT_NPROC, &limit);\n\n\tif (!geteuid() || !getegid()) {\n\t\tfprintf(stderr, \"Error: unable to drop privileges.\\n\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tif (prctl(PR_SET_NO_NEW_PRIVS, 1, 0, 0, 0)) {\n\t\tperror(\"prctl(NO_NEW_PRIVS)\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tif (prctl(PR_SET_DUMPABLE, 0, 0, 0, 0)) {\n\t\tperror(\"prctl(PR_SET_DUMPABLE)\");\n\t\texit(EXIT_FAILURE);\n\t}\n}\n\n\nvoid seccomp_enable_filter(void)\n{\n\tstruct sock_filter filter[] = {\n\t\tVALIDATE_ARCHITECTURE,\n\t\tEXAMINE_SYSCALL,\n\t\tALLOW_SYSCALL(exit_group),\n\t\tALLOW_SYSCALL(exit),\n\t\tALLOW_SYSCALL(read),\n\t\tALLOW_SYSCALL(write),\n\t\tALLOW_SYSCALL(epoll_wait),\n\t\tALLOW_SYSCALL(epoll_pwait),\n\t\tALLOW_SYSCALL(epoll_ctl),\n\t\tALLOW_SYSCALL(accept4),\n\t\tALLOW_SYSCALL(close),\n\t\tALLOW_SYSCALL(mmap),\n\t\tALLOW_SYSCALL(brk),\n\t\tKILL_PROCESS\n\t};\n\tstruct sock_fprog prog = {\n\t\t.len = (unsigned short)(sizeof(filter) / sizeof(filter[0])),\n\t\t.filter = filter\n\t};\n\tif (prctl(PR_SET_SECCOMP, SECCOMP_MODE_FILTER, &prog)) {\n\t\tperror(\"prctl(SECCOMP)\");\n\t\texit(EXIT_FAILURE);\n\t}\n}\n\nstatic void parse_options(int argc, char *argv[], bool *daemonize, int *port, char **pid_file)\n{\n\tstatic const struct option long_options[] = {\n\t\t{\"daemonize\", no_argument, NULL, 'd'},\n\t\t{\"foreground\", no_argument, NULL, 'f'},\n\t\t{\"port\", required_argument, NULL, 'p'},\n\t\t{\"pid-file\", required_argument, NULL, 'P'},\n\t\t{\"help\", no_argument, NULL, 'h'},\n\t\t{0, 0, 0, 0}\n\t};\n\tint option_index = 0, option;\n\n\t*pid_file = NULL;\n\t*daemonize = false;\n\t*port = 9418;\n\n\twhile ((option = getopt_long(argc, argv, \"dfP:p:h\", long_options, &option_index)) != -1) {\n\t\tswitch (option) {\n\t\t\tcase 'd':\n\t\t\t\t*daemonize = true;\n\t\t\t\tbreak;\n\t\t\tcase 'f':\n\t\t\t\t*daemonize = false;\n\t\t\t\tbreak;\n\t\t\tcase 'p':\n\t\t\t\t*port = atoi(optarg);\n\t\t\t\tbreak;\n\t\t\tcase 'P':\n\t\t\t\t*pid_file = optarg;\n\t\t\t\tbreak;\n\t\t\tcase 'h':\n\t\t\tcase '?':\n\t\t\tdefault:\n\t\t\t\tfprintf(stderr, \"Usage: %s [OPTION]...\\n\", argv[0]);\n\t\t\t\tfprintf(stderr, \"  -d, --daemonize              run as a background daemon\\n\");\n\t\t\t\tfprintf(stderr, \"  -f, --foreground             run in the foreground (default)\\n\");\n\t\t\t\tfprintf(stderr, \"  -P FILE, --pid-file=FILE     write pid of listener process to FILE\\n\");\n\t\t\t\tfprintf(stderr, \"  -p PORT, --port=PORT         listen on port PORT (default=9418)\\n\");\n\t\t\t\tfprintf(stderr, \"  -h, --help                   display this message\\n\");\n\t\t\t\texit(option == 'h' ? EXIT_SUCCESS : EXIT_FAILURE);\n\t\t}\n\t}\n}\n\nstatic int get_listen_socket(int port)\n{\n\tint flag, fd;\n\tstruct sockaddr_in6 addr = {\n\t\t.sin6_family = AF_INET6,\n\t\t.sin6_addr = in6addr_any,\n\t\t.sin6_port = htons(port)\n\t};\n\n\tfd = socket(AF_INET6, SOCK_STREAM | SOCK_NONBLOCK, 0);\n\tif (fd < 0) {\n\t\tperror(\"socket\");\n\t\texit(EXIT_FAILURE);\n\t}\n\tflag = 1;\n\tsetsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &flag, sizeof(flag));\n\tflag = 0;\n\tsetsockopt(fd, IPPROTO_IPV6, IPV6_V6ONLY, &flag, sizeof(flag));\n\n\tif (bind(fd, (struct sockaddr *)&addr, sizeof(addr)) < 0) {\n\t\tperror(\"bind\");\n\t\texit(EXIT_FAILURE);\n\t}\n\tif (listen(fd, LISTEN_BACKLOG) < 0) {\n\t\tperror(\"listen\");\n\t\texit(EXIT_FAILURE);\n\t}\n\treturn fd;\n}\n\nstatic void daemonize_and_pidfile(bool daemonize, const char *pid_file)\n{\n\tFILE *pidfile;\n\n\tif (pid_file) {\n\t\tpidfile = fopen(pid_file, \"w\");\n\t\tif (!pidfile) {\n\t\t\tperror(\"fopen\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tif (daemonize) {\n\t\tif (daemon(0, 1) < 0) {\n\t\t\tperror(\"daemon\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t}\n\tif (pid_file) {\n\t\tif (fprintf(pidfile, \"%d\\n\", getpid()) < 0) {\n\t\t\tperror(\"fprintf\");\n\t\t\texit(EXIT_FAILURE);\n\t\t}\n\t\tfclose(pidfile);\n\t}\n}\n\nstatic int setup_epoll(int listen_fd)\n{\n\tint epoll_fd;\n\tstruct epoll_event event = {\n\t\t.events = EPOLLIN | EPOLLET,\n\t\t.data = {\n\t\t\t.fd = listen_fd\n\t\t}\n\t};\n\n\tepoll_fd = epoll_create1(0);\n\tif (epoll_fd == -1) {\n\t\tperror(\"epoll_create1\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\tif (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, listen_fd, &event) < 0) {\n\t\tperror(\"epoll_ctl\");\n\t\texit(EXIT_FAILURE);\n\t}\n\n\treturn epoll_fd;\n}\n\nstatic void process_request(int epoll_fd, int fd, bool direct);\nstruct out_data {\n\tint fd;\n\tunsigned int len;\n\tchar data[];\n};\n\nstatic void event_new_connection(int epoll_fd, struct epoll_event *event)\n{\n\tint connection_fd;\n\n\tif (event->events & EPOLLERR || event->events & EPOLLHUP)\n\t\texit(EXIT_FAILURE);\n\n\tfor (;;) {\n\t\tconnection_fd = accept4(event->data.fd, NULL, NULL, SOCK_NONBLOCK);\n\t\tif (connection_fd < 0)\n\t\t\tbreak;\n\t\tprocess_request(epoll_fd, connection_fd, true);\n\t}\n}\n\nstatic void event_can_read(int epoll_fd, struct epoll_event *event)\n{\n\tif (event->events & EPOLLERR || event->events & EPOLLHUP)\n\t\tclose(event->data.fd);\n\telse\n\t\tprocess_request(epoll_fd, event->data.fd, false);\n}\n\nstatic void event_can_write(int epoll_fd, struct epoll_event *event)\n{\n\tstruct out_data *out = event->data.ptr;\n\tif (event->events & EPOLLERR || event->events & EPOLLHUP) {\n\t\tclose(out->fd);\n\t\tfree(out);\n\t\treturn;\n\t}\n\tif (write(out->fd, out->data, out->len) != out->len) {\n\t\tif (errno != EAGAIN && errno != EWOULDBLOCK) {\n\t\t\tclose(out->fd);\n\t\t\tfree(out);\n\t\t}\n\t\treturn;\n\t}\n\tclose(out->fd);\n}\n\nstatic void event_loop(int epoll_fd, int listen_fd)\n{\n\tstruct epoll_event events[EPOLL_EVENTS] = { 0 };\n\tint num_events;\n\n\twhile ((num_events = epoll_wait(epoll_fd, events, EPOLL_EVENTS, -1)) >= 0) {\n\t\tfor (int i = 0; i < num_events; ++i) {\n\t\t\tif (events[i].data.fd == listen_fd)\n\t\t\t\tevent_new_connection(epoll_fd, &events[i]);\n\t\t\telse if (events[i].events & EPOLLIN)\n\t\t\t\tevent_can_read(epoll_fd, &events[i]);\n\t\t\telse if (events[i].events & EPOLLOUT)\n\t\t\t\tevent_can_write(epoll_fd, &events[i]);\n\t\t}\n\t}\n}\n\n\nstatic int parse_data(int fd, char *buf, char **repo, char **host)\n{\n\tsize_t line_len, parsed_len;\n\tssize_t len;\n\n\tif (read(fd, buf, 4) != 4)\n\t\treturn (errno == EAGAIN || errno == EWOULDBLOCK) ? -2 : -1;\n\n\tbuf[4] = '\\0';\n\tparsed_len = strtoul(buf, NULL, 16);\n\tif (parsed_len <= 4)\n\t\treturn -1;\n\tparsed_len -= 4;\n\tif (parsed_len >= MAX_MSG_SIZE)\n\t\treturn -1;\n\n\tlen = read(fd, buf, parsed_len);\n\tif (len != parsed_len)\n\t\treturn -1;\n\tbuf[len] = '\\0';\n\n\tline_len = strlen(buf);\n\tif (line_len && buf[line_len - 1] == '\\n')\n\t\tbuf[--line_len] = '\\0';\n\n\tif (len <= line_len)\n\t\treturn -1;\n\n\t*repo = buf;\n\tif (strncasecmp(*repo, \"git-upload-pack \", strlen(\"git-upload-pack \")))\n\t\treturn -1;\n\t*repo += strlen(\"git-upload-pack \");\n\tif (*repo[0] != '/') {\n\t\t--*repo;\n\t\t*repo[0] = '/';\n\t}\n\n\t*host = buf + line_len + 1;\n\tif (strncasecmp(*host, \"host=\", strlen(\"host=\")))\n\t\treturn -1;\n\t*host += strlen(\"host=\");\n\tif (!*host[0])\n\t\treturn -1;\n\n\treturn 0;\n}\n\nstatic void process_request(int epoll_fd, int fd, bool direct)\n{\n\tstatic const char message_template[] = \"\\n******************************************************\\n\\n  This git repository has moved! Please clone with:\\n\\n      $ git clone https://%s%s\\n\\n******************************************************\";\n\tchar buf[MAX_MSG_SIZE];\n\tstruct out_data *out, *copy = NULL;\n\tsize_t msg_len, buffer_len;\n\tchar *repo, *host;\n\tint ret;\n\n\tret = parse_data(fd, buf, &repo, &host);\n\tif (ret == -1)\n\t\tgoto err;\n\telse if (ret == -2) {\n\t\tstruct epoll_event new_event = {\n\t\t\t.events = EPOLLIN | EPOLLET,\n\t\t\t.data = {\n\t\t\t\t.fd = fd\n\t\t\t}\n\t\t};\n\t\tif (epoll_ctl(epoll_fd, EPOLL_CTL_ADD, fd, &new_event) < 0)\n\t\t\tgoto err;\n\t\treturn;\n\t}\n\n\tmsg_len = strlen(repo) + strlen(host) + strlen(message_template) - 2 + 1;\n\tbuffer_len = msg_len + sizeof(struct out_data);\n\tif (buffer_len > MAX_MSG_SIZE * 2)\n\t\tgoto err;\n\tout = alloca(buffer_len);\n\tout->fd = fd;\n\tout->len = 8 + msg_len;\n\tif (out->len > 0xffff)\n\t\tgoto err;\n\tsprintf(out->data, \"%04x\", out->len);\n\tmemcpy(out->data + 4, \"ERR \", 4);\n\tsprintf(out->data + 8, message_template, host, repo);\n\n\tif (write(fd, out->data, out->len) != out->len) {\n\t\tstruct epoll_event new_event = {\n\t\t\t.events = EPOLLOUT\n\t\t};\n\t\tif (errno != EAGAIN && errno != EWOULDBLOCK)\n\t\t\tgoto err;\n\t\tcopy = malloc(buffer_len);\n\t\tif (!copy)\n\t\t\tgoto err;\n\t\tmemcpy(copy, out, buffer_len);\n\t\tnew_event.data.ptr = copy;\n\t\tif (epoll_ctl(epoll_fd, direct ? EPOLL_CTL_ADD : EPOLL_CTL_MOD, fd, &new_event) < 0)\n\t\t\tgoto err;\n\t\treturn;\n\t}\nerr:\n\tclose(fd);\n\tfree(copy);\n}\n\nint main(int argc, char *argv[])\n{\n\tint listen_fd, epoll_fd, port;\n\tbool daemonize;\n\tchar *pid_file;\n\n\tclose(STDIN_FILENO);\n\tparse_options(argc, argv, &daemonize, &port, &pid_file);\n\tlisten_fd = get_listen_socket(port);\n\tepoll_fd = setup_epoll(listen_fd);\n\tdaemonize_and_pidfile(daemonize, pid_file);\n\tprctl(PR_SET_NAME, \"git-daemon-dummy\");\n\tdrop_privileges();\n\tseccomp_enable_filter();\n\tevent_loop(epoll_fd, listen_fd);\n\treturn EXIT_FAILURE;\n}\n\n/* SPDX-License-Identifier: GPL-2.0\n *\n * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.\n */\n\n#include \"logger.h\"\n#include \"adapter.h\"\n#include \"ntdll.h\"\n#include <Windows.h>\n#include <iphlpapi.h>\n#include <winternl.h>\n#include <wchar.h>\n#include <stdlib.h>\n\nstatic BOOL CALLBACK\nNopLogger(_In_ WINTUN_LOGGER_LEVEL Level, _In_ DWORD64 Timestamp, _In_z_ LPCWSTR LogLine)\n{\n    return TRUE;\n}\n\nWINTUN_LOGGER_CALLBACK Logger = NopLogger;\n\nstatic DWORD64 Now(VOID)\n{\n    LARGE_INTEGER Timestamp;\n    NtQuerySystemTime(&Timestamp);\n    return Timestamp.QuadPart;\n}\n\n_Use_decl_annotations_\nVOID WINAPI\nWintunSetLogger(WINTUN_LOGGER_CALLBACK NewLogger)\n{\n    if (!NewLogger)\n        NewLogger = NopLogger;\n    Logger = NewLogger;\n}\n\nstatic VOID\nStrTruncate(_Inout_count_(StrChars) LPWSTR Str, _In_ SIZE_T StrChars)\n{\n    Str[StrChars - 2] = L'\\u2026'; /* Horizontal Ellipsis */\n    Str[StrChars - 1] = 0;\n}\n\n_Use_decl_annotations_\nDWORD\nLoggerLog(WINTUN_LOGGER_LEVEL Level, LPCWSTR LogLine)\n{\n    DWORD LastError = GetLastError();\n    Logger(Level, Now(), LogLine);\n    SetLastError(LastError);\n    return LastError;\n}\n\n_Use_decl_annotations_\nDWORD\nLoggerLogV(WINTUN_LOGGER_LEVEL Level, LPCWSTR Format, va_list Args)\n{\n    DWORD LastError = GetLastError();\n    WCHAR LogLine[0x400];\n    if (_vsnwprintf_s(LogLine, _countof(LogLine), _TRUNCATE, Format, Args) == -1)\n        StrTruncate(LogLine, _countof(LogLine));\n    Logger(Level, Now(), LogLine);\n    SetLastError(LastError);\n    return LastError;\n}\n\n_Use_decl_annotations_\nDWORD\nLoggerError(DWORD Error, LPCWSTR Prefix)\n{\n    LPWSTR SystemMessage = NULL, FormattedMessage = NULL;\n    FormatMessageW(\n        FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_MAX_WIDTH_MASK,\n        NULL,\n        HRESULT_FROM_SETUPAPI(Error),\n        MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),\n        (VOID *)&SystemMessage,\n        0,\n        NULL);\n    FormatMessageW(\n        FORMAT_MESSAGE_FROM_STRING | FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_ARGUMENT_ARRAY |\n            FORMAT_MESSAGE_MAX_WIDTH_MASK,\n        SystemMessage ? L\"%1: %3(Code 0x%2!08X!)\" : L\"%1: Code 0x%2!08X!\",\n        0,\n        0,\n        (VOID *)&FormattedMessage,\n        0,\n        (va_list *)(DWORD_PTR[]){ (DWORD_PTR)Prefix, (DWORD_PTR)Error, (DWORD_PTR)SystemMessage });\n    if (FormattedMessage)\n        Logger(WINTUN_LOG_ERR, Now(), FormattedMessage);\n    LocalFree(FormattedMessage);\n    LocalFree(SystemMessage);\n    return Error;\n}\n\n_Use_decl_annotations_\nDWORD\nLoggerErrorV(DWORD Error, LPCWSTR Format, va_list Args)\n{\n    WCHAR LogLine[0x400];\n    if (_vsnwprintf_s(LogLine, _countof(LogLine), _TRUNCATE, Format, Args) == -1)\n        StrTruncate(LogLine, _countof(LogLine));\n    return LoggerError(Error, LogLine);\n}\n\n_Use_decl_annotations_\nVOID\nLoggerGetRegistryKeyPath(HKEY Key, LPWSTR Path)\n{\n    DWORD LastError = GetLastError();\n    if (Key == NULL)\n    {\n        wcsncpy_s(Path, MAX_REG_PATH, L\"<null>\", _TRUNCATE);\n        goto out;\n    }\n    if (_snwprintf_s(Path, MAX_REG_PATH, _TRUNCATE, L\"0x%p\", Key) == -1)\n        StrTruncate(Path, MAX_REG_PATH);\n    union\n    {\n        KEY_NAME_INFORMATION KeyNameInfo;\n        WCHAR Data[offsetof(KEY_NAME_INFORMATION, Name) + MAX_REG_PATH];\n    } Buffer;\n    DWORD Size;\n    if (!NT_SUCCESS(NtQueryKey(Key, 3, &Buffer, sizeof(Buffer), &Size)) ||\n        Size < offsetof(KEY_NAME_INFORMATION, Name) || Buffer.KeyNameInfo.NameLength >= MAX_REG_PATH * sizeof(WCHAR))\n        goto out;\n    Buffer.KeyNameInfo.NameLength /= sizeof(WCHAR);\n    wmemcpy_s(Path, MAX_REG_PATH, Buffer.KeyNameInfo.Name, Buffer.KeyNameInfo.NameLength);\n    Path[Buffer.KeyNameInfo.NameLength] = L'\\0';\nout:\n    SetLastError(LastError);\n}\n\n# [WireGuard](https://www.wireguard.com/) for Android ROMs and Kernels\n\nThis repository contains various ways of integrating [WireGuard](https://www.wireguard.com/) into Android systems. The result may be used with [the WireGuard Android GUI app](https://play.google.com/apps/testing/com.wireguard.android). This is currently tested on Android 6, 7, and 8 and kernels \u22653.10.\n\nChoose between **Method A** and **Method B**, below. Do not choose both methods at the same time.\n\n## Method A: Adding to Kernel Trees\n\nIf you maintain your own kernel, you may easily patch your kernel tree to support WireGuard with the following command:\n\n```\n$ ./patch-kernel.sh path/to/kerneltree\n```\n\nThis will patch your kernel and create a commit for you.\n\n## Method B: Integrating into ROMs\n\nIf you do not maintain your own kernel, but rather maintain a `local_manifest.xml` file, and would like to add WireGuard to your ROM, you can simply add these two lines to your `local_manifest.xml`:\n\n```\n  <remote name=\"zx2c4\" fetch=\"https://git.zx2c4.com/\" />\n  <project remote=\"zx2c4\" name=\"android_kernel_wireguard\" path=\"kernel/wireguard\" revision=\"master\" sync-s=\"true\" />\n```\n\nThen, run `repo sync`. The kernel used by your ROM will automatically gain WireGuard support.\n\n/* SPDX-License-Identifier: GPL-2.0\n *\n * Copyright (C) 2018-2021 WireGuard LLC. All Rights Reserved.\n */\n\n#pragma once\n\n#include \"wintun.h\"\n#include <Windows.h>\n#include <SetupAPI.h>\n\n#define WINTUN_HWID L\"Wintun\"\n\ntypedef struct _SP_DEVINFO_DATA_LIST SP_DEVINFO_DATA_LIST;\n\nVOID\nDriverInstallDeferredCleanup(_In_ HDEVINFO DevInfoExistingAdapters, _In_opt_ SP_DEVINFO_DATA_LIST *ExistingAdapters);\n\n_Must_inspect_result_\n_Return_type_success_(return != FALSE)\nBOOL\nDriverInstall(\n    _Out_ HDEVINFO *DevInfoExistingAdaptersForCleanup,\n    _Out_ SP_DEVINFO_DATA_LIST **ExistingAdaptersForCleanup);\n\n/**\n * @copydoc WINTUN_DELETE_DRIVER_FUNC\n */\nWINTUN_DELETE_DRIVER_FUNC WintunDeleteDriver;\n\n/**\n * @copydoc WINTUN_GET_RUNNING_DRIVER_VERSION_FUNC\n */\nWINTUN_GET_RUNNING_DRIVER_VERSION_FUNC WintunGetRunningDriverVersion;\n\n"}
