[nat] Implement token based identification.

Based on the token the NAT/MUX is capable of figuring out
which LAC this BSC is supposed to satisfy. This will be
needed for messages like paging that can be done by LAC.
diff --git a/openbsc/src/nat/bsc_nat.c b/openbsc/src/nat/bsc_nat.c
index aee0095..8466876 100644
--- a/openbsc/src/nat/bsc_nat.c
+++ b/openbsc/src/nat/bsc_nat.c
@@ -379,8 +379,12 @@
 {
 	struct sccp_connections *sccp_patch, *tmp;
 	bsc_unregister_fd(&connection->bsc_fd);
+	close(connection->bsc_fd.fd);
 	llist_del(&connection->list_entry);
 
+	/* stop the timeout timer */
+	bsc_del_timer(&connection->id_timeout);
+
 	/* remove all SCCP connections */
 	llist_for_each_entry_safe(sccp_patch, tmp, &nat->sccp_connections, list_entry) {
 		if (sccp_patch->bsc != connection)
@@ -393,6 +397,29 @@
 	talloc_free(connection);
 }
 
+static void ipaccess_close_bsc(void *data)
+{
+	struct bsc_connection *conn = data;
+
+	LOGP(DNAT, LOGL_ERROR, "BSC didn't respond to identity request. Closing.\n");
+	remove_bsc_connection(conn);
+}
+
+static void ipaccess_auth_bsc(struct tlv_parsed *tvp, struct bsc_connection *bsc)
+{
+	struct bsc_config *conf;
+	const char* token = (const char *) TLVP_VAL(tvp, IPAC_IDTAG_UNITNAME);
+
+	llist_for_each_entry(conf, &bsc->nat->bsc_configs, entry) {
+		if (strcmp(conf->token, token) == 0) {
+			bsc->authenticated = 1;
+			bsc->lac = conf->lac;
+			bsc_del_timer(&bsc->id_timeout);
+			break;
+		}
+	}
+}
+
 static int forward_sccp_to_msc(struct bsc_fd *bfd, struct msgb *msg)
 {
 	struct bsc_connection *bsc;
@@ -459,6 +486,18 @@
 	if (parsed->bssap == 0 && parsed->gsm_type == BSS_MAP_MSG_RESET) {
 		send_reset_ack(bfd);
 		send_reset_ack(bfd);
+	} else if (parsed->ipa_proto == IPAC_PROTO_IPACCESS) {
+		/* do we know who is handling this? */
+		if (msg->l2h[0] == IPAC_MSGT_ID_RESP) {
+			struct tlv_parsed tvp;
+			ipaccess_idtag_parse(&tvp,
+					     (unsigned char *) msg->l2h + 2,
+					     msgb_l2len(msg) - 2);
+			if (TLVP_PRESENT(&tvp, IPAC_IDTAG_UNITNAME))
+				ipaccess_auth_bsc(&tvp, bsc);
+		}
+
+		goto exit2;
 	}
 
 exit2:
@@ -521,6 +560,7 @@
 		return -1;
 	}
 
+	bsc->nat = nat;
 	bsc->bsc_fd.data = bsc;
 	bsc->bsc_fd.fd = ret;
 	bsc->bsc_fd.cb = ipaccess_bsc_cb;
@@ -534,7 +574,15 @@
 
 	LOGP(DNAT, LOGL_INFO, "Registered new BSC\n");
 	llist_add(&bsc->list_entry, &nat->bsc_connections);
-	ipaccess_send_id_ack(ret);
+	ipaccess_send_id_ack(bsc->bsc_fd.fd);
+	ipaccess_send_id_req(ret);
+
+	/*
+	 * start the hangup timer
+	 */
+	bsc->id_timeout.data = bsc;
+	bsc->id_timeout.cb = ipaccess_close_bsc;
+	bsc_schedule_timer(&bsc->id_timeout, 2, 0);
 	return 0;
 }