1 /* 2 * p_ip.c packet editor: IPV4 header 3 * 4 * This program is free software; you can distribute it and/or 5 * modify it under the terms of the GNU General Public License 6 * as published by the Free Software Foundation; either version 7 * 2 of the License, or (at your option) any later version. 8 * 9 * Authors: J Hadi Salim (hadi (at) cyberus.ca) 10 * 11 */ 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <unistd.h> 16 #include <syslog.h> 17 #include <fcntl.h> 18 #include <sys/socket.h> 19 #include <netinet/in.h> 20 #include <arpa/inet.h> 21 #include <string.h> 22 #include "utils.h" 23 #include "tc_util.h" 24 #include "m_pedit.h" 25 26 static int 27 parse_ip(int *argc_p, char ***argv_p, 28 struct m_pedit_sel *sel, struct m_pedit_key *tkey) 29 { 30 int res = -1; 31 int argc = *argc_p; 32 char **argv = *argv_p; 33 34 if (argc < 2) 35 return -1; 36 37 tkey->htype = sel->extended ? 38 TCA_PEDIT_KEY_EX_HDR_TYPE_IP4 : 39 TCA_PEDIT_KEY_EX_HDR_TYPE_NETWORK; 40 41 if (strcmp(*argv, "src") == 0) { 42 NEXT_ARG(); 43 tkey->off = 12; 44 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey); 45 goto done; 46 } 47 if (strcmp(*argv, "dst") == 0) { 48 NEXT_ARG(); 49 tkey->off = 16; 50 res = parse_cmd(&argc, &argv, 4, TIPV4, RU32, sel, tkey); 51 goto done; 52 } 53 /* jamal - look at these and make them either old or new 54 ** scheme given diffserv 55 ** dont forget the CE bit 56 */ 57 if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { 58 NEXT_ARG(); 59 tkey->off = 1; 60 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 61 goto done; 62 } 63 if (strcmp(*argv, "ihl") == 0) { 64 NEXT_ARG(); 65 tkey->off = 0; 66 res = parse_cmd(&argc, &argv, 1, TU32, 0x0f, sel, tkey); 67 goto done; 68 } 69 if (strcmp(*argv, "ttl") == 0) { 70 NEXT_ARG(); 71 tkey->off = 8; 72 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 73 goto done; 74 } 75 if (strcmp(*argv, "protocol") == 0) { 76 NEXT_ARG(); 77 tkey->off = 9; 78 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 79 goto done; 80 } 81 /* jamal - fix this */ 82 if (matches(*argv, "precedence") == 0) { 83 NEXT_ARG(); 84 tkey->off = 1; 85 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 86 goto done; 87 } 88 /* jamal - validate this at some point */ 89 if (strcmp(*argv, "nofrag") == 0) { 90 NEXT_ARG(); 91 tkey->off = 6; 92 res = parse_cmd(&argc, &argv, 1, TU32, 0x3F, sel, tkey); 93 goto done; 94 } 95 /* jamal - validate this at some point */ 96 if (strcmp(*argv, "firstfrag") == 0) { 97 NEXT_ARG(); 98 tkey->off = 6; 99 res = parse_cmd(&argc, &argv, 1, TU32, 0x1F, sel, tkey); 100 goto done; 101 } 102 if (strcmp(*argv, "ce") == 0) { 103 NEXT_ARG(); 104 tkey->off = 6; 105 res = parse_cmd(&argc, &argv, 1, TU32, 0x80, sel, tkey); 106 goto done; 107 } 108 if (strcmp(*argv, "df") == 0) { 109 NEXT_ARG(); 110 tkey->off = 6; 111 res = parse_cmd(&argc, &argv, 1, TU32, 0x40, sel, tkey); 112 goto done; 113 } 114 if (strcmp(*argv, "mf") == 0) { 115 NEXT_ARG(); 116 tkey->off = 6; 117 res = parse_cmd(&argc, &argv, 1, TU32, 0x20, sel, tkey); 118 goto done; 119 } 120 121 if (sel->extended) 122 return -1; /* fields located outside IP header should be 123 * addressed using the relevant header type in 124 * extended pedit kABI 125 */ 126 127 if (strcmp(*argv, "dport") == 0) { 128 NEXT_ARG(); 129 tkey->off = 22; 130 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey); 131 goto done; 132 } 133 if (strcmp(*argv, "sport") == 0) { 134 NEXT_ARG(); 135 tkey->off = 20; 136 res = parse_cmd(&argc, &argv, 2, TU32, RU16, sel, tkey); 137 goto done; 138 } 139 if (strcmp(*argv, "icmp_type") == 0) { 140 NEXT_ARG(); 141 tkey->off = 20; 142 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 143 goto done; 144 } 145 if (strcmp(*argv, "icmp_code") == 0) { 146 NEXT_ARG(); 147 tkey->off = 20; 148 res = parse_cmd(&argc, &argv, 1, TU32, RU8, sel, tkey); 149 goto done; 150 } 151 return -1; 152 153 done: 154 *argc_p = argc; 155 *argv_p = argv; 156 return res; 157 } 158 159 struct m_pedit_util p_pedit_ip = { 160 NULL, 161 "ip", 162 parse_ip, 163 }; 164