diff --git a/Scripts/Generate.hs b/Scripts/Generate.hs
new file mode 100644
--- /dev/null
+++ b/Scripts/Generate.hs
@@ -0,0 +1,65 @@
+module Main where
+
+import Control.Arrow ((&&&))
+import Control.Monad (join)
+import Data.List (intersperse)
+import Data.Map (Map, union)
+import System.Environment (getArgs)
+
+import Helpers
+
+main :: IO ()
+main = do
+    [out] <- getArgs
+    let inc = mkIncludeBlock includeFiles
+    defines <- getDefinitions inc
+    enums <- getEnums inc
+    let (exports, definitions) = outputs defines enums
+        prelude = [
+            "{-# OPTIONS_HADDOCK hide, prune, ignore-exports #-}",
+            "{-# LANGUAGE GeneralizedNewtypeDeriving #-}",
+            "module System.Linux.Netlink.Constants (" ++
+            join (intersperse ", " $ join exports) ++
+            ") where",
+            "",
+            "import Data.Bits",
+            ""]
+    writeFile out $ unlines (prelude ++ join definitions)
+
+outputs :: Map String Integer -> [Map String Integer] -> ([[String]], [[String]])
+outputs d e = let define r = selectDefines r d
+                  enum r = selectEnum r e
+              in map fst &&& map snd $
+    [mkEnum "AddressFamily" $ define "^AF_",
+     mkEnum "MessageType" $
+       union (define "^NLMSG_(?!ALIGNTO)") (enum "^RTM_"),
+     mkFlag "MessageFlags"  $ define "^NLM_F_",
+     mkEnum "LinkType"      $ define "^ARPHRD_",
+     mkFlag "LinkFlags"     $
+       union (define "^IFF_") (enum "^IFF_"),
+     mkEnum "LinkAttrType"  $ enum   "^IFLA_",
+     mkFlag "AddrFlags"     $ define "^IFA_F_",
+     mkEnum "Scope"         $ enum   "^RT_SCOPE_",
+     mkEnum "AddrAttrType"  $ enum   "^IFA_",
+     mkEnum "RouteTableId"  $ enum   "^RT_TABLE_",
+     mkEnum "RouteProto"    $ define "^RTPROT_",
+     mkEnum "RouteType"     $ enum   "^RTN_",
+     mkFlag "RouteFlags"    $ define "^RTM_F_",
+     mkEnum "RouteAttrType" $ enum   "^RTA_",
+     mkEnum "NeighAttrType" $ enum   "^NDA_",
+     mkFlag "NeighStateFlags" $ define   "^NUD_",
+     mkEnum "NetlinkFamily" $ define   "^NETLINK_",
+     mkEnum "RtNetlinkGroups" $ enum   "^RTNLGRP_"]
+
+includeFiles :: [String]
+includeFiles = [ "sys/types.h"
+               , "sys/socket.h"
+               , "linux/if.h"
+               , "linux/if_tun.h"
+               , "linux/if_arp.h"
+               , "linux/if_link.h"
+               , "linux/netlink.h"
+               , "linux/rtnetlink.h"
+               , "linux/neighbour.h"
+               ]
+
diff --git a/Scripts/GenerateGenl.hs b/Scripts/GenerateGenl.hs
new file mode 100644
--- /dev/null
+++ b/Scripts/GenerateGenl.hs
@@ -0,0 +1,40 @@
+module Main where
+
+import Control.Arrow ((&&&))
+import Control.Monad (join)
+import Data.List (intersperse)
+import Data.Map (Map)
+import System.Environment (getArgs)
+
+import Helpers
+
+main :: IO ()
+main = do
+    [out] <- getArgs
+    let inc = mkIncludeBlock includeFiles
+    defines <- getDefinitions inc
+    enums <- getEnums inc
+    let (exports, definitions) = outputs defines enums
+        prelude = [
+            "{-# OPTIONS_HADDOCK hide, prune, ignore-exports #-}",
+            "{-# LANGUAGE GeneralizedNewtypeDeriving #-}",
+            "module System.Linux.Netlink.GeNetlink.Constants (" ++
+            join (intersperse ", " $ join exports) ++
+            ") where",
+            ""]
+    writeFile out $ unlines (prelude ++ join definitions)
+
+outputs :: Map String Integer -> [Map String Integer] -> ([[String]], [[String]])
+outputs _ e = let {-define r = selectDefines r d-}
+                  enum r = selectEnum r e
+              in map fst &&& map snd $
+    [mkEnum "ControlCommand" $ enum "^CTRL_CMD_[^_]+",
+     mkEnum "CtrlAttr"      $ enum "^CTRL_ATTR_",
+     mkEnum "CtrlAttrOp"    $ enum   "^CTRL_ATTR_OP_",
+     mkEnum "CtrlAttrMcast"  $ enum   "^CTRL_ATTR_MCAST_"]
+
+includeFiles :: [String]
+includeFiles = [ "sys/types.h"
+               , "sys/socket.h"
+               , "linux/genetlink.h"
+               ]
diff --git a/Scripts/GenerateNL80211.hs b/Scripts/GenerateNL80211.hs
new file mode 100644
--- /dev/null
+++ b/Scripts/GenerateNL80211.hs
@@ -0,0 +1,48 @@
+module Main where
+
+import Control.Arrow ((&&&))
+import Control.Monad (join)
+import Data.List (intersperse, isInfixOf)
+import Data.Map (Map, keys)
+import System.Environment (getArgs)
+
+import Helpers
+
+main :: IO ()
+main = do
+    [out] <- getArgs
+    let inc = mkIncludeBlock includeFiles ++ "#include \"headers/ieee80211.h\"\n"
+    defines <- getDefinitions inc
+    enums <- getEnums inc
+    let (exports, definitions) = outputs defines enums
+        prelude = [
+            "{-# OPTIONS_HADDOCK hide, prune, ignore-exports #-}",
+            "{-# LANGUAGE GeneralizedNewtypeDeriving #-}",
+            "module System.Linux.Netlink.GeNetlink.NL80211.Constants (" ++
+            join (intersperse ", " $ join exports) ++
+            ") where",
+            ""]
+    writeFile out $ unlines (prelude ++ join definitions)
+
+outputs :: Map String Integer -> [Map String Integer] -> ([[String]], [[String]])
+outputs _ e = let {-define r = selectDefines r d-}
+                  enum r = selectEnum r e
+              in map fst &&& map snd $
+       [ mkEnum "NL80211Commands" $ enum "^NL80211_CMD_"
+       , mkEnum "NL80211Attrs" $ enum "^NL80211_ATTR_([^C]|(C[^Q])|(CQ[^M])|(CQM$))|NUM_NL80211_ATTR$"
+       , mkEnum "NL80211Bss" . bssenum $selectEnums "^NL80211_BSS_" e
+       , mkEnum "Nl80211StaInfo" $ enum "^NL80211_STA_INFO_"
+       , mkEnum "IEEE80211EID" $ enum "^WLAN_EID_"
+       , mkEnum "NL80211RateInfo" $ enum "^NL80211_RATE_INFO_"
+       ]
+
+  where bssenum = getFirst . noChanWidth . noBssStatus . noBssSelect
+        getFirst (x:_) = x
+        getFirst [] = error "Couldn't find the bssenum enum in files"
+        noChanWidth = filter (all (not . isInfixOf "CHAN_WIDTH_") . keys)
+        noBssStatus = filter (all (not . isInfixOf "BSS_STATUS_") . keys)
+        noBssSelect = filter (all (not . isInfixOf "BSS_SELECT_") . keys)
+
+includeFiles :: [String]
+includeFiles = [ "linux/nl80211.h" ]
+
diff --git a/Scripts/Helpers.hs b/Scripts/Helpers.hs
new file mode 100644
--- /dev/null
+++ b/Scripts/Helpers.hs
@@ -0,0 +1,147 @@
+module Helpers
+  ( mkIncludeBlock
+  , getDefinitions
+  , getEnums
+  , selectDefines
+  , selectEnum
+  , mkEnum
+  , mkFlag
+  , selectEnums
+  )
+where
+
+--import Control.Applicative ((<$>))
+
+import Control.Monad (join)
+import Data.Char (isNumber)
+import Data.Function (on)
+import Data.List (isPrefixOf, sortBy, nubBy)
+import Data.Map (Map, elems, filterWithKey, fromList, insert,
+                 keys, mapKeys, toList, lookup, empty)
+import Data.Maybe (mapMaybe, fromJust)
+import Language.C.Analysis (runTrav_)
+import Language.C.Analysis.AstAnalysis (analyseAST)
+import Language.C.Analysis.SemRep (GlobalDecls(..), TagDef(EnumDef),
+                                   EnumType(..), Enumerator(..))
+import Language.C.Data.Ident (Ident(..))
+import Language.C.Data.InputStream (inputStreamFromString)
+import Language.C.Data.Position (position)
+import Language.C.Parser (parseC)
+import Language.C.Pretty (pretty)
+import Language.C.Syntax.Constants (getCInteger)
+import Language.C.Syntax.AST (CExpression(..), CExpr, CConstant(CIntConst), CBinaryOp(..))
+import System.Process (readProcess)
+import Text.Regex.PCRE ((=~))
+
+import Prelude hiding (lookup)
+
+mkIncludeBlock :: [String] -> String
+mkIncludeBlock = unlines . map (\e -> "#include <" ++ e ++ ">")
+
+mkFlag :: String -> Map String Integer -> ([String], [String])
+mkFlag name vals = (name : map fst values,
+                    ty : "" : join (map makeConst values))
+  where
+    ty = "newtype " ++ name ++ " = " ++
+          name ++
+          " Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)"
+    makeConst (n, v) = [n ++ " :: (Num a, Bits a) => a",
+                        n ++ " = " ++ show v]
+    values = sortBy (compare `on` snd) . toList . mapKeys ("f" ++) $ vals
+
+mkEnum :: String -> Map String Integer -> ([String], [String])
+mkEnum name vals = (name : fName : map fst values,
+                    ty : "" : fun : "" : join (map makeConst values))
+  where
+    ty = "newtype " ++ name ++ " = " ++
+          name ++
+          " Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)"
+    makeConst (n, v) = [n ++ " :: (Num a) => a",
+                        n ++ " = " ++ show v]
+    values = sortBy (compare `on` snd) . toList . mapKeys ('e' :) $ vals
+    (fName, fun) = showEnum name vals
+
+showEnum :: String -> Map String Integer -> (String, String)
+showEnum name vals = (fName,
+  fName ++ " :: (Num a) => (Show a) => (Eq a) => a -> String\n" ++
+  concatMap makeLine values ++
+  fName ++ " i = \"" ++ name ++ " #\" ++ (show i)\n")
+  where
+    makeLine (n, v) = fName ++ ' ':(show v) ++ " = \"" ++ n ++ "\"\n"
+    values = nubBy ((==) `on` snd) . sortBy (compare `on` snd) . toList $vals
+    fName = "show" ++ name
+
+selectDefines :: String -> Map String Integer -> Map String Integer
+selectDefines regex = filterWithKey (\k _ -> k =~ regex)
+
+selectEnum :: String -> [Map String Integer] -> Map String Integer
+selectEnum regex m = case selectEnums regex m of
+  (x:_) -> x
+  [] -> error ("Couldn't find enum for " ++ regex)
+
+selectEnums :: String -> [Map String Integer] -> [Map String Integer]
+selectEnums regex = filter (all (=~ regex) . keys)
+
+--full :: String -> String
+--full regex = "^" ++ regex ++ "$"
+
+getEnums :: String -> IO [Map String Integer]
+getEnums source = do
+    parsed <- flip parseC initPos . inputStreamFromString <$> preprocessed
+    let unit = gTags . fst . check $ runTrav_ (analyseAST $ check parsed)
+        enums = mapMaybe getEnum (elems unit)
+    return $ map cleanEnums enums
+  where
+    check (Left err) = error $ show err
+    check (Right a)   = a
+    preprocessed = readProcess "gcc" ["-E", "-"] source
+    initPos = position 0 "" 0 0
+    cleanEnums = filterWithKey (\k _ -> not ("_" `isPrefixOf` k))
+
+
+getEnum :: TagDef -> Maybe (Map String Integer)
+getEnum (EnumDef (EnumType _ es _ _)) = Just $foldl getEnumValue empty es
+getEnum _ = Nothing
+
+getEnumValue :: Map String Integer -> Enumerator -> Map String Integer
+getEnumValue m (Enumerator (Ident s _ _) v _ _) = insert s a m
+  where a = evalEExpr m v
+
+evalEExpr :: Map String Integer -> CExpr -> Integer
+evalEExpr _ (CConst (CIntConst v _)) = getCInteger v
+evalEExpr m (CBinary CAddOp a b _)   = evalEExpr m a + evalEExpr m b
+evalEExpr m (CBinary CSubOp a b _)   = evalEExpr m a - evalEExpr m b
+evalEExpr m (CBinary CShlOp a b _)   = evalEExpr m a * (2 ^ evalEExpr m b)
+evalEExpr m (CVar (Ident a _ _) _)   = fromJust $lookup a m
+evalEExpr _ other                    = error $ "Other: " ++ show (pretty other)
+
+
+--evalCExpr :: CExpr -> Integer
+--evalCExpr = evalEExpr empty
+
+
+sanitize :: [[String]] -> [[String]]
+sanitize (["@define",n]:_:[y]:xs) = ["@define",n,y]:sanitize xs
+sanitize (["@define",x,y]:xs) = ["@define",x,y]:sanitize xs
+sanitize (_:xs) = sanitize xs
+sanitize [] = []
+
+getDefinitions :: String -> IO (Map String Integer)
+getDefinitions headers = do
+    defines <- map words . lines <$> readDefines headers
+    let isDefine (c:n:_) = c == "#define" && '(' `notElem` n && not ("_" `isPrefixOf` n)
+        isDefine xs = error ("isDefine: Couldn't check: " ++ show xs)
+        hasValue = (>= 3) . length
+        names = map (!! 1) $ filter (\d -> isDefine d && hasValue d) defines
+        kludge = map (\n -> "@define \"" ++ n ++ "\" " ++ n) names
+    defines2 <- map words . lines <$> preprocess (headers ++ unlines kludge)
+    let isInteresting d = hasValue d &&
+                          ["@define"] `isPrefixOf` d &&
+                          (all isNumber (d !! 2) || "0x" `isPrefixOf` (d !! 2) &&
+                           all isNumber (drop 2 (d !! 2)))
+        realDefines = map (take 2 . drop 1) $ filter isInteresting $ sanitize defines2
+        clean [(_:k),v] = (init k, read v)
+        clean _ = error "Clean: got a weird list"
+    return $ fromList (map clean realDefines)
+  where readDefines = readProcess "gcc" ["-E", "-dM", "-"]
+        preprocess  = readProcess "gcc" ["-E", "-"]
diff --git a/System/Linux/Netlink.hs b/System/Linux/Netlink.hs
--- a/System/Linux/Netlink.hs
+++ b/System/Linux/Netlink.hs
@@ -33,6 +33,7 @@
   , getNetlinkFd
   , closeSocket
   , joinMulticastGroup
