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