# ffs.h

    00001 /*
    00002 ** The Sleuth Kit
    00003 **
    00004 ** $Date: 2007/04/19 19:01:32 $
    00005 **
    00006 ** Brian Carrier [carrier@sleuthkit.org]
    00007 ** Copyright (c) 2003-2005 Brian Carrier.  All rights reserved
    00008 **
    00009 ** TASK
    00010 ** Copyright (c) 2002 @stake Inc.  All rights reserved
    00011 */
    00012 #ifndef _FFS_H
    00013 #define _FFS_H
    00014
    00015 #ifdef __cplusplus
    00016 extern "C" {
    00017 #endif
    00018
    00019     extern uint8_t
    00020         ffs_dent_walk(TSK_FS_INFO *, INUM_T, TSK_FS_DENT_FLAG_ENUM,
    00021         TSK_FS_DENT_TYPE_WALK_CB, void *);
    00022
    00023     typedef uint32_t FFS_GRPNUM_T;
    00024 #define PRI_FFSGRP PRIu32
    00025
    00026 /*
    00027 ** CONSTANTS
    00028 **/
    00029 #define FFS_FIRSTINO    0       /* 0 & 1 are reserved (1 was bad blocks) */
    00030 #define FFS_ROOTINO             2       /* location of root directory inode */
    00031 #define FFS_NDADDR              12
    00032 #define FFS_NIADDR              3
    00033
    00034 #define UFS1_SBOFF      8192
    00035 #define UFS2_SBOFF      65536
    00036 #define UFS2_SBOFF2     262144
    00037
    00038 #define UFS1_FS_MAGIC   0x011954
    00039 #define UFS2_FS_MAGIC   0x19540119
    00040
    00041 #define FFS_MAXNAMLEN   255
    00042 #define FFS_MAXPATHLEN  1024
    00043 #define FFS_DIRBLKSIZ   512
    00044
    00045
    00046
    00047 #define FFS_DEV_BSIZE   512
    00048
    00049
    00050     typedef struct {
    00051         uint8_t dir_num[4];
    00052         uint8_t blk_free[4];
    00053         uint8_t ino_free[4];
    00054         uint8_t frag_free[4];
    00055     } ffs_csum1;
    00056
    00057     typedef struct {
    00058         uint8_t dir_num[8];
    00059         uint8_t blk_free[8];
    00060         uint8_t ino_free[8];
    00061         uint8_t frag_free[8];
    00062         uint8_t clust_free[8];
    00063         uint8_t f1[24];
    00064     } ffs_csum2;
    00065
    00066
    00067
    00068 /*
    00069  * Super Block Structure
    00070  */
    00071
    00072 // UFS 1
    00073     typedef struct {
    00074         uint8_t f1[8];
    00075         /* Offsets in each cylinder group */
    00076         uint8_t sb_off[4];      /* s32 */
    00077         uint8_t gd_off[4];      /* s32 */
    00078         uint8_t ino_off[4];     /* s32 */
    00079         uint8_t dat_off[4];     /* s32 */
    00080
    00081         /* How much the base of the admin data in each cyl group changes */
    00082         uint8_t cg_delta[4];    /* s32 */
    00083         uint8_t cg_cyc_mask[4]; /* s32 */
    00084
    00085         uint8_t wtime[4];       /* u32 : last written time */
    00086         uint8_t frag_num[4];    /* s32 - number of fragments in FS */
    00087         uint8_t data_frag_num[4];       /* s32 - number of frags not being used for admin data */
    00088         uint8_t cg_num[4];      /* s32 - number of cyl grps in FS */
    00089
    00090         uint8_t bsize_b[4];     /* s32 - size of block */
    00091         uint8_t fsize_b[4];     /* s32 - size of fragment */
    00092         uint8_t bsize_frag[4];  /* s32 - num of frag in block */
    00093         uint8_t f5[36];
    00094         uint8_t fs_fragshift[4];        /* s32 */
    00095         uint8_t f6[20];
    00096         uint8_t fs_inopb[4];    /* s32 */
    00097         uint8_t f7[20];
    00098         uint8_t fs_id[8];
    00099         uint8_t cg_saddr[4];    /* s32 */
    00100         uint8_t cg_ssize_b[4];  /* s32 */
    00101         uint8_t fs_cgsize[4];   /* s32 */
    00102         uint8_t f7c[12];
    00103         uint8_t fs_ncyl[4];     /* s32 */
    00104         uint8_t fs_cpg[4];      /* s32 */
    00105         uint8_t cg_inode_num[4];        /* s32 */
    00106         uint8_t cg_frag_num[4]; /* s32 */
    00107
    00108         ffs_csum1 cstotal;
    00109
    00110         uint8_t fs_fmod;
    00111         uint8_t fs_clean;
    00112         uint8_t fs_ronly;
    00113         uint8_t fs_flags;
    00114         uint8_t last_mnt[512];
    00115         uint8_t f8[648];
    00116         uint8_t magic[4];       /* s32 */
    00117         uint8_t f9[160];        /* filler so it is a multiple of 512 */
    00118     } ffs_sb1;
    00119
    00120
    00121 // UFS 2
    00122     typedef struct {
    00123         uint8_t f0[8];
    00124         /* Offsets in each cylinder group */
    00125         uint8_t sb_off[4];      /* s32 */
    00126         uint8_t gd_off[4];      /* s32 */
    00127         uint8_t ino_off[4];     /* s32 */
    00128         uint8_t dat_off[4];     /* s32 */
    00129
    00130         uint8_t f1[20];         /* s32 */
    00131
    00132         uint8_t cg_num[4];      /* s32 - number of cyl grps in FS */
    00133         uint8_t bsize_b[4];     /* s32 - size of block */
    00134         uint8_t fsize_b[4];     /* s32 - size of fragment */
    00135         uint8_t bsize_frag[4];  /* s32 - num of frag in block */
    00136         uint8_t f2[36];
    00137         uint8_t fs_fragshift[4];        /* s32 */
    00138         uint8_t f3[20];
    00139         uint8_t fs_inopb[4];    /* s32 */
    00140         uint8_t f4[32];
    00141         uint8_t cg_ssize_b[4];  /* s32 */
    00142         uint8_t fs_cgsize[4];   /* s32 */
    00143         uint8_t f5[20];
    00144         uint8_t cg_inode_num[4];        /* s32 */
    00145         uint8_t cg_frag_num[4]; /* s32 - fs_fpg */
    00146
    00147         uint8_t f6[16];
    00148         uint8_t fs_fmod;
    00149         uint8_t fs_clean;
    00150         uint8_t fs_ronly;
    00151         uint8_t f7;
    00152         uint8_t last_mnt[468];
    00153         uint8_t volname[32];
    00154         uint8_t swuid[8];
    00155         uint8_t f8[288];
    00156
    00157         ffs_csum2 cstotal;
    00158
    00159         uint8_t wtime[8];       /* u32 : last written time */
    00160         uint8_t frag_num[8];    /* s32 - number of fragments in FS */
    00161         uint8_t blk_num[8];     /* s32 - number of blocks in FS */
    00162         uint8_t cg_saddr[8];
    00163
    00164         uint8_t f9[208];
    00165         uint8_t fs_flags[4];
    00166         uint8_t f10[56];
    00167
    00168         uint8_t magic[4];       /* s32 */
    00169         uint8_t f11[160];       /* filler so it is a multiple of 512 */
    00170     } ffs_sb2;
    00171
    00172
    00173 #define FFS_SB_FLAG_UNCLEAN     0x01
    00174 #define FFS_SB_FLAG_SOFTDEP     0x02
    00175 #define FFS_SB_FLAG_NEEDFSCK    0x04
    00176 #define FFS_SB_FLAG_INDEXDIR    0x08
    00177 #define FFS_SB_FLAG_ACL         0x10
    00178 #define FFS_SB_FLAG_MULTILABEL  0x20
    00179 #define FFS_SB_FLAG_UPDATED     0x80
    00180
    00181
    00182 /* How the file system is optimized */
    00183 #define FFS_SB_OPT_TIME         0
    00184 #define FFS_SB_OPT_SPACE        1
    00185
    00186
    00187
    00188 /*
    00189  * Cylinder Group Descriptor
    00190  *
    00191  * UFS1 and UFS2 are the same for the data that we care about unless we
    00192  * want the wtime for 'fsstat'.
    00193  */
    00194     typedef struct {
    00195         uint8_t f1[4];
    00196         uint8_t magic[4];       /* 0x090255 */
    00197         uint8_t wtime[4];       /* last written time */
    00198         uint8_t cg_cgx[4];      /* s32 - my group number */
    00199         uint8_t cyl_num[2];     /* number of cyl in this group */
    00200         uint8_t ino_num[2];     /* number of inodes in this group */
    00201         uint8_t frag_num[4];    /* number of fragments in this group */
    00202         ffs_csum1 cs;
    00203         uint8_t last_alloc_blk[4];      /* last allocated blk relative to start */
    00204         uint8_t last_alloc_frag[4];     /* last alloc frag relative to start */
    00205         uint8_t last_alloc_ino[4];
    00206         uint8_t avail_frag[8][4];
    00207         uint8_t f2b[8];
    00208         uint8_t cg_iusedoff[4]; /* s32 */
    00209         uint8_t cg_freeoff[4];  /* s32 */
    00210         uint8_t f3[72];
    00211     } ffs_cgd;
    00212
    00213     typedef struct {
    00214         uint8_t f1[4];
    00215         uint8_t magic[4];       /* 0x090255 */
    00216         uint8_t f2[4];
    00217         uint8_t cg_cgx[4];      /* s32 - my group number */
    00218         uint8_t f2a[4];         /* number of cyl in this group */
    00219         uint8_t frag_num[4];    /* number of fragments in this group */
    00220         ffs_csum1 cs;
    00221         uint8_t last_alloc_blk[4];      /* last allocated blk relative to start */
    00222         uint8_t last_alloc_frag[4];     /* last alloc frag relative to start */
    00223         uint8_t last_alloc_ino[4];
    00224         uint8_t avail_frag[8][4];
    00225         uint8_t f2b[8];
    00226         uint8_t cg_iusedoff[4]; /* s32 */
    00227         uint8_t cg_freeoff[4];  /* s32 */
    00228
    00229         uint8_t cg_nextfreeoff[4];
    00230         uint8_t cg_clustersumoff[4];
    00231         uint8_t cg_clusteroff[4];
    00232         uint8_t cg_nclustersblks[4];
    00233         uint8_t cg_niblk[4];
    00234         uint8_t cg_initediblk[4];
    00235         uint8_t f3a[12];
    00236         uint8_t wtime[8];
    00237         uint8_t f3[24];
    00238     } ffs_cgd2;
    00239
    00240
    00241 /*
    00242  * inode
    00243  */
    00244
    00245 /* ffs_inode1: OpenBSD & FreeBSD etc. */
    00246     typedef struct {
    00247         uint8_t di_mode[2];     /* u16 */
    00248         uint8_t di_nlink[2];    /* s16 */
    00249         uint8_t f1[4];
    00250         uint8_t di_size[8];     /* u64 */
    00251         uint8_t di_atime[4];    /* s32 */
    00252         uint8_t di_atimensec[4];
    00253         uint8_t di_mtime[4];    /* s32 */
    00254         uint8_t di_mtimensec[4];
    00255         uint8_t di_ctime[4];    /* s32 */
    00256         uint8_t di_ctimensec[4];
    00257         uint8_t di_db[12][4];   /* s32 */
    00258         uint8_t di_ib[3][4];    /* s32 */
    00259         uint8_t f5[8];
    00260         uint8_t gen[4];
    00261         uint8_t di_uid[4];      /* u32 */
    00262         uint8_t di_gid[4];      /* u32 */
    00263         uint8_t f6[8];
    00264     } ffs_inode1;
    00265
    00266 /* ffs_inode1b: Solaris */
    00267     typedef struct {
    00268         uint8_t di_mode[2];     /* u16 */
    00269         uint8_t di_nlink[2];    /* s16 */
    00270         uint8_t f1[4];
    00271         uint8_t di_size[8];     /* u64 */
    00272         uint8_t di_atime[4];    /* s32 */
    00273         uint8_t f2[4];
    00274         uint8_t di_mtime[4];    /* s32 */
    00275         uint8_t f3[4];
    00276         uint8_t di_ctime[4];    /* s32 */
    00277         uint8_t f4[4];
    00278         uint8_t di_db[12][4];   /* s32 */
    00279         uint8_t di_ib[3][4];    /* s32 */
    00280         uint8_t f5[16];
    00281         uint8_t di_uid[4];      /* u32 */
    00282         uint8_t di_gid[4];      /* u32 */
    00283         uint8_t f6[4];
    00284     } ffs_inode1b;
    00285
    00286     typedef struct {
    00287         uint8_t di_mode[2];     /* u16 */
    00288         uint8_t di_nlink[2];    /* s16 */
    00289         uint8_t di_uid[4];
    00290         uint8_t di_gid[4];
    00291         uint8_t di_blksize[4];  /* u32 inode block size */
    00292         uint8_t di_size[8];     /* u64 */
    00293         uint8_t di_blocks[8];   /* u64 - bytes held */
    00294         uint8_t di_atime[8];    /* s64 */
    00295         uint8_t di_mtime[8];    /* s64 */
    00296         uint8_t di_ctime[8];    /* s64 */
    00297         uint8_t di_crtime[8];   /* s64 */
    00298         uint8_t di_mtimensec[4];        /* s32 */
    00299         uint8_t di_atimensec[4];
    00300         uint8_t di_ctimensec[4];
    00301         uint8_t di_crtimensec[4];
    00302         uint8_t di_gen[4];      /* s32 generation number */
    00303         uint8_t di_kflags[4];   /* u32 kernel flags */
    00304         uint8_t di_flags[4];    /* u32 flags */
    00305         uint8_t di_extsize[4];  /* s32 size of ext attributes block */
    00306         uint8_t di_extb[2][8];  /* Address of ext attribute blocks */
    00307         uint8_t di_db[12][8];   /* s32 */
    00308         uint8_t di_ib[3][8];    /* s32 */
    00309         uint8_t f2[24];         /* s32 */
    00310     } ffs_inode2;
    00311
    00312 #define FFS_IN_FMT       0170000        /* Mask of file type. */
    00313 #define FFS_IN_FIFO      0010000        /* Named pipe (fifo). */
    00314 #define FFS_IN_CHR       0020000        /* Character device. */
    00315 #define FFS_IN_DIR       0040000        /* Directory file. */
    00316 #define FFS_IN_BLK       0060000        /* Block device. */
    00317 #define FFS_IN_REG       0100000        /* Regular file. */
    00318 #define FFS_IN_LNK       0120000        /* Symbolic link. */
    00319 #define FFS_IN_SHAD              0130000        /* SOLARIS ONLY */
    00320 #define FFS_IN_SOCK      0140000        /* UNIX domain socket. */
    00321 #define FFS_IN_WHT       0160000        /* Whiteout. */
    00322
    00323
    00324
    00325     typedef struct {
    00326         uint8_t reclen[4];
    00327         uint8_t nspace;
    00328         uint8_t contpad;
    00329         uint8_t nlen;
    00330         uint8_t name[1];        /* of length nlen and padded so contents are on 8-byte boundary */
    00331
    00332     } ffs_extattr;
    00333
    00334 #define FFS_ATTR_CONT(x)        \
    00335   ((((x) + 7 + 7) / 8) * 2)
    00336
    00337
    00338 /*
    00339  * Directory Entries
    00340  */
    00341 /* ffs_dentry1: new OpenBSD & FreeBSD etc. */
    00342     typedef struct {
    00343         uint8_t d_ino[4];       /* u32 */
    00344         uint8_t d_reclen[2];    /* u16 */
    00345         uint8_t d_type;         /* u8 */
    00346         uint8_t d_namlen;       /* u8 */
    00347         char d_name[256];
    00348     } ffs_dentry1;
    00349
    00350 /* type field values */
    00351 #define FFS_DT_UNKNOWN   0
    00352 #define FFS_DT_FIFO      1
    00353 #define FFS_DT_CHR       2
    00354 #define FFS_DT_DIR       4
    00355 #define FFS_DT_BLK       6
    00356 #define FFS_DT_REG       8
    00357 #define FFS_DT_LNK      10
    00358 #define FFS_DT_SOCK     12
    00359 #define FFS_DT_WHT      14
    00360
    00361 /* ffs_dentry2: Solaris and old xBSDs (no type field) */
    00362     typedef struct {
    00363         uint8_t d_ino[4];       /* u32 */
    00364         uint8_t d_reclen[2];    /* u16 */
    00365         uint8_t d_namlen[2];    /* u16 */
    00366         char d_name[256];
    00367     } ffs_dentry2;
    00368
    00369
    00370 #define FFS_DIRSIZ_lcl(len) \
    00371     ((len + 8 + 3) & ~(3))
    00372
    00373
    00374
    00375
    00376
    00377
    00378 /* modified macros */
    00379
    00380 /* original:
    00381 ** cgbase(fs, c)   ((daddr_t)((fs)->fs_cg_frag_num * (c)))
    00382 */
    00383 #define cgbase_lcl(fsi, fs, c)  \
    00384         ((DADDR_T)(tsk_gets32(fsi->endian, (fs)->cg_frag_num) * (c)))
    00385
    00386
    00387 /* Macros to calc the locations of structures in cyl groups */
    00388
    00389 #define cgstart_lcl(fsi, fs, c)                          \
    00390         ((DADDR_T)((tsk_getu32((fsi)->endian, (fs)->magic) == UFS2_FS_MAGIC) ? \
    00391         (cgbase_lcl(fsi, fs, c)) :  \
    00392         (cgbase_lcl(fsi, fs, c) + tsk_gets32((fsi)->endian, (fs)->cg_delta) * \
    00393          ((c) & ~(tsk_gets32((fsi)->endian, (fs)->cg_cyc_mask)))) ))
    00394
    00395 /* cyl grp block */
    00396 #define cgtod_lcl(fsi, fs, c)   \
    00397         ((DADDR_T)(cgstart_lcl(fsi, fs, c) + tsk_gets32(fsi->endian, (fs)->gd_off)))
    00398
    00399 /* inode block in cyl grp */
    00400 #define cgimin_lcl(fsi, fs, c)  \
    00401         ((DADDR_T)(cgstart_lcl(fsi, fs, c) + tsk_gets32(fsi->endian, (fs)->ino_off)))
    00402
    00403 /* 1st data  block in cyl grp*/
    00404 #define cgdmin_lcl(fsi, fs, c)   \
    00405         ((DADDR_T)(cgstart_lcl(fsi, fs, c) + tsk_gets32(fsi->endian, (fs)->dat_off)))
    00406
    00407 /* super blk in cyl grp*/
    00408 #define cgsblock_lcl(fsi, fs, c)        \
    00409         ((DADDR_T)(cgstart_lcl(fsi, fs, c) + tsk_gets32(fsi->endian, (fs)->sb_off)))
    00410
    00411 /* original:
    00412 ** blkstofrags(fs, blks)
    00413 **    ((blks) << (fs)->fs_fragshift)
    00414 */
    00415 #define blkstofrags_lcl(fsi, fs, blks)  \
    00416     ((blks) << tsk_gets32(fsi->endian, (fs)->fs_fragshift))
    00417
    00418 /* original:
    00419 ** itod(fs, x) \
    00420 **      ((DADDR_T)(cgimin(fs, itog(fs, x)) + \
    00421 **      (blkstofrags((fs), (((x)%(ulong_t)(fs)->cg_inode_num)/(ulong_t)INOPB(fs))))))
    00422 */
    00423 #define itod_lcl(fsi, fs, x) \
    00424       ((DADDR_T)(cgimin_lcl(fsi, fs, itog_lcl(fsi, fs, x)) + \
    00425       (blkstofrags_lcl(fsi, (fs), (((x)%(ULONG)tsk_gets32(fsi->endian, (fs)->cg_inode_num))/ \
    00426           (ULONG)tsk_gets32(fsi->endian, (fs)->fs_inopb))))))
    00427
    00428 /* original:
    00429 ** itoo(fs, x) ((x) % (uint32_t)INOPB(fs))
    00430 */
    00431 #define itoo_lcl(fsi, fs, x)    \
    00432         ((x) % (uint32_t)tsk_getu32(fsi->endian, (fs)->fs_inopb))
    00433
    00434 /* original:
    00435 ** #define itog(fs, x)    ((x) / (fs)->fs_cg_inode_num)
    00436 */
    00437 #define itog_lcl(fsi, fs, x)    \
    00438         (FFS_GRPNUM_T)((x) / tsk_gets32(fsi->endian, (fs)->cg_inode_num))
    00439
    00440 /* original:
    00441 ** dtog(fs, d) ((d) / (fs)->fs_cg_frag_num)
    00442 */
    00443 #define dtog_lcl(fsi, fs, d)    \
    00444         (FFS_GRPNUM_T)((d) / tsk_gets32(fsi->endian, (fs)->cg_frag_num))
    00445
    00446 #define cg_inosused_lcl(fsi, cgp)       \
    00447         ((uint8_t *)((uint8_t *)(cgp) + tsk_gets32(fsi->endian, (cgp)->cg_iusedoff)))
    00448
    00449 #define cg_blksfree_lcl(fsi, cgp) \
    00450         ((uint8_t *)((uint8_t *)(cgp) + tsk_gets32(fsi->endian, (cgp)->cg_freeoff)))
    00451
    00452
    00453
    00454
    00455 /*
    00456  * Structure of a fast file system handle.
    00457  */
    00458     typedef struct {
    00459         TSK_FS_INFO fs_info;    /* super class */
    00460         union {
    00461             ffs_sb1 *sb1;       /* super block buffer */
    00462             ffs_sb2 *sb2;       /* super block buffer */
    00463         } fs;
    00464
    00465         char *dino_buf;         /* cached disk inode */
    00466         INUM_T dino_inum;       /* address of cached disk inode */
    00467
    00468         TSK_DATA_BUF *itbl_buf; /* cached inode block buffer */
    00469
    00470         TSK_DATA_BUF *grp_buf;  /* Cached cylinder group buffer */
    00471         FFS_GRPNUM_T grp_num;   /* number of cached cyl */
    00472
    00473         FFS_GRPNUM_T groups_count;      /* nr of descriptor group blocks */
    00474
    00475         unsigned int ffsbsize_f;        /* num of frags in an FFS block */
    00476         unsigned int ffsbsize_b;        /* size of an FFS block in bytes */
    00477     } FFS_INFO;
    00478
    00479 #ifdef __cplusplus
    00480 }
    00481 #endif
    00482 #endif                          /* _FFS_H */