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