+  , leaveMulticastGroup
 
   , query
   , queryOne
@@ -306,9 +307,16 @@
 -- |Join a netlink multicast group
 joinMulticastGroup
   :: NetlinkSocket -- ^The socket to join with
-  -> Word32  -- ^The id of the group to join
+  -> Word32  -- ^The id of the group to join, values of System.Linux.Netlink.Constants.eRTNLGRP_*
   -> IO ()
 joinMulticastGroup (NS fd) = C.joinMulticastGroup fd
+
+-- |Leave a netlink multicast group
+leaveMulticastGroup
+  :: NetlinkSocket -- ^The socket to leave
+  -> Word32  -- ^The id of the group to leave, values of System.Linux.Netlink.Constants.eRTNLGRP_*
+  -> IO ()
+leaveMulticastGroup (NS fd) = C.leaveMulticastGroup fd
 
 
 
diff --git a/System/Linux/Netlink/C.hsc b/System/Linux/Netlink/C.hsc
--- a/System/Linux/Netlink/C.hsc
+++ b/System/Linux/Netlink/C.hsc
@@ -16,6 +16,7 @@
     , sendmsg
     , recvmsg
     , joinMulticastGroup
+    , leaveMulticastGroup
     )
 where
 
@@ -38,7 +39,7 @@
 import Foreign.Ptr (Ptr, castPtr, plusPtr)
 import Foreign.Storable (Storable(..))
 
-import System.Linux.Netlink.Constants (eAF_NETLINK)
+import System.Linux.Netlink.Constants (eAF_NETLINK, eNETLINK_ADD_MEMBERSHIP, eNETLINK_DROP_MEMBERSHIP)
 
 #include <unistd.h>
 #include <string.h>
@@ -161,11 +162,25 @@
 void act = act >> return ()
 
 
--- |Join a netlink multicast group
-joinMulticastGroup :: CInt -> Word32 -> IO ()
-joinMulticastGroup fd fid = do
+-- |Set membership to netlink multicast group
+joinOrLeaveMulticastGroup :: Bool -> CInt -> Word32 -> IO ()
+joinOrLeaveMulticastGroup beMember fd fid = do
   _ <- throwErrnoIfMinus1 "joinMulticast" $ with fid (\ptr ->
-    c_setsockopt fd sol_netlink 1 (castPtr ptr) size)
+    c_setsockopt fd sol_netlink value (castPtr ptr) size)
   return ()
