Home | History | Annotate | Download | only in ip
      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