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