-  where size = fromIntegral $sizeOf (undefined :: CInt)
-        sol_netlink = 270 :: CInt
+  where
+    size = fromIntegral $sizeOf (undefined :: CInt)
+    sol_netlink = 270 :: CInt
+    value = if beMember
+      then eNETLINK_ADD_MEMBERSHIP
+      else eNETLINK_DROP_MEMBERSHIP
+
+-- |Join a netlink multicast group
+joinMulticastGroup :: CInt -> Word32 -> IO ()
+joinMulticastGroup = joinOrLeaveMulticastGroup True
+
+-- |Leave a netlink multicast group
+leaveMulticastGroup :: CInt -> Word32 -> IO ()
+leaveMulticastGroup = joinOrLeaveMulticastGroup False
+
+
diff --git a/System/Linux/Netlink/Constants.hs b/System/Linux/Netlink/Constants.hs
--- a/System/Linux/Netlink/Constants.hs
+++ b/System/Linux/Netlink/Constants.hs
@@ -1,6 +1,6 @@
 {-# OPTIONS_HADDOCK hide, prune, ignore-exports #-}
 {-# LANGUAGE GeneralizedNewtypeDeriving #-}
-module System.Linux.Netlink.Constants (AddressFamily, showAddressFamily, eAF_UNSPEC, eAF_FILE, eAF_LOCAL, eAF_UNIX, eAF_INET, eAF_AX25, eAF_IPX, eAF_APPLETALK, eAF_NETROM, eAF_BRIDGE, eAF_ATMPVC, eAF_X25, eAF_INET6, eAF_ROSE, eAF_DECnet, eAF_NETBEUI, eAF_SECURITY, eAF_KEY, eAF_NETLINK, eAF_ROUTE, eAF_PACKET, eAF_ASH, eAF_ECONET, eAF_ATMSVC, eAF_RDS, eAF_SNA, eAF_IRDA, eAF_PPPOX, eAF_WANPIPE, eAF_LLC, eAF_IB, eAF_MPLS, eAF_CAN, eAF_TIPC, eAF_BLUETOOTH, eAF_IUCV, eAF_RXRPC, eAF_ISDN, eAF_PHONET, eAF_IEEE802154, eAF_CAIF, eAF_ALG, eAF_NFC, eAF_VSOCK, eAF_MAX, MessageType, showMessageType, eNLMSG_NOOP, eNLMSG_ERROR, eNLMSG_DONE, eNLMSG_OVERRUN, eNLMSG_MIN_TYPE, eRTM_BASE, eRTM_NEWLINK, eRTM_DELLINK, eRTM_GETLINK, eRTM_SETLINK, eRTM_NEWADDR, eRTM_DELADDR, eRTM_GETADDR, eRTM_NEWROUTE, eRTM_DELROUTE, eRTM_GETROUTE, eRTM_NEWNEIGH, eRTM_DELNEIGH, eRTM_GETNEIGH, eRTM_NEWRULE, eRTM_DELRULE, eRTM_GETRULE, eRTM_NEWQDISC, eRTM_DELQDISC, eRTM_GETQDISC, eRTM_NEWTCLASS, eRTM_DELTCLASS, eRTM_GETTCLASS, eRTM_NEWTFILTER, eRTM_DELTFILTER, eRTM_GETTFILTER, eRTM_NEWACTION, eRTM_DELACTION, eRTM_GETACTION, eRTM_NEWPREFIX, eRTM_GETMULTICAST, eRTM_GETANYCAST, eRTM_NEWNEIGHTBL, eRTM_GETNEIGHTBL, eRTM_SETNEIGHTBL, eRTM_NEWNDUSEROPT, eRTM_NEWADDRLABEL, eRTM_DELADDRLABEL, eRTM_GETADDRLABEL, eRTM_GETDCB, eRTM_SETDCB, eRTM_NEWNETCONF, eRTM_GETNETCONF, eRTM_NEWMDB, eRTM_DELMDB, eRTM_GETMDB, eRTM_NEWNSID, eRTM_DELNSID, eRTM_GETNSID, MessageFlags, fNLM_F_REQUEST, fNLM_F_MULTI, fNLM_F_ACK, fNLM_F_ECHO, fNLM_F_DUMP_INTR, fNLM_F_DUMP_FILTERED, fNLM_F_REPLACE, fNLM_F_ROOT, fNLM_F_EXCL, fNLM_F_MATCH, fNLM_F_ATOMIC, fNLM_F_CREATE, fNLM_F_APPEND, LinkType, showLinkType, eARPHRD_NETROM, eARPHRD_ETHER, eARPHRD_EETHER, eARPHRD_AX25, eARPHRD_PRONET, eARPHRD_CHAOS, eARPHRD_IEEE802, eARPHRD_ARCNET, eARPHRD_APPLETLK, eARPHRD_DLCI, eARPHRD_ATM, eARPHRD_METRICOM, eARPHRD_IEEE1394, eARPHRD_EUI64, eARPHRD_INFINIBAND, eARPHRD_SLIP, eARPHRD_CSLIP, eARPHRD_SLIP6, eARPHRD_CSLIP6, eARPHRD_RSRVD, eARPHRD_ADAPT, eARPHRD_ROSE, eARPHRD_X25, eARPHRD_HWX25, eARPHRD_CAN, eARPHRD_PPP, eARPHRD_CISCO, eARPHRD_HDLC, eARPHRD_LAPB, eARPHRD_DDCMP, eARPHRD_RAWHDLC, eARPHRD_TUNNEL, eARPHRD_TUNNEL6, eARPHRD_FRAD, eARPHRD_SKIP, eARPHRD_LOOPBACK, eARPHRD_LOCALTLK, eARPHRD_FDDI, eARPHRD_BIF, eARPHRD_SIT, eARPHRD_IPDDP, eARPHRD_IPGRE, eARPHRD_PIMREG, eARPHRD_HIPPI, eARPHRD_ASH, eARPHRD_ECONET, eARPHRD_IRDA, eARPHRD_FCPP, eARPHRD_FCAL, eARPHRD_FCPL, eARPHRD_FCFABRIC, eARPHRD_IEEE802_TR, eARPHRD_IEEE80211, eARPHRD_IEEE80211_PRISM, eARPHRD_IEEE80211_RADIOTAP, eARPHRD_IEEE802154, eARPHRD_IEEE802154_MONITOR, eARPHRD_PHONET, eARPHRD_PHONET_PIPE, eARPHRD_CAIF, eARPHRD_IP6GRE, eARPHRD_NETLINK, eARPHRD_6LOWPAN, LinkFlags, fIFF_TUN, fIFF_UP, fIFF_BROADCAST, fIFF_TAP, fIFF_DEBUG, fIFF_LOOPBACK, fIFF_POINTOPOINT, fIFF_NOTRAILERS, fIFF_RUNNING, fIFF_NOARP, fIFF_MULTI_QUEUE, fIFF_PROMISC, fIFF_ALLMULTI, fIFF_ATTACH_QUEUE, fIFF_DETACH_QUEUE, fIFF_MASTER, fIFF_PERSIST, fIFF_SLAVE, fIFF_MULTICAST, fIFF_NOFILTER, fIFF_NO_PI, fIFF_ONE_QUEUE, fIFF_PORTSEL, fIFF_AUTOMEDIA, fIFF_VNET_HDR, fIFF_DYNAMIC, fIFF_TUN_EXCL, fIFF_LOWER_UP, fIFF_DORMANT, fIFF_ECHO, LinkAttrType, showLinkAttrType, eIFLA_UNSPEC, eIFLA_ADDRESS, eIFLA_BROADCAST, eIFLA_IFNAME, eIFLA_MTU, eIFLA_LINK, eIFLA_QDISC, eIFLA_STATS, eIFLA_COST, eIFLA_PRIORITY, eIFLA_MASTER, eIFLA_WIRELESS, eIFLA_PROTINFO, eIFLA_TXQLEN, eIFLA_MAP, eIFLA_WEIGHT, eIFLA_OPERSTATE, eIFLA_LINKMODE, eIFLA_LINKINFO, eIFLA_NET_NS_PID, eIFLA_IFALIAS, eIFLA_NUM_VF, eIFLA_VFINFO_LIST, eIFLA_STATS64, eIFLA_VF_PORTS, eIFLA_PORT_SELF, eIFLA_AF_SPEC, eIFLA_GROUP, eIFLA_NET_NS_FD, eIFLA_EXT_MASK, eIFLA_PROMISCUITY, eIFLA_NUM_TX_QUEUES, eIFLA_NUM_RX_QUEUES, eIFLA_CARRIER, eIFLA_PHYS_PORT_ID, eIFLA_CARRIER_CHANGES, eIFLA_PHYS_SWITCH_ID, eIFLA_LINK_NETNSID, eIFLA_PHYS_PORT_NAME, eIFLA_PROTO_DOWN, AddrFlags, fIFA_F_SECONDARY, fIFA_F_TEMPORARY, fIFA_F_NODAD, fIFA_F_OPTIMISTIC, fIFA_F_DADFAILED, fIFA_F_HOMEADDRESS, fIFA_F_DEPRECATED, fIFA_F_TENTATIVE, fIFA_F_PERMANENT, fIFA_F_MANAGETEMPADDR, fIFA_F_NOPREFIXROUTE, fIFA_F_MCAUTOJOIN, fIFA_F_STABLE_PRIVACY, Scope, showScope, eRT_SCOPE_UNIVERSE, eRT_SCOPE_SITE, eRT_SCOPE_LINK, eRT_SCOPE_HOST, eRT_SCOPE_NOWHERE, AddrAttrType, showAddrAttrType, eIFA_UNSPEC, eIFA_ADDRESS, eIFA_LOCAL, eIFA_LABEL, eIFA_BROADCAST, eIFA_ANYCAST, eIFA_CACHEINFO, eIFA_MULTICAST, eIFA_FLAGS, RouteTableId, showRouteTableId, eRT_TABLE_UNSPEC, eRT_TABLE_COMPAT, eRT_TABLE_DEFAULT, eRT_TABLE_MAIN, eRT_TABLE_LOCAL, eRT_TABLE_MAX, RouteProto, showRouteProto, eRTPROT_UNSPEC, eRTPROT_REDIRECT, eRTPROT_KERNEL, eRTPROT_BOOT, eRTPROT_STATIC, eRTPROT_GATED, eRTPROT_RA, eRTPROT_MRT, eRTPROT_ZEBRA, eRTPROT_BIRD, eRTPROT_DNROUTED, eRTPROT_XORP, eRTPROT_NTK, eRTPROT_DHCP, eRTPROT_MROUTED, eRTPROT_BABEL, RouteType, showRouteType, eRTN_UNSPEC, eRTN_UNICAST, eRTN_LOCAL, eRTN_BROADCAST, eRTN_ANYCAST, eRTN_MULTICAST, eRTN_BLACKHOLE, eRTN_UNREACHABLE, eRTN_PROHIBIT, eRTN_THROW, eRTN_NAT, eRTN_XRESOLVE, RouteFlags, fRTM_F_NOTIFY, fRTM_F_CLONED, fRTM_F_EQUALIZE, fRTM_F_PREFIX, fRTM_F_LOOKUP_TABLE, RouteAttrType, showRouteAttrType, eRTA_UNSPEC, eRTA_DST, eRTA_SRC, eRTA_IIF, eRTA_OIF, eRTA_GATEWAY, eRTA_PRIORITY, eRTA_PREFSRC, eRTA_METRICS, eRTA_MULTIPATH, eRTA_PROTOINFO, eRTA_FLOW, eRTA_CACHEINFO, eRTA_SESSION, eRTA_MP_ALGO, eRTA_TABLE, eRTA_MARK, eRTA_MFC_STATS, eRTA_VIA, eRTA_NEWDST, eRTA_PREF, eRTA_ENCAP_TYPE, eRTA_ENCAP) where
+module System.Linux.Netlink.Constants (AddressFamily, showAddressFamily, eAF_UNSPEC, eAF_FILE, eAF_LOCAL, eAF_UNIX, eAF_INET, eAF_AX25, eAF_IPX, eAF_APPLETALK, eAF_NETROM, eAF_BRIDGE, eAF_ATMPVC, eAF_X25, eAF_INET6, eAF_ROSE, eAF_DECnet, eAF_NETBEUI, eAF_SECURITY, eAF_KEY, eAF_NETLINK, eAF_ROUTE, eAF_PACKET, eAF_ASH, eAF_ECONET, eAF_ATMSVC, eAF_RDS, eAF_SNA, eAF_IRDA, eAF_PPPOX, eAF_WANPIPE, eAF_LLC, eAF_IB, eAF_MPLS, eAF_CAN, eAF_TIPC, eAF_BLUETOOTH, eAF_IUCV, eAF_RXRPC, eAF_ISDN, eAF_PHONET, eAF_IEEE802154, eAF_CAIF, eAF_ALG, eAF_NFC, eAF_VSOCK, eAF_KCM, eAF_MAX, MessageType, showMessageType, eNLMSG_NOOP, eNLMSG_ERROR, eNLMSG_DONE, eNLMSG_OVERRUN, eNLMSG_MIN_TYPE, eRTM_BASE, eRTM_NEWLINK, eRTM_DELLINK, eRTM_GETLINK, eRTM_SETLINK, eRTM_NEWADDR, eRTM_DELADDR, eRTM_GETADDR, eRTM_NEWROUTE, eRTM_DELROUTE, eRTM_GETROUTE, eRTM_NEWNEIGH, eRTM_DELNEIGH, eRTM_GETNEIGH, eRTM_NEWRULE, eRTM_DELRULE, eRTM_GETRULE, eRTM_NEWQDISC, eRTM_DELQDISC, eRTM_GETQDISC, eRTM_NEWTCLASS, eRTM_DELTCLASS, eRTM_GETTCLASS, eRTM_NEWTFILTER, eRTM_DELTFILTER, eRTM_GETTFILTER, eRTM_NEWACTION, eRTM_DELACTION, eRTM_GETACTION, eRTM_NEWPREFIX, eRTM_GETMULTICAST, eRTM_GETANYCAST, eRTM_NEWNEIGHTBL, eRTM_GETNEIGHTBL, eRTM_SETNEIGHTBL, eRTM_NEWNDUSEROPT, eRTM_NEWADDRLABEL, eRTM_DELADDRLABEL, eRTM_GETADDRLABEL, eRTM_GETDCB, eRTM_SETDCB, eRTM_NEWNETCONF, eRTM_GETNETCONF, eRTM_NEWMDB, eRTM_DELMDB, eRTM_GETMDB, eRTM_NEWNSID, eRTM_DELNSID, eRTM_GETNSID, eRTM_NEWSTATS, eRTM_GETSTATS, MessageFlags, fNLM_F_REQUEST, fNLM_F_MULTI, fNLM_F_ACK, fNLM_F_ECHO, fNLM_F_DUMP_INTR, fNLM_F_DUMP_FILTERED, fNLM_F_REPLACE, fNLM_F_ROOT, fNLM_F_EXCL, fNLM_F_MATCH, fNLM_F_ATOMIC, fNLM_F_CREATE, fNLM_F_APPEND, LinkType, showLinkType, eARPHRD_NETROM, eARPHRD_ETHER, eARPHRD_EETHER, eARPHRD_AX25, eARPHRD_PRONET, eARPHRD_CHAOS, eARPHRD_IEEE802, eARPHRD_ARCNET, eARPHRD_APPLETLK, eARPHRD_DLCI, eARPHRD_ATM, eARPHRD_METRICOM, eARPHRD_IEEE1394, eARPHRD_EUI64, eARPHRD_INFINIBAND, eARPHRD_SLIP, eARPHRD_CSLIP, eARPHRD_SLIP6, eARPHRD_CSLIP6, eARPHRD_RSRVD, eARPHRD_ADAPT, eARPHRD_ROSE, eARPHRD_X25, eARPHRD_HWX25, eARPHRD_CAN, eARPHRD_PPP, eARPHRD_CISCO, eARPHRD_HDLC, eARPHRD_LAPB, eARPHRD_DDCMP, eARPHRD_RAWHDLC, eARPHRD_TUNNEL, eARPHRD_TUNNEL6, eARPHRD_FRAD, eARPHRD_SKIP, eARPHRD_LOOPBACK, eARPHRD_LOCALTLK, eARPHRD_FDDI, eARPHRD_BIF, eARPHRD_SIT, eARPHRD_IPDDP, eARPHRD_IPGRE, eARPHRD_PIMREG, eARPHRD_HIPPI, eARPHRD_ASH, eARPHRD_ECONET, eARPHRD_IRDA, eARPHRD_FCPP, eARPHRD_FCAL, eARPHRD_FCPL, eARPHRD_FCFABRIC, eARPHRD_IEEE802_TR, eARPHRD_IEEE80211, eARPHRD_IEEE80211_PRISM, eARPHRD_IEEE80211_RADIOTAP, eARPHRD_IEEE802154, eARPHRD_IEEE802154_MONITOR, eARPHRD_PHONET, eARPHRD_PHONET_PIPE, eARPHRD_CAIF, eARPHRD_IP6GRE, eARPHRD_NETLINK, eARPHRD_6LOWPAN, LinkFlags, fIFF_TUN, fIFF_UP, fIFF_BROADCAST, fIFF_TAP, fIFF_DEBUG, fIFF_LOOPBACK, fIFF_POINTOPOINT, fIFF_NOTRAILERS, fIFF_RUNNING, fIFF_NOARP, fIFF_MULTI_QUEUE, fIFF_PROMISC, fIFF_ALLMULTI, fIFF_ATTACH_QUEUE, fIFF_DETACH_QUEUE, fIFF_MASTER, fIFF_PERSIST, fIFF_SLAVE, fIFF_MULTICAST, fIFF_NOFILTER, fIFF_NO_PI, fIFF_ONE_QUEUE, fIFF_PORTSEL, fIFF_AUTOMEDIA, fIFF_VNET_HDR, fIFF_DYNAMIC, fIFF_TUN_EXCL, fIFF_LOWER_UP, fIFF_DORMANT, fIFF_ECHO, LinkAttrType, showLinkAttrType, eIFLA_UNSPEC, eIFLA_ADDRESS, eIFLA_BROADCAST, eIFLA_IFNAME, eIFLA_MTU, eIFLA_LINK, eIFLA_QDISC, eIFLA_STATS, eIFLA_COST, eIFLA_PRIORITY, eIFLA_MASTER, eIFLA_WIRELESS, eIFLA_PROTINFO, eIFLA_TXQLEN, eIFLA_MAP, eIFLA_WEIGHT, eIFLA_OPERSTATE, eIFLA_LINKMODE, eIFLA_LINKINFO, eIFLA_NET_NS_PID, eIFLA_IFALIAS, eIFLA_NUM_VF, eIFLA_VFINFO_LIST, eIFLA_STATS64, eIFLA_VF_PORTS, eIFLA_PORT_SELF, eIFLA_AF_SPEC, eIFLA_GROUP, eIFLA_NET_NS_FD, eIFLA_EXT_MASK, eIFLA_PROMISCUITY, eIFLA_NUM_TX_QUEUES, eIFLA_NUM_RX_QUEUES, eIFLA_CARRIER, eIFLA_PHYS_PORT_ID, eIFLA_CARRIER_CHANGES, eIFLA_PHYS_SWITCH_ID, eIFLA_LINK_NETNSID, eIFLA_PHYS_PORT_NAME, eIFLA_PROTO_DOWN, eIFLA_GSO_MAX_SEGS, eIFLA_GSO_MAX_SIZE, eIFLA_PAD, eIFLA_XDP, AddrFlags, fIFA_F_SECONDARY, fIFA_F_TEMPORARY, fIFA_F_NODAD, fIFA_F_OPTIMISTIC, fIFA_F_DADFAILED, fIFA_F_HOMEADDRESS, fIFA_F_DEPRECATED, fIFA_F_TENTATIVE, fIFA_F_PERMANENT, fIFA_F_MANAGETEMPADDR, fIFA_F_NOPREFIXROUTE, fIFA_F_MCAUTOJOIN, fIFA_F_STABLE_PRIVACY, Scope, showScope, eRT_SCOPE_UNIVERSE, eRT_SCOPE_SITE, eRT_SCOPE_LINK, eRT_SCOPE_HOST, eRT_SCOPE_NOWHERE, AddrAttrType, showAddrAttrType, eIFA_UNSPEC, eIFA_ADDRESS, eIFA_LOCAL, eIFA_LABEL, eIFA_BROADCAST, eIFA_ANYCAST, eIFA_CACHEINFO, eIFA_MULTICAST, eIFA_FLAGS, RouteTableId, showRouteTableId, eRT_TABLE_UNSPEC, eRT_TABLE_COMPAT, eRT_TABLE_DEFAULT, eRT_TABLE_MAIN, eRT_TABLE_LOCAL, eRT_TABLE_MAX, RouteProto, showRouteProto, eRTPROT_UNSPEC, eRTPROT_REDIRECT, eRTPROT_KERNEL, eRTPROT_BOOT, eRTPROT_STATIC, eRTPROT_GATED, eRTPROT_RA, eRTPROT_MRT, eRTPROT_ZEBRA, eRTPROT_BIRD, eRTPROT_DNROUTED, eRTPROT_XORP, eRTPROT_NTK, eRTPROT_DHCP, eRTPROT_MROUTED, eRTPROT_BABEL, RouteType, showRouteType, eRTN_UNSPEC, eRTN_UNICAST, eRTN_LOCAL, eRTN_BROADCAST, eRTN_ANYCAST, eRTN_MULTICAST, eRTN_BLACKHOLE, eRTN_UNREACHABLE, eRTN_PROHIBIT, eRTN_THROW, eRTN_NAT, eRTN_XRESOLVE, RouteFlags, fRTM_F_NOTIFY, fRTM_F_CLONED, fRTM_F_EQUALIZE, fRTM_F_PREFIX, fRTM_F_LOOKUP_TABLE, RouteAttrType, showRouteAttrType, eRTA_UNSPEC, eRTA_DST, eRTA_SRC, eRTA_IIF, eRTA_OIF, eRTA_GATEWAY, eRTA_PRIORITY, eRTA_PREFSRC, eRTA_METRICS, eRTA_MULTIPATH, eRTA_PROTOINFO, eRTA_FLOW, eRTA_CACHEINFO, eRTA_SESSION, eRTA_MP_ALGO, eRTA_TABLE, eRTA_MARK, eRTA_MFC_STATS, eRTA_VIA, eRTA_NEWDST, eRTA_PREF, eRTA_ENCAP_TYPE, eRTA_ENCAP, eRTA_EXPIRES, eRTA_PAD, eRTA_UID, NeighAttrType, showNeighAttrType, eNDA_UNSPEC, eNDA_DST, eNDA_LLADDR, eNDA_CACHEINFO, eNDA_PROBES, eNDA_VLAN, eNDA_PORT, eNDA_VNI, eNDA_IFINDEX, eNDA_MASTER, eNDA_LINK_NETNSID, NeighStateFlags, fNUD_NONE, fNUD_INCOMPLETE, fNUD_REACHABLE, fNUD_STALE, fNUD_DELAY, fNUD_PROBE, fNUD_FAILED, fNUD_NOARP, fNUD_PERMANENT, NetlinkFamily, showNetlinkFamily, eNETLINK_ROUTE, eNETLINK_ADD_MEMBERSHIP, eNETLINK_UNUSED, eNETLINK_DROP_MEMBERSHIP, eNETLINK_USERSOCK, eNETLINK_FIREWALL, eNETLINK_PKTINFO, eNETLINK_BROADCAST_ERROR, eNETLINK_INET_DIAG, eNETLINK_SOCK_DIAG, eNETLINK_NFLOG, eNETLINK_NO_ENOBUFS, eNETLINK_RX_RING, eNETLINK_XFRM, eNETLINK_SELINUX, eNETLINK_TX_RING, eNETLINK_ISCSI, eNETLINK_LISTEN_ALL_NSID, eNETLINK_AUDIT, eNETLINK_LIST_MEMBERSHIPS, eNETLINK_CAP_ACK, eNETLINK_FIB_LOOKUP, eNETLINK_CONNECTOR, eNETLINK_NETFILTER, eNETLINK_IP6_FW, eNETLINK_DNRTMSG, eNETLINK_KOBJECT_UEVENT, eNETLINK_GENERIC, eNETLINK_SCSITRANSPORT, eNETLINK_ECRYPTFS, eNETLINK_RDMA, eNETLINK_CRYPTO, RtNetlinkGroups, showRtNetlinkGroups, eRTNLGRP_NONE, eRTNLGRP_LINK, eRTNLGRP_NOTIFY, eRTNLGRP_NEIGH, eRTNLGRP_TC, eRTNLGRP_IPV4_IFADDR, eRTNLGRP_IPV4_MROUTE, eRTNLGRP_IPV4_ROUTE, eRTNLGRP_IPV4_RULE, eRTNLGRP_IPV6_IFADDR, eRTNLGRP_IPV6_MROUTE, eRTNLGRP_IPV6_ROUTE, eRTNLGRP_IPV6_IFINFO, eRTNLGRP_DECnet_IFADDR, eRTNLGRP_NOP2, eRTNLGRP_DECnet_ROUTE, eRTNLGRP_DECnet_RULE, eRTNLGRP_NOP4, eRTNLGRP_IPV6_PREFIX, eRTNLGRP_IPV6_RULE, eRTNLGRP_ND_USEROPT, eRTNLGRP_PHONET_IFADDR, eRTNLGRP_PHONET_ROUTE, eRTNLGRP_DCB, eRTNLGRP_IPV4_NETCONF, eRTNLGRP_IPV6_NETCONF, eRTNLGRP_MDB, eRTNLGRP_MPLS_ROUTE, eRTNLGRP_NSID) where
 
 import Data.Bits
 
@@ -48,7 +48,8 @@
 showAddressFamily 38 = "AF_ALG"
 showAddressFamily 39 = "AF_NFC"
 showAddressFamily 40 = "AF_VSOCK"
-showAddressFamily 41 = "AF_MAX"
+showAddressFamily 41 = "AF_KCM"
+showAddressFamily 42 = "AF_MAX"
 showAddressFamily i = "AddressFamily #" ++ (show i)
 
 
@@ -140,8 +141,10 @@
 eAF_NFC = 39
 eAF_VSOCK :: (Num a) => a
 eAF_VSOCK = 40
+eAF_KCM :: (Num a) => a
+eAF_KCM = 41
 eAF_MAX :: (Num a) => a
-eAF_MAX = 41
+eAF_MAX = 42
 newtype MessageType = MessageType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)
 
 showMessageType :: (Num a) => (Show a) => (Eq a) => a -> String
@@ -197,6 +200,8 @@
 showMessageType 88 = "RTM_NEWNSID"
 showMessageType 89 = "RTM_DELNSID"
 showMessageType 90 = "RTM_GETNSID"
+showMessageType 92 = "RTM_NEWSTATS"
+showMessageType 94 = "RTM_GETSTATS"
 showMessageType i = "MessageType #" ++ (show i)
 
 
@@ -308,6 +313,10 @@
 eRTM_DELNSID = 89
 eRTM_GETNSID :: (Num a) => a
 eRTM_GETNSID = 90
+eRTM_NEWSTATS :: (Num a) => a
+eRTM_NEWSTATS = 92
+eRTM_GETSTATS :: (Num a) => a
+eRTM_GETSTATS = 94
 newtype MessageFlags = MessageFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)
 
 fNLM_F_REQUEST :: (Num a, Bits a) => a
