Main Page | Data Structures | Directories | File List | Data Fields | Globals

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 */

Generated on Thu Apr 19 14:58:53 2007 for The Sleuth Kit (Incomplete) by  doxygen 1.4.2