From 7f168c0d95c8b0e9b769a0ec11029f83d415b541 Mon Sep 17 00:00:00 2001 From: Song Gao Date: Mon, 25 Mar 2013 18:56:46 -0700 Subject: [PATCH] Create gh-pages branch via GitHub --- images/arrow-down.png | Bin 0 -> 423 bytes images/octocat-small.png | Bin 0 -> 570 bytes index.html | 143 ++++++++++++ javascripts/scale.fix.js | 20 ++ params.json | 1 + stylesheets/pygment_trac.css | 69 ++++++ stylesheets/styles.css | 413 +++++++++++++++++++++++++++++++++++ 7 files changed, 646 insertions(+) create mode 100644 images/arrow-down.png create mode 100644 images/octocat-small.png create mode 100644 index.html create mode 100644 javascripts/scale.fix.js create mode 100644 params.json create mode 100644 stylesheets/pygment_trac.css create mode 100644 stylesheets/styles.css diff --git a/images/arrow-down.png b/images/arrow-down.png new file mode 100644 index 0000000000000000000000000000000000000000..585b0bddba878b95acc961fc5c0c55c3ea2e75db GIT binary patch literal 423 zcmeAS@N?(olHy`uVBq!ia0vp^JU}eW!3HFke0{SLNU;<^miKrK zR4D>d>0FeWSdy8arx22vo62CJZ=!E#Q zuUEhHFKq}eVcf!fOXk2252o^`A0Pfx?pl-`?tS^o=dZa}n)o-rOj#-_e`l7jy7u+r zhj0Hd|L1+)z+f_A|GJISy4qrPpME*#k;S{#M4)d)HS2xXctpM~nN-ejV$=G%1)}zh z6_&;B=NTB*Rz&o)EN^QNw)=Nauj9or^J@~D*Th}TXM8@bL&NZxPHmc!SKl9%dr^gl zqh@m|zG6sNdzVY`kauM4^m$&|dG9N?-~61nSXA6TxH5R=Pxc4Kow9qMI-LOq1%s!n KpUXO@geCw=gQOS$ literal 0 HcmV?d00001 diff --git a/images/octocat-small.png b/images/octocat-small.png new file mode 100644 index 0000000000000000000000000000000000000000..66c25398dd9090905e37aa2d48bb2d77a0ac6255 GIT binary patch literal 570 zcmV-A0>%A_P)V>IRB3Hx05~r+FEKJgdgKHE00ELo zL_t(Ijg^xed`v89bwq|>- zBcAI>wNjQ~{V)H%tlWtR3ZPgl_WI*s7zQut?CiWv)3hNC$Q&OX?xs?y7lFshPE4M* zWwYbCv9ZzqmMOqA&6xTyFpvlX0a(^MlwlaPupofy>3N$E3)SoOTg`Kw1aKY(ER{+J z8i40IIbbma`(6R7dL#-k0u){W3czrO-f82x&g$~grz@IyWqNvQc6)p4Nm@33tb3m8 zqya>Phsa&m{#?w>&fMT<@_Edvm9hja12DK_rqO6@Dy6#qH=`bjY5@o|v#Lj;wod}b>JrdoE#olbS0=7RdB$LTJ@R`4#*!KNI_tZAjO+JC<^Z)<=07*qo IM6N<$f|}m$2LJ#7 literal 0 HcmV?d00001 diff --git a/index.html b/index.html new file mode 100644 index 0000000..c2712e5 --- /dev/null +++ b/index.html @@ -0,0 +1,143 @@ + + + + + + Water by songgao + + + + + + + + +
+
+

Water

+

A simple TUN/TAP library written in native Go.

+ + + +

This project is maintained by songgao

+ + +
+
+

water

+ +

water is a native Go library for TUN/TAP interfaces.

+ +

water is designed to be simple and efficient. It

+ +
    +
  • wraps almost only syscalls and uses only Go standard types;
  • +
  • exposes standard interfaces; plays well with standard packages like io, bufio, etc..
  • +
  • does not handle memory management (allocating/destructing slice). It's up to user to decide how to deal with buffers; whether to use GC.
  • +