@@ -635,6 +644,10 @@
 showLinkAttrType 37 = "IFLA_LINK_NETNSID"
 showLinkAttrType 38 = "IFLA_PHYS_PORT_NAME"
 showLinkAttrType 39 = "IFLA_PROTO_DOWN"
+showLinkAttrType 40 = "IFLA_GSO_MAX_SEGS"
+showLinkAttrType 41 = "IFLA_GSO_MAX_SIZE"
+showLinkAttrType 42 = "IFLA_PAD"
+showLinkAttrType 43 = "IFLA_XDP"
 showLinkAttrType i = "LinkAttrType #" ++ (show i)
 
 
@@ -718,6 +731,14 @@
 eIFLA_PHYS_PORT_NAME = 38
 eIFLA_PROTO_DOWN :: (Num a) => a
 eIFLA_PROTO_DOWN = 39
+eIFLA_GSO_MAX_SEGS :: (Num a) => a
+eIFLA_GSO_MAX_SEGS = 40
+eIFLA_GSO_MAX_SIZE :: (Num a) => a
+eIFLA_GSO_MAX_SIZE = 41
+eIFLA_PAD :: (Num a) => a
+eIFLA_PAD = 42
+eIFLA_XDP :: (Num a) => a
+eIFLA_XDP = 43
 newtype AddrFlags = AddrFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)
 
 fIFA_F_SECONDARY :: (Num a, Bits a) => a
