uint32_t peer_tunnel_id;
uint32_t session_id;
uint32_t peer_session_id;
- uint32_t offset;
- uint32_t peer_offset;
enum l2tp_encap_type encap;
uint16_t local_udp_port;
uint16_t peer_udp_port;
inet_prefix peer_ip;
uint16_t pw_type;
- uint16_t mtu;
- int udp6_csum_tx:1;
- int udp6_csum_rx:1;
- int udp_csum:1;
- int recv_seq:1;
- int send_seq:1;
- int lns_mode:1;
- int data_seq:2;
- int tunnel:1;
- int session:1;
+ unsigned int udp6_csum_tx:1;
+ unsigned int udp6_csum_rx:1;
+ unsigned int udp_csum:1;
+ unsigned int recv_seq:1;
+ unsigned int send_seq:1;
+ unsigned int tunnel:1;
+ unsigned int session:1;
int reorder_timeout;
const char *ifname;
uint8_t l2spec_type;
if (p->local_ip.family == AF_INET6)
local_attr = L2TP_ATTR_IP6_SADDR;
- addattr_l(&req.n, 1024, local_attr, &p->local_ip.data, p->local_ip.bytelen);
+ addattr_l(&req.n, 1024, local_attr, &p->local_ip.data,
+ p->local_ip.bytelen);
if (p->peer_ip.family == AF_INET6)
peer_attr = L2TP_ATTR_IP6_DADDR;
- addattr_l(&req.n, 1024, peer_attr, &p->peer_ip.data, p->peer_ip.bytelen);
+ addattr_l(&req.n, 1024, peer_attr, &p->peer_ip.data,
+ p->peer_ip.bytelen);
if (p->encap == L2TP_ENCAPTYPE_UDP) {
addattr16(&req.n, 1024, L2TP_ATTR_UDP_SPORT, p->local_udp_port);
addattr16(&req.n, 1024, L2TP_ATTR_UDP_DPORT, p->peer_udp_port);
if (p->udp_csum)
- addattr(&req.n, 1024, L2TP_ATTR_UDP_CSUM);
+ addattr8(&req.n, 1024, L2TP_ATTR_UDP_CSUM, 1);
if (!p->udp6_csum_tx)
addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_TX);
if (!p->udp6_csum_rx)
addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_RX);
}
- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
return -2;
return 0;
addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->tunnel_id);
- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
return -2;
return 0;
addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_TYPE, p->l2spec_type);
addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_LEN, p->l2spec_len);
- if (p->mtu) addattr16(&req.n, 1024, L2TP_ATTR_MTU, p->mtu);
- if (p->recv_seq) addattr(&req.n, 1024, L2TP_ATTR_RECV_SEQ);
- if (p->send_seq) addattr(&req.n, 1024, L2TP_ATTR_SEND_SEQ);
- if (p->lns_mode) addattr(&req.n, 1024, L2TP_ATTR_LNS_MODE);
- if (p->data_seq) addattr8(&req.n, 1024, L2TP_ATTR_DATA_SEQ, p->data_seq);
- if (p->reorder_timeout) addattr64(&req.n, 1024, L2TP_ATTR_RECV_TIMEOUT,
+ if (p->recv_seq)
+ addattr8(&req.n, 1024, L2TP_ATTR_RECV_SEQ, 1);
+ if (p->send_seq)
+ addattr8(&req.n, 1024, L2TP_ATTR_SEND_SEQ, 1);
+ if (p->reorder_timeout)
+ addattr64(&req.n, 1024, L2TP_ATTR_RECV_TIMEOUT,
p->reorder_timeout);
- if (p->offset) addattr16(&req.n, 1024, L2TP_ATTR_OFFSET, p->offset);
- if (p->cookie_len) addattr_l(&req.n, 1024, L2TP_ATTR_COOKIE,
- p->cookie, p->cookie_len);
- if (p->peer_cookie_len) addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE,
- p->peer_cookie, p->peer_cookie_len);
- if (p->ifname && p->ifname[0])
+ if (p->cookie_len)
+ addattr_l(&req.n, 1024, L2TP_ATTR_COOKIE,
+ p->cookie, p->cookie_len);
+ if (p->peer_cookie_len)
+ addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE,
+ p->peer_cookie, p->peer_cookie_len);
+ if (p->ifname)
addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname);
- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
return -2;
return 0;
addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id);
addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id);
- if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0)
+ if (rtnl_talk(&genl_rth, &req.n, NULL) < 0)
return -2;
return 0;
}
-static void print_cookie(char *name, const uint8_t *cookie, int len)
+static void print_cookie(const char *name, const char *fmt,
+ const uint8_t *cookie, int len)
{
- printf(" %s %02x%02x%02x%02x", name,
- cookie[0], cookie[1],
- cookie[2], cookie[3]);
+ char abuf[32];
+ size_t n;
+
+ n = snprintf(abuf, sizeof(abuf),
+ "%02x%02x%02x%02x",
+ cookie[0], cookie[1], cookie[2], cookie[3]);
if (len == 8)
- printf("%02x%02x%02x%02x",
- cookie[4], cookie[5],
- cookie[6], cookie[7]);
+ snprintf(abuf + n, sizeof(abuf) - n,
+ "%02x%02x%02x%02x",
+ cookie[4], cookie[5],
+ cookie[6], cookie[7]);
+
+ print_string(PRINT_ANY, name, fmt, abuf);
}
static void print_tunnel(const struct l2tp_data *data)
const struct l2tp_parm *p = &data->config;
char buf[INET6_ADDRSTRLEN];
- printf("Tunnel %u, encap %s\n",
- p->tunnel_id,
- p->encap == L2TP_ENCAPTYPE_UDP ? "UDP" :
- p->encap == L2TP_ENCAPTYPE_IP ? "IP" : "??");
- printf(" From %s ", inet_ntop(p->local_ip.family, p->local_ip.data, buf, sizeof(buf)));
- printf("to %s\n", inet_ntop(p->peer_ip.family, p->peer_ip.data, buf, sizeof(buf)));
- printf(" Peer tunnel %u\n",
- p->peer_tunnel_id);
-
- if (p->encap == L2TP_ENCAPTYPE_UDP)
- printf(" UDP source / dest ports: %hu/%hu\n",
- p->local_udp_port, p->peer_udp_port);
+ open_json_object(NULL);
+ print_uint(PRINT_ANY, "tunnel_id", "Tunnel %u,", p->tunnel_id);
+ print_string(PRINT_ANY, "encap", " encap %s",
+ p->encap == L2TP_ENCAPTYPE_UDP ? "UDP" :
+ p->encap == L2TP_ENCAPTYPE_IP ? "IP" : "??");
+ print_nl();
+
+ print_string(PRINT_ANY, "local", " From %s ",
+ inet_ntop(p->local_ip.family, p->local_ip.data,
+ buf, sizeof(buf)));
+ print_string(PRINT_ANY, "peer", "to %s",
+ inet_ntop(p->peer_ip.family, p->peer_ip.data,
+ buf, sizeof(buf)));
+ print_nl();
+
+ print_uint(PRINT_ANY, "peer_tunnel", " Peer tunnel %u",
+ p->peer_tunnel_id);
+ print_nl();
+
+ if (p->encap == L2TP_ENCAPTYPE_UDP) {
+ print_string(PRINT_FP, NULL,
+ " UDP source / dest ports:", NULL);
+
+ print_uint(PRINT_ANY, "local_port", " %hu",
+ p->local_udp_port);
+ print_uint(PRINT_ANY, "peer_port", "/%hu",
+ p->peer_udp_port);
+ print_nl();
+
+ switch (p->local_ip.family) {
+ case AF_INET:
+ print_bool(PRINT_JSON, "checksum",
+ NULL, p->udp_csum);
+ print_string(PRINT_FP, NULL,
+ " UDP checksum: %s\n",
+ p->udp_csum ? "enabled" : "disabled");
+ break;
+ case AF_INET6:
+ if (is_json_context()) {
+ print_bool(PRINT_JSON, "checksum_tx",
+ NULL, p->udp6_csum_tx);
+
+ print_bool(PRINT_JSON, "checksum_rx",
+ NULL, p->udp6_csum_tx);
+ } else {
+ printf(" UDP checksum: %s%s%s%s\n",
+ p->udp6_csum_tx && p->udp6_csum_rx
+ ? "enabled" : "",
+ p->udp6_csum_tx && !p->udp6_csum_rx
+ ? "tx" : "",
+ !p->udp6_csum_tx && p->udp6_csum_rx
+ ? "rx" : "",
+ !p->udp6_csum_tx && !p->udp6_csum_rx
+ ? "disabled" : "");
+ }
+ break;
+ }
+ }
+ close_json_object();
}
static void print_session(struct l2tp_data *data)
{
struct l2tp_parm *p = &data->config;
- printf("Session %u in tunnel %u\n",
- p->session_id, p->tunnel_id);
- printf(" Peer session %u, tunnel %u\n",
- p->peer_session_id, p->peer_tunnel_id);
+ open_json_object(NULL);
+
+ print_uint(PRINT_ANY, "session_id", "Session %u", p->session_id);
+ print_uint(PRINT_ANY, "tunnel_id", " in tunnel %u", p->tunnel_id);
+ print_nl();
+
+ print_uint(PRINT_ANY, "peer_session_id",
+ " Peer session %u,", p->peer_session_id);
+ print_uint(PRINT_ANY, "peer_tunnel_id",
+ " tunnel %u", p->peer_tunnel_id);
+ print_nl();
if (p->ifname != NULL) {
- printf(" interface name: %s\n", p->ifname);
+ print_color_string(PRINT_ANY, COLOR_IFNAME,
+ "interface", " interface name: %s" , p->ifname);
+ print_nl();
}
- printf(" offset %u, peer offset %u\n",
- p->offset, p->peer_offset);
+
+ /* Show offsets only for plain console output (for legacy scripts) */
+ print_uint(PRINT_FP, "offset", " offset %u,", 0);
+ print_uint(PRINT_FP, "peer_offset", " peer offset %u\n", 0);
+
if (p->cookie_len > 0)
- print_cookie("cookie", p->cookie, p->cookie_len);
+ print_cookie("cookie", " cookie %s",
+ p->cookie, p->cookie_len);
+
if (p->peer_cookie_len > 0)
- print_cookie("peer cookie", p->peer_cookie, p->peer_cookie_len);
+ print_cookie("peer_cookie", " peer cookie %s",
+ p->peer_cookie, p->peer_cookie_len);
if (p->reorder_timeout != 0)
- printf(" reorder timeout: %u\n", p->reorder_timeout);
- else
- printf("\n");
+ print_uint(PRINT_ANY, "reorder_timeout",
+ " reorder timeout: %u", p->reorder_timeout);
+
+
+ if (p->send_seq || p->recv_seq) {
+ print_string(PRINT_FP, NULL, "%s sequence numbering:", _SL_);
+
+ if (p->send_seq)
+ print_null(PRINT_ANY, "send_seq", " send", NULL);
+ if (p->recv_seq)
+ print_null(PRINT_ANY, "recv_seq", " recv", NULL);
+
+ }
+ print_string(PRINT_FP, NULL, "\n", NULL);
+ close_json_object();
}
static int get_response(struct nlmsghdr *n, void *arg)
struct l2tp_data *data = arg;
struct l2tp_parm *p = &data->config;
struct rtattr *attrs[L2TP_ATTR_MAX + 1];
- struct rtattr *nla_stats;
+ struct rtattr *nla_stats, *rta;
int len;
/* Validate message and parse attributes */
p->pw_type = rta_getattr_u16(attrs[L2TP_ATTR_PW_TYPE]);
if (attrs[L2TP_ATTR_ENCAP_TYPE])
p->encap = rta_getattr_u16(attrs[L2TP_ATTR_ENCAP_TYPE]);
- if (attrs[L2TP_ATTR_OFFSET])
- p->offset = rta_getattr_u16(attrs[L2TP_ATTR_OFFSET]);
- if (attrs[L2TP_ATTR_DATA_SEQ])
- p->data_seq = rta_getattr_u16(attrs[L2TP_ATTR_DATA_SEQ]);
if (attrs[L2TP_ATTR_CONN_ID])
p->tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_CONN_ID]);
if (attrs[L2TP_ATTR_PEER_CONN_ID])
if (attrs[L2TP_ATTR_L2SPEC_LEN])
p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]);
- p->udp_csum = !!attrs[L2TP_ATTR_UDP_CSUM];
- /*
- * Not fetching from L2TP_ATTR_UDP_ZERO_CSUM6_{T,R}X because the
- * kernel doesn't send it so just leave it as default value.
- */
- p->udp6_csum_tx = 1;
- p->udp6_csum_rx = 1;
+ if (attrs[L2TP_ATTR_UDP_CSUM])
+ p->udp_csum = !!rta_getattr_u8(attrs[L2TP_ATTR_UDP_CSUM]);
+
+ p->udp6_csum_tx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX];
+ p->udp6_csum_rx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX];
+
if (attrs[L2TP_ATTR_COOKIE])
memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]),
p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE]));
memcpy(p->peer_cookie, RTA_DATA(attrs[L2TP_ATTR_PEER_COOKIE]),
p->peer_cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_PEER_COOKIE]));
- p->recv_seq = !!attrs[L2TP_ATTR_RECV_SEQ];
- p->send_seq = !!attrs[L2TP_ATTR_SEND_SEQ];
+ if (attrs[L2TP_ATTR_RECV_SEQ])
+ p->recv_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_RECV_SEQ]);
+ if (attrs[L2TP_ATTR_SEND_SEQ])
+ p->send_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_SEND_SEQ]);
if (attrs[L2TP_ATTR_RECV_TIMEOUT])
p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]);
- if (attrs[L2TP_ATTR_IP_SADDR]) {
- p->local_ip.family = AF_INET;
- p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]);
- p->local_ip.bytelen = 4;
- p->local_ip.bitlen = -1;
- }
- if (attrs[L2TP_ATTR_IP_DADDR]) {
- p->peer_ip.family = AF_INET;
- p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]);
- p->peer_ip.bytelen = 4;
- p->peer_ip.bitlen = -1;
- }
- if (attrs[L2TP_ATTR_IP6_SADDR]) {
+
+ rta = attrs[L2TP_ATTR_IP_SADDR];
+ p->local_ip.family = AF_INET;
+ if (!rta) {
+ rta = attrs[L2TP_ATTR_IP6_SADDR];
p->local_ip.family = AF_INET6;
- memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]),
- p->local_ip.bytelen = 16);
- p->local_ip.bitlen = -1;
}
- if (attrs[L2TP_ATTR_IP6_DADDR]) {
+ if (rta && get_addr_rta(&p->local_ip, rta, p->local_ip.family))
+ return -1;
+
+ rta = attrs[L2TP_ATTR_IP_DADDR];
+ p->peer_ip.family = AF_INET;
+ if (!rta) {
+ rta = attrs[L2TP_ATTR_IP6_DADDR];
p->peer_ip.family = AF_INET6;
- memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]),
- p->peer_ip.bytelen = 16);
- p->peer_ip.bitlen = -1;
}
+ if (rta && get_addr_rta(&p->peer_ip, rta, p->peer_ip.family))
+ return -1;
+
if (attrs[L2TP_ATTR_UDP_SPORT])
p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]);
if (attrs[L2TP_ATTR_UDP_DPORT])
p->peer_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_DPORT]);
- if (attrs[L2TP_ATTR_MTU])
- p->mtu = rta_getattr_u16(attrs[L2TP_ATTR_MTU]);
if (attrs[L2TP_ATTR_IFNAME])
p->ifname = rta_getattr_str(attrs[L2TP_ATTR_IFNAME]);
return 0;
}
-static int session_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int session_nlmsg(struct nlmsghdr *n, void *arg)
{
int ret = get_response(n, arg);
if (p->config.tunnel_id && p->config.session_id) {
addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->config.tunnel_id);
- addattr32(&req.n, 128, L2TP_ATTR_SESSION_ID, p->config.session_id);
+ addattr32(&req.n, 128, L2TP_ATTR_SESSION_ID,
+ p->config.session_id);
}
if (rtnl_send(&genl_rth, &req, req.n.nlmsg_len) < 0)
return -2;
+ new_json_obj(json);
if (rtnl_dump_filter(&genl_rth, session_nlmsg, p) < 0) {
fprintf(stderr, "Dump terminated\n");
exit(1);
}
+ delete_json_obj();
+ fflush(stdout);
return 0;
}
-static int tunnel_nlmsg(const struct sockaddr_nl *who, struct nlmsghdr *n, void *arg)
+static int tunnel_nlmsg(struct nlmsghdr *n, void *arg)
{
int ret = get_response(n, arg);
if (rtnl_send(&genl_rth, &req, req.n.nlmsg_len) < 0)
return -2;
+ new_json_obj(json);
if (rtnl_dump_filter(&genl_rth, tunnel_nlmsg, p) < 0) {
fprintf(stderr, "Dump terminated\n");
exit(1);
}
+ delete_json_obj();
+ fflush(stdout);
return 0;
}
* Command parser
*****************************************************************************/
-static int hex2mem(const char *buf, uint8_t *mem, int count)
-{
- int i, j;
- int c;
-
- for (i = 0, j = 0; i < count; i++, j += 2) {
- c = get_hex(buf[j]);
- if (c < 0)
- goto err;
-
- mem[i] = c << 4;
-
- c = get_hex(buf[j + 1]);
- if (c < 0)
- goto err;
-
- mem[i] |= c;
- }
-
- return 0;
-
-err:
- return -1;
-}
-
static void usage(void) __attribute__((noreturn));
static void usage(void)
{
- fprintf(stderr, "Usage: ip l2tp add tunnel\n");
- fprintf(stderr, " remote ADDR local ADDR\n");
- fprintf(stderr, " tunnel_id ID peer_tunnel_id ID\n");
- fprintf(stderr, " [ encap { ip | udp } ]\n");
- fprintf(stderr, " [ udp_sport PORT ] [ udp_dport PORT ]\n");
- fprintf(stderr, " [ udp_csum { on | off } ]\n");
- fprintf(stderr, " [ udp6_csum_tx { on | off } ]\n");
- fprintf(stderr, " [ udp6_csum_rx { on | off } ]\n");
- fprintf(stderr, "Usage: ip l2tp add session [ name NAME ]\n");
- fprintf(stderr, " tunnel_id ID\n");
- fprintf(stderr, " session_id ID peer_session_id ID\n");
- fprintf(stderr, " [ cookie HEXSTR ] [ peer_cookie HEXSTR ]\n");
- fprintf(stderr, " [ offset OFFSET ] [ peer_offset OFFSET ]\n");
- fprintf(stderr, " [ l2spec_type L2SPEC ]\n");
- fprintf(stderr, " ip l2tp del tunnel tunnel_id ID\n");
- fprintf(stderr, " ip l2tp del session tunnel_id ID session_id ID\n");
- fprintf(stderr, " ip l2tp show tunnel [ tunnel_id ID ]\n");
- fprintf(stderr, " ip l2tp show session [ tunnel_id ID ] [ session_id ID ]\n");
- fprintf(stderr, "\n");
- fprintf(stderr, "Where: NAME := STRING\n");
- fprintf(stderr, " ADDR := { IP_ADDRESS | any }\n");
- fprintf(stderr, " PORT := { 0..65535 }\n");
- fprintf(stderr, " ID := { 1..4294967295 }\n");
- fprintf(stderr, " HEXSTR := { 8 or 16 hex digits (4 / 8 bytes) }\n");
- fprintf(stderr, " L2SPEC := { none | default }\n");
+ fprintf(stderr, "Usage: ip l2tp add tunnel\n"
+ " remote ADDR local ADDR\n"
+ " tunnel_id ID peer_tunnel_id ID\n"
+ " [ encap { ip | udp } ]\n"
+ " [ udp_sport PORT ] [ udp_dport PORT ]\n"
+ " [ udp_csum { on | off } ]\n"
+ " [ udp6_csum_tx { on | off } ]\n"
+ " [ udp6_csum_rx { on | off } ]\n"
+ "Usage: ip l2tp add session [ name NAME ]\n"
+ " tunnel_id ID\n"
+ " session_id ID peer_session_id ID\n"
+ " [ cookie HEXSTR ] [ peer_cookie HEXSTR ]\n"
+ " [ seq { none | send | recv | both } ]\n"
+ " [ l2spec_type L2SPEC ]\n"
+ " ip l2tp del tunnel tunnel_id ID\n"
+ " ip l2tp del session tunnel_id ID session_id ID\n"
+ " ip l2tp show tunnel [ tunnel_id ID ]\n"
+ " ip l2tp show session [ tunnel_id ID ] [ session_id ID ]\n"
+ "\n"
+ "Where: NAME := STRING\n"
+ " ADDR := { IP_ADDRESS | any }\n"
+ " PORT := { 0..65535 }\n"
+ " ID := { 1..4294967295 }\n"
+ " HEXSTR := { 8 or 16 hex digits (4 / 8 bytes) }\n"
+ " L2SPEC := { none | default }\n");
+
exit(-1);
}
}
} else if (strcmp(*argv, "name") == 0) {
NEXT_ARG();
+ if (check_ifname(*argv))
+ invarg("\"name\" not a valid ifname", *argv);
p->ifname = *argv;
} else if (strcmp(*argv, "remote") == 0) {
NEXT_ARG();
invarg("invalid option for udp6_csum_tx\n"
, *argv);
} else if (strcmp(*argv, "offset") == 0) {
- __u8 uval;
-
+ fprintf(stderr, "Ignoring option \"offset\"\n");
NEXT_ARG();
- if (get_u8(&uval, *argv, 0))
- invarg("invalid offset\n", *argv);
- p->offset = uval;
} else if (strcmp(*argv, "peer_offset") == 0) {
- __u8 uval;
-
+ fprintf(stderr, "Ignoring option \"peer_offset\"\n");
NEXT_ARG();
- if (get_u8(&uval, *argv, 0))
- invarg("invalid offset\n", *argv);
- p->peer_offset = uval;
} else if (strcmp(*argv, "cookie") == 0) {
int slen;
p->l2spec_type = L2TP_L2SPECTYPE_NONE;
p->l2spec_len = 0;
} else {
- fprintf(stderr, "Unknown layer2specific header type \"%s\"\n", *argv);
+ fprintf(stderr,
+ "Unknown layer2specific header type \"%s\"\n",
+ *argv);
+ exit(-1);
+ }
+ } else if (strcmp(*argv, "seq") == 0) {
+ NEXT_ARG();
+ if (strcasecmp(*argv, "both") == 0) {
+ p->recv_seq = 1;
+ p->send_seq = 1;
+ } else if (strcasecmp(*argv, "recv") == 0) {
+ p->recv_seq = 1;
+ } else if (strcasecmp(*argv, "send") == 0) {
+ p->send_seq = 1;
+ } else if (strcasecmp(*argv, "none") == 0) {
+ p->recv_seq = 0;
+ p->send_seq = 0;
+ } else {
+ fprintf(stderr,
+ "Unknown seq value \"%s\"\n", *argv);
exit(-1);
}
} else if (strcmp(*argv, "tunnel") == 0) {
matches(*argv, "list") == 0)
return do_show(argc-1, argv+1);
- fprintf(stderr, "Command \"%s\" is unknown, try \"ip l2tp help\".\n", *argv);
+ fprintf(stderr,
+ "Command \"%s\" is unknown, try \"ip l2tp help\".\n", *argv);
exit(-1);
}