add helper methods for request flags/attrs data
diff --git a/request-attrs.go b/request-attrs.go
new file mode 100644
index 0000000..0149d93
--- /dev/null
+++ b/request-attrs.go
@@ -0,0 +1,63 @@
+package sftp
+
+// Methods on the Request object to make working with the Flags bitmasks and
+// Attr(ibutes) byte blob easier. Use Pflags() when working with an Open/Write
+// request and AttrFlags() and Attributes() when working with SetStat requests.
+
+import "os"
+
+// Open packet pflags
+type pflags struct {
+	Read, Write, Append, Creat, Trunc, Excl bool
+}
+
+// testable constructor
+func newPflags(flags uint32) pflags {
+	return pflags{
+		Read:   flags&ssh_FXF_READ != 0,
+		Write:  flags&ssh_FXF_WRITE != 0,
+		Append: flags&ssh_FXF_APPEND != 0,
+		Creat:  flags&ssh_FXF_CREAT != 0,
+		Trunc:  flags&ssh_FXF_TRUNC != 0,
+		Excl:   flags&ssh_FXF_EXCL != 0,
+	}
+}
+
+// Check bitmap/uint32 for Open packet pflag values
+func (r *Request) Pflags() pflags {
+	return newPflags(r.Flags)
+}
+
+// File attribute flags
+type aflags struct {
+	Size, UidGid, Permissions, Acmodtime bool
+}
+
+// testable constructor
+func newAflags(flags uint32) aflags {
+	return aflags{
+		Size:        (flags & ssh_FILEXFER_ATTR_SIZE) != 0,
+		UidGid:      (flags & ssh_FILEXFER_ATTR_UIDGID) != 0,
+		Permissions: (flags & ssh_FILEXFER_ATTR_PERMISSIONS) != 0,
+		Acmodtime:   (flags & ssh_FILEXFER_ATTR_ACMODTIME) != 0,
+	}
+}
+
+// Check bitmap/uint32 for file attribute flags
+func (r *Request) AttrFlags(flags uint32) aflags {
+	return newAflags(r.Flags)
+}
+
+// File attributes
+type fileattrs FileStat
+
+// Return Mode wrapped in os.FileMode
+func (a fileattrs) FileMode() os.FileMode {
+	return os.FileMode(a.Mode)
+}
+
+// Parse file attributes byte blob and return them in object
+func (r *Request) Attributes() fileattrs {
+	fa, _ := getFileStat(r.Flags, r.Attrs)
+	return fileattrs(*fa)
+}
diff --git a/request-attrs_test.go b/request-attrs_test.go
new file mode 100644
index 0000000..bcbb06a
--- /dev/null
+++ b/request-attrs_test.go
@@ -0,0 +1,51 @@
+package sftp
+
+import (
+	"os"
+
+	"github.com/stretchr/testify/assert"
+
+	"testing"
+)
+
+func TestRequestPflags(t *testing.T) {
+	pflags := newPflags(ssh_FXF_READ | ssh_FXF_WRITE | ssh_FXF_APPEND)
+	assert.True(t, pflags.Read)
+	assert.True(t, pflags.Write)
+	assert.True(t, pflags.Append)
+	assert.False(t, pflags.Creat)
+	assert.False(t, pflags.Trunc)
+	assert.False(t, pflags.Excl)
+}
+
+func TestRequestAflags(t *testing.T) {
+	aflags := newAflags(ssh_FILEXFER_ATTR_SIZE | ssh_FILEXFER_ATTR_UIDGID)
+	assert.True(t, aflags.Size)
+	assert.True(t, aflags.UidGid)
+	assert.False(t, aflags.Acmodtime)
+	assert.False(t, aflags.Permissions)
+}
+
+func TestRequestAttributes(t *testing.T) {
+	// UID/GID
+	fa := fileattrs{UID: 1, GID: 2}
+	fl := uint32(ssh_FILEXFER_ATTR_UIDGID)
+	at := []byte{}
+	at = marshalUint32(at, 1)
+	at = marshalUint32(at, 2)
+	test_fs, _ := getFileStat(fl, at)
+	assert.Equal(t, fa, fileattrs(*test_fs))
+	// Size and Mode
+	fa = fileattrs{Mode: 700, Size: 99}
+	fl = uint32(ssh_FILEXFER_ATTR_SIZE | ssh_FILEXFER_ATTR_PERMISSIONS)
+	at = []byte{}
+	at = marshalUint64(at, 99)
+	at = marshalUint32(at, 700)
+	test_fs, _ = getFileStat(fl, at)
+	test_fa := fileattrs(*test_fs)
+	assert.Equal(t, fa, test_fa)
+	// FileMode
+	assert.True(t, test_fa.FileMode().IsRegular())
+	assert.False(t, test_fa.FileMode().IsDir())
+	assert.Equal(t, test_fa.FileMode().Perm(), os.FileMode(700).Perm())
+}