1 /* 2 * ipl2tp.c "ip l2tp" 3 * 4 * This program is free software; you can redistribute 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 * Original Author: James Chapman <jchapman (at) katalix.com> 10 * 11 */ 12 13 #include <stdio.h> 14 #include <stdlib.h> 15 #include <string.h> 16 #include <unistd.h> 17 #include <errno.h> 18 #include <sys/types.h> 19 #include <sys/socket.h> 20 #include <arpa/inet.h> 21 #include <sys/ioctl.h> 22 #include <linux/if.h> 23 #include <linux/if_arp.h> 24 #include <linux/ip.h> 25 26 #include <linux/genetlink.h> 27 #include <linux/l2tp.h> 28 #include "libgenl.h" 29 30 #include "utils.h" 31 #include "ip_common.h" 32 33 enum { 34 L2TP_ADD, 35 L2TP_CHG, 36 L2TP_DEL, 37 L2TP_GET 38 }; 39 40 struct l2tp_parm { 41 uint32_t tunnel_id; 42 uint32_t peer_tunnel_id; 43 uint32_t session_id; 44 uint32_t peer_session_id; 45 uint32_t offset; 46 uint32_t peer_offset; 47 enum l2tp_encap_type encap; 48 uint16_t local_udp_port; 49 uint16_t peer_udp_port; 50 int cookie_len; 51 uint8_t cookie[8]; 52 int peer_cookie_len; 53 uint8_t peer_cookie[8]; 54 inet_prefix local_ip; 55 inet_prefix peer_ip; 56 57 uint16_t pw_type; 58 uint16_t mtu; 59 unsigned int udp6_csum_tx:1; 60 unsigned int udp6_csum_rx:1; 61 unsigned int udp_csum:1; 62 unsigned int recv_seq:1; 63 unsigned int send_seq:1; 64 unsigned int lns_mode:1; 65 unsigned int data_seq:2; 66 unsigned int tunnel:1; 67 unsigned int session:1; 68 int reorder_timeout; 69 const char *ifname; 70 uint8_t l2spec_type; 71 uint8_t l2spec_len; 72 }; 73 74 struct l2tp_stats { 75 uint64_t data_rx_packets; 76 uint64_t data_rx_bytes; 77 uint64_t data_rx_errors; 78 uint64_t data_rx_oos_packets; 79 uint64_t data_rx_oos_discards; 80 uint64_t data_tx_packets; 81 uint64_t data_tx_bytes; 82 uint64_t data_tx_errors; 83 }; 84 85 struct l2tp_data { 86 struct l2tp_parm config; 87 struct l2tp_stats stats; 88 }; 89 90 /* netlink socket */ 91 static struct rtnl_handle genl_rth; 92 static int genl_family = -1; 93 94 /***************************************************************************** 95 * Netlink actions 96 *****************************************************************************/ 97 98 static int create_tunnel(struct l2tp_parm *p) 99 { 100 uint32_t local_attr = L2TP_ATTR_IP_SADDR; 101 uint32_t peer_attr = L2TP_ATTR_IP_DADDR; 102 103 GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION, 104 L2TP_CMD_TUNNEL_CREATE, NLM_F_REQUEST | NLM_F_ACK); 105 106 addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id); 107 addattr32(&req.n, 1024, L2TP_ATTR_PEER_CONN_ID, p->peer_tunnel_id); 108 addattr8(&req.n, 1024, L2TP_ATTR_PROTO_VERSION, 3); 109 addattr16(&req.n, 1024, L2TP_ATTR_ENCAP_TYPE, p->encap); 110 111 if (p->local_ip.family == AF_INET6) 112 local_attr = L2TP_ATTR_IP6_SADDR; 113 addattr_l(&req.n, 1024, local_attr, &p->local_ip.data, 114 p->local_ip.bytelen); 115 116 if (p->peer_ip.family == AF_INET6) 117 peer_attr = L2TP_ATTR_IP6_DADDR; 118 addattr_l(&req.n, 1024, peer_attr, &p->peer_ip.data, 119 p->peer_ip.bytelen); 120 121 if (p->encap == L2TP_ENCAPTYPE_UDP) { 122 addattr16(&req.n, 1024, L2TP_ATTR_UDP_SPORT, p->local_udp_port); 123 addattr16(&req.n, 1024, L2TP_ATTR_UDP_DPORT, p->peer_udp_port); 124 if (p->udp_csum) 125 addattr8(&req.n, 1024, L2TP_ATTR_UDP_CSUM, 1); 126 if (!p->udp6_csum_tx) 127 addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_TX); 128 if (!p->udp6_csum_rx) 129 addattr(&req.n, 1024, L2TP_ATTR_UDP_ZERO_CSUM6_RX); 130 } 131 132 if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) 133 return -2; 134 135 return 0; 136 } 137 138 static int delete_tunnel(struct l2tp_parm *p) 139 { 140 GENL_REQUEST(req, 128, genl_family, 0, L2TP_GENL_VERSION, 141 L2TP_CMD_TUNNEL_DELETE, NLM_F_REQUEST | NLM_F_ACK); 142 143 addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->tunnel_id); 144 145 if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) 146 return -2; 147 148 return 0; 149 } 150 151 static int create_session(struct l2tp_parm *p) 152 { 153 GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION, 154 L2TP_CMD_SESSION_CREATE, NLM_F_REQUEST | NLM_F_ACK); 155 156 addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id); 157 addattr32(&req.n, 1024, L2TP_ATTR_PEER_CONN_ID, p->peer_tunnel_id); 158 addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id); 159 addattr32(&req.n, 1024, L2TP_ATTR_PEER_SESSION_ID, p->peer_session_id); 160 addattr16(&req.n, 1024, L2TP_ATTR_PW_TYPE, p->pw_type); 161 addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_TYPE, p->l2spec_type); 162 addattr8(&req.n, 1024, L2TP_ATTR_L2SPEC_LEN, p->l2spec_len); 163 164 if (p->mtu) 165 addattr16(&req.n, 1024, L2TP_ATTR_MTU, p->mtu); 166 if (p->recv_seq) 167 addattr8(&req.n, 1024, L2TP_ATTR_RECV_SEQ, 1); 168 if (p->send_seq) 169 addattr8(&req.n, 1024, L2TP_ATTR_SEND_SEQ, 1); 170 if (p->lns_mode) 171 addattr(&req.n, 1024, L2TP_ATTR_LNS_MODE); 172 if (p->data_seq) 173 addattr8(&req.n, 1024, L2TP_ATTR_DATA_SEQ, p->data_seq); 174 if (p->reorder_timeout) 175 addattr64(&req.n, 1024, L2TP_ATTR_RECV_TIMEOUT, 176 p->reorder_timeout); 177 if (p->offset) 178 addattr16(&req.n, 1024, L2TP_ATTR_OFFSET, p->offset); 179 if (p->cookie_len) 180 addattr_l(&req.n, 1024, L2TP_ATTR_COOKIE, 181 p->cookie, p->cookie_len); 182 if (p->peer_cookie_len) 183 addattr_l(&req.n, 1024, L2TP_ATTR_PEER_COOKIE, 184 p->peer_cookie, p->peer_cookie_len); 185 if (p->ifname) 186 addattrstrz(&req.n, 1024, L2TP_ATTR_IFNAME, p->ifname); 187 188 if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) 189 return -2; 190 191 return 0; 192 } 193 194 static int delete_session(struct l2tp_parm *p) 195 { 196 GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION, 197 L2TP_CMD_SESSION_DELETE, NLM_F_REQUEST | NLM_F_ACK); 198 199 addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->tunnel_id); 200 addattr32(&req.n, 1024, L2TP_ATTR_SESSION_ID, p->session_id); 201 if (rtnl_talk(&genl_rth, &req.n, NULL, 0) < 0) 202 return -2; 203 204 return 0; 205 } 206 207 static void print_cookie(char *name, const uint8_t *cookie, int len) 208 { 209 printf(" %s %02x%02x%02x%02x", name, 210 cookie[0], cookie[1], 211 cookie[2], cookie[3]); 212 if (len == 8) 213 printf("%02x%02x%02x%02x", 214 cookie[4], cookie[5], 215 cookie[6], cookie[7]); 216 } 217 218 static void print_tunnel(const struct l2tp_data *data) 219 { 220 const struct l2tp_parm *p = &data->config; 221 char buf[INET6_ADDRSTRLEN]; 222 223 printf("Tunnel %u, encap %s\n", 224 p->tunnel_id, 225 p->encap == L2TP_ENCAPTYPE_UDP ? "UDP" : 226 p->encap == L2TP_ENCAPTYPE_IP ? "IP" : "??"); 227 printf(" From %s ", 228 inet_ntop(p->local_ip.family, p->local_ip.data, 229 buf, sizeof(buf))); 230 printf("to %s\n", 231 inet_ntop(p->peer_ip.family, p->peer_ip.data, 232 buf, sizeof(buf))); 233 printf(" Peer tunnel %u\n", 234 p->peer_tunnel_id); 235 236 if (p->encap == L2TP_ENCAPTYPE_UDP) { 237 printf(" UDP source / dest ports: %hu/%hu\n", 238 p->local_udp_port, p->peer_udp_port); 239 240 switch (p->local_ip.family) { 241 case AF_INET: 242 printf(" UDP checksum: %s\n", 243 p->udp_csum ? "enabled" : "disabled"); 244 break; 245 case AF_INET6: 246 printf(" UDP checksum: %s%s%s%s\n", 247 p->udp6_csum_tx && p->udp6_csum_rx 248 ? "enabled" : "", 249 p->udp6_csum_tx && !p->udp6_csum_rx 250 ? "tx" : "", 251 !p->udp6_csum_tx && p->udp6_csum_rx 252 ? "rx" : "", 253 !p->udp6_csum_tx && !p->udp6_csum_rx 254 ? "disabled" : ""); 255 break; 256 } 257 } 258 } 259 260 static void print_session(struct l2tp_data *data) 261 { 262 struct l2tp_parm *p = &data->config; 263 264 printf("Session %u in tunnel %u\n", 265 p->session_id, p->tunnel_id); 266 printf(" Peer session %u, tunnel %u\n", 267 p->peer_session_id, p->peer_tunnel_id); 268 269 if (p->ifname != NULL) 270 printf(" interface name: %s\n", p->ifname); 271 272 printf(" offset %u, peer offset %u\n", 273 p->offset, p->peer_offset); 274 if (p->cookie_len > 0) 275 print_cookie("cookie", p->cookie, p->cookie_len); 276 if (p->peer_cookie_len > 0) 277 print_cookie("peer cookie", p->peer_cookie, p->peer_cookie_len); 278 279 if (p->reorder_timeout != 0) 280 printf(" reorder timeout: %u\n", p->reorder_timeout); 281 else 282 printf("\n"); 283 if (p->send_seq || p->recv_seq) { 284 printf(" sequence numbering:"); 285 if (p->send_seq) 286 printf(" send"); 287 if (p->recv_seq) 288 printf(" recv"); 289 printf("\n"); 290 } 291 } 292 293 static int get_response(struct nlmsghdr *n, void *arg) 294 { 295 struct genlmsghdr *ghdr; 296 struct l2tp_data *data = arg; 297 struct l2tp_parm *p = &data->config; 298 struct rtattr *attrs[L2TP_ATTR_MAX + 1]; 299 struct rtattr *nla_stats; 300 int len; 301 302 /* Validate message and parse attributes */ 303 if (n->nlmsg_type == NLMSG_ERROR) 304 return -EBADMSG; 305 306 ghdr = NLMSG_DATA(n); 307 len = n->nlmsg_len - NLMSG_LENGTH(sizeof(*ghdr)); 308 if (len < 0) 309 return -1; 310 311 parse_rtattr(attrs, L2TP_ATTR_MAX, (void *)ghdr + GENL_HDRLEN, len); 312 313 if (attrs[L2TP_ATTR_PW_TYPE]) 314 p->pw_type = rta_getattr_u16(attrs[L2TP_ATTR_PW_TYPE]); 315 if (attrs[L2TP_ATTR_ENCAP_TYPE]) 316 p->encap = rta_getattr_u16(attrs[L2TP_ATTR_ENCAP_TYPE]); 317 if (attrs[L2TP_ATTR_OFFSET]) 318 p->offset = rta_getattr_u16(attrs[L2TP_ATTR_OFFSET]); 319 if (attrs[L2TP_ATTR_DATA_SEQ]) 320 p->data_seq = rta_getattr_u16(attrs[L2TP_ATTR_DATA_SEQ]); 321 if (attrs[L2TP_ATTR_CONN_ID]) 322 p->tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_CONN_ID]); 323 if (attrs[L2TP_ATTR_PEER_CONN_ID]) 324 p->peer_tunnel_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_CONN_ID]); 325 if (attrs[L2TP_ATTR_SESSION_ID]) 326 p->session_id = rta_getattr_u32(attrs[L2TP_ATTR_SESSION_ID]); 327 if (attrs[L2TP_ATTR_PEER_SESSION_ID]) 328 p->peer_session_id = rta_getattr_u32(attrs[L2TP_ATTR_PEER_SESSION_ID]); 329 if (attrs[L2TP_ATTR_L2SPEC_TYPE]) 330 p->l2spec_type = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_TYPE]); 331 if (attrs[L2TP_ATTR_L2SPEC_LEN]) 332 p->l2spec_len = rta_getattr_u8(attrs[L2TP_ATTR_L2SPEC_LEN]); 333 334 if (attrs[L2TP_ATTR_UDP_CSUM]) 335 p->udp_csum = !!rta_getattr_u8(attrs[L2TP_ATTR_UDP_CSUM]); 336 337 p->udp6_csum_tx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_TX]; 338 p->udp6_csum_rx = !attrs[L2TP_ATTR_UDP_ZERO_CSUM6_RX]; 339 340 if (attrs[L2TP_ATTR_COOKIE]) 341 memcpy(p->cookie, RTA_DATA(attrs[L2TP_ATTR_COOKIE]), 342 p->cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_COOKIE])); 343 344 if (attrs[L2TP_ATTR_PEER_COOKIE]) 345 memcpy(p->peer_cookie, RTA_DATA(attrs[L2TP_ATTR_PEER_COOKIE]), 346 p->peer_cookie_len = RTA_PAYLOAD(attrs[L2TP_ATTR_PEER_COOKIE])); 347 348 if (attrs[L2TP_ATTR_RECV_SEQ]) 349 p->recv_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_RECV_SEQ]); 350 if (attrs[L2TP_ATTR_SEND_SEQ]) 351 p->send_seq = !!rta_getattr_u8(attrs[L2TP_ATTR_SEND_SEQ]); 352 353 if (attrs[L2TP_ATTR_RECV_TIMEOUT]) 354 p->reorder_timeout = rta_getattr_u64(attrs[L2TP_ATTR_RECV_TIMEOUT]); 355 if (attrs[L2TP_ATTR_IP_SADDR]) { 356 p->local_ip.family = AF_INET; 357 p->local_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_SADDR]); 358 p->local_ip.bytelen = 4; 359 p->local_ip.bitlen = -1; 360 } 361 if (attrs[L2TP_ATTR_IP_DADDR]) { 362 p->peer_ip.family = AF_INET; 363 p->peer_ip.data[0] = rta_getattr_u32(attrs[L2TP_ATTR_IP_DADDR]); 364 p->peer_ip.bytelen = 4; 365 p->peer_ip.bitlen = -1; 366 } 367 if (attrs[L2TP_ATTR_IP6_SADDR]) { 368 p->local_ip.family = AF_INET6; 369 memcpy(&p->local_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_SADDR]), 370 p->local_ip.bytelen = 16); 371 p->local_ip.bitlen = -1; 372 } 373 if (attrs[L2TP_ATTR_IP6_DADDR]) { 374 p->peer_ip.family = AF_INET6; 375 memcpy(&p->peer_ip.data, RTA_DATA(attrs[L2TP_ATTR_IP6_DADDR]), 376 p->peer_ip.bytelen = 16); 377 p->peer_ip.bitlen = -1; 378 } 379 if (attrs[L2TP_ATTR_UDP_SPORT]) 380 p->local_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_SPORT]); 381 if (attrs[L2TP_ATTR_UDP_DPORT]) 382 p->peer_udp_port = rta_getattr_u16(attrs[L2TP_ATTR_UDP_DPORT]); 383 if (attrs[L2TP_ATTR_MTU]) 384 p->mtu = rta_getattr_u16(attrs[L2TP_ATTR_MTU]); 385 if (attrs[L2TP_ATTR_IFNAME]) 386 p->ifname = rta_getattr_str(attrs[L2TP_ATTR_IFNAME]); 387 388 nla_stats = attrs[L2TP_ATTR_STATS]; 389 if (nla_stats) { 390 struct rtattr *tb[L2TP_ATTR_STATS_MAX + 1]; 391 392 parse_rtattr_nested(tb, L2TP_ATTR_STATS_MAX, nla_stats); 393 394 if (tb[L2TP_ATTR_TX_PACKETS]) 395 data->stats.data_tx_packets = rta_getattr_u64(tb[L2TP_ATTR_TX_PACKETS]); 396 if (tb[L2TP_ATTR_TX_BYTES]) 397 data->stats.data_tx_bytes = rta_getattr_u64(tb[L2TP_ATTR_TX_BYTES]); 398 if (tb[L2TP_ATTR_TX_ERRORS]) 399 data->stats.data_tx_errors = rta_getattr_u64(tb[L2TP_ATTR_TX_ERRORS]); 400 if (tb[L2TP_ATTR_RX_PACKETS]) 401 data->stats.data_rx_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_PACKETS]); 402 if (tb[L2TP_ATTR_RX_BYTES]) 403 data->stats.data_rx_bytes = rta_getattr_u64(tb[L2TP_ATTR_RX_BYTES]); 404 if (tb[L2TP_ATTR_RX_ERRORS]) 405 data->stats.data_rx_errors = rta_getattr_u64(tb[L2TP_ATTR_RX_ERRORS]); 406 if (tb[L2TP_ATTR_RX_SEQ_DISCARDS]) 407 data->stats.data_rx_oos_discards = rta_getattr_u64(tb[L2TP_ATTR_RX_SEQ_DISCARDS]); 408 if (tb[L2TP_ATTR_RX_OOS_PACKETS]) 409 data->stats.data_rx_oos_packets = rta_getattr_u64(tb[L2TP_ATTR_RX_OOS_PACKETS]); 410 } 411 412 return 0; 413 } 414 415 static int session_nlmsg(const struct sockaddr_nl *who, 416 struct nlmsghdr *n, void *arg) 417 { 418 int ret = get_response(n, arg); 419 420 if (ret == 0) 421 print_session(arg); 422 423 return ret; 424 } 425 426 static int get_session(struct l2tp_data *p) 427 { 428 GENL_REQUEST(req, 128, genl_family, 0, L2TP_GENL_VERSION, 429 L2TP_CMD_SESSION_GET, 430 NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST); 431 432 req.n.nlmsg_seq = genl_rth.dump = ++genl_rth.seq; 433 434 if (p->config.tunnel_id && p->config.session_id) { 435 addattr32(&req.n, 128, L2TP_ATTR_CONN_ID, p->config.tunnel_id); 436 addattr32(&req.n, 128, L2TP_ATTR_SESSION_ID, 437 p->config.session_id); 438 } 439 440 if (rtnl_send(&genl_rth, &req, req.n.nlmsg_len) < 0) 441 return -2; 442 443 if (rtnl_dump_filter(&genl_rth, session_nlmsg, p) < 0) { 444 fprintf(stderr, "Dump terminated\n"); 445 exit(1); 446 } 447 448 return 0; 449 } 450 451 static int tunnel_nlmsg(const struct sockaddr_nl *who, 452 struct nlmsghdr *n, void *arg) 453 { 454 int ret = get_response(n, arg); 455 456 if (ret == 0) 457 print_tunnel(arg); 458 459 return ret; 460 } 461 462 static int get_tunnel(struct l2tp_data *p) 463 { 464 GENL_REQUEST(req, 1024, genl_family, 0, L2TP_GENL_VERSION, 465 L2TP_CMD_TUNNEL_GET, 466 NLM_F_ROOT | NLM_F_MATCH | NLM_F_REQUEST); 467 468 req.n.nlmsg_seq = genl_rth.dump = ++genl_rth.seq; 469 470 if (p->config.tunnel_id) 471 addattr32(&req.n, 1024, L2TP_ATTR_CONN_ID, p->config.tunnel_id); 472 473 if (rtnl_send(&genl_rth, &req, req.n.nlmsg_len) < 0) 474 return -2; 475 476 if (rtnl_dump_filter(&genl_rth, tunnel_nlmsg, p) < 0) { 477 fprintf(stderr, "Dump terminated\n"); 478 exit(1); 479 } 480 481 return 0; 482 } 483 484 /***************************************************************************** 485 * Command parser 486 *****************************************************************************/ 487 488 static void usage(void) __attribute__((noreturn)); 489 490 static void usage(void) 491 { 492 fprintf(stderr, "Usage: ip l2tp add tunnel\n" 493 " remote ADDR local ADDR\n" 494 " tunnel_id ID peer_tunnel_id ID\n" 495 " [ encap { ip | udp } ]\n" 496 " [ udp_sport PORT ] [ udp_dport PORT ]\n" 497 " [ udp_csum { on | off } ]\n" 498 " [ udp6_csum_tx { on | off } ]\n" 499 " [ udp6_csum_rx { on | off } ]\n" 500 "Usage: ip l2tp add session [ name NAME ]\n" 501 " tunnel_id ID\n" 502 " session_id ID peer_session_id ID\n" 503 " [ cookie HEXSTR ] [ peer_cookie HEXSTR ]\n" 504 " [ offset OFFSET ] [ peer_offset OFFSET ]\n" 505 " [ seq { none | send | recv | both } ]\n" 506 " [ l2spec_type L2SPEC ]\n" 507 " ip l2tp del tunnel tunnel_id ID\n" 508 " ip l2tp del session tunnel_id ID session_id ID\n" 509 " ip l2tp show tunnel [ tunnel_id ID ]\n" 510 " ip l2tp show session [ tunnel_id ID ] [ session_id ID ]\n" 511 "\n" 512 "Where: NAME := STRING\n" 513 " ADDR := { IP_ADDRESS | any }\n" 514 " PORT := { 0..65535 }\n" 515 " ID := { 1..4294967295 }\n" 516 " HEXSTR := { 8 or 16 hex digits (4 / 8 bytes) }\n" 517 " L2SPEC := { none | default }\n"); 518 519 exit(-1); 520 } 521 522 static int parse_args(int argc, char **argv, int cmd, struct l2tp_parm *p) 523 { 524 memset(p, 0, sizeof(*p)); 525 526 if (argc == 0) 527 usage(); 528 529 /* Defaults */ 530 p->l2spec_type = L2TP_L2SPECTYPE_DEFAULT; 531 p->l2spec_len = 4; 532 p->udp6_csum_rx = 1; 533 p->udp6_csum_tx = 1; 534 535 while (argc > 0) { 536 if (strcmp(*argv, "encap") == 0) { 537 NEXT_ARG(); 538 if (strcmp(*argv, "ip") == 0) { 539 p->encap = L2TP_ENCAPTYPE_IP; 540 } else if (strcmp(*argv, "udp") == 0) { 541 p->encap = L2TP_ENCAPTYPE_UDP; 542 } else { 543 fprintf(stderr, "Unknown tunnel encapsulation \"%s\"\n", *argv); 544 exit(-1); 545 } 546 } else if (strcmp(*argv, "name") == 0) { 547 NEXT_ARG(); 548 if (check_ifname(*argv)) 549 invarg("\"name\" not a valid ifname", *argv); 550 p->ifname = *argv; 551 } else if (strcmp(*argv, "remote") == 0) { 552 NEXT_ARG(); 553 if (get_addr(&p->peer_ip, *argv, AF_UNSPEC)) 554 invarg("invalid remote address\n", *argv); 555 } else if (strcmp(*argv, "local") == 0) { 556 NEXT_ARG(); 557 if (get_addr(&p->local_ip, *argv, AF_UNSPEC)) 558 invarg("invalid local address\n", *argv); 559 } else if ((strcmp(*argv, "tunnel_id") == 0) || 560 (strcmp(*argv, "tid") == 0)) { 561 __u32 uval; 562 563 NEXT_ARG(); 564 if (get_u32(&uval, *argv, 0)) 565 invarg("invalid ID\n", *argv); 566 p->tunnel_id = uval; 567 } else if ((strcmp(*argv, "peer_tunnel_id") == 0) || 568 (strcmp(*argv, "ptid") == 0)) { 569 __u32 uval; 570 571 NEXT_ARG(); 572 if (get_u32(&uval, *argv, 0)) 573 invarg("invalid ID\n", *argv); 574 p->peer_tunnel_id = uval; 575 } else if ((strcmp(*argv, "session_id") == 0) || 576 (strcmp(*argv, "sid") == 0)) { 577 __u32 uval; 578 579 NEXT_ARG(); 580 if (get_u32(&uval, *argv, 0)) 581 invarg("invalid ID\n", *argv); 582 p->session_id = uval; 583 } else if ((strcmp(*argv, "peer_session_id") == 0) || 584 (strcmp(*argv, "psid") == 0)) { 585 __u32 uval; 586 587 NEXT_ARG(); 588 if (get_u32(&uval, *argv, 0)) 589 invarg("invalid ID\n", *argv); 590 p->peer_session_id = uval; 591 } else if (strcmp(*argv, "udp_sport") == 0) { 592 __u16 uval; 593 594 NEXT_ARG(); 595 if (get_u16(&uval, *argv, 0)) 596 invarg("invalid port\n", *argv); 597 p->local_udp_port = uval; 598 } else if (strcmp(*argv, "udp_dport") == 0) { 599 __u16 uval; 600 601 NEXT_ARG(); 602 if (get_u16(&uval, *argv, 0)) 603 invarg("invalid port\n", *argv); 604 p->peer_udp_port = uval; 605 } else if (strcmp(*argv, "udp_csum") == 0) { 606 NEXT_ARG(); 607 if (strcmp(*argv, "on") == 0) 608 p->udp_csum = 1; 609 else if (strcmp(*argv, "off") == 0) 610 p->udp_csum = 0; 611 else 612 invarg("invalid option for udp_csum\n", *argv); 613 } else if (strcmp(*argv, "udp6_csum_rx") == 0) { 614 NEXT_ARG(); 615 if (strcmp(*argv, "on") == 0) 616 p->udp6_csum_rx = 1; 617 else if (strcmp(*argv, "off") == 0) 618 p->udp6_csum_rx = 0; 619 else 620 invarg("invalid option for udp6_csum_rx\n" 621 , *argv); 622 } else if (strcmp(*argv, "udp6_csum_tx") == 0) { 623 NEXT_ARG(); 624 if (strcmp(*argv, "on") == 0) 625 p->udp6_csum_tx = 1; 626 else if (strcmp(*argv, "off") == 0) 627 p->udp6_csum_tx = 0; 628 else 629 invarg("invalid option for udp6_csum_tx\n" 630 , *argv); 631 } else if (strcmp(*argv, "offset") == 0) { 632 __u8 uval; 633 634 NEXT_ARG(); 635 if (get_u8(&uval, *argv, 0)) 636 invarg("invalid offset\n", *argv); 637 p->offset = uval; 638 } else if (strcmp(*argv, "peer_offset") == 0) { 639 __u8 uval; 640 641 NEXT_ARG(); 642 if (get_u8(&uval, *argv, 0)) 643 invarg("invalid offset\n", *argv); 644 p->peer_offset = uval; 645 } else if (strcmp(*argv, "cookie") == 0) { 646 int slen; 647 648 NEXT_ARG(); 649 slen = strlen(*argv); 650 if ((slen != 8) && (slen != 16)) 651 invarg("cookie must be either 8 or 16 hex digits\n", *argv); 652 653 p->cookie_len = slen / 2; 654 if (hex2mem(*argv, p->cookie, p->cookie_len) < 0) 655 invarg("cookie must be a hex string\n", *argv); 656 } else if (strcmp(*argv, "peer_cookie") == 0) { 657 int slen; 658 659 NEXT_ARG(); 660 slen = strlen(*argv); 661 if ((slen != 8) && (slen != 16)) 662 invarg("cookie must be either 8 or 16 hex digits\n", *argv); 663 664 p->peer_cookie_len = slen / 2; 665 if (hex2mem(*argv, p->peer_cookie, p->peer_cookie_len) < 0) 666 invarg("cookie must be a hex string\n", *argv); 667 } else if (strcmp(*argv, "l2spec_type") == 0) { 668 NEXT_ARG(); 669 if (strcasecmp(*argv, "default") == 0) { 670 p->l2spec_type = L2TP_L2SPECTYPE_DEFAULT; 671 p->l2spec_len = 4; 672 } else if (strcasecmp(*argv, "none") == 0) { 673 p->l2spec_type = L2TP_L2SPECTYPE_NONE; 674 p->l2spec_len = 0; 675 } else { 676 fprintf(stderr, 677 "Unknown layer2specific header type \"%s\"\n", 678 *argv); 679 exit(-1); 680 } 681 } else if (strcmp(*argv, "seq") == 0) { 682 NEXT_ARG(); 683 if (strcasecmp(*argv, "both") == 0) { 684 p->recv_seq = 1; 685 p->send_seq = 1; 686 } else if (strcasecmp(*argv, "recv") == 0) { 687 p->recv_seq = 1; 688 } else if (strcasecmp(*argv, "send") == 0) { 689 p->send_seq = 1; 690 } else if (strcasecmp(*argv, "none") == 0) { 691 p->recv_seq = 0; 692 p->send_seq = 0; 693 } else { 694 fprintf(stderr, 695 "Unknown seq value \"%s\"\n", *argv); 696 exit(-1); 697 } 698 } else if (strcmp(*argv, "tunnel") == 0) { 699 p->tunnel = 1; 700 } else if (strcmp(*argv, "session") == 0) { 701 p->session = 1; 702 } else if (matches(*argv, "help") == 0) { 703 usage(); 704 } else { 705 fprintf(stderr, "Unknown command: %s\n", *argv); 706 usage(); 707 } 708 709 argc--; argv++; 710 } 711 712 return 0; 713 } 714 715 716 static int do_add(int argc, char **argv) 717 { 718 struct l2tp_parm p; 719 int ret = 0; 720 721 if (parse_args(argc, argv, L2TP_ADD, &p) < 0) 722 return -1; 723 724 if (!p.tunnel && !p.session) 725 missarg("tunnel or session"); 726 727 if (p.tunnel_id == 0) 728 missarg("tunnel_id"); 729 730 /* session_id and peer_session_id must be provided for sessions */ 731 if ((p.session) && (p.peer_session_id == 0)) 732 missarg("peer_session_id"); 733 if ((p.session) && (p.session_id == 0)) 734 missarg("session_id"); 735 736 /* peer_tunnel_id is needed for tunnels */ 737 if ((p.tunnel) && (p.peer_tunnel_id == 0)) 738 missarg("peer_tunnel_id"); 739 740 if (p.tunnel) { 741 if (p.local_ip.family == AF_UNSPEC) 742 missarg("local"); 743 744 if (p.peer_ip.family == AF_UNSPEC) 745 missarg("remote"); 746 747 if (p.encap == L2TP_ENCAPTYPE_UDP) { 748 if (p.local_udp_port == 0) 749 missarg("udp_sport"); 750 if (p.peer_udp_port == 0) 751 missarg("udp_dport"); 752 } 753 754 ret = create_tunnel(&p); 755 } 756 757 if (p.session) { 758 /* Only ethernet pseudowires supported */ 759 p.pw_type = L2TP_PWTYPE_ETH; 760 761 ret = create_session(&p); 762 } 763 764 return ret; 765 } 766 767 static int do_del(int argc, char **argv) 768 { 769 struct l2tp_parm p; 770 771 if (parse_args(argc, argv, L2TP_DEL, &p) < 0) 772 return -1; 773 774 if (!p.tunnel && !p.session) 775 missarg("tunnel or session"); 776 777 if ((p.tunnel) && (p.tunnel_id == 0)) 778 missarg("tunnel_id"); 779 if ((p.session) && (p.session_id == 0)) 780 missarg("session_id"); 781 782 if (p.session_id) 783 return delete_session(&p); 784 else 785 return delete_tunnel(&p); 786 787 return -1; 788 } 789 790 static int do_show(int argc, char **argv) 791 { 792 struct l2tp_data data; 793 struct l2tp_parm *p = &data.config; 794 795 if (parse_args(argc, argv, L2TP_GET, p) < 0) 796 return -1; 797 798 if (!p->tunnel && !p->session) 799 missarg("tunnel or session"); 800 801 if (p->session) 802 get_session(&data); 803 else 804 get_tunnel(&data); 805 806 return 0; 807 } 808 809 int do_ipl2tp(int argc, char **argv) 810 { 811 if (argc < 1 || !matches(*argv, "help")) 812 usage(); 813 814 if (genl_init_handle(&genl_rth, L2TP_GENL_NAME, &genl_family)) 815 exit(1); 816 817 if (matches(*argv, "add") == 0) 818 return do_add(argc-1, argv+1); 819 if (matches(*argv, "delete") == 0) 820 return do_del(argc-1, argv+1); 821 if (matches(*argv, "show") == 0 || 822 matches(*argv, "lst") == 0 || 823 matches(*argv, "list") == 0) 824 return do_show(argc-1, argv+1); 825 826 fprintf(stderr, 827 "Command \"%s\" is unknown, try \"ip l2tp help\".\n", *argv); 828 exit(-1); 829 } 830