static int pack_mac(struct m_pedit_sel *sel, struct m_pedit_key *tkey, __u8 *mac) { int ret = 0; if (!(tkey->off & 0x3)) { tkey->mask = 0; tkey->val = ntohl(*((__u32 *)mac)); ret |= pack_key32(~0, sel, tkey); tkey->off += 4; tkey->mask = 0; tkey->val = ntohs(*((__u16 *)&mac[4])); ret |= pack_key16(~0, sel, tkey); } else if (!(tkey->off & 0x1)) { tkey->mask = 0; tkey->val = ntohs(*((__u16 *)mac)); ret |= pack_key16(~0, sel, tkey); tkey->off += 4; tkey->mask = 0; tkey->val = ntohl(*((__u32 *)(mac + 2))); ret |= pack_key32(~0, sel, tkey); } else { fprintf(stderr, "pack_mac: mac offsets must begin in 32bit or 16bit boundaries\n"); return -1; } return ret; }
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc < 2) return -1; if (strcmp(*argv, "src") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 12); } else if (strcmp(*argv, "dst") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 16); } else if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); } else if (strcmp(*argv, "ihl") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 0, 0); } else if (strcmp(*argv, "protocol") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 9, 0); } else if (matches(*argv, "precedence") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); } else if (strcmp(*argv, "nofrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x3FFF, 6, 0); } else if (strcmp(*argv, "firstfrag") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x3FFF, 6, 0); } else if (strcmp(*argv, "df") == 0) { argc--; argv++; res = pack_key16(sel, 0x4000, 0x4000, 6, 0); } else if (strcmp(*argv, "mf") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x2000, 6, 0); } else if (strcmp(*argv, "dport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 22, 0); } else if (strcmp(*argv, "sport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 20, 0); } else if (strcmp(*argv, "icmp_type") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 0); } else if (strcmp(*argv, "icmp_code") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 21, 0); } else return -1; *argc_p = argc; *argv_p = argv; return res; }
static int parse_u16(int *argc_p, char ***argv_p, struct tc_u32_sel *sel, int off, int offmask) { int res = -1; int argc = *argc_p; char **argv = *argv_p; __u32 key; __u32 mask; if (argc < 2) return -1; if (get_u32(&key, *argv, 0)) return -1; argc--; argv++; if (get_u32(&mask, *argv, 16)) return -1; argc--; argv++; if (argc > 0 && strcmp(argv[0], "at") == 0) { NEXT_ARG(); if (parse_at(&argc, &argv, &off, &offmask)) return -1; } res = pack_key16(sel, key, mask, off, offmask); *argc_p = argc; *argv_p = argv; return res; }
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type, __u32 retain, struct m_pedit_sel *sel, struct m_pedit_key *tkey) { __u32 mask[4] = { 0 }; __u32 val[4] = { 0 }; __u32 *m = &mask[0]; __u32 *v = &val[0]; __u32 o = 0xFF; int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc <= 0) return -1; if (pedit_debug) printf("parse_cmd argc %d %s offset %d length %d\n", argc, *argv, tkey->off, len); if (len == 2) o = 0xFFFF; if (len == 4) o = 0xFFFFFFFF; if (matches(*argv, "invert") == 0) { *v = *m = o; } else if (matches(*argv, "set") == 0 || matches(*argv, "add") == 0) { if (matches(*argv, "add") == 0) tkey->cmd = TCA_PEDIT_KEY_EX_CMD_ADD; if (!sel->extended && tkey->cmd) { fprintf(stderr, "Non extended mode. only 'set' command is supported\n"); return -1; } NEXT_ARG(); if (parse_val(&argc, &argv, val, type)) return -1; } else if (matches(*argv, "preserve") == 0) { retain = 0; } else { if (matches(*argv, "clear") != 0) return -1; } argc--; argv++; if (argc && matches(*argv, "retain") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &retain, TU32)) return -1; argc--; argv++; } if (len > 4 && retain != ~0) { fprintf(stderr, "retain is not supported for fields longer the 32 bits\n"); return -1; } if (type == TMAC) { res = pack_mac(sel, tkey, (__u8 *)val); goto done; } if (type == TIPV6) { res = pack_ipv6(sel, tkey, val); goto done; } tkey->val = *v; tkey->mask = *m; if (type == TIPV4) tkey->val = ntohl(tkey->val); if (len == 1) { res = pack_key8(retain, sel, tkey); goto done; } if (len == 2) { res = pack_key16(retain, sel, tkey); goto done; } if (len == 4) { res = pack_key32(retain, sel, tkey); goto done; } return -1; done: if (pedit_debug) printf("parse_cmd done argc %d %s offset %d length %d\n", argc, *argv, tkey->off, len); *argc_p = argc; *argv_p = argv; return res; }
int parse_cmd(int *argc_p, char ***argv_p, __u32 len, int type,__u32 retain,struct tc_pedit_sel *sel,struct tc_pedit_key *tkey) { __u32 mask = 0, val = 0; __u32 o = 0xFF; int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc <= 0) return -1; if (pedit_debug) printf("parse_cmd argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); if (len == 2) o = 0xFFFF; if (len == 4) o = 0xFFFFFFFF; if (matches(*argv, "invert") == 0) { retain = val = mask = o; } else if (matches(*argv, "set") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &val, type)) return -1; } else if (matches(*argv, "preserve") == 0) { retain = mask = o; } else { if (matches(*argv, "clear") != 0) return -1; } argc--; argv++; if (argc && matches(*argv, "retain") == 0) { NEXT_ARG(); if (parse_val(&argc, &argv, &retain, TU32)) return -1; argc--; argv++; } tkey->val = val; if (len == 1) { tkey->mask = 0xFF; res = pack_key8(retain,sel,tkey); goto done; } if (len == 2) { tkey->mask = mask; res = pack_key16(retain,sel,tkey); goto done; } if (len == 4) { tkey->mask = mask; res = pack_key32(retain,sel,tkey); goto done; } return -1; done: if (pedit_debug) printf("parse_cmd done argc %d %s offset %d length %d\n",argc,*argv,tkey->off,len); *argc_p = argc; *argv_p = argv; return res; }
static int parse_ip(int *argc_p, char ***argv_p, struct tc_u32_sel *sel) { int res = -1; int argc = *argc_p; char **argv = *argv_p; if (argc < 2) return -1; if (strcmp(*argv, "src") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 12); goto done; } if (strcmp(*argv, "dst") == 0) { NEXT_ARG(); res = parse_ip_addr(&argc, &argv, sel, 16); goto done; } //------------->richie: add to parse ip range if (strcmp(*argv, "ssrc") == 0) { //fprintf(stderr, "enter ssrc\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_SSRC_IP); goto done; } if (strcmp(*argv, "esrc") == 0) { //fprintf(stderr, "enter esrc\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 12, TC_ESRC_IP); goto done; } if (strcmp(*argv, "sdst") == 0) { //fprintf(stderr, "enter sdst\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_SDST_IP); goto done; } if (strcmp(*argv, "edst") == 0) { //fprintf(stderr, "enter edst\n"); NEXT_ARG(); res = nk_parse_ip_addr(&argc, &argv, sel, 16, TC_EDST_IP); goto done; } //<-------------------- if (strcmp(*argv, "tos") == 0 || matches(*argv, "dsfield") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); goto done; } if (strcmp(*argv, "ihl") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 0, 0); goto done; } if (strcmp(*argv, "protocol") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 9, 0); goto done; } if (matches(*argv, "precedence") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 1, 0); goto done; } if (strcmp(*argv, "nofrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x3FFF, 6, 0); goto done; } if (strcmp(*argv, "firstfrag") == 0) { argc--; argv++; res = pack_key16(sel, 0, 0x1FFF, 6, 0); goto done; } if (strcmp(*argv, "df") == 0) { argc--; argv++; res = pack_key16(sel, 0x4000, 0x4000, 6, 0); goto done; } if (strcmp(*argv, "mf") == 0) { argc--; argv++; res = pack_key16(sel, 0x2000, 0x2000, 6, 0); goto done; } if (strcmp(*argv, "dport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 22, 0); goto done; } if (strcmp(*argv, "sport") == 0) { NEXT_ARG(); res = parse_u16(&argc, &argv, sel, 20, 0); goto done; } // 2004/05/12 Ryan : added to support QoS for port range setting // --> if (strcmp(*argv, "ssport") == 0) { NEXT_ARG(); //printf("enter ssport\n"); //fprintf(stderr, "enter ssport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_SSRC_PORT); goto done; } if (strcmp(*argv, "esport") == 0) { NEXT_ARG(); //printf("enter esport\n"); //fprintf(stderr, "enter esport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 20, 0 , TC_ESRC_PORT); goto done; } if (strcmp(*argv, "sdport") == 0) { NEXT_ARG(); //printf("enter sdport\n"); //fprintf(stderr, "enter sdport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_SDST_PORT); goto done; } if (strcmp(*argv, "edport") == 0) { NEXT_ARG(); //printf("enter edport\n"); //fprintf(stderr, "enter edport!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 22, 0 , TC_EDST_PORT); goto done; } // <-- //2004/09/29 richie: add to support inbound QoS by interface if (strcmp(*argv, "wanif") == 0) { NEXT_ARG(); //printf("enter wanif!!!!!!!!!!!!!!!!!!!!!!!!!!11"); res = nk_parse_u16(&argc, &argv, sel, 100, 0 , TC_WANIF); goto done; } // //2004/09/29 richie: add to support inbound QoS by ALG type if (strcmp(*argv, "ap_type") == 0) { NEXT_ARG(); //printf("enter ap_type!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); res = nk_parse_u16(&argc, &argv, sel, 120, 0 , TC_AP_TYPE); goto done; } // if (strcmp(*argv, "icmp_type") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 0); goto done; } if (strcmp(*argv, "icmp_code") == 0) { NEXT_ARG(); res = parse_u8(&argc, &argv, sel, 20, 1); goto done; } return -1; done: *argc_p = argc; *argv_p = argv; return res; }