]> rtime.felk.cvut.cz Git - lisovros/iproute2_canprio.git/commitdiff
[iproute2] XFRM: support ICMP/ICMPv6's type and code
authororg[shemminger]!nakam <org[shemminger]!nakam>
Tue, 28 Sep 2004 18:42:35 +0000 (18:42 +0000)
committerorg[shemminger]!nakam <org[shemminger]!nakam>
Tue, 28 Sep 2004 18:42:35 +0000 (18:42 +0000)
(Logical change 1.85)

ip/ipxfrm.c
ip/xfrm_policy.c
ip/xfrm_state.c

index e47b9a826dc2ec9e9ac3c95ce561f323777323b4..b6228c975885660dc5a1d4fda5318a31021a9942 100644 (file)
@@ -389,10 +389,25 @@ void xfrm_selector_print(struct xfrm_selector *sel, __u16 family,
 
        if (sel->proto)
                fprintf(fp, "proto %s ", strxf_proto(sel->proto));
-       if (sel->sport)
-               fprintf(fp, "sport %u ", ntohs(sel->sport));
-       if (sel->dport)
-               fprintf(fp, "dport %u ", ntohs(sel->dport));
+       switch (sel->proto) {
+       case IPPROTO_TCP:
+       case IPPROTO_UDP:
+       case IPPROTO_SCTP:
+       default: /* XXX */
+               if (sel->sport_mask)
+                       fprintf(fp, "sport %u ", ntohs(sel->sport));
+               if (sel->dport_mask)
+                       fprintf(fp, "dport %u ", ntohs(sel->dport));
+               break;
+       case IPPROTO_ICMP:
+       case IPPROTO_ICMPV6:
+               /* type/code is stored at sport/dport in selector */
+               if (sel->sport_mask)
+                       fprintf(fp, "type %u ", ntohs(sel->sport));
+               if (sel->dport_mask)
+                       fprintf(fp, "code %u ", ntohs(sel->dport));
+               break;
+       }
 
        if (sel->ifindex > 0) {
                char buf[IF_NAMESIZE];
@@ -677,6 +692,10 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
 {
        int argc = *argcp;
        char **argv = *argvp;
+       char *sportp = NULL;
+       char *dportp = NULL;
+       char *typep = NULL;
+       char *codep = NULL;
 
        while (1) {
                if (strcmp(*argv, "proto") == 0) {
@@ -701,6 +720,8 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
                        filter.upspec_proto_mask = XFRM_FILTER_MASK_FULL;
 
                } else if (strcmp(*argv, "sport") == 0) {
+                       sportp = *argv;
+
                        NEXT_ARG();
 
                        if (get_u16(&sel->sport, *argv, 0))
@@ -712,6 +733,8 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
                        filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;
 
                } else if (strcmp(*argv, "dport") == 0) {
+                       dportp = *argv;
+
                        NEXT_ARG();
 
                        if (get_u16(&sel->dport, *argv, 0))
@@ -722,6 +745,33 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
 
                        filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;
 
+               } else if (strcmp(*argv, "type") == 0) {
+                       typep = *argv;
+
+                       NEXT_ARG();
+
+                       if (get_u16(&sel->sport, *argv, 0) ||
+                           (sel->sport & ~((__u16)0xff)))
+                               invarg("\"type\" value is invalid", *argv);
+                       sel->sport = htons(sel->sport);
+                       sel->sport_mask = ~((__u16)0);
+
+                       filter.upspec_sport_mask = XFRM_FILTER_MASK_FULL;
+
+
+               } else if (strcmp(*argv, "code") == 0) {
+                       codep = *argv;
+
+                       NEXT_ARG();
+
+                       if (get_u16(&sel->dport, *argv, 0) ||
+                           (sel->dport & ~((__u16)0xff)))
+                               invarg("\"code\" value is invalid", *argv);
+                       sel->dport = htons(sel->dport);
+                       sel->dport_mask = ~((__u16)0);
+
+                       filter.upspec_dport_mask = XFRM_FILTER_MASK_FULL;
+
                } else {
                        PREV_ARG(); /* back track */
                        break;
@@ -733,6 +783,27 @@ static int xfrm_selector_upspec_parse(struct xfrm_selector *sel,
        }
        if (argc == *argcp)
                missarg("UPSPEC");
+       if (sportp || dportp) {
+               switch (sel->proto) {
+               case IPPROTO_TCP:
+               case IPPROTO_UDP:
+               case IPPROTO_SCTP:
+                       break;
+               default:
+                       fprintf(stderr, "\"sport\" and \"dport\" are invalid with proto=%s\n", strxf_proto(sel->proto));
+                       exit(1);
+               }
+       }
+       if (typep || codep) {
+               switch (sel->proto) {
+               case IPPROTO_ICMP:
+               case IPPROTO_ICMPV6:
+                       break;
+               default:
+                       fprintf(stderr, "\"type\" and \"code\" are invalid with proto=%s\n", strxf_proto(sel->proto));
+                       exit(1);
+               }
+       }
 
        *argcp = argc;
        *argvp = argv;
index 8d6f8f97a7039cadf91f56daacb97d9f1cc100b3..fc17a645eef97241dd67e2ad5efa25309b238584 100644 (file)
@@ -62,7 +62,8 @@ static void usage(void)
 
        fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ UPSPEC ] [ dev DEV ]\n");
 
-       fprintf(stderr, "UPSPEC := proto PROTO [ sport PORT ] [ dport PORT ]\n");
+       fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n");
+       fprintf(stderr, "                        [ type NUMBER ] [ code NUMBER ] ]\n");
 
        //fprintf(stderr, "DEV - device name(default=none)\n");
 
index 8a87cf2e7403835bec9919b482c6da71a35f4ead..54750f4fdf46519e9e88800e168e4e45d219087e 100644 (file)
@@ -91,7 +91,9 @@ static void usage(void)
 
        fprintf(stderr, "SELECTOR := src ADDR[/PLEN] dst ADDR[/PLEN] [ upspec UPSPEC ] [ dev DEV ]\n");
 
-       fprintf(stderr, "UPSPEC := proto PROTO [ sport PORT ] [ dport PORT ]\n");
+       fprintf(stderr, "UPSPEC := proto PROTO [ [ sport PORT ] [ dport PORT ] |\n");
+       fprintf(stderr, "                        [ type NUMBER ] [ code NUMBER ] ]\n");
+
 
        //fprintf(stderr, "DEV - device name(default=none)\n");
        fprintf(stderr, "LIMIT-LIST := [ LIMIT-LIST ] | [ limit LIMIT ]\n");