ffs.h

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

Generated on Wed Nov 28 16:11:14 2007 for The Sleuth Kit (Incomplete) by  doxygen 1.5.1