@@ -958,6 +979,9 @@
 showRouteAttrType 20 = "RTA_PREF"
 showRouteAttrType 21 = "RTA_ENCAP_TYPE"
 showRouteAttrType 22 = "RTA_ENCAP"
+showRouteAttrType 23 = "RTA_EXPIRES"
+showRouteAttrType 24 = "RTA_PAD"
+showRouteAttrType 25 = "RTA_UID"
 showRouteAttrType i = "RouteAttrType #" ++ (show i)
 
 
@@ -1007,3 +1031,252 @@
 eRTA_ENCAP_TYPE = 21
 eRTA_ENCAP :: (Num a) => a
 eRTA_ENCAP = 22
+eRTA_EXPIRES :: (Num a) => a
+eRTA_EXPIRES = 23
+eRTA_PAD :: (Num a) => a
+eRTA_PAD = 24
+eRTA_UID :: (Num a) => a
+eRTA_UID = 25
+newtype NeighAttrType = NeighAttrType Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)
+
+showNeighAttrType :: (Num a) => (Show a) => (Eq a) => a -> String
+showNeighAttrType 0 = "NDA_UNSPEC"
+showNeighAttrType 1 = "NDA_DST"
+showNeighAttrType 2 = "NDA_LLADDR"
+showNeighAttrType 3 = "NDA_CACHEINFO"
+showNeighAttrType 4 = "NDA_PROBES"
+showNeighAttrType 5 = "NDA_VLAN"
+showNeighAttrType 6 = "NDA_PORT"
+showNeighAttrType 7 = "NDA_VNI"
+showNeighAttrType 8 = "NDA_IFINDEX"
+showNeighAttrType 9 = "NDA_MASTER"
+showNeighAttrType 10 = "NDA_LINK_NETNSID"
+showNeighAttrType i = "NeighAttrType #" ++ (show i)
+
+
+eNDA_UNSPEC :: (Num a) => a
+eNDA_UNSPEC = 0
+eNDA_DST :: (Num a) => a
+eNDA_DST = 1
+eNDA_LLADDR :: (Num a) => a
+eNDA_LLADDR = 2
+eNDA_CACHEINFO :: (Num a) => a
+eNDA_CACHEINFO = 3
+eNDA_PROBES :: (Num a) => a
+eNDA_PROBES = 4
+eNDA_VLAN :: (Num a) => a
+eNDA_VLAN = 5
+eNDA_PORT :: (Num a) => a
+eNDA_PORT = 6
+eNDA_VNI :: (Num a) => a
+eNDA_VNI = 7
+eNDA_IFINDEX :: (Num a) => a
+eNDA_IFINDEX = 8
+eNDA_MASTER :: (Num a) => a
+eNDA_MASTER = 9
+eNDA_LINK_NETNSID :: (Num a) => a
+eNDA_LINK_NETNSID = 10
+newtype NeighStateFlags = NeighStateFlags Int deriving (Bits, Eq, Enum, Integral, Num, Ord, Real, Show)
+
+fNUD_NONE :: (Num a, Bits a) => a
+fNUD_NONE = 0
+fNUD_INCOMPLETE :: (Num a, Bits a) => a
+fNUD_INCOMPLETE = 1
+fNUD_REACHABLE :: (Num a, Bits a) => a
+fNUD_REACHABLE = 2
+fNUD_STALE :: (Num a, Bits a) => a
+fNUD_STALE = 4
+fNUD_DELAY :: (Num a, Bits a) => a
+fNUD_DELAY = 8
+fNUD_PROBE :: (Num a, Bits a) => a
+fNUD_PROBE = 16
+fNUD_FAILED :: (Num a, Bits a) => a
+fNUD_FAILED = 32
+fNUD_NOARP :: (Num a, Bits a) => a
+fNUD_NOARP = 64
+fNUD_PERMANENT :: (Num a, Bits a) => a
+fNUD_PERMANENT = 128
+newtype NetlinkFamily = NetlinkFamily Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)
+
+showNetlinkFamily :: (Num a) => (Show a) => (Eq a) => a -> String
+showNetlinkFamily 0 = "NETLINK_ROUTE"
+showNetlinkFamily 1 = "NETLINK_ADD_MEMBERSHIP"
+showNetlinkFamily 2 = "NETLINK_DROP_MEMBERSHIP"
+showNetlinkFamily 3 = "NETLINK_FIREWALL"
+showNetlinkFamily 4 = "NETLINK_BROADCAST_ERROR"
+showNetlinkFamily 5 = "NETLINK_NFLOG"
+showNetlinkFamily 6 = "NETLINK_RX_RING"
+showNetlinkFamily 7 = "NETLINK_SELINUX"
+showNetlinkFamily 8 = "NETLINK_ISCSI"
+showNetlinkFamily 9 = "NETLINK_AUDIT"
+showNetlinkFamily 10 = "NETLINK_CAP_ACK"
+showNetlinkFamily 11 = "NETLINK_CONNECTOR"
+showNetlinkFamily 12 = "NETLINK_NETFILTER"
+showNetlinkFamily 13 = "NETLINK_IP6_FW"
+showNetlinkFamily 14 = "NETLINK_DNRTMSG"
+showNetlinkFamily 15 = "NETLINK_KOBJECT_UEVENT"
+showNetlinkFamily 16 = "NETLINK_GENERIC"
+showNetlinkFamily 18 = "NETLINK_SCSITRANSPORT"
+showNetlinkFamily 19 = "NETLINK_ECRYPTFS"
+showNetlinkFamily 20 = "NETLINK_RDMA"
+showNetlinkFamily 21 = "NETLINK_CRYPTO"
+showNetlinkFamily i = "NetlinkFamily #" ++ (show i)
+
+
+eNETLINK_ROUTE :: (Num a) => a
+eNETLINK_ROUTE = 0
+eNETLINK_ADD_MEMBERSHIP :: (Num a) => a
+eNETLINK_ADD_MEMBERSHIP = 1
+eNETLINK_UNUSED :: (Num a) => a
+eNETLINK_UNUSED = 1
+eNETLINK_DROP_MEMBERSHIP :: (Num a) => a
+eNETLINK_DROP_MEMBERSHIP = 2
+eNETLINK_USERSOCK :: (Num a) => a
+eNETLINK_USERSOCK = 2
+eNETLINK_FIREWALL :: (Num a) => a
+eNETLINK_FIREWALL = 3
+eNETLINK_PKTINFO :: (Num a) => a
+eNETLINK_PKTINFO = 3
+eNETLINK_BROADCAST_ERROR :: (Num a) => a
+eNETLINK_BROADCAST_ERROR = 4
+eNETLINK_INET_DIAG :: (Num a) => a
+eNETLINK_INET_DIAG = 4
+eNETLINK_SOCK_DIAG :: (Num a) => a
+eNETLINK_SOCK_DIAG = 4
+eNETLINK_NFLOG :: (Num a) => a
+eNETLINK_NFLOG = 5
+eNETLINK_NO_ENOBUFS :: (Num a) => a
+eNETLINK_NO_ENOBUFS = 5
+eNETLINK_RX_RING :: (Num a) => a
+eNETLINK_RX_RING = 6
+eNETLINK_XFRM :: (Num a) => a
+eNETLINK_XFRM = 6
+eNETLINK_SELINUX :: (Num a) => a
+eNETLINK_SELINUX = 7
+eNETLINK_TX_RING :: (Num a) => a
+eNETLINK_TX_RING = 7
+eNETLINK_ISCSI :: (Num a) => a
+eNETLINK_ISCSI = 8
+eNETLINK_LISTEN_ALL_NSID :: (Num a) => a
+eNETLINK_LISTEN_ALL_NSID = 8
+eNETLINK_AUDIT :: (Num a) => a
+eNETLINK_AUDIT = 9
+eNETLINK_LIST_MEMBERSHIPS :: (Num a) => a
+eNETLINK_LIST_MEMBERSHIPS = 9
+eNETLINK_CAP_ACK :: (Num a) => a
+eNETLINK_CAP_ACK = 10
+eNETLINK_FIB_LOOKUP :: (Num a) => a
+eNETLINK_FIB_LOOKUP = 10
+eNETLINK_CONNECTOR :: (Num a) => a
+eNETLINK_CONNECTOR = 11
+eNETLINK_NETFILTER :: (Num a) => a
+eNETLINK_NETFILTER = 12
+eNETLINK_IP6_FW :: (Num a) => a
+eNETLINK_IP6_FW = 13
+eNETLINK_DNRTMSG :: (Num a) => a
+eNETLINK_DNRTMSG = 14
+eNETLINK_KOBJECT_UEVENT :: (Num a) => a
+eNETLINK_KOBJECT_UEVENT = 15
+eNETLINK_GENERIC :: (Num a) => a
+eNETLINK_GENERIC = 16
+eNETLINK_SCSITRANSPORT :: (Num a) => a
+eNETLINK_SCSITRANSPORT = 18
+eNETLINK_ECRYPTFS :: (Num a) => a
+eNETLINK_ECRYPTFS = 19
+eNETLINK_RDMA :: (Num a) => a
+eNETLINK_RDMA = 20
+eNETLINK_CRYPTO :: (Num a) => a
+eNETLINK_CRYPTO = 21
+newtype RtNetlinkGroups = RtNetlinkGroups Int deriving (Eq, Enum, Integral, Num, Ord, Real, Show)
+
+showRtNetlinkGroups :: (Num a) => (Show a) => (Eq a) => a -> String
+showRtNetlinkGroups 0 = "RTNLGRP_NONE"
+showRtNetlinkGroups 1 = "RTNLGRP_LINK"
+showRtNetlinkGroups 2 = "RTNLGRP_NOTIFY"
+showRtNetlinkGroups 3 = "RTNLGRP_NEIGH"
+showRtNetlinkGroups 4 = "RTNLGRP_TC"
+showRtNetlinkGroups 5 = "RTNLGRP_IPV4_IFADDR"
+showRtNetlinkGroups 6 = "RTNLGRP_IPV4_MROUTE"
+showRtNetlinkGroups 7 = "RTNLGRP_IPV4_ROUTE"
+showRtNetlinkGroups 8 = "RTNLGRP_IPV4_RULE"
+showRtNetlinkGroups 9 = "RTNLGRP_IPV6_IFADDR"
+showRtNetlinkGroups 10 = "RTNLGRP_IPV6_MROUTE"
+showRtNetlinkGroups 11 = "RTNLGRP_IPV6_ROUTE"
+showRtNetlinkGroups 12 = "RTNLGRP_IPV6_IFINFO"
+showRtNetlinkGroups 13 = "RTNLGRP_DECnet_IFADDR"
+showRtNetlinkGroups 14 = "RTNLGRP_NOP2"
+showRtNetlinkGroups 15 = "RTNLGRP_DECnet_ROUTE"
+showRtNetlinkGroups 16 = "RTNLGRP_DECnet_RULE"
+showRtNetlinkGroups 17 = "RTNLGRP_NOP4"
+showRtNetlinkGroups 18 = "RTNLGRP_IPV6_PREFIX"
+showRtNetlinkGroups 19 = "RTNLGRP_IPV6_RULE"
+showRtNetlinkGroups 20 = "RTNLGRP_ND_USEROPT"
+showRtNetlinkGroups 21 = "RTNLGRP_PHONET_IFADDR"
+showRtNetlinkGroups 22 = "RTNLGRP_PHONET_ROUTE"
+showRtNetlinkGroups 23 = "RTNLGRP_DCB"
+showRtNetlinkGroups 24 = "RTNLGRP_IPV4_NETCONF"
+showRtNetlinkGroups 25 = "RTNLGRP_IPV6_NETCONF"
+showRtNetlinkGroups 26 = "RTNLGRP_MDB"
+showRtNetlinkGroups 27 = "RTNLGRP_MPLS_ROUTE"
+showRtNetlinkGroups 28 = "RTNLGRP_NSID"
+showRtNetlinkGroups i = "RtNetlinkGroups #" ++ (show i)
+
+
+eRTNLGRP_NONE :: (Num a) => a
+eRTNLGRP_NONE = 0
+eRTNLGRP_LINK :: (Num a) => a
+eRTNLGRP_LINK = 1
+eRTNLGRP_NOTIFY :: (Num a) => a
+eRTNLGRP_NOTIFY = 2
+eRTNLGRP_NEIGH :: (Num a) => a
+eRTNLGRP_NEIGH = 3
+eRTNLGRP_TC :: (Num a) => a
+eRTNLGRP_TC = 4
+eRTNLGRP_IPV4_IFADDR :: (Num a) => a
+eRTNLGRP_IPV4_IFADDR = 5
+eRTNLGRP_IPV4_MROUTE :: (Num a) => a
+eRTNLGRP_IPV4_MROUTE = 6
+eRTNLGRP_IPV4_ROUTE :: (Num a) => a
+eRTNLGRP_IPV4_ROUTE = 7
+eRTNLGRP_IPV4_RULE :: (Num a) => a
+eRTNLGRP_IPV4_RULE = 8
+eRTNLGRP_IPV6_IFADDR :: (Num a) => a
+eRTNLGRP_IPV6_IFADDR = 9
+eRTNLGRP_IPV6_MROUTE :: (Num a) => a
+eRTNLGRP_IPV6_MROUTE = 10
+eRTNLGRP_IPV6_ROUTE :: (Num a) => a
+eRTNLGRP_IPV6_ROUTE = 11
+eRTNLGRP_IPV6_IFINFO :: (Num a) => a
+eRTNLGRP_IPV6_IFINFO = 12
+eRTNLGRP_DECnet_IFADDR :: (Num a) => a
+eRTNLGRP_DECnet_IFADDR = 13
+eRTNLGRP_NOP2 :: (Num a) => a
+eRTNLGRP_NOP2 = 14
+eRTNLGRP_DECnet_ROUTE :: (Num a) => a
+eRTNLGRP_DECnet_ROUTE = 15
+eRTNLGRP_DECnet_RULE :: (Num a) => a
+eRTNLGRP_DECnet_RULE = 16
+eRTNLGRP_NOP4 :: (Num a) => a
+eRTNLGRP_NOP4 = 17
+eRTNLGRP_IPV6_PREFIX :: (Num a) => a
+eRTNLGRP_IPV6_PREFIX = 18
+eRTNLGRP_IPV6_RULE :: (Num a) => a
+eRTNLGRP_IPV6_RULE = 19
+eRTNLGRP_ND_USEROPT :: (Num a) => a
+eRTNLGRP_ND_USEROPT = 20
+eRTNLGRP_PHONET_IFADDR :: (Num a) => a
+eRTNLGRP_PHONET_IFADDR = 21
+eRTNLGRP_PHONET_ROUTE :: (Num a) => a
+eRTNLGRP_PHONET_ROUTE = 22
+eRTNLGRP_DCB :: (Num a) => a
+eRTNLGRP_DCB = 23
+eRTNLGRP_IPV4_NETCONF :: (Num a) => a
+eRTNLGRP_IPV4_NETCONF = 24
+eRTNLGRP_IPV6_NETCONF :: (Num a) => a
+eRTNLGRP_IPV6_NETCONF = 25
+eRTNLGRP_MDB :: (Num a) => a
+eRTNLGRP_MDB = 26
+eRTNLGRP_MPLS_ROUTE :: (Num a) => a
+eRTNLGRP_MPLS_ROUTE = 27
+eRTNLGRP_NSID :: (Num a) => a
+eRTNLGRP_NSID = 28
diff --git a/System/Linux/Netlink/Route.hs b/System/Linux/Netlink/Route.hs
--- a/System/Linux/Netlink/Route.hs
+++ b/System/Linux/Netlink/Route.hs
@@ -26,6 +26,9 @@
     , getLinkMTU
     , getLinkQDisc
     , getLinkTXQLen
