1dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat/* 2dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * m_pedit.c generic packet editor actions module 3dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 4dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * This program is free software; you can distribute it and/or 5dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * modify it under the terms of the GNU General Public License 6dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * as published by the Free Software Foundation; either version 7dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2 of the License, or (at your option) any later version. 8dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 9dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * Authors: J Hadi Salim (hadi@cyberus.ca) 10dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 11dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * TODO: 12dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 1) Big endian broken in some spots 13dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 2) A lot of this stuff was added on the fly; get a big double-double 14dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * and clean it up at some point. 15dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat * 16dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat */ 17dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 18dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdio.h> 19dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <stdlib.h> 20dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <unistd.h> 21dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <syslog.h> 22dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <fcntl.h> 23dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <sys/socket.h> 24dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <netinet/in.h> 25dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <arpa/inet.h> 26dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <string.h> 27dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include <dlfcn.h> 28dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "utils.h" 29dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "tc_util.h" 30dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat#include "m_pedit.h" 31dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 32dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic struct m_pedit_util *pedit_list; 33dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint pedit_debug = 1; 34dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 35dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void 36dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatexplain(void) 37dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 38dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Usage: ... pedit munge <MUNGE>\n"); 39dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 40dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "Where: MUNGE := <RAW>|<LAYERED>\n" 41dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t<RAW>:= <OFFSETC>[ATC]<CMD>\n " 42dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tOFFSETC:= offset <offval> <u8|u16|u32>\n " 43dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tATC:= at <atval> offmask <maskval> shift <shiftval>\n " 44dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tNOTE: offval is byte offset, must be multiple of 4\n " 45dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tNOTE: maskval is a 32 bit hex number\n " 46dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tNOTE: shiftval is a is a shift value\n " 47dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t\tCMD:= clear | invert | set <setval>| retain\n " 48dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "\t<LAYERED>:= ip <ipdata> | ip6 <ip6data> \n " 49dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat " \t\t| udp <udpdata> | tcp <tcpdata> | icmp <icmpdata> \n" 50dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "For Example usage look at the examples directory\n"); 51dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 52dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 53dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 54dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic void 55dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatusage(void) 56dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 57dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 58dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat exit(-1); 59dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 60dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 61dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstatic int 62dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpedit_parse_nopopt (int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 63dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 64dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 65dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 66dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 67dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc) { 68dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Unknown action hence option \"%s\" is unparsable\n", *argv); 69dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 70dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 71dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 72dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 73dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 74dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 75dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 76dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct m_pedit_util 77dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat*get_pedit_kind(char *str) 78dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 79dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat static void *pBODY; 80dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat void *dlh; 81dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char buf[256]; 82dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct m_pedit_util *p; 83dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 84dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (p = pedit_list; p; p = p->next) { 85dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (strcmp(p->id, str) == 0) 86dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return p; 87dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 88dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 89dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat snprintf(buf, sizeof(buf), "p_%s.so", str); 90dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dlh = dlopen(buf, RTLD_LAZY); 91dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (dlh == NULL) { 92dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dlh = pBODY; 93dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (dlh == NULL) { 94dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat dlh = pBODY = dlopen(NULL, RTLD_LAZY); 95dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (dlh == NULL) 96dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto noexist; 97dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 98dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 99dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 100dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat snprintf(buf, sizeof(buf), "p_pedit_%s", str); 101dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p = dlsym(dlh, buf); 102dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p == NULL) 103dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto noexist; 104dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 105dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatreg: 106dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->next = pedit_list; 107dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat pedit_list = p; 108dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return p; 109dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 110dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatnoexist: 111dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p = malloc(sizeof(*p)); 112dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (p) { 113dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(p, 0, sizeof(*p)); 114dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(p->id, str, sizeof(p->id)-1); 115dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p->parse_peopt = pedit_parse_nopopt; 116dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto reg; 117dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 118dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return p; 119dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 120dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 121dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 122dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpack_key(struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 123dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 124dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int hwm = sel->nkeys; 125dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 126dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (hwm >= MAX_OFFS) 127dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 128dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 129dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tkey->off % 4) { 130dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "offsets MUST be in 32 bit boundaries\n"); 131dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 132dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 133dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 134dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].val = tkey->val; 135dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].mask = tkey->mask; 136dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].off = tkey->off; 137dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].at = tkey->at; 138dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].offmask = tkey->offmask; 139dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->keys[hwm].shift = tkey->shift; 140dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel->nkeys++; 141dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 142dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 143dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 144dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 145dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 146dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpack_key32(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 147dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 148dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tkey->off > (tkey->off & ~3)) { 149dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, 150dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat "pack_key32: 32 bit offsets must begin in 32bit boundaries\n"); 151dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 152dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 153dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 154dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->val = htonl(tkey->val & retain); 155dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = htonl(tkey->mask | ~retain); 156dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* jamal remove this - it is not necessary given the if check above */ 157dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->off &= ~3; 158dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return pack_key(sel,tkey); 159dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 160dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 161dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 162dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpack_key16(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 163dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 164dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ind = 0, stride = 0; 165dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 m[4] = {0xFFFF0000,0xFF0000FF,0x0000FFFF}; 166dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 167dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > tkey->off) { 168dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off + 1; 169dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > ind) 170dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = -1*ind; 171dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 172dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off; 173dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 174dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 175dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tkey->val > 0xFFFF || tkey->mask > 0xFFFF) { 176dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "pack_key16 bad value\n"); 177dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 178dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 179dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 180dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off & 3; 181dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 182dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > ind || 2 < ind) { 183dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "pack_key16 bad index value %d\n",ind); 184dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 185dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 186dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 187dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat stride = 8 * ind; 188dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->val = htons(tkey->val); 189dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (stride > 0) { 190dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->val <<= stride; 191dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask <<= stride; 192dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain <<= stride; 193dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 194dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = retain|m[ind]; 195dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 196dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->off &= ~3; 197dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 198dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (pedit_debug) 199dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("pack_key16: Final val %08x mask %08x \n",tkey->val,tkey->mask); 200dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return pack_key(sel,tkey); 201dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 202dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 203dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 204dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 205dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpack_key8(__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 206dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 207dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ind = 0, stride = 0; 208dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 m[4] = {0xFFFFFF00,0xFFFF00FF,0xFF00FFFF,0x00FFFFFF}; 209dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 210dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > tkey->off) { 211dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off + 1; 212dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (0 > ind) 213dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = -1*ind; 214dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 215dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off; 216dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 217dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 218dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tkey->val > 0xFF || tkey->mask > 0xFF) { 219dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "pack_key8 bad value (val %x mask %x\n", tkey->val, tkey->mask); 220dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 221dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 222dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 223dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ind = tkey->off & 3; 224dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat stride = 8 * ind; 225dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->val <<= stride; 226dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask <<= stride; 227dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain <<= stride; 228dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = retain|m[ind]; 229dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->off &= ~3; 230dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 231dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (pedit_debug) 232dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("pack_key8: Final word off %d val %08x mask %08x \n",tkey->off , tkey->val,tkey->mask); 233dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return pack_key(sel,tkey); 234dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 235dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 236dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 237dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatparse_val(int *argc_p, char ***argv_p, __u32 * val, int type) 238dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 239dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 240dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 241dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 242dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) 243dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 244dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 245dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (TINT == type) 246dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return get_integer((int *) val, *argv, 0); 247dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 248dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (TU32 == type) 249dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return get_u32(val, *argv, 0); 250dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 251dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (TIPV4 == type) { 252dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat inet_prefix addr; 253dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_prefix_1(&addr, *argv, AF_INET)) { 254dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 255dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 256dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *val=addr.data[0]; 257dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 258dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 259dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (TIPV6 == type) { 260dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* not implemented yet */ 261dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 262dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 263dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 264dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 265dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 266dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 267dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 268dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatparse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 269dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 270dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 mask = 0, val = 0; 271dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 o = 0xFF; 272dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int res = -1; 273dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 274dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 275dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 276dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) 277dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 278dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 279dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (pedit_debug) 280dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); 281dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 282dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len == 2) 283dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat o = 0xFFFF; 284dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len == 4) 285dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat o = 0xFFFFFFFF; 286dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 287dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "invert") == 0) { 288dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain = val = mask = o; 289dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "set") == 0) { 290dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 291dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_val(&argc, &argv, &val, type)) 292dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 293dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "preserve") == 0) { 294dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain = mask = o; 295dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 296dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "clear") != 0) 297dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 298dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 299dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 300dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 301dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 302dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc && matches(*argv, "retain") == 0) { 303dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 304dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_val(&argc, &argv, &retain, TU32)) 305dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 306dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; argv++; 307dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 308dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 309dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->val = val; 310dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 311dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len == 1) { 312dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = 0xFF; 313dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = pack_key8(retain,sel,tkey); 314dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 315dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 316dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len == 2) { 317dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = mask; 318dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = pack_key16(retain,sel,tkey); 319dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 320dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 321dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (len == 4) { 322dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->mask = mask; 323dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = pack_key32(retain,sel,tkey); 324dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 325dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 326dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 327dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 328dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatdone: 329dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (pedit_debug) 330dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); 331dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = argc; 332dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 333dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return res; 334dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 335dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 336dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 337dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 338dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatparse_offset(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) 339dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 340dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int off; 341dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 len, retain; 342dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 343dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 344dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int res = -1; 345dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 346dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) 347dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 348dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 349dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_integer(&off, *argv, 0)) 350dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 351dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->off = off; 352dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 353dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; 354dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv++; 355dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 356dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) 357dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 358dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 359dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 360dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "u32") == 0) { 361dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 4; 362dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain = 0xFFFFFFFF; 363dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 364dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 365dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "u16") == 0) { 366dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 2; 367dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain = 0x0; 368dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 369dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 370dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "u8") == 0) { 371dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat len = 1; 372dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat retain = 0x0; 373dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 374dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 375dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 376dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 377dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 378dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatdone: 379dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 380dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 381dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 382dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat /* [at <someval> offmask <maskval> shift <shiftval>] */ 383dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "at") == 0) { 384dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 385dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat __u32 atv=0,offmask=0x0,shift=0; 386dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 387dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 388dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&atv, *argv, 0)) 389dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 390dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->at = atv; 391dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 392dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 393dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 394dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&offmask, *argv, 16)) 395dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 396dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->offmask = offmask; 397dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 398dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 399dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 400dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&shift, *argv, 0)) 401dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 402dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tkey->shift = shift; 403dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 404dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 405dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 406dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 407dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = parse_cmd(&argc, &argv, len, TU32,retain,sel,tkey); 408dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 409dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = argc; 410dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 411dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return res; 412dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 413dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 414dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 415dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatparse_munge(int *argc_p, char ***argv_p,struct tc_pedit_sel *sel) 416dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 417dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_pedit_key tkey; 418dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 419dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 420dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int res = -1; 421dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 422dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc <= 0) 423dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 424dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 425dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&tkey, 0, sizeof(tkey)); 426dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 427dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "offset") == 0) { 428dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 429dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = parse_offset(&argc, &argv,sel,&tkey); 430dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 431dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 432dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char k[16]; 433dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct m_pedit_util *p = NULL; 434dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 435dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat strncpy(k, *argv, sizeof (k) - 1); 436dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 437dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc > 0 ) { 438dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat p = get_pedit_kind(k); 439dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (NULL == p) 440dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto bad_val; 441dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat res = p->parse_peopt(&argc, &argv, sel,&tkey); 442dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (res < 0) { 443dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr,"bad pedit parsing\n"); 444dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto bad_val; 445dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 446dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat goto done; 447dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 448dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 449dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 450dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatbad_val: 451dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 452dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 453dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatdone: 454dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 455dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = argc; 456dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 457dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return res; 458dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 459dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 460dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 461dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatparse_pedit(struct action_util *a, int *argc_p, char ***argv_p, int tca_id, struct nlmsghdr *n) 462dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 463dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct { 464dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_pedit_sel sel; 465dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_pedit_key keys[MAX_OFFS]; 466dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } sel; 467dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 468dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int argc = *argc_p; 469dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat char **argv = *argv_p; 470dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int ok = 0, iok = 0; 471dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tail; 472dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 473dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat memset(&sel, 0, sizeof(sel)); 474dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 475dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat while (argc > 0) { 476dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (pedit_debug > 1) 477dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "while pedit (%d:%s)\n",argc, *argv); 478dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "pedit") == 0) { 479dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 480dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 481dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat continue; 482dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "help") == 0) { 483dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat usage(); 484dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "munge") == 0) { 485dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok) { 486dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); 487dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 488dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 489dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 490dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 491dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (parse_munge(&argc, &argv,&sel.sel)) { 492dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Illegal pedit construct (%s) \n", *argv); 493dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 494dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 495dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 496dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat ok++; 497dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 498dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat break; 499dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 500dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 501dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 502dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 503dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (!ok) { 504dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat explain(); 505dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 506dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 507dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 508dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc) { 509dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "reclassify") == 0) { 510dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel.sel.action = TC_ACT_RECLASSIFY; 511dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 512dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "pipe") == 0) { 513dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel.sel.action = TC_ACT_PIPE; 514dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 515dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "drop") == 0 || 516dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat matches(*argv, "shot") == 0) { 517dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel.sel.action = TC_ACT_SHOT; 518dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 519dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "continue") == 0) { 520dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel.sel.action = TC_ACT_UNSPEC; 521dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 522dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else if (matches(*argv, "pass") == 0) { 523dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel.sel.action = TC_ACT_OK; 524dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 525dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 526dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 527dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 528dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (argc) { 529dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (matches(*argv, "index") == 0) { 530dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat NEXT_ARG(); 531dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (get_u32(&sel.sel.index, *argv, 10)) { 532dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(stderr, "Pedit: Illegal \"index\"\n"); 533dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 534dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 535dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argc--; 536dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat argv++; 537dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat iok++; 538dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 539dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 540dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 541dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail = NLMSG_TAIL(n); 542dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, tca_id, NULL, 0); 543dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat addattr_l(n, MAX_MSG, TCA_PEDIT_PARMS,&sel, sizeof(sel.sel)+sel.sel.nkeys*sizeof(struct tc_pedit_key)); 544dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat tail->rta_len = (void *) NLMSG_TAIL(n) - (void *) tail; 545dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 546dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argc_p = argc; 547dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat *argv_p = argv; 548dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 549dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 550dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 551dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 552dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatprint_pedit(struct action_util *au,FILE * f, struct rtattr *arg) 553dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 554dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_pedit_sel *sel; 555dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct rtattr *tb[TCA_PEDIT_MAX + 1]; 556dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat SPRINT_BUF(b1); 557dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 558dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (arg == NULL) 559dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 560dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 561dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat parse_rtattr_nested(tb, TCA_PEDIT_MAX, arg); 562dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 563dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_PEDIT_PARMS] == NULL) { 564dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "[NULL pedit parameters]"); 565dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return -1; 566dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 567dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat sel = RTA_DATA(tb[TCA_PEDIT_PARMS]); 568dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 569dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " pedit action %s keys %d\n ", action_n2a(sel->action, b1, sizeof (b1)),sel->nkeys); 570dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\t index %d ref %d bind %d", sel->index,sel->refcnt, sel->bindcnt); 571dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 572dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (show_stats) { 573dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (tb[TCA_PEDIT_TM]) { 574dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tcf_t *tm = RTA_DATA(tb[TCA_PEDIT_TM]); 575dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat print_tm(f,tm); 576dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 577dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 578dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat if (sel->nkeys) { 579dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat int i; 580dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat struct tc_pedit_key *key = sel->keys; 581dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 582dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat for (i=0; i<sel->nkeys; i++, key++) { 583dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\n\t key #%d",i); 584dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, " at %d: val %08x mask %08x", 585dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (unsigned int)key->off, 586dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (unsigned int)ntohl(key->val), 587dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat (unsigned int)ntohl(key->mask)); 588dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 589dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } else { 590dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\npedit %x keys %d is not LEGIT", sel->index,sel->nkeys); 591dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat } 592dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 593dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 594dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat fprintf(f, "\n "); 595dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 596dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 597dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 598dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatint 599dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatpedit_print_xstats(struct action_util *au, FILE *f, struct rtattr *xstats) 600dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat{ 601dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat return 0; 602dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat} 603dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat 604dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehatstruct action_util pedit_action_util = { 605dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .id = "pedit", 606dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .parse_aopt = parse_pedit, 607dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat .print_aopt = print_pedit, 608dcfb7a77f8709125e97c313cb8ab6ec4d87468f4San Mehat}; 609