kernel/netgraph7: Replace usage of MALLOC/FREE with kmalloc/kfree here too.
[dragonfly.git] / sys / netgraph7 / ng_async.c
CommitLineData
b06ebda0
MD
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 $
5a975a3d 41 * $DragonFly: src/sys/netgraph7/ng_async.c,v 1.2 2008/06/26 23:05:35 dillon Exp $
b06ebda0
MD
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
5a975a3d
MD
57#include "ng_message.h"
58#include "netgraph.h"
59#include "ng_async.h"
60#include "ng_parse.h"
b06ebda0
MD
61
62#include <net/ppp_defs.h>
63
64#ifdef NG_SEPARATE_MALLOC
65MALLOC_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 */
77struct 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};
90typedef 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 */
98static ng_constructor_t nga_constructor;
99static ng_rcvdata_t nga_rcvdata;
100static ng_rcvmsg_t nga_rcvmsg;
101static ng_shutdown_t nga_shutdown;
102static ng_newhook_t nga_newhook;
103static ng_disconnect_t nga_disconnect;
104
105/* Helper stuff */
106static int nga_rcv_sync(const sc_p sc, item_p item);
107static int nga_rcv_async(const sc_p sc, item_p item);
108
109/* Parse type for struct ng_async_cfg */
110static const struct ng_parse_struct_field nga_config_type_fields[]
111 = NG_ASYNC_CONFIG_TYPE_INFO;
112static 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 */
118static const struct ng_parse_struct_field nga_stats_type_fields[]
119 = NG_ASYNC_STATS_TYPE_INFO;
120static 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 */
126static 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 */
159static 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};
170NETGRAPH_INIT(async, &typestruct);
171
172/* CRC table */
173static const u_int16_t fcstab[];
174
175/******************************************************************
176 NETGRAPH NODE METHODS
177******************************************************************/
178
179/*
180 * Initialize a new node
181 */
182static int
183nga_constructor(node_p node)
184{
185 sc_p sc;
186
fc025606
SW
187 sc = kmalloc(sizeof(*sc), M_NETGRAPH_ASYNC,
188 M_WAITOK | M_NULLOK | M_ZERO);
b06ebda0
MD
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;
fc025606
SW
195 sc->abuf = kmalloc(ASYNC_BUF_SIZE(sc->cfg.smru), M_NETGRAPH_ASYNC,
196 M_WAITOK | M_NULLOK);
b06ebda0
MD
197 if (sc->abuf == NULL)
198 goto fail;
fc025606
SW
199 sc->sbuf = kmalloc(SYNC_BUF_SIZE(sc->cfg.amru), M_NETGRAPH_ASYNC,
200 M_WAITOK | M_NULLOK);
b06ebda0 201 if (sc->sbuf == NULL) {
fc025606 202 kfree(sc->abuf, M_NETGRAPH_ASYNC);
b06ebda0 203fail:
fc025606 204 kfree(sc, M_NETGRAPH_ASYNC);
b06ebda0
MD
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 */
215static int
216nga_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 */
252static int
253nga_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 */
267static int
268nga_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:
5a975a3d 280 NG_MKRESPONSE(resp, msg, sizeof(sc->stats), M_WAITOK | M_NULLOK);
b06ebda0
MD
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 */
fc025606
SW
303 buf = kmalloc(ASYNC_BUF_SIZE(cfg->smru),
304 M_NETGRAPH_ASYNC,
305 M_WAITOK | M_NULLOK);
b06ebda0
MD
306 if (!buf)
307 ERROUT(ENOMEM);
fc025606 308 kfree(sc->abuf, M_NETGRAPH_ASYNC);
b06ebda0
MD
309 sc->abuf = buf;
310 }
311 if (cfg->amru > sc->cfg.amru) { /* reallocate buffer */
fc025606
SW
312 buf = kmalloc(SYNC_BUF_SIZE(cfg->amru),
313 M_NETGRAPH_ASYNC,
314 M_WAITOK | M_NULLOK);
b06ebda0
MD
315 if (!buf)
316 ERROUT(ENOMEM);
fc025606 317 kfree(sc->sbuf, M_NETGRAPH_ASYNC);
b06ebda0
MD
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:
5a975a3d 330 NG_MKRESPONSE(resp, msg, sizeof(sc->cfg), M_WAITOK | M_NULLOK);
b06ebda0
MD
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 }
342done:
343 NG_RESPOND_MSG(error, node, item, resp);
344 NG_FREE_MSG(msg);
345 return (error);
346}
347
348/*
349 * Shutdown this node
350 */
351static int
352nga_shutdown(node_p node)
353{
354 const sc_p sc = NG_NODE_PRIVATE(node);
355
fc025606
SW
356 kfree(sc->abuf, M_NETGRAPH_ASYNC);
357 kfree(sc->sbuf, M_NETGRAPH_ASYNC);
b06ebda0 358 bzero(sc, sizeof(*sc));
fc025606 359 kfree(sc, M_NETGRAPH_ASYNC);
b06ebda0
MD
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 */
368static int
369nga_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 */
398static __inline void
399nga_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 */
414static int
415nga_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 */
506static int
507nga_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++;
567reset:
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 */
611static 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};