14008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Shared library add-on to ip6tables to add Routing header support. */ 24008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <stdio.h> 34008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <netdb.h> 44008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <string.h> 54008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <stdlib.h> 64008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <getopt.h> 74008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <errno.h> 84008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <ip6tables.h> 94008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/*#include <linux/in6.h>*/ 104008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <linux/netfilter_ipv6/ip6t_rt.h> 114008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <sys/types.h> 124008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <sys/socket.h> 134008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#include <arpa/inet.h> 144008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 154008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/*#define DEBUG 1*/ 164008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 174008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Function which prints out usage message. */ 184008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 194008138e2b5248940265b160fae001d8954fae21The Android Open Source Projecthelp(void) 204008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 214008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf( 224008138e2b5248940265b160fae001d8954fae21The Android Open Source Project"RT v%s options:\n" 234008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-type [!] type match the type\n" 244008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-segsleft [!] num[:num] match the Segments Left field (range)\n" 254008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-len [!] length total length of this header\n" 264008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-0-res check the reserved filed, too (type 0)\n" 274008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-0-addrs ADDR[,ADDR...] Type=0 addresses (list, max: %d)\n" 284008138e2b5248940265b160fae001d8954fae21The Android Open Source Project" --rt-0-not-strict List of Type=0 addresses not a strict list\n", 294008138e2b5248940265b160fae001d8954fae21The Android Open Source ProjectIPTABLES_VERSION, IP6T_RT_HOPS); 304008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 314008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 324008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic struct option opts[] = { 334008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-type", 1, 0, '1' }, 344008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-segsleft", 1, 0, '2' }, 354008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-len", 1, 0, '3' }, 364008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-0-res", 0, 0, '4' }, 374008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-0-addrs", 1, 0, '5' }, 384008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { "rt-0-not-strict", 0, 0, '6' }, 394008138e2b5248940265b160fae001d8954fae21The Android Open Source Project {0} 404008138e2b5248940265b160fae001d8954fae21The Android Open Source Project}; 414008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 424008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic u_int32_t 434008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectparse_rt_num(const char *idstr, const char *typestr) 444008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 454008138e2b5248940265b160fae001d8954fae21The Android Open Source Project unsigned long int id; 464008138e2b5248940265b160fae001d8954fae21The Android Open Source Project char* ep; 474008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 484008138e2b5248940265b160fae001d8954fae21The Android Open Source Project id = strtoul(idstr,&ep,0) ; 494008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 504008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( idstr == ep ) { 514008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 524008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "RT no valid digits in %s `%s'", typestr, idstr); 534008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 544008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( id == ULONG_MAX && errno == ERANGE ) { 554008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 564008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "%s `%s' specified too big: would overflow", 574008138e2b5248940265b160fae001d8954fae21The Android Open Source Project typestr, idstr); 584008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 594008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( *idstr != '\0' && *ep != '\0' ) { 604008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 614008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "RT error parsing %s `%s'", typestr, idstr); 624008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 634008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return (u_int32_t) id; 644008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 654008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 664008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 674008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectparse_rt_segsleft(const char *idstring, u_int32_t *ids) 684008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 694008138e2b5248940265b160fae001d8954fae21The Android Open Source Project char *buffer; 704008138e2b5248940265b160fae001d8954fae21The Android Open Source Project char *cp; 714008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 724008138e2b5248940265b160fae001d8954fae21The Android Open Source Project buffer = strdup(idstring); 734008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ((cp = strchr(buffer, ':')) == NULL) 744008138e2b5248940265b160fae001d8954fae21The Android Open Source Project ids[0] = ids[1] = parse_rt_num(buffer,"segsleft"); 754008138e2b5248940265b160fae001d8954fae21The Android Open Source Project else { 764008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *cp = '\0'; 774008138e2b5248940265b160fae001d8954fae21The Android Open Source Project cp++; 784008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 794008138e2b5248940265b160fae001d8954fae21The Android Open Source Project ids[0] = buffer[0] ? parse_rt_num(buffer,"segsleft") : 0; 804008138e2b5248940265b160fae001d8954fae21The Android Open Source Project ids[1] = cp[0] ? parse_rt_num(cp,"segsleft") : 0xFFFFFFFF; 814008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 824008138e2b5248940265b160fae001d8954fae21The Android Open Source Project free(buffer); 834008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 844008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 854008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic char * 864008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectaddr_to_numeric(const struct in6_addr *addrp) 874008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 884008138e2b5248940265b160fae001d8954fae21The Android Open Source Project static char buf[50+1]; 894008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return (char *)inet_ntop(AF_INET6, addrp, buf, sizeof(buf)); 904008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 914008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 924008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic struct in6_addr * 934008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectnumeric_to_addr(const char *num) 944008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 954008138e2b5248940265b160fae001d8954fae21The Android Open Source Project static struct in6_addr ap; 964008138e2b5248940265b160fae001d8954fae21The Android Open Source Project int err; 974008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 984008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ((err=inet_pton(AF_INET6, num, &ap)) == 1) 994008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return ≈ 1004008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#ifdef DEBUG 1014008138e2b5248940265b160fae001d8954fae21The Android Open Source Project fprintf(stderr, "\nnumeric2addr: %d\n", err); 1024008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#endif 1034008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, "bad address: %s", num); 1044008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1054008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return (struct in6_addr *)NULL; 1064008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 1074008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1084008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1094008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic int 1104008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectparse_addresses(const char *addrstr, struct in6_addr *addrp) 1114008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 1124008138e2b5248940265b160fae001d8954fae21The Android Open Source Project char *buffer, *cp, *next; 1134008138e2b5248940265b160fae001d8954fae21The Android Open Source Project unsigned int i; 1144008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1154008138e2b5248940265b160fae001d8954fae21The Android Open Source Project buffer = strdup(addrstr); 1164008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (!buffer) exit_error(OTHER_PROBLEM, "strdup failed"); 1174008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1184008138e2b5248940265b160fae001d8954fae21The Android Open Source Project for (cp=buffer, i=0; cp && i<IP6T_RT_HOPS; cp=next,i++) 1194008138e2b5248940265b160fae001d8954fae21The Android Open Source Project { 1204008138e2b5248940265b160fae001d8954fae21The Android Open Source Project next=strchr(cp, ','); 1214008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (next) *next++='\0'; 1224008138e2b5248940265b160fae001d8954fae21The Android Open Source Project memcpy(&(addrp[i]), numeric_to_addr(cp), sizeof(struct in6_addr)); 1234008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#if DEBUG 1244008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("addr str: %s\n", cp); 1254008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("addr ip6: %s\n", addr_to_numeric((numeric_to_addr(cp)))); 1264008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("addr [%d]: %s\n", i, addr_to_numeric(&(addrp[i]))); 1274008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#endif 1284008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 1294008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (cp) exit_error(PARAMETER_PROBLEM, "too many addresses specified"); 1304008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1314008138e2b5248940265b160fae001d8954fae21The Android Open Source Project free(buffer); 1324008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1334008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#if DEBUG 1344008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("addr nr: %d\n", i); 1354008138e2b5248940265b160fae001d8954fae21The Android Open Source Project#endif 1364008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1374008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return i; 1384008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 1394008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1404008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Initialize the match. */ 1414008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 1424008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectinit(struct ip6t_entry_match *m, unsigned int *nfcache) 1434008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 1444008138e2b5248940265b160fae001d8954fae21The Android Open Source Project struct ip6t_rt *rtinfo = (struct ip6t_rt *)m->data; 1454008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1464008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->rt_type = 0x0L; 1474008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->segsleft[0] = 0x0L; 1484008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->segsleft[1] = 0xFFFFFFFF; 1494008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->hdrlen = 0; 1504008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags = 0; 1514008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags = 0; 1524008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->addrnr = 0; 1534008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 1544008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1554008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Function which parses command options; returns true if it 1564008138e2b5248940265b160fae001d8954fae21The Android Open Source Project ate an option */ 1574008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic int 1584008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectparse(int c, char **argv, int invert, unsigned int *flags, 1594008138e2b5248940265b160fae001d8954fae21The Android Open Source Project const struct ip6t_entry *entry, 1604008138e2b5248940265b160fae001d8954fae21The Android Open Source Project unsigned int *nfcache, 1614008138e2b5248940265b160fae001d8954fae21The Android Open Source Project struct ip6t_entry_match **match) 1624008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 1634008138e2b5248940265b160fae001d8954fae21The Android Open Source Project struct ip6t_rt *rtinfo = (struct ip6t_rt *)(*match)->data; 1644008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 1654008138e2b5248940265b160fae001d8954fae21The Android Open Source Project switch (c) { 1664008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '1': 1674008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_TYP) 1684008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 1694008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-type' allowed"); 1704008138e2b5248940265b160fae001d8954fae21The Android Open Source Project check_inverse(optarg, &invert, &optind, 0); 1714008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->rt_type = parse_rt_num(argv[optind-1], "type"); 1724008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (invert) 1734008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags |= IP6T_RT_INV_TYP; 1744008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_TYP; 1754008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_TYP; 1764008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 1774008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '2': 1784008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_SGS) 1794008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 1804008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-segsleft' allowed"); 1814008138e2b5248940265b160fae001d8954fae21The Android Open Source Project check_inverse(optarg, &invert, &optind, 0); 1824008138e2b5248940265b160fae001d8954fae21The Android Open Source Project parse_rt_segsleft(argv[optind-1], rtinfo->segsleft); 1834008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (invert) 1844008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags |= IP6T_RT_INV_SGS; 1854008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_SGS; 1864008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_SGS; 1874008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 1884008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '3': 1894008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_LEN) 1904008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 1914008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-len' allowed"); 1924008138e2b5248940265b160fae001d8954fae21The Android Open Source Project check_inverse(optarg, &invert, &optind, 0); 1934008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->hdrlen = parse_rt_num(argv[optind-1], "length"); 1944008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (invert) 1954008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags |= IP6T_RT_INV_LEN; 1964008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_LEN; 1974008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_LEN; 1984008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 1994008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '4': 2004008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_RES) 2014008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2024008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-0-res' allowed"); 2034008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( !(*flags & IP6T_RT_TYP) || (rtinfo->rt_type != 0) || (rtinfo->invflags & IP6T_RT_INV_TYP) ) 2044008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2054008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "`--rt-type 0' required before `--rt-0-res'"); 2064008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_RES; 2074008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_RES; 2084008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 2094008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '5': 2104008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_FST) 2114008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2124008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-0-addrs' allowed"); 2134008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( !(*flags & IP6T_RT_TYP) || (rtinfo->rt_type != 0) || (rtinfo->invflags & IP6T_RT_INV_TYP) ) 2144008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2154008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "`--rt-type 0' required before `--rt-0-addrs'"); 2164008138e2b5248940265b160fae001d8954fae21The Android Open Source Project check_inverse(optarg, &invert, &optind, 0); 2174008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (invert) 2184008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2194008138e2b5248940265b160fae001d8954fae21The Android Open Source Project " '!' not allowed with `--rt-0-addrs'"); 2204008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->addrnr = parse_addresses(argv[optind-1], rtinfo->addrs); 2214008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_FST; 2224008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_FST; 2234008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 2244008138e2b5248940265b160fae001d8954fae21The Android Open Source Project case '6': 2254008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (*flags & IP6T_RT_FST_NSTRICT) 2264008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2274008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "Only one `--rt-0-not-strict' allowed"); 2284008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if ( !(*flags & IP6T_RT_FST) ) 2294008138e2b5248940265b160fae001d8954fae21The Android Open Source Project exit_error(PARAMETER_PROBLEM, 2304008138e2b5248940265b160fae001d8954fae21The Android Open Source Project "`--rt-0-addr ...' required before `--rt-0-not-strict'"); 2314008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->flags |= IP6T_RT_FST_NSTRICT; 2324008138e2b5248940265b160fae001d8954fae21The Android Open Source Project *flags |= IP6T_RT_FST_NSTRICT; 2334008138e2b5248940265b160fae001d8954fae21The Android Open Source Project break; 2344008138e2b5248940265b160fae001d8954fae21The Android Open Source Project default: 2354008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return 0; 2364008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 2374008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2384008138e2b5248940265b160fae001d8954fae21The Android Open Source Project return 1; 2394008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 2404008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2414008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Final check; we don't care. */ 2424008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 2434008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectfinal_check(unsigned int flags) 2444008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 2454008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 2464008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2474008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 2484008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectprint_nums(const char *name, u_int32_t min, u_int32_t max, 2494008138e2b5248940265b160fae001d8954fae21The Android Open Source Project int invert) 2504008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 2514008138e2b5248940265b160fae001d8954fae21The Android Open Source Project const char *inv = invert ? "!" : ""; 2524008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2534008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (min != 0 || max != 0xFFFFFFFF || invert) { 2544008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%s", name); 2554008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (min == max) { 2564008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf(":%s", inv); 2574008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u", min); 2584008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } else { 2594008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("s:%s", inv); 2604008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u",min); 2614008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf(":"); 2624008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u",max); 2634008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 2644008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf(" "); 2654008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 2664008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 2674008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2684008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 2694008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectprint_addresses(int addrnr, struct in6_addr *addrp) 2704008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 2714008138e2b5248940265b160fae001d8954fae21The Android Open Source Project unsigned int i; 2724008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2734008138e2b5248940265b160fae001d8954fae21The Android Open Source Project for(i=0; i<addrnr; i++){ 2744008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%s%c", addr_to_numeric(&(addrp[i])), (i!=addrnr-1)?',':' '); 2754008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 2764008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 2774008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2784008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Prints out the union ip6t_matchinfo. */ 2794008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void 2804008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectprint(const struct ip6t_ip6 *ip, 2814008138e2b5248940265b160fae001d8954fae21The Android Open Source Project const struct ip6t_entry_match *match, int numeric) 2824008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 2834008138e2b5248940265b160fae001d8954fae21The Android Open Source Project const struct ip6t_rt *rtinfo = (struct ip6t_rt *)match->data; 2844008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 2854008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("rt "); 2864008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_TYP) 2874008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("type:%s%d ", rtinfo->invflags & IP6T_RT_INV_TYP ? "!" : "", 2884008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->rt_type); 2894008138e2b5248940265b160fae001d8954fae21The Android Open Source Project print_nums("segsleft", rtinfo->segsleft[0], rtinfo->segsleft[1], 2904008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags & IP6T_RT_INV_SGS); 2914008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_LEN) { 2924008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("length"); 2934008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf(":%s", rtinfo->invflags & IP6T_RT_INV_LEN ? "!" : ""); 2944008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u", rtinfo->hdrlen); 2954008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf(" "); 2964008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 2974008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_RES) printf("reserved "); 2984008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_FST) printf("0-addrs "); 2994008138e2b5248940265b160fae001d8954fae21The Android Open Source Project print_addresses(rtinfo->addrnr, (struct in6_addr *)rtinfo->addrs); 3004008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_FST_NSTRICT) printf("0-not-strict "); 3014008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->invflags & ~IP6T_RT_INV_MASK) 3024008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("Unknown invflags: 0x%X ", 3034008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->invflags & ~IP6T_RT_INV_MASK); 3044008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 3054008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3064008138e2b5248940265b160fae001d8954fae21The Android Open Source Project/* Saves the union ip6t_matchinfo in parsable form to stdout. */ 3074008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic void save(const struct ip6t_ip6 *ip, const struct ip6t_entry_match *match) 3084008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 3094008138e2b5248940265b160fae001d8954fae21The Android Open Source Project const struct ip6t_rt *rtinfo = (struct ip6t_rt *)match->data; 3104008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3114008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_TYP) { 3124008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("--rt-type %s%u ", 3134008138e2b5248940265b160fae001d8954fae21The Android Open Source Project (rtinfo->invflags & IP6T_RT_INV_TYP) ? "! " : "", 3144008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->rt_type); 3154008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 3164008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3174008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (!(rtinfo->segsleft[0] == 0 3184008138e2b5248940265b160fae001d8954fae21The Android Open Source Project && rtinfo->segsleft[1] == 0xFFFFFFFF)) { 3194008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("--rt-segsleft %s", 3204008138e2b5248940265b160fae001d8954fae21The Android Open Source Project (rtinfo->invflags & IP6T_RT_INV_SGS) ? "! " : ""); 3214008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->segsleft[0] 3224008138e2b5248940265b160fae001d8954fae21The Android Open Source Project != rtinfo->segsleft[1]) 3234008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u:%u ", 3244008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->segsleft[0], 3254008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->segsleft[1]); 3264008138e2b5248940265b160fae001d8954fae21The Android Open Source Project else 3274008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("%u ", 3284008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->segsleft[0]); 3294008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 3304008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3314008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_LEN) { 3324008138e2b5248940265b160fae001d8954fae21The Android Open Source Project printf("--rt-len %s%u ", 3334008138e2b5248940265b160fae001d8954fae21The Android Open Source Project (rtinfo->invflags & IP6T_RT_INV_LEN) ? "! " : "", 3344008138e2b5248940265b160fae001d8954fae21The Android Open Source Project rtinfo->hdrlen); 3354008138e2b5248940265b160fae001d8954fae21The Android Open Source Project } 3364008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3374008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_RES) printf("--rt-0-res "); 3384008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_FST) printf("--rt-0-addrs "); 3394008138e2b5248940265b160fae001d8954fae21The Android Open Source Project print_addresses(rtinfo->addrnr, (struct in6_addr *)rtinfo->addrs); 3404008138e2b5248940265b160fae001d8954fae21The Android Open Source Project if (rtinfo->flags & IP6T_RT_FST_NSTRICT) printf("--rt-0-not-strict "); 3414008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3424008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 3434008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3444008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectstatic struct ip6tables_match rt = { 3454008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .name = "rt", 3464008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .version = IPTABLES_VERSION, 3474008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .size = IP6T_ALIGN(sizeof(struct ip6t_rt)), 3484008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .userspacesize = IP6T_ALIGN(sizeof(struct ip6t_rt)), 3494008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .help = &help, 3504008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .init = &init, 3514008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .parse = &parse, 3524008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .final_check = &final_check, 3534008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .print = &print, 3544008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .save = &save, 3554008138e2b5248940265b160fae001d8954fae21The Android Open Source Project .extra_opts = opts, 3564008138e2b5248940265b160fae001d8954fae21The Android Open Source Project}; 3574008138e2b5248940265b160fae001d8954fae21The Android Open Source Project 3584008138e2b5248940265b160fae001d8954fae21The Android Open Source Projectvoid 3594008138e2b5248940265b160fae001d8954fae21The Android Open Source Project_init(void) 3604008138e2b5248940265b160fae001d8954fae21The Android Open Source Project{ 3614008138e2b5248940265b160fae001d8954fae21The Android Open Source Project register_match6(&rt); 3624008138e2b5248940265b160fae001d8954fae21The Android Open Source Project} 363