water/waterutil has some useful functions to interpret MAC farme headers and IP packet headers. It also contains some constants such as protocol numbers and ethernet frame types.

+ +

Installation

+ +
go get -u github.com/songgao/water
+go get -u github.com/songgao/water/waterutil
+
+ +

Documentation

+ +

http://godoc.org/github.com/songgao/water

+ +

http://godoc.org/github.com/songgao/water/waterutil

+ +

Example

+ +
package main
+
+import (
+    "github.com/songgao/water"
+    "github.com/songgao/water/waterutil"
+    "fmt"
+)
+
+const BUFFERSIZE = 1522
+
+func main() {
+    ifce, err := water.NewTAP("")
+    fmt.Printf("%v, %v\n\n", err, ifce)
+    buffer := make([]byte, BUFFERSIZE)
+    for {
+        _, err = ifce.Read(buffer)
+        if err != nil {
+            break
+        }
+        ethertype := waterutil.MACEthertype(buffer)
+        if ethertype == waterutil.IPv4 {
+            packet := waterutil.MACPayload(buffer)
+            if waterutil.IsIPv4(packet) {
+                fmt.Printf("Source:      %v [%v]\n", waterutil.MACSource(buffer), waterutil.IPv4Source(packet))
+                fmt.Printf("Destination: %v [%v]\n", waterutil.MACDestination(buffer), waterutil.IPv4Destination(packet))
+                fmt.Printf("Protocol:    %v\n\n", waterutil.IPv4Protocol(packet))
+            }
+        }
+    }
+}
+
+ +

This piece of code creates a TAP interface, and prints some header information for every IPv4 packet. After pull up the main.go, you'll need to bring up the interface and assign IP address. All of these need root permission.

+ +
sudo go run main.go
+
+ +
sudo ip link set dev tap0 up
+sudo ip addr add 10.0.0.1/24 dev tap0
+
+ +

Now, try sending some ICMP broadcast message:

+ +
ping -b 10.0.0.255
+
+ +

You'll see the main.go print something like:

+ +
<nil>, &{true 0xf84003f058 tap0}
+
+Source:      42:35:da:af:2b:00 [10.0.0.1]
+Destination: ff:ff:ff:ff:ff:ff [10.0.0.255]
+Protocol:    1
+
+Source:      42:35:da:af:2b:00 [10.0.0.1]
+Destination: ff:ff:ff:ff:ff:ff [10.0.0.255]
+Protocol:    1
+
+Source:      42:35:da:af:2b:00 [10.0.0.1]
+Destination: ff:ff:ff:ff:ff:ff [10.0.0.255]
+Protocol:    1
+
+ +

TODO

+ +
    +
  • IPv6 Support in waterutil +
  • +
  • Darwin(Mac) Support
  • +

LICENSE

+ +

GNU LESSER GENERAL PUBLIC LICENSE Version 3

+ +

Alternatives

+ +

tuntap: https://code.google.com/p/tuntap/