+    , getIFAddr
+    , getLLAddr
+    , getDstAddr
 
     , putLinkAddress
     , putLinkBroadcast
@@ -39,7 +42,7 @@
 
 #if MIN_VERSION_base(4,8,0)
 #else
-import Control.Applicative ((<$>))
+import Control.Applicative ((<$>), (<*>))
 #endif
 
 import qualified Data.ByteString as BS (length)
@@ -49,7 +52,8 @@
 import Data.Map (insert, lookup, toList)
 import Data.Serialize.Get
 import Data.Serialize.Put
-import Data.Word (Word8, Word32)
+import Data.Word (Word8, Word16, Word32)
+import Data.Int (Int32)
 
 import System.Linux.Netlink.Constants
 import System.Linux.Netlink
@@ -61,7 +65,7 @@
     {
       interfaceType  :: LinkType
     , interfaceIndex :: Word32
-    , interfaceFlags :: Word32
+    , interfaceFlags :: Word32 -- ^ System.Linux.Netlink.Constants.fIFF_* flags
     }
              | NAddrMsg
     {
@@ -70,6 +74,13 @@
     , addrFlags          :: Word8
     , addrScope          :: Word8
     , addrInterfaceIndex :: Word32
+    } 
+             | NNeighMsg
+    { neighFamily  :: Word8 -- ^ One of System.Linux.Netlink.Constants.eAF_* values
+    , neighIfindex :: Int32
+    , neighState   :: Word16 -- ^ System.Linux.Netlink.Constants.fNUD_* flags
+    , neighFlags   :: Word8
+    , neighType    :: Word8
     } deriving (Eq)
 
 instance Show Message where
