2 protocol.c -- handle the meta-protocol
3 Copyright (C) 1999,2000 Ivo Timmermans <itimmermans@bigfoot.com>,
4 2000 Guus Sliepen <guus@sliepen.warande.net>
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 2 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program; if not, write to the Free Software
18 Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
20 $Id: protocol.c,v 1.28.4.12 2000/06/27 20:55:12 guus Exp $
25 #include <sys/types.h>
30 #include <sys/socket.h>
45 char buffer[MAXBUFSIZE+1];
48 /* Outgoing request routines */
50 int send_ack(conn_list_t *cl)
54 syslog(LOG_DEBUG, _("Sending ACK to " IP_ADDR_S " (%s)"),
55 IP_ADDR_V(cl->vpn_ip), cl->hostname);
57 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", ACK);
59 if((write(cl->meta_socket, buffer, buflen)) < 0)
61 syslog(LOG_ERR, _("Send failed: %d:%d: %m"), __FILE__, __LINE__);
66 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
67 IP_ADDR_V(cl->vpn_ip), cl->hostname);
72 int send_termreq(conn_list_t *cl)
76 syslog(LOG_DEBUG, _("Sending TERMREQ to " IP_ADDR_S " (%s)"),
77 IP_ADDR_V(cl->vpn_ip), cl->hostname);
79 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", TERMREQ, myself->vpn_ip);
81 if(write(cl->meta_socket, buffer, buflen) < 0)
84 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
91 int send_timeout(conn_list_t *cl)
95 syslog(LOG_DEBUG, _("Sending TIMEOUT to " IP_ADDR_S " (%s)"),
96 IP_ADDR_V(cl->vpn_ip), cl->hostname);
98 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", PINGTIMEOUT, myself->vpn_ip);
100 if((write(cl->meta_socket, buffer, buflen)) < 0)
102 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
109 int send_del_host(conn_list_t *cl, conn_list_t *new_host)
113 syslog(LOG_DEBUG, _("Sending DEL_HOST for " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
114 IP_ADDR_V(new_host->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
116 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", DEL_HOST, new_host->vpn_ip);
118 if((write(cl->meta_socket, buffer, buflen)) < 0)
120 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
127 int send_ping(conn_list_t *cl)
131 syslog(LOG_DEBUG, _("Sending PING to " IP_ADDR_S " (%s)"),
132 IP_ADDR_V(cl->vpn_ip), cl->hostname);
134 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PING);
136 if((write(cl->meta_socket, buffer, buflen)) < 0)
138 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
145 int send_pong(conn_list_t *cl)
149 syslog(LOG_DEBUG, _("Sending PONG to " IP_ADDR_S " (%s)"),
150 IP_ADDR_V(cl->vpn_ip), cl->hostname);
152 buflen = snprintf(buffer, MAXBUFSIZE, "%d\n", PONG);
154 if((write(cl->meta_socket, buffer, buflen)) < 0)
156 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
163 int send_add_host(conn_list_t *cl, conn_list_t *new_host)
169 real_ip = new_host->real_ip;
170 hostname = new_host->hostname;
171 flags = new_host->flags;
173 /* If we need to propagate information about a new host that wants us to export
174 * it's indirectdata flag, we set the INDIRECTDATA flag and unset the EXPORT...
175 * flag, and set it's real_ip to our vpn_ip, so that net.c send_packet() will
179 if(flags & EXPORTINDIRECTDATA)
181 flags &= ~EXPORTINDIRECTDATA;
182 flags |= INDIRECTDATA;
183 real_ip = myself->vpn_ip;
184 hostname = myself->hostname;
188 syslog(LOG_DEBUG, _("Sending ADD_HOST for " IP_ADDR_S " (%s) to " IP_ADDR_S " (%s)"),
189 IP_ADDR_V(new_host->vpn_ip), hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
191 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx/%lx:%x %d\n", ADD_HOST, real_ip, new_host->vpn_ip, new_host->vpn_mask, new_host->port, flags);
193 if((write(cl->meta_socket, buffer, buflen)) < 0)
195 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
202 int send_key_changed(conn_list_t *cl, conn_list_t *src)
206 syslog(LOG_DEBUG, _("Sending KEY_CHANGED origin " IP_ADDR_S " to " IP_ADDR_S " (%s)"),
207 IP_ADDR_V(src->vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
209 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx\n", KEY_CHANGED, src->vpn_ip);
211 if((write(cl->meta_socket, buffer, buflen)) < 0)
213 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
220 void send_key_changed_all(void)
224 for(p = conn_list; p != NULL; p = p->next)
225 if(p->status.meta && p->status.active)
226 send_key_changed(p, myself);
230 int send_basic_info(conn_list_t *cl)
234 syslog(LOG_DEBUG, _("Sending BASIC_INFO to %s"),
237 buflen = snprintf(buffer, MAXBUFSIZE, "%d %d %lx/%lx:%x %d\n", BASIC_INFO, PROT_CURRENT, myself->vpn_ip, myself->vpn_mask, myself->port, myself->flags);
239 if((write(cl->meta_socket, buffer, buflen)) < 0)
241 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
248 int send_passphrase(conn_list_t *cl)
252 encrypt_passphrase(&tmp);
255 syslog(LOG_DEBUG, _("Sending PASSPHRASE to " IP_ADDR_S " (%s)"),
256 IP_ADDR_V(cl->vpn_ip), cl->hostname);
258 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PASSPHRASE, tmp.phrase);
260 if((write(cl->meta_socket, buffer, buflen)) < 0)
262 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
269 int send_public_key(conn_list_t *cl)
273 syslog(LOG_DEBUG, _("Sending PUBLIC_KEY to " IP_ADDR_S " (%s)"),
274 IP_ADDR_V(cl->vpn_ip), cl->hostname);
276 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", PUBLIC_KEY, my_public_key_base36);
278 if((write(cl->meta_socket, buffer, buflen)) < 0)
280 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
287 /* WDN doet deze functie? (GS)
288 int send_calculate(conn_list_t *cl, char *k)
291 buflen = snprintf(buffer, MAXBUFSIZE, "%d %s\n", CALCULATE, k);
293 if((write(cl->meta_socket, buffer, buflen)) < 0)
295 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
303 int send_key_request(ip_t to)
307 fw = lookup_conn(to);
310 syslog(LOG_ERR, _("Attempting to send REQ_KEY to " IP_ADDR_S ", which does not exist?"),
316 syslog(LOG_DEBUG, _("Sending REQ_KEY to " IP_ADDR_S " (%s)"),
317 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
319 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx\n", REQ_KEY, to, myself->vpn_ip);
321 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
323 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
326 fw->status.waitingforkey = 1;
331 int send_key_answer(conn_list_t *cl, ip_t to)
336 fw = lookup_conn(to);
340 syslog(LOG_ERR, _("Attempting to send ANS_KEY to " IP_ADDR_S ", which does not exist?"),
346 syslog(LOG_DEBUG, _("Sending ANS_KEY to " IP_ADDR_S " (%s)"),
347 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
349 buflen = snprintf(buffer, MAXBUFSIZE, "%d %lx %lx %d %s\n", ANS_KEY, to, myself->vpn_ip, my_key_expiry, my_public_key_base36);
351 if((write(fw->nexthop->meta_socket, buffer, buflen)) < 0)
353 syslog(LOG_ERR, _("send failed: %s:%d: %m"), __FILE__, __LINE__);
361 notify all my direct connections of a new host
362 that was added to the vpn, with the exception
363 of the source of the announcement.
365 int notify_others(conn_list_t *new, conn_list_t *source,
366 int (*function)(conn_list_t*, conn_list_t*))
370 for(p = conn_list; p != NULL; p = p->next)
371 if(p != new && p != source && p->status.meta && p->status.active)
378 notify one connection of everything
381 int notify_one(conn_list_t *new)
385 for(p = conn_list; p != NULL; p = p->next)
386 if(p != new && p->status.active)
387 send_add_host(new, p);
393 The incoming request handlers
396 int basic_info_h(conn_list_t *cl)
400 syslog(LOG_DEBUG, _("Got BASIC_INFO from %s"), cl->hostname);
402 if(sscanf(cl->buffer, "%*d %d %lx/%lx:%hx %d", &cl->protocol_version, &cl->vpn_ip, &cl->vpn_mask, &cl->port, &cl->flags) != 5)
404 syslog(LOG_ERR, _("Got bad BASIC_INFO from %s"),
409 if(cl->protocol_version != PROT_CURRENT)
411 syslog(LOG_ERR, _("Peer uses incompatible protocol version %d"),
412 cl->protocol_version);
416 if(cl->status.outgoing)
418 if(setup_vpn_connection(cl) < 0)
424 if(setup_vpn_connection(cl) < 0)
432 int passphrase_h(conn_list_t *cl)
435 cl->pp = xmalloc(sizeof(*(cl->pp)));
437 if(sscanf(cl->buffer, "%*d %as", &(cl->pp->phrase)) != 1)
439 syslog(LOG_ERR, _("Got bad PASSPHRASE from " IP_ADDR_S " (%s)"),
440 IP_ADDR_V(cl->vpn_ip), cl->hostname);
443 cl->pp->len = strlen(cl->pp->phrase);
446 syslog(LOG_DEBUG, _("Got PASSPHRASE from " IP_ADDR_S " (%s)"),
447 IP_ADDR_V(cl->vpn_ip), cl->hostname);
449 if(cl->status.outgoing)
457 int public_key_h(conn_list_t *cl)
462 if(sscanf(cl->buffer, "%*d %as", &g_n) != 1)
464 syslog(LOG_ERR, _("Got bad PUBLIC_KEY from " IP_ADDR_S " (%s)"),
465 IP_ADDR_V(cl->vpn_ip), cl->hostname);
470 syslog(LOG_DEBUG, _("Got PUBLIC_KEY from " IP_ADDR_S " (%s)"),
471 IP_ADDR_V(cl->vpn_ip), cl->hostname);
473 if(verify_passphrase(cl, g_n))
476 syslog(LOG_ERR, _("Intruder: passphrase does not match!"));
480 if(cl->status.outgoing)
486 /* Okay, before we active the connection, we check if there is another entry
487 in the connection list with the same vpn_ip. If so, it presumably is an
488 old connection that has timed out but we don't know it yet. Because our
489 conn_list entry is not active, lookup_conn will skip ourself. */
491 while(old = lookup_conn(cl->vpn_ip))
492 terminate_connection(old);
494 cl->status.active = 1;
495 notify_others(cl, NULL, send_add_host);
502 int ack_h(conn_list_t *cl)
506 syslog(LOG_DEBUG, _("Got ACK from " IP_ADDR_S " (%s)"),
507 IP_ADDR_V(cl->vpn_ip), cl->hostname);
509 cl->status.active = 1;
510 syslog(LOG_NOTICE, _("Connection with " IP_ADDR_S " (%s) activated"),
511 IP_ADDR_V(cl->vpn_ip), cl->hostname);
517 int termreq_h(conn_list_t *cl)
520 if(!cl->status.active)
522 syslog(LOG_ERR, _("Got unauthorized TERMREQ from " IP_ADDR_S " (%s)"),
523 IP_ADDR_V(cl->vpn_ip), cl->hostname);
528 syslog(LOG_DEBUG, _("Got TERMREQ from " IP_ADDR_S " (%s)"),
529 IP_ADDR_V(cl->vpn_ip), cl->hostname);
531 cl->status.termreq = 1;
533 if(cl->status.active)
534 notify_others(cl, NULL, send_del_host);
536 cl->status.active = 0;
538 terminate_connection(cl);
543 int timeout_h(conn_list_t *cl)
546 if(!cl->status.active)
548 syslog(LOG_ERR, _("Got unauthorized TIMEOUT from " IP_ADDR_S " (%s)"),
549 IP_ADDR_V(cl->vpn_ip), cl->hostname);
554 syslog(LOG_DEBUG, _("Got TIMEOUT from " IP_ADDR_S " (%s)"),
555 IP_ADDR_V(cl->vpn_ip), cl->hostname);
557 cl->status.termreq = 1;
558 terminate_connection(cl);
563 int del_host_h(conn_list_t *cl)
568 if(!cl->status.active)
570 syslog(LOG_ERR, _("Got unauthorized DEL_HOST from " IP_ADDR_S " (%s)"),
571 IP_ADDR_V(cl->vpn_ip), cl->hostname);
575 if(sscanf(cl->buffer, "%*d %lx", &vpn_ip) != 1)
577 syslog(LOG_ERR, _("Got bad DEL_HOST from " IP_ADDR_S " (%s)"),
578 IP_ADDR_V(cl->vpn_ip), cl->hostname);
583 syslog(LOG_DEBUG, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
584 IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
586 if(!(fw = lookup_conn(vpn_ip)))
588 syslog(LOG_ERR, _("Got DEL_HOST for " IP_ADDR_S " from " IP_ADDR_S " (%s) which does not exist?"),
589 IP_ADDR_V(vpn_ip), IP_ADDR_V(cl->vpn_ip), cl->hostname);
593 notify_others(fw, cl, send_del_host);
595 fw->status.termreq = 1;
596 fw->status.active = 0;
598 terminate_connection(fw);
603 int ping_h(conn_list_t *cl)
606 if(!cl->status.active)
608 syslog(LOG_ERR, _("Got unauthorized PING from " IP_ADDR_S " (%s)"),
609 IP_ADDR_V(cl->vpn_ip), cl->hostname);
614 syslog(LOG_DEBUG, _("Got PING from " IP_ADDR_S " (%s)"),
615 IP_ADDR_V(cl->vpn_ip), cl->hostname);
617 cl->status.pinged = 0;
618 cl->status.got_pong = 1;
625 int pong_h(conn_list_t *cl)
628 if(!cl->status.active)
630 syslog(LOG_ERR, _("Got unauthorized PONG from " IP_ADDR_S " (%s)"),
631 IP_ADDR_V(cl->vpn_ip), cl->hostname);
636 syslog(LOG_DEBUG, _("Got PONG from " IP_ADDR_S " (%s)"),
637 IP_ADDR_V(cl->vpn_ip), cl->hostname);
639 cl->status.got_pong = 1;
644 int add_host_h(conn_list_t *cl)
651 conn_list_t *ncn, *old;
653 if(!cl->status.active)
655 syslog(LOG_ERR, _("Got unauthorized ADD_HOST from " IP_ADDR_S " (%s)"),
656 IP_ADDR_V(cl->vpn_ip), cl->hostname);
660 if(sscanf(cl->buffer, "%*d %lx %lx/%lx:%hx %d", &real_ip, &vpn_ip, &vpn_mask, &port, &flags) != 5)
662 syslog(LOG_ERR, _("Got bad ADD_HOST from " IP_ADDR_S " (%s)"),
663 IP_ADDR_V(cl->vpn_ip), cl->hostname);
667 while(old = lookup_conn(vpn_ip))
668 terminate_connection(old);
670 ncn = new_conn_list();
671 ncn->real_ip = real_ip;
672 ncn->hostname = hostlookup(htonl(real_ip));
673 ncn->vpn_ip = vpn_ip;
674 ncn->vpn_mask = vpn_mask;
678 ncn->next = conn_list;
680 ncn->status.active = 1;
683 syslog(LOG_DEBUG, _("Got ADD_HOST for " IP_ADDR_S " (%s) from " IP_ADDR_S " (%s)"),
684 IP_ADDR_V(ncn->vpn_ip), ncn->hostname, IP_ADDR_V(cl->vpn_ip), cl->hostname);
686 notify_others(ncn, cl, send_add_host);
691 int req_key_h(conn_list_t *cl)
697 if(!cl->status.active)
699 syslog(LOG_ERR, _("Got unauthorized REQ_KEY from " IP_ADDR_S " (%s)"),
700 IP_ADDR_V(cl->vpn_ip), cl->hostname);
704 if(sscanf(cl->buffer, "%*d %lx %lx", &to, &from) != 2)
706 syslog(LOG_ERR, _("Got bad REQ_KEY from " IP_ADDR_S " (%s)"),
707 IP_ADDR_V(cl->vpn_ip), cl->hostname);
712 syslog(LOG_DEBUG, _("Got REQ_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
713 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
715 if((to & myself->vpn_mask) == (myself->vpn_ip & myself->vpn_mask))
716 { /* hey! they want something from ME! :) */
717 send_key_answer(cl, from);
721 fw = lookup_conn(to);
725 syslog(LOG_ERR, _("Attempting to forward REQ_KEY to " IP_ADDR_S ", which does not exist?"),
731 syslog(LOG_DEBUG, _("Forwarding REQ_KEY to " IP_ADDR_S " (%s)"),
732 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
734 cl->buffer[cl->reqlen-1] = '\n';
736 if(write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen) < 0)
738 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
745 void set_keys(conn_list_t *cl, int expiry, char *key)
751 cl->public_key = xmalloc(sizeof(*cl->key));
752 cl->public_key->key = NULL;
755 if(cl->public_key->key)
756 free(cl->public_key->key);
757 cl->public_key->length = strlen(key);
758 cl->public_key->expiry = expiry;
759 cl->public_key->key = xmalloc(cl->public_key->length + 1);
760 strcpy(cl->public_key->key, key);
762 ek = make_shared_key(key);
766 cl->key = xmalloc(sizeof(*cl->key));
773 cl->key->length = strlen(ek);
774 cl->key->expiry = expiry;
775 cl->key->key = xmalloc(cl->key->length + 1);
776 strcpy(cl->key->key, ek);
780 int ans_key_h(conn_list_t *cl)
786 conn_list_t *fw, *gk;
788 if(!cl->status.active)
790 syslog(LOG_ERR, _("Got unauthorized ANS_KEY from " IP_ADDR_S " (%s)"),
791 IP_ADDR_V(cl->vpn_ip), cl->hostname);
795 if(sscanf(cl->buffer, "%*d %lx %lx %d %as", &to, &from, &expiry, &key) != 4)
797 syslog(LOG_ERR, _("Got bad ANS_KEY from " IP_ADDR_S " (%s)"),
798 IP_ADDR_V(cl->vpn_ip), cl->hostname);
803 syslog(LOG_DEBUG, _("Got ANS_KEY origin " IP_ADDR_S " destination " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
804 IP_ADDR_V(from), IP_ADDR_V(to), IP_ADDR_V(cl->vpn_ip), cl->hostname);
806 if(to == myself->vpn_ip)
807 { /* hey! that key's for ME! :) */
808 gk = lookup_conn(from);
812 syslog(LOG_ERR, _("Receiving ANS_KEY from " IP_ADDR_S ", which does not exist?"),
817 set_keys(gk, expiry, key);
818 gk->status.validkey = 1;
819 gk->status.waitingforkey = 0;
824 fw = lookup_conn(to);
828 syslog(LOG_ERR, _("Attempting to forward ANS_KEY to " IP_ADDR_S ", which does not exist?"),
834 syslog(LOG_DEBUG, _("Forwarding ANS_KEY to " IP_ADDR_S " (%s)"),
835 IP_ADDR_V(fw->nexthop->vpn_ip), fw->nexthop->hostname);
837 cl->buffer[cl->reqlen-1] = '\n';
839 if((write(fw->nexthop->meta_socket, cl->buffer, cl->reqlen)) < 0)
841 syslog(LOG_ERR, _("Send failed: %s:%d: %m"), __FILE__, __LINE__);
848 int key_changed_h(conn_list_t *cl)
853 if(!cl->status.active)
855 syslog(LOG_ERR, _("Got unauthorized KEY_CHANGED from " IP_ADDR_S " (%s)"),
856 IP_ADDR_V(cl->vpn_ip), cl->hostname);
860 if(sscanf(cl->buffer, "%*d %lx", &from) != 1)
862 syslog(LOG_ERR, _("Got bad KEY_CHANGED from " IP_ADDR_S " (%s)"),
863 IP_ADDR_V(cl->vpn_ip), cl->hostname);
868 syslog(LOG_DEBUG, _("Got KEY_CHANGED origin " IP_ADDR_S " from " IP_ADDR_S " (%s)"),
869 IP_ADDR_V(from), IP_ADDR_V(cl->vpn_ip), cl->hostname);
871 ik = lookup_conn(from);
875 syslog(LOG_ERR, _("Got KEY_CHANGED from " IP_ADDR_S ", which does not exist?"),
880 ik->status.validkey = 0;
881 ik->status.waitingforkey = 0;
883 notify_others(ik, cl, send_key_changed);
888 int (*request_handlers[256])(conn_list_t*) = {
889 0, ack_h, 0, 0, 0, 0, 0, 0, 0, 0,
890 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
891 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
892 termreq_h, timeout_h, del_host_h, 0, 0, 0, 0, 0, 0, 0,
893 ping_h, pong_h, 0, 0, 0, 0, 0, 0, 0, 0,
894 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
895 add_host_h, basic_info_h, passphrase_h, public_key_h, 0, 0, 0, 0, 0, 0,
896 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
897 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
898 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
899 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
900 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
901 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
902 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
903 req_key_h, ans_key_h, key_changed_h, 0, 0, 0, 0, 0, 0, 0,
904 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
905 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
906 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
907 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
908 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0