4 * The contents of this file are subject to the terms of the
5 * Common Development and Distribution License, Version 1.0 only
6 * (the "License"). You may not use this file except in compliance
9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
10 * or http://www.opensolaris.org/os/licensing.
11 * See the License for the specific language governing permissions
12 * and limitations under the License.
14 * When distributing Covered Code, include this CDDL HEADER in each
15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
16 * If applicable, add the following below this CDDL HEADER, with the
17 * fields enclosed by brackets "[]" replaced with your own identifying
18 * information: Portions Copyright [yyyy] [name of copyright owner]
23 * Copyright (c) 1999 by Sun Microsystems, Inc.
24 * All rights reserved.
27 #pragma ident "%Z%%M% %I% %E% SMI"
30 * Library of support routines for UDFS data structures and conversions.
36 #include <sys/mutex.h>
37 #include <sys/vnode.h>
38 #include <sys/fs/udf_volume.h>
43 "invalid checksum", /* TAGERR_CKSUM */
44 "unknown tag id", /* TAGERR_ID */
45 "invalid version", /* TAGERR_VERSION */
46 "CRC length too large", /* TAGERR_TOOBIG */
47 "invalid CRC", /* TAGERR_CRC */
48 "location mismatch" /* TAGERR_LOC */
52 #define SWAP16(x) (((x) & 0xff) << 8 | ((x) >> 8) & 0xff)
53 #define SWAP32(x) (((x) & 0xff) << 24 | ((x) & 0xff00) << 8 | \
54 ((x) & 0xff0000) >> 8 | ((x) >> 24) & 0xff)
55 #define SWAP64(x) (SWAP32((x) >> 32) & 0xffffffff | SWAP32(x) << 32)
62 static void ud_swap_ext_ad(struct extent_ad
*);
63 static void ud_swap_tstamp(struct tstamp
*);
64 static void ud_swap_icb_tag(struct icb_tag
*);
65 void ud_swap_short_ad(struct short_ad
*);
66 void ud_swap_long_ad(struct long_ad
*);
67 static void ud_swap_pri_vol_desc(struct pri_vol_desc
*);
68 static void ud_swap_vdp(struct vol_desc_ptr
*);
69 static void ud_swap_iuvd(struct iuvd_desc
*);
70 static void ud_swap_avdp(struct anch_vol_desc_ptr
*);
71 static void ud_swap_part_desc(struct part_desc
*);
72 static void ud_swap_log_desc(struct log_vol_desc
*);
73 static void ud_swap_unall_desc(struct unall_spc_desc
*);
74 static void ud_swap_lvint(struct log_vol_int_desc
*);
75 static void ud_swap_fileset_desc(struct file_set_desc
*);
76 static void ud_swap_term_desc(struct term_desc
*);
77 static void ud_swap_file_id(struct file_id
*);
78 static void ud_swap_file_entry(struct file_entry
*, int);
79 static void ud_swap_alloc_ext(struct alloc_ext_desc
*);
80 static void ud_swap_tstamp(tstamp_t
*);
81 static void ud_swap_space_bitmap(struct space_bmap_desc
*);
82 static uint16_t crc16(uint8_t *, int32_t, int32_t);
84 extern uint32_t ecma_version
;
87 maketag(struct tag
*itp
, struct tag
*otp
)
93 bcopy((unsigned char *)(itp
+ 1), (unsigned char *)(otp
+ 1),
98 switch (itp
->tag_id
) {
100 ud_swap_pri_vol_desc((struct pri_vol_desc
*)otp
);
102 case UD_ANCH_VOL_DESC
:
103 ud_swap_avdp((struct anch_vol_desc_ptr
*)otp
);
105 case UD_VOL_DESC_PTR
:
106 ud_swap_vdp((struct vol_desc_ptr
*)otp
);
108 case UD_IMPL_USE_DESC
:
109 ud_swap_iuvd((struct iuvd_desc
*)otp
);
112 ud_swap_part_desc((struct part_desc
*)otp
);
114 case UD_LOG_VOL_DESC
:
115 ud_swap_log_desc((struct log_vol_desc
*)otp
);
117 case UD_UNALL_SPA_DESC
:
118 ud_swap_unall_desc((struct unall_spc_desc
*)otp
);
121 ud_swap_term_desc((struct term_desc
*)otp
);
125 ud_swap_lvint((struct log_vol_int_desc
*)otp
);
127 case UD_FILE_SET_DESC
:
128 ud_swap_fileset_desc((struct file_set_desc
*)otp
);
130 case UD_FILE_ID_DESC
:
131 ud_swap_file_id((struct file_id
*)otp
);
133 case UD_ALLOC_EXT_DESC
:
135 case UD_INDIRECT_ENT
:
137 case UD_TERMINAL_ENT
:
141 ud_swap_file_entry((struct file_entry
*)otp
, 0);
143 case UD_EXT_ATTR_HDR
:
145 case UD_UNALL_SPA_ENT
:
147 case UD_SPA_BMAP_DESC
:
148 ud_swap_space_bitmap((struct space_bmap_desc
*)otp
);
150 case UD_PART_INT_DESC
:
153 otp
->tag_id
= SWAP16(itp
->tag_id
);
154 otp
->tag_desc_ver
= SWAP16(itp
->tag_desc_ver
);
155 otp
->tag_cksum
= otp
->tag_res
= 0;
156 otp
->tag_sno
= SWAP16(itp
->tag_sno
);
157 otp
->tag_crc
= SWAP16(crc16((unsigned char *)(otp
+1),
158 itp
->tag_crc_len
, 0));
159 otp
->tag_crc_len
= SWAP16(itp
->tag_crc_len
);
160 otp
->tag_loc
= SWAP32(itp
->tag_loc
);
163 * Now do checksum on tag itself
165 cp
= (unsigned char *)otp
;
167 for (i
= 0; i
< sizeof (*otp
); i
++)
169 otp
->tag_cksum
= sum
;
174 verifytag(struct tag
*tp
, uint32_t loc
, struct tag
*otp
, int expect
)
177 uint32_t id
, vers
, length
, tloc
;
180 sum
= -tp
->tag_cksum
;
181 cp
= (unsigned char *)tp
;
182 for (i
= 0; i
< sizeof (*tp
); i
++)
184 if ((sum
& 0xff) != tp
->tag_cksum
)
185 return (TAGERR_CKSUM
);
186 id
= SWAP16(tp
->tag_id
);
187 if (id
> 9 && id
< 256 || id
> 266 || (expect
> 0 && id
!= expect
))
189 vers
= SWAP16(tp
->tag_desc_ver
);
190 if (vers
> ecma_version
)
191 return (TAGERR_VERSION
);
192 length
= SWAP16(tp
->tag_crc_len
);
193 if (length
> MAXBSIZE
)
194 return (TAGERR_TOOBIG
);
195 if (crc16((unsigned char *)(tp
+1), length
, SWAP16(tp
->tag_crc
)) != 0)
197 tloc
= SWAP32(tp
->tag_loc
);
198 if ((int)loc
!= -1 && tloc
!= loc
)
203 otp
->tag_desc_ver
= vers
;
204 otp
->tag_cksum
= tp
->tag_cksum
;
206 otp
->tag_sno
= SWAP16(tp
->tag_sno
);
207 otp
->tag_crc
= SWAP16(tp
->tag_crc
);
208 otp
->tag_crc_len
= length
;
212 bcopy((unsigned char *)(tp
+ 1), (unsigned char *)(otp
+ 1),
215 switch (otp
->tag_id
) {
216 case UD_PRI_VOL_DESC
:
217 ud_swap_pri_vol_desc((struct pri_vol_desc
*)otp
);
219 case UD_ANCH_VOL_DESC
:
220 ud_swap_avdp((struct anch_vol_desc_ptr
*)otp
);
222 case UD_VOL_DESC_PTR
:
223 ud_swap_vdp((struct vol_desc_ptr
*)otp
);
225 case UD_IMPL_USE_DESC
:
226 ud_swap_iuvd((struct iuvd_desc
*)otp
);
229 ud_swap_part_desc((struct part_desc
*)otp
);
231 case UD_LOG_VOL_DESC
:
232 ud_swap_log_desc((struct log_vol_desc
*)otp
);
234 case UD_UNALL_SPA_DESC
:
235 ud_swap_unall_desc((struct unall_spc_desc
*)otp
);
238 ud_swap_term_desc((struct term_desc
*)otp
);
242 ud_swap_lvint((struct log_vol_int_desc
*)otp
);
244 case UD_FILE_SET_DESC
:
245 ud_swap_fileset_desc((struct file_set_desc
*)otp
);
247 case UD_FILE_ID_DESC
:
248 ud_swap_file_id((struct file_id
*)otp
);
250 case UD_ALLOC_EXT_DESC
:
251 ud_swap_alloc_ext((struct alloc_ext_desc
*)otp
);
253 case UD_INDIRECT_ENT
:
255 case UD_TERMINAL_ENT
:
259 ud_swap_file_entry((struct file_entry
*)otp
, 1);
261 case UD_EXT_ATTR_HDR
:
263 case UD_UNALL_SPA_ENT
:
265 case UD_SPA_BMAP_DESC
:
266 ud_swap_space_bitmap((struct space_bmap_desc
*)otp
);
268 case UD_PART_INT_DESC
:
275 ud_swap_ext_ad(struct extent_ad
*p
)
277 p
->ext_len
= SWAP32(p
->ext_len
);
278 p
->ext_loc
= SWAP32(p
->ext_loc
);
284 ud_swap_regid(struct regid
*p
)
289 ud_swap_icb_tag(struct icb_tag
*p
)
291 p
->itag_prnde
= SWAP32(p
->itag_prnde
);
292 p
->itag_strategy
= SWAP16(p
->itag_strategy
);
293 p
->itag_param
= SWAP16(p
->itag_param
);
294 p
->itag_max_ent
= SWAP16(p
->itag_max_ent
);
295 p
->itag_lb_loc
= SWAP32(p
->itag_lb_loc
);
296 p
->itag_lb_prn
= SWAP16(p
->itag_lb_prn
);
297 p
->itag_flags
= SWAP16(p
->itag_flags
);
301 ud_swap_short_ad(struct short_ad
*p
)
303 p
->sad_ext_len
= SWAP32(p
->sad_ext_len
);
304 p
->sad_ext_loc
= SWAP32(p
->sad_ext_loc
);
308 ud_swap_long_ad(struct long_ad
*p
)
310 p
->lad_ext_len
= SWAP32(p
->lad_ext_len
);
311 p
->lad_ext_loc
= SWAP32(p
->lad_ext_loc
);
312 p
->lad_ext_prn
= SWAP16(p
->lad_ext_prn
);
316 ud_swap_pri_vol_desc(struct pri_vol_desc
*p
)
318 p
->pvd_vdsn
= SWAP32(p
->pvd_vdsn
);
319 p
->pvd_pvdn
= SWAP32(p
->pvd_pvdn
);
320 p
->pvd_vsn
= SWAP16(p
->pvd_vsn
);
321 p
->pvd_mvsn
= SWAP16(p
->pvd_mvsn
);
322 p
->pvd_il
= SWAP16(p
->pvd_il
);
323 p
->pvd_mil
= SWAP16(p
->pvd_mil
);
324 p
->pvd_csl
= SWAP32(p
->pvd_csl
);
325 p
->pvd_mcsl
= SWAP32(p
->pvd_mcsl
);
326 ud_swap_ext_ad(&p
->pvd_vol_abs
);
327 ud_swap_ext_ad(&p
->pvd_vcn
);
328 ud_swap_regid(&p
->pvd_appl_id
);
329 ud_swap_tstamp(&p
->pvd_time
);
330 ud_swap_regid(&p
->pvd_ii
);
331 p
->pvd_pvdsl
= SWAP32(p
->pvd_pvdsl
);
332 p
->pvd_flags
= SWAP16(p
->pvd_flags
);
336 ud_swap_iuvd(struct iuvd_desc
*p
)
338 p
->iuvd_vdsn
= SWAP32(p
->iuvd_vdsn
);
339 ud_swap_regid(&p
->iuvd_ii
);
340 ud_swap_regid(&p
->iuvd_iid
);
344 ud_swap_vdp(struct vol_desc_ptr
*p
)
346 p
->vdp_vdsn
= SWAP32(p
->vdp_vdsn
);
347 ud_swap_ext_ad(&p
->vdp_nvdse
);
351 ud_swap_avdp(struct anch_vol_desc_ptr
*p
)
353 ud_swap_ext_ad(&p
->avd_main_vdse
);
354 ud_swap_ext_ad(&p
->avd_res_vdse
);
358 ud_swap_part_desc(struct part_desc
*p
)
360 struct phdr_desc
*php
;
362 p
->pd_vdsn
= SWAP32(p
->pd_vdsn
);
363 p
->pd_pflags
= SWAP16(p
->pd_pflags
);
364 p
->pd_pnum
= SWAP16(p
->pd_pnum
);
365 ud_swap_regid(&p
->pd_pcontents
);
366 p
->pd_acc_type
= SWAP32(p
->pd_acc_type
);
367 p
->pd_part_start
= SWAP32(p
->pd_part_start
);
368 p
->pd_part_length
= SWAP32(p
->pd_part_length
);
369 ud_swap_regid(&p
->pd_ii
);
370 if (strncmp(p
->pd_pcontents
.reg_id
, "+NSR", 4) == 0) {
372 php
= (struct phdr_desc
*)p
->pd_pc_use
;
373 ud_swap_short_ad(&php
->phdr_ust
);
374 ud_swap_short_ad(&php
->phdr_usb
);
375 ud_swap_short_ad(&php
->phdr_it
);
376 ud_swap_short_ad(&php
->phdr_fst
);
377 ud_swap_short_ad(&php
->phdr_fsb
);
382 ud_swap_log_desc(struct log_vol_desc
*p
)
384 p
->lvd_vdsn
= SWAP32(p
->lvd_vdsn
);
385 p
->lvd_log_bsize
= SWAP32(p
->lvd_log_bsize
);
386 ud_swap_regid(&p
->lvd_dom_id
);
387 ud_swap_long_ad(&p
->lvd_lvcu
);
388 p
->lvd_mtbl_len
= SWAP32(p
->lvd_mtbl_len
);
389 p
->lvd_num_pmaps
= SWAP32(p
->lvd_num_pmaps
);
390 ud_swap_regid(&p
->lvd_ii
);
391 ud_swap_ext_ad(&p
->lvd_int_seq_ext
);
395 ud_swap_unall_desc(struct unall_spc_desc
*p
)
397 p
->ua_vdsn
= SWAP32(p
->ua_vdsn
);
398 p
->ua_nad
= SWAP32(p
->ua_nad
);
402 ud_swap_lvint(struct log_vol_int_desc
*p
)
404 struct lvid_iu
*lvup
;
406 ud_swap_tstamp(&p
->lvid_tstamp
);
407 p
->lvid_int_type
= SWAP32(p
->lvid_int_type
);
408 ud_swap_ext_ad(&p
->lvid_nie
);
409 p
->lvid_npart
= SWAP32(p
->lvid_npart
);
410 p
->lvid_liu
= SWAP32(p
->lvid_liu
);
411 p
->lvid_uniqid
= SWAP64(p
->lvid_uniqid
);
412 p
->lvid_fst
[0] = SWAP32(p
->lvid_fst
[0]);
413 p
->lvid_fst
[1] = SWAP32(p
->lvid_fst
[1]);
415 lvup
= (struct lvid_iu
*)&p
->lvid_fst
[2];
416 ud_swap_regid(&lvup
->lvidiu_regid
);
417 lvup
->lvidiu_nfiles
= SWAP32(lvup
->lvidiu_nfiles
);
418 lvup
->lvidiu_ndirs
= SWAP32(lvup
->lvidiu_ndirs
);
419 lvup
->lvidiu_mread
= SWAP16(lvup
->lvidiu_mread
);
420 lvup
->lvidiu_mwrite
= SWAP16(lvup
->lvidiu_mwrite
);
421 lvup
->lvidiu_maxwr
= SWAP16(lvup
->lvidiu_maxwr
);
425 ud_swap_fileset_desc(struct file_set_desc
*p
)
427 ud_swap_tstamp(&p
->fsd_time
);
428 p
->fsd_ilevel
= SWAP16(p
->fsd_ilevel
);
429 p
->fsd_mi_level
= SWAP16(p
->fsd_mi_level
);
430 p
->fsd_cs_list
= SWAP32(p
->fsd_cs_list
);
431 p
->fsd_mcs_list
= SWAP32(p
->fsd_mcs_list
);
432 p
->fsd_fs_no
= SWAP32(p
->fsd_fs_no
);
433 p
->fsd_fsd_no
= SWAP32(p
->fsd_fsd_no
);
434 ud_swap_long_ad(&p
->fsd_root_icb
);
435 ud_swap_regid(&p
->fsd_did
);
436 ud_swap_long_ad(&p
->fsd_next
);
441 ud_swap_term_desc(struct term_desc
*p
)
446 ud_swap_file_id(struct file_id
*p
)
448 p
->fid_ver
= SWAP16(p
->fid_ver
);
449 ud_swap_long_ad(&p
->fid_icb
);
450 p
->fid_iulen
= SWAP16(p
->fid_iulen
);
454 ud_swap_alloc_ext(struct alloc_ext_desc
*p
)
456 p
->aed_rev_ael
= SWAP32(p
->aed_rev_ael
);
457 p
->aed_len_aed
= SWAP32(p
->aed_len_aed
);
461 ud_swap_space_bitmap(struct space_bmap_desc
*p
)
463 p
->sbd_nbits
= SWAP32(p
->sbd_nbits
);
464 p
->sbd_nbytes
= SWAP32(p
->sbd_nbytes
);
468 ud_swap_file_entry(struct file_entry
*p
, int32_t rdflag
)
474 /* Do Extended Attributes and Allocation Descriptors */
476 p
->fe_len_adesc
= SWAP32(p
->fe_len_adesc
);
477 p
->fe_len_ear
= SWAP32(p
->fe_len_ear
);
478 ud_swap_icb_tag(&p
->fe_icb_tag
);
480 switch (p
->fe_icb_tag
.itag_flags
& 0x3) {
481 case ICB_FLAG_SHORT_AD
:
483 sap
= (short_ad_t
*)(p
->fe_spec
+ p
->fe_len_ear
);
484 for (i
= 0; i
< p
->fe_len_adesc
/ sizeof (short_ad_t
);
486 ud_swap_short_ad(sap
);
488 case ICB_FLAG_LONG_AD
:
490 lap
= (long_ad_t
*)(p
->fe_spec
+ p
->fe_len_ear
);
491 for (i
= 0; i
< p
->fe_len_adesc
/ sizeof (long_ad_t
);
493 ud_swap_long_ad(lap
);
495 case ICB_FLAG_EXT_AD
:
497 case ICB_FLAG_ONE_AD
:
500 p
->fe_uid
= SWAP32(p
->fe_uid
);
501 p
->fe_gid
= SWAP32(p
->fe_gid
);
502 p
->fe_perms
= SWAP32(p
->fe_perms
);
503 p
->fe_lcount
= SWAP16(p
->fe_lcount
);
504 p
->fe_rec_len
= SWAP32(p
->fe_rec_len
);
505 p
->fe_info_len
= SWAP64(p
->fe_info_len
);
506 p
->fe_lbr
= SWAP64(p
->fe_lbr
);
507 ud_swap_tstamp(&p
->fe_acc_time
);
508 ud_swap_tstamp(&p
->fe_mod_time
);
509 ud_swap_tstamp(&p
->fe_attr_time
);
510 p
->fe_ckpoint
= SWAP32(p
->fe_ckpoint
);
511 ud_swap_long_ad(&p
->fe_ea_icb
);
512 ud_swap_regid(&p
->fe_impl_id
);
513 p
->fe_uniq_id
= SWAP64(p
->fe_uniq_id
);
515 p
->fe_len_adesc
= SWAP32(p
->fe_len_adesc
);
516 p
->fe_len_ear
= SWAP32(p
->fe_len_ear
);
517 ud_swap_icb_tag(&p
->fe_icb_tag
);
522 ud_swap_tstamp(tstamp_t
*tp
)
524 tp
->ts_tzone
= SWAP16(tp
->ts_tzone
);
525 tp
->ts_year
= SWAP16(tp
->ts_year
);
529 setcharspec(struct charspec
*cp
, int32_t type
, uint8_t *info
)
532 bzero(cp
->cs_info
, sizeof (cp
->cs_info
));
533 (void) strncpy(cp
->cs_info
, (int8_t *)info
, sizeof (cp
->cs_info
));
536 static unsigned short crctab
[] = {
537 0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
538 0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
539 0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
540 0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
541 0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
542 0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
543 0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
544 0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
545 0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
546 0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
547 0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
548 0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
549 0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
550 0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
551 0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
552 0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
553 0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
554 0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
555 0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
556 0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
557 0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
558 0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
559 0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
560 0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
561 0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
562 0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
563 0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
564 0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
565 0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
566 0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
567 0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
568 0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
572 crc16(uint8_t *buf
, int32_t size
, int32_t rem
)
577 crc
= (crc
<< 8) ^ crctab
[((crc
>> 8) ^ *buf
++) & 0xff];
578 return ((crc
^ rem
) & 0xffff);