@@ -78,6 +89,9 @@
   show (NAddrMsg f l fl s i) =
     "AddrMessage. Family: " ++ show f ++ ", MLength: " ++ show l ++ ", Flags: " ++ 
     show fl ++ ", Scope: " ++ show s ++ ", Index: " ++ show i
+  show (NNeighMsg f i s fl t) =
+    "NeighMessage. Family: " ++ show f ++ ", Index: " ++ show i ++ ", State: " ++ 
+    show s ++ ", Flags: " ++ show fl ++ ", Type: " ++ show t
 
 instance Convertable Message where
   getGet = getMessage
@@ -97,10 +111,20 @@
     "RoutePacket: " ++ showRouteHeader hdr ++ "\n" ++
     show cus ++ "\n" ++
     --TODO: is this the case every time? maybe match on other to get which enum to use
-    "Attrs: \n" ++ concatMap showLinkAttr (toList attrs) ++ "\n"
+    "Attrs: \n" ++ concatMap (showMsgAttr (messageType hdr)) (toList attrs) ++ "\n"
   show p = showPacket p
 
 
+showMsgAttr :: MessageType -> (Int, ByteString) -> String
+showMsgAttr msgType
+  | msgType == eRTM_NEWNEIGH = showNeighAttr
+  | msgType == eRTM_DELNEIGH = showNeighAttr
+  | msgType == eRTM_GETNEIGH = showNeighAttr
+  | otherwise = showLinkAttr --default to original behavior
+
+showNeighAttr :: (Int, ByteString) -> String
+showNeighAttr = showAttr showNeighAttrType
+
 showLinkAttr :: (Int, ByteString) -> String
 showLinkAttr (i, v)
   | i == eIFLA_STATS64 = "IFLA_STATS64:\n" ++ showStats64 v
