kernel/netgraph7: Replace usage of MALLOC/FREE with kmalloc/kfree here too.
[dragonfly.git] / sys / netgraph7 / ng_async.c
1 /*
2  * ng_async.c
3  */
4
5 /*-
6  * Copyright (c) 1996-1999 Whistle Communications, Inc.
7  * All rights reserved.
8  * 
9  * Subject to the following obligations and disclaimer of warranty, use and
10  * redistribution of this software, in source or object code forms, with or
11  * without modifications are expressly permitted by Whistle Communications;
12  * provided, however, that:
13  * 1. Any and all reproductions of the source or object code must include the
14  *    copyright notice above and the following disclaimer of warranties; and
15  * 2. No rights are granted, in any manner or form, to use Whistle
16  *    Communications, Inc. trademarks, including the mark "WHISTLE
17  *    COMMUNICATIONS" on advertising, endorsements, or otherwise except as
18  *    such appears in the above copyright notice or in the software.
19  * 
20  * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND
21  * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO
22  * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE,
23  * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF
24  * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT.
25  * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY
26  * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS
27  * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE.
28  * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES
29  * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING
30  * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY,
31  * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR
32  * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER ANY
33  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
34  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35  * THIS SOFTWARE, EVEN IF WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY
36  * OF SUCH DAMAGE.
37  *
38  * Author: Archie Cobbs <archie@freebsd.org>
39  *
40  * $FreeBSD: src/sys/netgraph/ng_async.c,v 1.22 2005/01/07 01:45:39 imp Exp $
41  * $DragonFly: src/sys/netgraph7/ng_async.c,v 1.2 2008/06/26 23:05:35 dillon Exp $
42  * $Whistle: ng_async.c,v 1.17 1999/11/01 09:24:51 julian Exp $
43  */
44
45 /*
46  * This node type implements a PPP style sync <-> async converter.
47  * See RFC 1661 for details of how asynchronous encoding works.
48  */
49
50 #include <sys/param.h>
51 #include <sys/systm.h>
52 #include <sys/kernel.h>
53 #include <sys/mbuf.h>
54 #include <sys/malloc.h>
55 #include <sys/errno.h>
56
57 #include "ng_message.h"
58 #include "netgraph.h"
59 #include "ng_async.h"
60 #include "ng_parse.h"
61
62 #include <net/ppp_defs.h>
63
64 #ifdef NG_SEPARATE_MALLOC
65 MALLOC_DEFINE(M_NETGRAPH_ASYNC, "netgraph_async", "netgraph async node ");
66 #else
67 #define M_NETGRAPH_ASYNC M_NETGRAPH
68 #endif
69
70
71 /* Async decode state */
72 #define MODE_HUNT       0
73 #define MODE_NORMAL     1
74 #define MODE_ESC        2
75
76 /* Private data structure */
77 struct ng_async_private {
78         node_p          node;           /* Our node */
79         hook_p          async;          /* Asynchronous side */
80         hook_p          sync;           /* Synchronous side */
81         u_char          amode;          /* Async hunt/esape mode */
82         u_int16_t       fcs;            /* Decoded async FCS (so far) */
83         u_char         *abuf;           /* Buffer to encode sync into */
84         u_char         *sbuf;           /* Buffer to decode async into */
85         u_int           slen;           /* Length of data in sbuf */
86         long            lasttime;       /* Time of last async packet sent */
87         struct          ng_async_cfg    cfg;    /* Configuration */
88         struct          ng_async_stat   stats;  /* Statistics */
89 };
90 typedef struct ng_async_private *sc_p;
91
92 /* Useful macros */
93 #define ASYNC_BUF_SIZE(smru)    (2 * (smru) + 10)
94 #define SYNC_BUF_SIZE(amru)     ((amru) + 10)
95 #define ERROUT(x)               do { error = (x); goto done; } while (0)
96
97 /* Netgraph methods */
98 static ng_constructor_t         nga_constructor;
99 static ng_rcvdata_t             nga_rcvdata;
100 static ng_rcvmsg_t              nga_rcvmsg;
101 static ng_shutdown_t            nga_shutdown;
102 static ng_newhook_t             nga_newhook;
103 static ng_disconnect_t          nga_disconnect;
104
105 /* Helper stuff */
106 static int      nga_rcv_sync(const sc_p sc, item_p item);
107 static int      nga_rcv_async(const sc_p sc, item_p item);
108
109 /* Parse type for struct ng_async_cfg */
110 static const struct ng_parse_struct_field nga_config_type_fields[]
111         = NG_ASYNC_CONFIG_TYPE_INFO;
112 static const struct ng_parse_type nga_config_type = {
113         &ng_parse_struct_type,
114         &nga_config_type_fields
115 };
116
117 /* Parse type for struct ng_async_stat */
118 static const struct ng_parse_struct_field nga_stats_type_fields[]
119         = NG_ASYNC_STATS_TYPE_INFO;
120 static const struct ng_parse_type nga_stats_type = {
121         &ng_parse_struct_type,
122         &nga_stats_type_fields
123 };
124
125 /* List of commands and how to convert arguments to/from ASCII */
126 static const struct ng_cmdlist nga_cmdlist[] = {
127         {
128           NGM_ASYNC_COOKIE,
129           NGM_ASYNC_CMD_SET_CONFIG,
130           "setconfig",
131           &nga_config_type,
132           NULL
133         },
134         {
135           NGM_ASYNC_COOKIE,
136           NGM_ASYNC_CMD_GET_CONFIG,
137           "getconfig",
138           NULL,
139           &nga_config_type
140         },
141         {
142           NGM_ASYNC_COOKIE,
143           NGM_ASYNC_CMD_GET_STATS,
144           "getstats",
145           NULL,
146           &nga_stats_type
147         },
148         {
149           NGM_ASYNC_COOKIE,
150           NGM_ASYNC_CMD_CLR_STATS,
151           "clrstats",
152           &nga_stats_type,
153           NULL
154         },
155         { 0 }
156 };
157
158 /* Define the netgraph node type */
159 static struct ng_type typestruct = {
160         .version =      NG_ABI_VERSION,
161         .name =         NG_ASYNC_NODE_TYPE,
162         .constructor =  nga_constructor,
163         .rcvmsg =       nga_rcvmsg,
164         .shutdown =     nga_shutdown,
165         .newhook =      nga_newhook,
166         .rcvdata =      nga_rcvdata,
167         .disconnect =   nga_disconnect,
168         .cmdlist =      nga_cmdlist
169 };
170 NETGRAPH_INIT(async, &typestruct);
171
172 /* CRC table */
173 static const u_int16_t fcstab[];
174
175 /******************************************************************
176                     NETGRAPH NODE METHODS
177 ******************************************************************/
178
179 /*
180  * Initialize a new node
181  */
182 static int
183 nga_constructor(node_p node)
184 {
185         sc_p sc;
186
187         sc = kmalloc(sizeof(*sc), M_NETGRAPH_ASYNC,
188                      M_WAITOK | M_NULLOK | M_ZERO);
189         if (sc == NULL)
190                 return (ENOMEM);
191         sc->amode = MODE_HUNT;
192         sc->cfg.accm = ~0;
193         sc->cfg.amru = NG_ASYNC_DEFAULT_MRU;
194         sc->cfg.smru = NG_ASYNC_DEFAULT_MRU;
195         sc->abuf = kmalloc(ASYNC_BUF_SIZE(sc->cfg.smru), M_NETGRAPH_ASYNC,
196                            M_WAITOK | M_NULLOK);
197         if (sc->abuf == NULL)
198                 goto fail;
199         sc->sbuf = kmalloc(SYNC_BUF_SIZE(sc->cfg.amru), M_NETGRAPH_ASYNC,
200                            M_WAITOK | M_NULLOK);
201         if (sc->sbuf == NULL) {
202                 kfree(sc->abuf, M_NETGRAPH_ASYNC);
203 fail:
204                 kfree(sc, M_NETGRAPH_ASYNC);
205                 return (ENOMEM);
206         }
207         NG_NODE_SET_PRIVATE(node, sc);
208         sc->node = node;
209         return (0);
210 }
211
212 /*
213  * Reserve a hook for a pending connection
214  */
215 static int
216 nga_newhook(node_p node, hook_p hook, const char *name)
217 {
218         const sc_p sc = NG_NODE_PRIVATE(node);
219         hook_p *hookp;
220
221         if (!strcmp(name, NG_ASYNC_HOOK_ASYNC)) {
222                 /*
223                  * We use a static buffer here so only one packet
224                  * at a time can be allowed to travel in this direction.
225                  * Force Writer semantics.
226                  */
227                 NG_HOOK_FORCE_WRITER(hook);
228                 hookp = &sc->async;
229         } else if (!strcmp(name, NG_ASYNC_HOOK_SYNC)) {
230                 /*
231                  * We use a static state here so only one packet
232                  * at a time can be allowed to travel in this direction.
233                  * Force Writer semantics.
234                  * Since we set this for both directions
235                  * we might as well set it for the whole node
236                  * bit I haven;t done that (yet).
237                  */
238                 NG_HOOK_FORCE_WRITER(hook);
239                 hookp = &sc->sync;
240         } else {
241                 return (EINVAL);
242         }
243         if (*hookp) /* actually can't happen I think [JRE] */
244                 return (EISCONN);
245         *hookp = hook;
246         return (0);
247 }
248
249 /*
250  * Receive incoming data
251  */
252 static int
253 nga_rcvdata(hook_p hook, item_p item)
254 {
255         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
256
257         if (hook == sc->sync)
258                 return (nga_rcv_sync(sc, item));
259         if (hook == sc->async)
260                 return (nga_rcv_async(sc, item));
261         panic(__func__);
262 }
263
264 /*
265  * Receive incoming control message
266  */
267 static int
268 nga_rcvmsg(node_p node, item_p item, hook_p lasthook)
269 {
270         const sc_p sc = NG_NODE_PRIVATE(node);
271         struct ng_mesg *resp = NULL;
272         int error = 0;
273         struct ng_mesg *msg;
274         
275         NGI_GET_MSG(item, msg);
276         switch (msg->header.typecookie) {
277         case NGM_ASYNC_COOKIE:
278                 switch (msg->header.cmd) {
279                 case NGM_ASYNC_CMD_GET_STATS:
280                         NG_MKRESPONSE(resp, msg, sizeof(sc->stats), M_WAITOK | M_NULLOK);
281                         if (resp == NULL)
282                                 ERROUT(ENOMEM);
283                         *((struct ng_async_stat *) resp->data) = sc->stats;
284                         break;
285                 case NGM_ASYNC_CMD_CLR_STATS:
286                         bzero(&sc->stats, sizeof(sc->stats));
287                         break;
288                 case NGM_ASYNC_CMD_SET_CONFIG:
289                     {
290                         struct ng_async_cfg *const cfg =
291                                 (struct ng_async_cfg *) msg->data;
292                         u_char *buf;
293
294                         if (msg->header.arglen != sizeof(*cfg))
295                                 ERROUT(EINVAL);
296                         if (cfg->amru < NG_ASYNC_MIN_MRU
297                             || cfg->amru > NG_ASYNC_MAX_MRU
298                             || cfg->smru < NG_ASYNC_MIN_MRU
299                             || cfg->smru > NG_ASYNC_MAX_MRU)
300                                 ERROUT(EINVAL);
301                         cfg->enabled = !!cfg->enabled;  /* normalize */
302                         if (cfg->smru > sc->cfg.smru) { /* reallocate buffer */
303                                 buf = kmalloc(ASYNC_BUF_SIZE(cfg->smru),
304                                               M_NETGRAPH_ASYNC,
305                                               M_WAITOK | M_NULLOK);
306                                 if (!buf)
307                                         ERROUT(ENOMEM);
308                                 kfree(sc->abuf, M_NETGRAPH_ASYNC);
309                                 sc->abuf = buf;
310                         }
311                         if (cfg->amru > sc->cfg.amru) { /* reallocate buffer */
312                                 buf = kmalloc(SYNC_BUF_SIZE(cfg->amru),
313                                               M_NETGRAPH_ASYNC,
314                                               M_WAITOK | M_NULLOK);
315                                 if (!buf)
316                                         ERROUT(ENOMEM);
317                                 kfree(sc->sbuf, M_NETGRAPH_ASYNC);
318                                 sc->sbuf = buf;
319                                 sc->amode = MODE_HUNT;
320                                 sc->slen = 0;
321                         }
322                         if (!cfg->enabled) {
323                                 sc->amode = MODE_HUNT;
324                                 sc->slen = 0;
325                         }
326                         sc->cfg = *cfg;
327                         break;
328                     }
329                 case NGM_ASYNC_CMD_GET_CONFIG:
330                         NG_MKRESPONSE(resp, msg, sizeof(sc->cfg), M_WAITOK | M_NULLOK);
331                         if (!resp)
332                                 ERROUT(ENOMEM);
333                         *((struct ng_async_cfg *) resp->data) = sc->cfg;
334                         break;
335                 default:
336                         ERROUT(EINVAL);
337                 }
338                 break;
339         default:
340                 ERROUT(EINVAL);
341         }
342 done:
343         NG_RESPOND_MSG(error, node, item, resp);
344         NG_FREE_MSG(msg);
345         return (error);
346 }
347
348 /*
349  * Shutdown this node
350  */
351 static int
352 nga_shutdown(node_p node)
353 {
354         const sc_p sc = NG_NODE_PRIVATE(node);
355
356         kfree(sc->abuf, M_NETGRAPH_ASYNC);
357         kfree(sc->sbuf, M_NETGRAPH_ASYNC);
358         bzero(sc, sizeof(*sc));
359         kfree(sc, M_NETGRAPH_ASYNC);
360         NG_NODE_SET_PRIVATE(node, NULL);
361         NG_NODE_UNREF(node);
362         return (0);
363 }
364
365 /*
366  * Lose a hook. When both hooks go away, we disappear.
367  */
368 static int
369 nga_disconnect(hook_p hook)
370 {
371         const sc_p sc = NG_NODE_PRIVATE(NG_HOOK_NODE(hook));
372         hook_p *hookp;
373
374         if (hook == sc->async)
375                 hookp = &sc->async;
376         else if (hook == sc->sync)
377                 hookp = &sc->sync;
378         else
379                 panic(__func__);
380         if (!*hookp)
381                 panic("%s 2", __func__);
382         *hookp = NULL;
383         bzero(&sc->stats, sizeof(sc->stats));
384         sc->lasttime = 0;
385         if ((NG_NODE_NUMHOOKS(NG_HOOK_NODE(hook)) == 0)
386         && (NG_NODE_IS_VALID(NG_HOOK_NODE(hook))))
387                 ng_rmnode_self(NG_HOOK_NODE(hook));
388         return (0);
389 }
390
391 /******************************************************************
392                     INTERNAL HELPER STUFF
393 ******************************************************************/
394
395 /*
396  * Encode a byte into the async buffer
397  */
398 static __inline void
399 nga_async_add(const sc_p sc, u_int16_t *fcs, u_int32_t accm, int *len, u_char x)
400 {
401         *fcs = PPP_FCS(*fcs, x);
402         if ((x < 32 && ((1 << x) & accm))
403             || (x == PPP_ESCAPE)
404             || (x == PPP_FLAG)) {
405                 sc->abuf[(*len)++] = PPP_ESCAPE;
406                 x ^= PPP_TRANS;
407         }
408         sc->abuf[(*len)++] = x;
409 }
410
411 /*
412  * Receive incoming synchronous data.
413  */
414 static int
415 nga_rcv_sync(const sc_p sc, item_p item)
416 {
417         struct ifnet *rcvif;
418         int alen, error = 0;
419         struct timeval time;
420         u_int16_t fcs, fcs0;
421         u_int32_t accm;
422         struct mbuf *m;
423
424
425 #define ADD_BYTE(x)     nga_async_add(sc, &fcs, accm, &alen, (x))
426
427         /* Check for bypass mode */
428         if (!sc->cfg.enabled) {
429                 NG_FWD_ITEM_HOOK(error, item, sc->async );
430                 return (error);
431         }
432         NGI_GET_M(item, m);
433
434         rcvif = m->m_pkthdr.rcvif;
435
436         /* Get ACCM; special case LCP frames, which use full ACCM */
437         accm = sc->cfg.accm;
438         if (m->m_pkthdr.len >= 4) {
439                 static const u_char lcphdr[4] = {
440                     PPP_ALLSTATIONS,
441                     PPP_UI,
442                     (u_char)(PPP_LCP >> 8),
443                     (u_char)(PPP_LCP & 0xff)
444                 };
445                 u_char buf[4];
446
447                 m_copydata(m, 0, 4, (caddr_t)buf);
448                 if (bcmp(buf, &lcphdr, 4) == 0)
449                         accm = ~0;
450         }
451
452         /* Check for overflow */
453         if (m->m_pkthdr.len > sc->cfg.smru) {
454                 sc->stats.syncOverflows++;
455                 NG_FREE_M(m);
456                 NG_FREE_ITEM(item);
457                 return (EMSGSIZE);
458         }
459
460         /* Update stats */
461         sc->stats.syncFrames++;
462         sc->stats.syncOctets += m->m_pkthdr.len;
463
464         /* Initialize async encoded version of input mbuf */
465         alen = 0;
466         fcs = PPP_INITFCS;
467
468         /* Add beginning sync flag if it's been long enough to need one */
469         getmicrotime(&time);
470         if (time.tv_sec >= sc->lasttime + 1) {
471                 sc->abuf[alen++] = PPP_FLAG;
472                 sc->lasttime = time.tv_sec;
473         }
474
475         /* Add packet payload */
476         while (m != NULL) {
477                 while (m->m_len > 0) {
478                         ADD_BYTE(*mtod(m, u_char *));
479                         m->m_data++;
480                         m->m_len--;
481                 }
482                 m = m_free(m);
483         }
484
485         /* Add checksum and final sync flag */
486         fcs0 = fcs;
487         ADD_BYTE(~fcs0 & 0xff);
488         ADD_BYTE(~fcs0 >> 8);
489         sc->abuf[alen++] = PPP_FLAG;
490
491         /* Put frame in an mbuf and ship it off */
492         if (!(m = m_devget(sc->abuf, alen, 0, rcvif, NULL))) {
493                 NG_FREE_ITEM(item);
494                 error = ENOBUFS;
495         } else {
496                 NG_FWD_NEW_DATA(error, item, sc->async, m);
497         }
498         return (error);
499 }
500
501 /*
502  * Receive incoming asynchronous data
503  * XXX Technically, we should strip out incoming characters
504  *     that are in our ACCM. Not sure if this is good or not.
505  */
506 static int
507 nga_rcv_async(const sc_p sc, item_p item)
508 {
509         struct ifnet *rcvif;
510         int error;
511         struct mbuf *m;
512
513         if (!sc->cfg.enabled) {
514                 NG_FWD_ITEM_HOOK(error, item,  sc->sync);
515                 return (error);
516         }
517         NGI_GET_M(item, m);
518         rcvif = m->m_pkthdr.rcvif;
519         while (m) {
520                 struct mbuf *n;
521
522                 for (; m->m_len > 0; m->m_data++, m->m_len--) {
523                         u_char  ch = *mtod(m, u_char *);
524
525                         sc->stats.asyncOctets++;
526                         if (ch == PPP_FLAG) {   /* Flag overrides everything */
527                                 int     skip = 0;
528
529                                 /* Check for runts */
530                                 if (sc->slen < 2) {
531                                         if (sc->slen > 0)
532                                                 sc->stats.asyncRunts++;
533                                         goto reset;
534                                 }
535
536                                 /* Verify CRC */
537                                 if (sc->fcs != PPP_GOODFCS) {
538                                         sc->stats.asyncBadCheckSums++;
539                                         goto reset;
540                                 }
541                                 sc->slen -= 2;
542
543                                 /* Strip address and control fields */
544                                 if (sc->slen >= 2
545                                     && sc->sbuf[0] == PPP_ALLSTATIONS
546                                     && sc->sbuf[1] == PPP_UI)
547                                         skip = 2;
548
549                                 /* Check for frame too big */
550                                 if (sc->slen - skip > sc->cfg.amru) {
551                                         sc->stats.asyncOverflows++;
552                                         goto reset;
553                                 }
554
555                                 /* OK, ship it out */
556                                 if ((n = m_devget(sc->sbuf + skip,
557                                            sc->slen - skip, 0, rcvif, NULL))) {
558                                         if (item) { /* sets NULL -> item */
559                                                 NG_FWD_NEW_DATA(error, item,
560                                                         sc->sync, n);
561                                         } else {
562                                                 NG_SEND_DATA_ONLY(error,
563                                                         sc->sync ,n);
564                                         }
565                                 }
566                                 sc->stats.asyncFrames++;
567 reset:
568                                 sc->amode = MODE_NORMAL;
569                                 sc->fcs = PPP_INITFCS;
570                                 sc->slen = 0;
571                                 continue;
572                         }
573                         switch (sc->amode) {
574                         case MODE_NORMAL:
575                                 if (ch == PPP_ESCAPE) {
576                                         sc->amode = MODE_ESC;
577                                         continue;
578                                 }
579                                 break;
580                         case MODE_ESC:
581                                 ch ^= PPP_TRANS;
582                                 sc->amode = MODE_NORMAL;
583                                 break;
584                         case MODE_HUNT:
585                         default:
586                                 continue;
587                         }
588
589                         /* Add byte to frame */
590                         if (sc->slen >= SYNC_BUF_SIZE(sc->cfg.amru)) {
591                                 sc->stats.asyncOverflows++;
592                                 sc->amode = MODE_HUNT;
593                                 sc->slen = 0;
594                         } else {
595                                 sc->sbuf[sc->slen++] = ch;
596                                 sc->fcs = PPP_FCS(sc->fcs, ch);
597                         }
598                 }
599                 m = m_free(m);
600         }
601         if (item)
602                 NG_FREE_ITEM(item);
603         return (0);
604 }
605
606 /*
607  * CRC table
608  *
609  * Taken from RFC 1171 Appendix B
610  */
611 static const u_int16_t fcstab[256] = {
612          0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
613          0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
614          0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
615          0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
616          0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
617          0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
618          0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
619          0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
620          0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
621          0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
622          0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
623          0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
624          0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
625          0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
626          0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
627          0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
628          0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
629          0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
630          0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
631          0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
632          0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
633          0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
634          0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
635          0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
636          0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
637          0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
638          0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
639          0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
640          0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
641          0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
642          0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
643          0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
644 };