+
+ +
+ + + + \ No newline at end of file diff --git a/javascripts/scale.fix.js b/javascripts/scale.fix.js new file mode 100644 index 0000000..08716c0 --- /dev/null +++ b/javascripts/scale.fix.js @@ -0,0 +1,20 @@ +fixScale = function(doc) { + + var addEvent = 'addEventListener', + type = 'gesturestart', + qsa = 'querySelectorAll', + scales = [1, 1], + meta = qsa in doc ? doc[qsa]('meta[name=viewport]') : []; + + function fix() { + meta.content = 'width=device-width,minimum-scale=' + scales[0] + ',maximum-scale=' + scales[1]; + doc.removeEventListener(type, fix, true); + } + + if ((meta = meta[meta.length - 1]) && addEvent in doc) { + fix(); + scales = [.25, 1.6]; + doc[addEvent](type, fix, true); + } + +}; \ No newline at end of file diff --git a/params.json b/params.json new file mode 100644 index 0000000..1e20364 --- /dev/null +++ b/params.json @@ -0,0 +1 @@ +{"name":"Water","tagline":"A simple TUN/TAP library written in native Go.","body":"# water\r\n`water` is a native Go library for [TUN/TAP](http://en.wikipedia.org/wiki/TUN/TAP) interfaces.\r\n\r\n`water` is designed to be simple and efficient. It\r\n\r\n* wraps almost only syscalls and uses only Go standard types;\r\n* exposes standard interfaces; plays well with standard packages like `io`, `bufio`, etc..\r\n* does not handle memory management (allocating/destructing slice). It's up to user to decide how to deal with buffers; whether to use GC.\r\n\r\n`water/waterutil` has some useful functions to interpret MAC farme headers and IP packet headers. It also contains some constants such as protocol numbers and ethernet frame types.\r\n\r\n## Installation\r\n```\r\ngo get -u github.com/songgao/water\r\ngo get -u github.com/songgao/water/waterutil\r\n```\r\n\r\n## Documentation\r\n[http://godoc.org/github.com/songgao/water](http://godoc.org/github.com/songgao/water)\r\n\r\n[http://godoc.org/github.com/songgao/water/waterutil](http://godoc.org/github.com/songgao/water/waterutil)\r\n\r\n## Example\r\n\r\n```go\r\npackage main\r\n\r\nimport (\r\n\t\"github.com/songgao/water\"\r\n\t\"github.com/songgao/water/waterutil\"\r\n\t\"fmt\"\r\n)\r\n\r\nconst BUFFERSIZE = 1522\r\n\r\nfunc main() {\r\n\tifce, err := water.NewTAP(\"\")\r\n\tfmt.Printf(\"%v, %v\\n\\n\", err, ifce)\r\n\tbuffer := make([]byte, BUFFERSIZE)\r\n\tfor {\r\n\t\t_, err = ifce.Read(buffer)\r\n\t\tif err != nil {\r\n\t\t\tbreak\r\n\t\t}\r\n\t\tethertype := waterutil.MACEthertype(buffer)\r\n\t\tif ethertype == waterutil.IPv4 {\r\n\t\t\tpacket := waterutil.MACPayload(buffer)\r\n\t\t\tif waterutil.IsIPv4(packet) {\r\n\t\t\t\tfmt.Printf(\"Source: %v [%v]\\n\", waterutil.MACSource(buffer), waterutil.IPv4Source(packet))\r\n\t\t\t\tfmt.Printf(\"Destination: %v [%v]\\n\", waterutil.MACDestination(buffer), waterutil.IPv4Destination(packet))\r\n\t\t\t\tfmt.Printf(\"Protocol: %v\\n\\n\", waterutil.IPv4Protocol(packet))\r\n\t\t\t}\r\n\t\t}\r\n\t}\r\n}\r\n```\r\n\r\nThis piece of code creates a `TAP` interface, and prints some header information for every IPv4 packet. After pull up the `main.go`, you'll need to bring up the interface and assign IP address. All of these need root permission.\r\n\r\n```bash\r\nsudo go run main.go\r\n```\r\n\r\n```bash\r\nsudo ip link set dev tap0 up\r\nsudo ip addr add 10.0.0.1/24 dev tap0\r\n```\r\n\r\nNow, try sending some ICMP broadcast message:\r\n```bash\r\nping -b 10.0.0.255\r\n```\r\n\r\nYou'll see the `main.go` print something like:\r\n```\r\n, &{true 0xf84003f058 tap0}\r\n\r\nSource: 42:35:da:af:2b:00 [10.0.0.1]\r\nDestination: ff:ff:ff:ff:ff:ff [10.0.0.255]\r\nProtocol: 1\r\n\r\nSource: 42:35:da:af:2b:00 [10.0.0.1]\r\nDestination: ff:ff:ff:ff:ff:ff [10.0.0.255]\r\nProtocol: 1\r\n\r\nSource: 42:35:da:af:2b:00 [10.0.0.1]\r\nDestination: ff:ff:ff:ff:ff:ff [10.0.0.255]\r\nProtocol: 1\r\n```\r\n\r\n## TODO\r\n* IPv6 Support in `waterutil`\r\n* Darwin(Mac) Support\r\n\r\n## LICENSE\r\nGNU LESSER GENERAL PUBLIC LICENSE Version 3\r\n\r\n## Alternatives\r\n`tuntap`: [https://code.google.com/p/tuntap/](https://code.google.com/p/tuntap/)\r\n","google":"","note":"Don't delete this file! It's used internally to help with page regeneration."} \ No newline at end of file diff --git a/stylesheets/pygment_trac.css b/stylesheets/pygment_trac.css new file mode 100644 index 0000000..c6a6452 --- /dev/null +++ b/stylesheets/pygment_trac.css @@ -0,0 +1,69 @@ +.highlight { background: #ffffff; } +.highlight .c { color: #999988; font-style: italic } /* Comment */ +.highlight .err { color: #a61717; background-color: #e3d2d2 } /* Error */ +.highlight .k { font-weight: bold } /* Keyword */ +.highlight .o { font-weight: bold } /* Operator */ +.highlight .cm { color: #999988; font-style: italic } /* Comment.Multiline */ +.highlight .cp { color: #999999; font-weight: bold } /* Comment.Preproc */ +.highlight .c1 { color: #999988; font-style: italic } /* Comment.Single */ +.highlight .cs { color: #999999; font-weight: bold; font-style: italic } /* Comment.Special */ +.highlight .gd { color: #000000; background-color: #ffdddd } /* Generic.Deleted */ +.highlight .gd .x { color: #000000; background-color: #ffaaaa } /* Generic.Deleted.Specific */ +.highlight .ge { font-style: italic } /* Generic.Emph */ +.highlight .gr { color: #aa0000 } /* Generic.Error */ +.highlight .gh { color: #999999 } /* Generic.Heading */ +.highlight .gi { color: #000000; background-color: #ddffdd } /* Generic.Inserted */ +.highlight .gi .x { color: #000000; background-color: #aaffaa } /* Generic.Inserted.Specific */ +.highlight .go { color: #888888 } /* Generic.Output */ +.highlight .gp { color: #555555 } /* Generic.Prompt */ +.highlight .gs { font-weight: bold } /* Generic.Strong */ +.highlight .gu { color: #800080; font-weight: bold; } /* Generic.Subheading */ +.highlight .gt { color: #aa0000 } /* Generic.Traceback */ +.highlight .kc { font-weight: bold } /* Keyword.Constant */ +.highlight .kd { font-weight: bold } /* Keyword.Declaration */ +.highlight .kn { font-weight: bold } /* Keyword.Namespace */ +.highlight .kp { font-weight: bold } /* Keyword.Pseudo */ +.highlight .kr { font-weight: bold } /* Keyword.Reserved */ +.highlight .kt { color: #445588; font-weight: bold } /* Keyword.Type */ +.highlight .m { color: #009999 } /* Literal.Number */ +.highlight .s { color: #d14 } /* Literal.String */ +.highlight .na { color: #008080 } /* Name.Attribute */ +.highlight .nb { color: #0086B3 } /* Name.Builtin */ +.highlight .nc { color: #445588; font-weight: bold } /* Name.Class */ +.highlight .no { color: #008080 } /* Name.Constant */ +.highlight .ni { color: #800080 } /* Name.Entity */ +.highlight .ne { color: #990000; font-weight: bold } /* Name.Exception */ +.highlight .nf { color: #990000; font-weight: bold } /* Name.Function */ +.highlight .nn { color: #555555 } /* Name.Namespace */ +.highlight .nt { color: #000080 } /* Name.Tag */ +.highlight .nv { color: #008080 } /* Name.Variable */ +.highlight .ow { font-weight: bold } /* Operator.Word */ +.highlight .w { color: #bbbbbb } /* Text.Whitespace */ +.highlight .mf { color: #009999 } /* Literal.Number.Float */ +.highlight .mh { color: #009999 } /* Literal.Number.Hex */ +.highlight .mi { color: #009999 } /* Literal.Number.Integer */ +.highlight .mo { color: #009999 } /* Literal.Number.Oct */ +.highlight .sb { color: #d14 } /* Literal.String.Backtick */ +.highlight .sc { color: #d14 } /* Literal.String.Char */ +.highlight .sd { color: #d14 } /* Literal.String.Doc */ +.highlight .s2 { color: #d14 } /* Literal.String.Double */ +.highlight .se { color: #d14 } /* Literal.String.Escape */ +.highlight .sh { color: #d14 } /* Literal.String.Heredoc */ +.highlight .si { color: #d14 } /* Literal.String.Interpol */ +.highlight .sx { color: #d14 } /* Literal.String.Other */ +.highlight .sr { color: #009926 } /* Literal.String.Regex */ +.highlight .s1 { color: #d14 } /* Literal.String.Single */ +.highlight .ss { color: #990073 } /* Literal.String.Symbol */ +.highlight .bp { color: #999999 } /* Name.Builtin.Pseudo */ +.highlight .vc { color: #008080 } /* Name.Variable.Class */ +.highlight .vg { color: #008080 } /* Name.Variable.Global */ +.highlight .vi { color: #008080 } /* Name.Variable.Instance */ +.highlight .il { color: #009999 } /* Literal.Number.Integer.Long */ + +.type-csharp .highlight .k { color: #0000FF } +.type-csharp .highlight .kt { color: #0000FF } +.type-csharp .highlight .nf { color: #000000; font-weight: normal } +.type-csharp .highlight .nc { color: #2B91AF } +.type-csharp .highlight .nn { color: #000000 } +.type-csharp .highlight .s { color: #A31515 } +.type-csharp .highlight .sc { color: #A31515 } diff --git a/stylesheets/styles.css b/stylesheets/styles.css new file mode 100644 index 0000000..f14d9e4 --- /dev/null +++ b/stylesheets/styles.css @@ -0,0 +1,413 @@ +@import url(https://fonts.googleapis.com/css?family=Arvo:400,700,400italic); + +/* MeyerWeb Reset */ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + + +/* Base text styles */ + +body { + padding:10px 50px 0 0; + font-family:"Helvetica Neue", Helvetica, Arial, sans-serif; + font-size: 14px; + color: #232323; + background-color: #FBFAF7; + margin: 0; + line-height: 1.8em; + -webkit-font-smoothing: antialiased; + +} + +h1, h2, h3, h4, h5, h6 { + color:#232323; + margin:36px 0 10px; +} + +p, ul, ol, table, dl { + margin:0 0 22px; +} + +h1, h2, h3 { + font-family: Arvo, Monaco, serif; + line-height:1.3; + font-weight: normal; +} + +h1,h2, h3 { + display: block; + border-bottom: 1px solid #ccc; + padding-bottom: 5px; +} + +h1 { + font-size: 30px; +} + +h2 { + font-size: 24px; +} + +h3 { + font-size: 18px; +} + +h4, h5, h6 { + font-family: Arvo, Monaco, serif; + font-weight: 700; +} + +a { + color:#C30000; + font-weight:200; + text-decoration:none; +} + +a:hover { + text-decoration: underline; +} + +a small { + font-size: 12px; +} + +em { + font-style: italic; +} + +strong { + font-weight:700; +} + +ul li { + list-style: inside; + padding-left: 25px; +} + +ol li { + list-style: decimal inside; + padding-left: 20px; +} + +blockquote { + margin: 0; + padding: 0 0 0 20px; + font-style: italic; +} + +dl, dt, dd, dl p { + font-color: #444; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + border:0; + background:#ccc; + height:1px; + margin:0 0 24px; +} + +/* Images */ + +img { + position: relative; + margin: 0 auto; + max-width: 650px; + padding: 5px; + margin: 10px 0 32px 0; + border: 1px solid #ccc; +} + + +/* Code blocks */ + +code, pre { + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + color:#000; + font-size:14px; +} + +pre { + padding: 4px 12px; + background: #FDFEFB; + border-radius:4px; + border:1px solid #D7D8C8; + overflow: auto; + overflow-y: hidden; + margin-bottom: 32px; +} + + +/* Tables */ + +table { + width:100%; +} + +table { + border: 1px solid #ccc; + margin-bottom: 32px; + text-align: left; + } + +th { + font-family: 'Arvo', Helvetica, Arial, sans-serif; + font-size: 18px; + font-weight: normal; + padding: 10px; + background: #232323; + color: #FDFEFB; + } + +td { + padding: 10px; + background: #ccc; + } + + +/* Wrapper */ +.wrapper { + width:960px; +} + + +/* Header */ + +header { + background-color: #171717; + color: #FDFDFB; + width:170px; + float:left; + position:fixed; + border: 1px solid #000; + -webkit-border-top-right-radius: 4px; + -webkit-border-bottom-right-radius: 4px; + -moz-border-radius-topright: 4px; + -moz-border-radius-bottomright: 4px; + border-top-right-radius: 4px; + border-bottom-right-radius: 4px; + padding: 34px 25px 22px 50px; + margin: 30px 25px 0 0; + -webkit-font-smoothing: antialiased; +} + +p.header { + font-size: 16px; +} + +h1.header { + font-family: Arvo, sans-serif; + font-size: 30px; + font-weight: 300; + line-height: 1.3em; + border-bottom: none; + margin-top: 0; +} + + +h1.header, a.header, a.name, header a{ + color: #fff; +} + +a.header { + text-decoration: underline; +} + +a.name { + white-space: nowrap; +} + +header ul { + list-style:none; + padding:0; +} + +header li { + list-style-type: none; + width:132px; + height:15px; + margin-bottom: 12px; + line-height: 1em; + padding: 6px 6px 6px 7px; + + background: #AF0011; + background: -moz-linear-gradient(top, #AF0011 0%, #820011 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -o-linear-gradient(top, #AF0011 0%,#820011 100%); + background: -ms-linear-gradient(top, #AF0011 0%,#820011 100%); + background: linear-gradient(top, #AF0011 0%,#820011 100%); + + border-radius:4px; + border:1px solid #0D0D0D; + + -webkit-box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + box-shadow: inset 0px 1px 1px 0 rgba(233,2,38, 1); + +} + +header li:hover { + background: #C3001D; + background: -moz-linear-gradient(top, #C3001D 0%, #950119 100%); + background: -webkit-gradient(linear, left top, left bottom, color-stop(0%,#f8f8f8), color-stop(100%,#dddddd)); + background: -webkit-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -o-linear-gradient(top, #C3001D 0%,#950119 100%); + background: -ms-linear-gradient(top, #C3001D 0%,#950119 100%); + background: linear-gradient(top, #C3001D 0%,#950119 100%); +} + +a.buttons { + -webkit-font-smoothing: antialiased; + background: url(../images/arrow-down.png) no-repeat; + font-weight: normal; + text-shadow: rgba(0, 0, 0, 0.4) 0 -1px 0; + padding: 2px 2px 2px 22px; + height: 30px; +} + +a.github { + background: url(../images/octocat-small.png) no-repeat 1px; +} + +a.buttons:hover { + color: #fff; + text-decoration: none; +} + + +/* Section - for main page content */ + +section { + width:650px; + float:right; + padding-bottom:50px; +} + + +/* Footer */ + +footer { + width:170px; + float:left; + position:fixed; + bottom:10px; + padding-left: 50px; +} + +@media print, screen and (max-width: 960px) { + + div.wrapper { + width:auto; + margin:0; + } + + header, section, footer { + float:none; + position:static; + width:auto; + } + + footer { + border-top: 1px solid #ccc; + margin:0 84px 0 50px; + padding:0; + } + + header { + padding-right:320px; + } + + section { + padding:20px 84px 20px 50px; + margin:0 0 20px; + } + + header a small { + display:inline; + } + + header ul { + position:absolute; + right:130px; + top:84px; + } +} + +@media print, screen and (max-width: 720px) { + body { + word-wrap:break-word; + } + + header { + padding:10px 20px 0; + margin-right: 0; + } + + section { + padding:10px 0 10px 20px; + margin:0 0 30px; + } + + footer { + margin: 0 0 0 30px; + } + + header ul, header p.view { + position:static; + } +} + +@media print, screen and (max-width: 480px) { + + header ul li.download { + display:none; + } + + footer { + margin: 0 0 0 20px; + } + + footer a{ + display:block; + } + +} + +@media print { + body { + padding:0.4in; + font-size:12pt; + color:#444; + } +} \ No newline at end of file