@@ -143,6 +167,11 @@
                    | msgtype == eRTM_NEWADDR = getMessageAddr
                    | msgtype == eRTM_GETADDR = getMessageAddr
                    | msgtype == eRTM_DELADDR = getMessageAddr
+
+                   | msgtype == eRTM_GETNEIGH = getMessageNeigh
+                   | msgtype == eRTM_NEWNEIGH = getMessageNeigh
+                   | msgtype == eRTM_DELNEIGH = getMessageNeigh
+
                    | otherwise               =
                        error $ "Can't decode message " ++ show msgtype
 
@@ -164,6 +193,14 @@
     idx <- g32
     return $ NAddrMsg fam maskLen flags scope idx
 
+getMessageNeigh :: Get Message
+getMessageNeigh = NNeighMsg
+    <$> g8
+    <*> (skip 3 >> fromIntegral <$> g32)
+    <*> g16
+    <*> g8
+    <*> g8
+
 putMessage :: Message -> Put
 putMessage (NLinkMsg ty idx flags) = do
     p8 eAF_UNSPEC >> p8 0
@@ -177,6 +214,13 @@
     p8 flags
     p8 (fromIntegral scope)
     p32 idx
+putMessage (NNeighMsg f i s fl t) = do
+    p8 f
+    p8 0 >> p8 0 >> p8 0 --padding
+    p32 (fromIntegral i)
+    p16 s
+    p8 fl
+    p8 t
 
 -- |'Get' a route message or an error
 getRoutePackets :: ByteString -> Either String [RoutePacket]
@@ -253,6 +297,18 @@
 -- TODO: IFLA_{LINKMODE,LINKINFO} - see Documentation/networking/operstates.txt
 
 -- TODO: IFLA_{NET_NS_PID,IFALIAS} - need to figure out
+
+-- |get interface address from netlink attributes of 'NAddrMsg'
+getIFAddr :: AttributeReader ByteString
+getIFAddr = lookup eIFA_ADDRESS
+
+-- |get L2 address from netlink attributes of 'NNeighMsg'
+getLLAddr :: AttributeReader LinkAddress
+getLLAddr attrs = decodeMAC <$> lookup eNDA_LLADDR attrs
+
+-- |get destination address from netlink attributes of 'NNeighMsg'
+getDstAddr :: AttributeReader ByteString
+getDstAddr = lookup eNDA_DST
 
 --
 -- Helpers
diff --git a/Utils/DumpRTNL.hs b/Utils/DumpRTNL.hs
--- a/Utils/DumpRTNL.hs
+++ b/Utils/DumpRTNL.hs
@@ -3,6 +3,7 @@
 
 import System.Linux.Netlink
 import System.Linux.Netlink.Route
+import System.Linux.Netlink.Constants
 
 printLoop :: NetlinkSocket -> IO ()
 printLoop sock = do
@@ -15,6 +16,7 @@
 main = do
   sock <- makeSocket
   putStrLn "Opened socket"
-  joinMulticastGroup sock 1
+  joinMulticastGroup sock eRTNLGRP_LINK
+  joinMulticastGroup sock eRTNLGRP_NEIGH
   putStrLn "Joined multicast group"
   printLoop sock
diff --git a/netlink.cabal b/netlink.cabal
--- a/netlink.cabal
+++ b/netlink.cabal
@@ -1,5 +1,5 @@
 Name:                netlink
-Version:             1.1.0.0
+Version:             1.1.1.0
 Synopsis:            Netlink communication for Haskell
 Description:         Library to comminicate with Linux kernel via Netlink
 Homepage:            https://github.com/Ongy/netlink-hs
@@ -17,6 +17,11 @@
   type:       git
   location:   https://github.com/Ongy/netlink-hs
 
+Flag Generators
+  description: Build the generator scripts for constants
+  default: False
+  manual: True
+
 executable dump_nl80211
   hs-source-dirs: Utils
   main-is: DumpNL80211.hs
@@ -41,6 +46,57 @@
   default-language: Haskell2010
   ghc-options: -Wall
 
+executable Generate
+  if flag(Generators)
+    Buildable: True
+  else
+    Buildable: False
+  hs-source-dirs: Scripts
+  main-is: Generate.hs
+  other-modules: Helpers
+  default-language: Haskell2010
+  ghc-options: -Wall
+
+  if flag(Generators)
+    build-depends: base >=4.6 && <5,
+                   language-c <0.7,
+                   containers,
+                   process,
+                   regex-pcre
+
+executable GenerateGenl
+  if flag(Generators)
+    Buildable: True
+  else
+    Buildable: False
+  hs-source-dirs: Scripts
+  main-is: GenerateGenl.hs
+  other-modules: Helpers
+  default-language: Haskell2010
+  ghc-options: -Wall
+  if flag(Generators)
+    build-depends: base >=4.6 && <5,
+                   language-c <0.7,
+                   containers,
+                   process,
+                   regex-pcre
+
+executable GenerateNL80211
+  if flag(Generators)
+    Buildable: True
+  else
+    Buildable: False
+  hs-source-dirs: Scripts
+  main-is: GenerateNL80211.hs
+  other-modules: Helpers
+  default-language: Haskell2010
+  ghc-options: -Wall
+  if flag(Generators)
+    build-depends: base >=4.6 && <5,
+                   language-c <0.7,
+                   containers,
+                   process,
+                   regex-pcre
 
 Library
   Exposed-modules:   System.Linux.Netlink
