perf trace beauty: Add script to autogenerate socket families table
authorArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 12 Aug 2020 11:30:06 +0000 (08:30 -0300)
committerArnaldo Carvalho de Melo <acme@redhat.com>
Wed, 12 Aug 2020 11:38:36 +0000 (08:38 -0300)
To use with 'perf trace', to convert the protocol families to strings,
e.g:

  $ tools/perf/trace/beauty/socket.sh
  static const char *socket_families[] = {
   [0] = "UNSPEC",
   [1] = "LOCAL",
   [2] = "INET",
   [3] = "AX25",
   [4] = "IPX",
   [5] = "APPLETALK",
   [6] = "NETROM",
   [7] = "BRIDGE",
   [8] = "ATMPVC",
   [9] = "X25",
   [10] = "INET6",
   [11] = "ROSE",
   [12] = "DECnet",
   [13] = "NETBEUI",
   [14] = "SECURITY",
   [15] = "KEY",
   [16] = "NETLINK",
   [17] = "PACKET",
   [18] = "ASH",
   [19] = "ECONET",
   [20] = "ATMSVC",
   [21] = "RDS",
   [22] = "SNA",
   [23] = "IRDA",
   [24] = "PPPOX",
   [25] = "WANPIPE",
   [26] = "LLC",
   [27] = "IB",
   [28] = "MPLS",
   [29] = "CAN",
   [30] = "TIPC",
   [31] = "BLUETOOTH",
   [32] = "IUCV",
   [33] = "RXRPC",
   [34] = "ISDN",
   [35] = "PHONET",
   [36] = "IEEE802154",
   [37] = "CAIF",
   [38] = "ALG",
   [39] = "NFC",
   [40] = "VSOCK",
   [41] = "KCM",
   [42] = "QIPCRTR",
   [43] = "SMC",
   [44] = "XDP",
  };
  $

This uses a copy of include/linux/socket.h that is kept in a directory
to be used just for these table generation scripts and for checking if
the kernel has a new file that maybe gets something new for these
tables.

This allows us to:

- Avoid accessing files outside tools/, in the kernel sources, that may
  be changed in unexpected ways and thus break these scripts.

- Notice when those files change and thus check if the changes don't
  break those scripts, update them to automatically get the new
  definitions, a new socket family, for instance.

- Not add then to the tools/include/ where it may end up used while
  building the tools and end up requiring dragging yet more stuff from
  the kernel or plain break the build in some of the myriad environments
  where perf may be built.

This will replace the previous static array in tools/perf/ that was
dated and was already missing the AF_KCM, AF_QIPCRTR, AF_SMC and AF_XDP
families.

The next cset will wire this up to the perf build process.

At some point this must be made into a library to be used in places such
as libtraceevent, bpftrace, etc.

Cc: Adrian Hunter <adrian.hunter@intel.com>
Cc: Jiri Olsa <jolsa@kernel.org>
Cc: Namhyung Kim <namhyung@kernel.org>
Cc: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Arnaldo Carvalho de Melo <acme@redhat.com>
tools/perf/trace/beauty/include/linux/socket.h [new file with mode: 0644]
tools/perf/trace/beauty/socket.sh [new file with mode: 0755]

diff --git a/tools/perf/trace/beauty/include/linux/socket.h b/tools/perf/trace/beauty/include/linux/socket.h
new file mode 100644 (file)
index 0000000..e9cb30d
--- /dev/null
@@ -0,0 +1,442 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _LINUX_SOCKET_H
+#define _LINUX_SOCKET_H
+
+
+#include <asm/socket.h>                        /* arch-dependent defines       */
+#include <linux/sockios.h>             /* the SIOCxxx I/O controls     */
+#include <linux/uio.h>                 /* iovec support                */
+#include <linux/types.h>               /* pid_t                        */
+#include <linux/compiler.h>            /* __user                       */
+#include <uapi/linux/socket.h>
+
+struct file;
+struct pid;
+struct cred;
+struct socket;
+
+#define __sockaddr_check_size(size)    \
+       BUILD_BUG_ON(((size) > sizeof(struct __kernel_sockaddr_storage)))
+
+#ifdef CONFIG_PROC_FS
+struct seq_file;
+extern void socket_seq_show(struct seq_file *seq);
+#endif
+
+typedef __kernel_sa_family_t   sa_family_t;
+
+/*
+ *     1003.1g requires sa_family_t and that sa_data is char.
+ */
+
+struct sockaddr {
+       sa_family_t     sa_family;      /* address family, AF_xxx       */
+       char            sa_data[14];    /* 14 bytes of protocol address */
+};
+
+struct linger {
+       int             l_onoff;        /* Linger active                */
+       int             l_linger;       /* How long to linger for       */
+};
+
+#define sockaddr_storage __kernel_sockaddr_storage
+
+/*
+ *     As we do 4.4BSD message passing we use a 4.4BSD message passing
+ *     system, not 4.3. Thus msg_accrights(len) are now missing. They
+ *     belong in an obscure libc emulation or the bin.
+ */
+
+struct msghdr {
+       void            *msg_name;      /* ptr to socket address structure */
+       int             msg_namelen;    /* size of socket address structure */
+       struct iov_iter msg_iter;       /* data */
+
+       /*
+        * Ancillary data. msg_control_user is the user buffer used for the
+        * recv* side when msg_control_is_user is set, msg_control is the kernel
+        * buffer used for all other cases.
+        */
+       union {
+               void            *msg_control;
+               void __user     *msg_control_user;
+       };
+       bool            msg_control_is_user : 1;
+       __kernel_size_t msg_controllen; /* ancillary data buffer length */
+       unsigned int    msg_flags;      /* flags on received message */
+       struct kiocb    *msg_iocb;      /* ptr to iocb for async requests */
+};
+
+struct user_msghdr {
+       void            __user *msg_name;       /* ptr to socket address structure */
+       int             msg_namelen;            /* size of socket address structure */
+       struct iovec    __user *msg_iov;        /* scatter/gather array */
+       __kernel_size_t msg_iovlen;             /* # elements in msg_iov */
+       void            __user *msg_control;    /* ancillary data */
+       __kernel_size_t msg_controllen;         /* ancillary data buffer length */
+       unsigned int    msg_flags;              /* flags on received message */
+};
+
+/* For recvmmsg/sendmmsg */
+struct mmsghdr {
+       struct user_msghdr  msg_hdr;
+       unsigned int        msg_len;
+};
+
+/*
+ *     POSIX 1003.1g - ancillary data object information
+ *     Ancillary data consits of a sequence of pairs of
+ *     (cmsghdr, cmsg_data[])
+ */
+
+struct cmsghdr {
+       __kernel_size_t cmsg_len;       /* data byte count, including hdr */
+        int            cmsg_level;     /* originating protocol */
+        int            cmsg_type;      /* protocol-specific type */
+};
+
+/*
+ *     Ancillary data object information MACROS
+ *     Table 5-14 of POSIX 1003.1g
+ */
+
+#define __CMSG_NXTHDR(ctl, len, cmsg) __cmsg_nxthdr((ctl),(len),(cmsg))
+#define CMSG_NXTHDR(mhdr, cmsg) cmsg_nxthdr((mhdr), (cmsg))
+
+#define CMSG_ALIGN(len) ( ((len)+sizeof(long)-1) & ~(sizeof(long)-1) )
+
+#define CMSG_DATA(cmsg) \
+       ((void *)(cmsg) + sizeof(struct cmsghdr))
+#define CMSG_USER_DATA(cmsg) \
+       ((void __user *)(cmsg) + sizeof(struct cmsghdr))
+#define CMSG_SPACE(len) (sizeof(struct cmsghdr) + CMSG_ALIGN(len))
+#define CMSG_LEN(len) (sizeof(struct cmsghdr) + (len))
+
+#define __CMSG_FIRSTHDR(ctl,len) ((len) >= sizeof(struct cmsghdr) ? \
+                                 (struct cmsghdr *)(ctl) : \
+                                 (struct cmsghdr *)NULL)
+#define CMSG_FIRSTHDR(msg)     __CMSG_FIRSTHDR((msg)->msg_control, (msg)->msg_controllen)
+#define CMSG_OK(mhdr, cmsg) ((cmsg)->cmsg_len >= sizeof(struct cmsghdr) && \
+                            (cmsg)->cmsg_len <= (unsigned long) \
+                            ((mhdr)->msg_controllen - \
+                             ((char *)(cmsg) - (char *)(mhdr)->msg_control)))
+#define for_each_cmsghdr(cmsg, msg) \
+       for (cmsg = CMSG_FIRSTHDR(msg); \
+            cmsg; \
+            cmsg = CMSG_NXTHDR(msg, cmsg))
+
+/*
+ *     Get the next cmsg header
+ *
+ *     PLEASE, do not touch this function. If you think, that it is
+ *     incorrect, grep kernel sources and think about consequences
+ *     before trying to improve it.
+ *
+ *     Now it always returns valid, not truncated ancillary object
+ *     HEADER. But caller still MUST check, that cmsg->cmsg_len is
+ *     inside range, given by msg->msg_controllen before using
+ *     ancillary object DATA.                          --ANK (980731)
+ */
+
+static inline struct cmsghdr * __cmsg_nxthdr(void *__ctl, __kernel_size_t __size,
+                                              struct cmsghdr *__cmsg)
+{
+       struct cmsghdr * __ptr;
+
+       __ptr = (struct cmsghdr*)(((unsigned char *) __cmsg) +  CMSG_ALIGN(__cmsg->cmsg_len));
+       if ((unsigned long)((char*)(__ptr+1) - (char *) __ctl) > __size)
+               return (struct cmsghdr *)0;
+
+       return __ptr;
+}
+
+static inline struct cmsghdr * cmsg_nxthdr (struct msghdr *__msg, struct cmsghdr *__cmsg)
+{
+       return __cmsg_nxthdr(__msg->msg_control, __msg->msg_controllen, __cmsg);
+}
+
+static inline size_t msg_data_left(struct msghdr *msg)
+{
+       return iov_iter_count(&msg->msg_iter);
+}
+
+/* "Socket"-level control message types: */
+
+#define        SCM_RIGHTS      0x01            /* rw: access rights (array of int) */
+#define SCM_CREDENTIALS 0x02           /* rw: struct ucred             */
+#define SCM_SECURITY   0x03            /* rw: security label           */
+
+struct ucred {
+       __u32   pid;
+       __u32   uid;
+       __u32   gid;
+};
+
+/* Supported address families. */
+#define AF_UNSPEC      0
+#define AF_UNIX                1       /* Unix domain sockets          */
+#define AF_LOCAL       1       /* POSIX name for AF_UNIX       */
+#define AF_INET                2       /* Internet IP Protocol         */
+#define AF_AX25                3       /* Amateur Radio AX.25          */
+#define AF_IPX         4       /* Novell IPX                   */
+#define AF_APPLETALK   5       /* AppleTalk DDP                */
+#define AF_NETROM      6       /* Amateur Radio NET/ROM        */
+#define AF_BRIDGE      7       /* Multiprotocol bridge         */
+#define AF_ATMPVC      8       /* ATM PVCs                     */
+#define AF_X25         9       /* Reserved for X.25 project    */
+#define AF_INET6       10      /* IP version 6                 */
+#define AF_ROSE                11      /* Amateur Radio X.25 PLP       */
+#define AF_DECnet      12      /* Reserved for DECnet project  */
+#define AF_NETBEUI     13      /* Reserved for 802.2LLC project*/
+#define AF_SECURITY    14      /* Security callback pseudo AF */
+#define AF_KEY         15      /* PF_KEY key management API */
+#define AF_NETLINK     16
+#define AF_ROUTE       AF_NETLINK /* Alias to emulate 4.4BSD */
+#define AF_PACKET      17      /* Packet family                */
+#define AF_ASH         18      /* Ash                          */
+#define AF_ECONET      19      /* Acorn Econet                 */
+#define AF_ATMSVC      20      /* ATM SVCs                     */
+#define AF_RDS         21      /* RDS sockets                  */
+#define AF_SNA         22      /* Linux SNA Project (nutters!) */
+#define AF_IRDA                23      /* IRDA sockets                 */
+#define AF_PPPOX       24      /* PPPoX sockets                */
+#define AF_WANPIPE     25      /* Wanpipe API Sockets */
+#define AF_LLC         26      /* Linux LLC                    */
+#define AF_IB          27      /* Native InfiniBand address    */
+#define AF_MPLS                28      /* MPLS */
+#define AF_CAN         29      /* Controller Area Network      */
+#define AF_TIPC                30      /* TIPC sockets                 */
+#define AF_BLUETOOTH   31      /* Bluetooth sockets            */
+#define AF_IUCV                32      /* IUCV sockets                 */
+#define AF_RXRPC       33      /* RxRPC sockets                */
+#define AF_ISDN                34      /* mISDN sockets                */
+#define AF_PHONET      35      /* Phonet sockets               */
+#define AF_IEEE802154  36      /* IEEE802154 sockets           */
+#define AF_CAIF                37      /* CAIF sockets                 */
+#define AF_ALG         38      /* Algorithm sockets            */
+#define AF_NFC         39      /* NFC sockets                  */
+#define AF_VSOCK       40      /* vSockets                     */
+#define AF_KCM         41      /* Kernel Connection Multiplexor*/
+#define AF_QIPCRTR     42      /* Qualcomm IPC Router          */
+#define AF_SMC         43      /* smc sockets: reserve number for
+                                * PF_SMC protocol family that
+                                * reuses AF_INET address family
+                                */
+#define AF_XDP         44      /* XDP sockets                  */
+
+#define AF_MAX         45      /* For now.. */
+
+/* Protocol families, same as address families. */
+#define PF_UNSPEC      AF_UNSPEC
+#define PF_UNIX                AF_UNIX
+#define PF_LOCAL       AF_LOCAL
+#define PF_INET                AF_INET
+#define PF_AX25                AF_AX25
+#define PF_IPX         AF_IPX
+#define PF_APPLETALK   AF_APPLETALK
+#define        PF_NETROM       AF_NETROM
+#define PF_BRIDGE      AF_BRIDGE
+#define PF_ATMPVC      AF_ATMPVC
+#define PF_X25         AF_X25
+#define PF_INET6       AF_INET6
+#define PF_ROSE                AF_ROSE
+#define PF_DECnet      AF_DECnet
+#define PF_NETBEUI     AF_NETBEUI
+#define PF_SECURITY    AF_SECURITY
+#define PF_KEY         AF_KEY
+#define PF_NETLINK     AF_NETLINK
+#define PF_ROUTE       AF_ROUTE
+#define PF_PACKET      AF_PACKET
+#define PF_ASH         AF_ASH
+#define PF_ECONET      AF_ECONET
+#define PF_ATMSVC      AF_ATMSVC
+#define PF_RDS         AF_RDS
+#define PF_SNA         AF_SNA
+#define PF_IRDA                AF_IRDA
+#define PF_PPPOX       AF_PPPOX
+#define PF_WANPIPE     AF_WANPIPE
+#define PF_LLC         AF_LLC
+#define PF_IB          AF_IB
+#define PF_MPLS                AF_MPLS
+#define PF_CAN         AF_CAN
+#define PF_TIPC                AF_TIPC
+#define PF_BLUETOOTH   AF_BLUETOOTH
+#define PF_IUCV                AF_IUCV
+#define PF_RXRPC       AF_RXRPC
+#define PF_ISDN                AF_ISDN
+#define PF_PHONET      AF_PHONET
+#define PF_IEEE802154  AF_IEEE802154
+#define PF_CAIF                AF_CAIF
+#define PF_ALG         AF_ALG
+#define PF_NFC         AF_NFC
+#define PF_VSOCK       AF_VSOCK
+#define PF_KCM         AF_KCM
+#define PF_QIPCRTR     AF_QIPCRTR
+#define PF_SMC         AF_SMC
+#define PF_XDP         AF_XDP
+#define PF_MAX         AF_MAX
+
+/* Maximum queue length specifiable by listen.  */
+#define SOMAXCONN      4096
+
+/* Flags we can use with send/ and recv.
+   Added those for 1003.1g not all are supported yet
+ */
+
+#define MSG_OOB                1
+#define MSG_PEEK       2
+#define MSG_DONTROUTE  4
+#define MSG_TRYHARD     4       /* Synonym for MSG_DONTROUTE for DECnet */
+#define MSG_CTRUNC     8
+#define MSG_PROBE      0x10    /* Do not send. Only probe path f.e. for MTU */
+#define MSG_TRUNC      0x20
+#define MSG_DONTWAIT   0x40    /* Nonblocking io                */
+#define MSG_EOR         0x80   /* End of record */
+#define MSG_WAITALL    0x100   /* Wait for a full request */
+#define MSG_FIN         0x200
+#define MSG_SYN                0x400
+#define MSG_CONFIRM    0x800   /* Confirm path validity */
+#define MSG_RST                0x1000
+#define MSG_ERRQUEUE   0x2000  /* Fetch message from error queue */
+#define MSG_NOSIGNAL   0x4000  /* Do not generate SIGPIPE */
+#define MSG_MORE       0x8000  /* Sender will send more */
+#define MSG_WAITFORONE 0x10000 /* recvmmsg(): block until 1+ packets avail */
+#define MSG_SENDPAGE_NOPOLICY 0x10000 /* sendpage() internal : do no apply policy */
+#define MSG_SENDPAGE_NOTLAST 0x20000 /* sendpage() internal : not the last page */
+#define MSG_BATCH      0x40000 /* sendmmsg(): more messages coming */
+#define MSG_EOF         MSG_FIN
+#define MSG_NO_SHARED_FRAGS 0x80000 /* sendpage() internal : page frags are not shared */
+#define MSG_SENDPAGE_DECRYPTED 0x100000 /* sendpage() internal : page may carry
+                                         * plain text and require encryption
+                                         */
+
+#define MSG_ZEROCOPY   0x4000000       /* Use user data in kernel path */
+#define MSG_FASTOPEN   0x20000000      /* Send data in TCP SYN */
+#define MSG_CMSG_CLOEXEC 0x40000000    /* Set close_on_exec for file
+                                          descriptor received through
+                                          SCM_RIGHTS */
+#if defined(CONFIG_COMPAT)
+#define MSG_CMSG_COMPAT        0x80000000      /* This message needs 32 bit fixups */
+#else
+#define MSG_CMSG_COMPAT        0               /* We never have 32 bit fixups */
+#endif
+
+
+/* Setsockoptions(2) level. Thanks to BSD these must match IPPROTO_xxx */
+#define SOL_IP         0
+/* #define SOL_ICMP    1       No-no-no! Due to Linux :-) we cannot use SOL_ICMP=1 */
+#define SOL_TCP                6
+#define SOL_UDP                17
+#define SOL_IPV6       41
+#define SOL_ICMPV6     58
+#define SOL_SCTP       132
+#define SOL_UDPLITE    136     /* UDP-Lite (RFC 3828) */
+#define SOL_RAW                255
+#define SOL_IPX                256
+#define SOL_AX25       257
+#define SOL_ATALK      258
+#define SOL_NETROM     259
+#define SOL_ROSE       260
+#define SOL_DECNET     261
+#define        SOL_X25         262
+#define SOL_PACKET     263
+#define SOL_ATM                264     /* ATM layer (cell level) */
+#define SOL_AAL                265     /* ATM Adaption Layer (packet level) */
+#define SOL_IRDA        266
+#define SOL_NETBEUI    267
+#define SOL_LLC                268
+#define SOL_DCCP       269
+#define SOL_NETLINK    270
+#define SOL_TIPC       271
+#define SOL_RXRPC      272
+#define SOL_PPPOL2TP   273
+#define SOL_BLUETOOTH  274
+#define SOL_PNPIPE     275
+#define SOL_RDS                276
+#define SOL_IUCV       277
+#define SOL_CAIF       278
+#define SOL_ALG                279
+#define SOL_NFC                280
+#define SOL_KCM                281
+#define SOL_TLS                282
+#define SOL_XDP                283
+
+/* IPX options */
+#define IPX_TYPE       1
+
+extern int move_addr_to_kernel(void __user *uaddr, int ulen, struct sockaddr_storage *kaddr);
+extern int put_cmsg(struct msghdr*, int level, int type, int len, void *data);
+
+struct timespec64;
+struct __kernel_timespec;
+struct old_timespec32;
+
+struct scm_timestamping_internal {
+       struct timespec64 ts[3];
+};
+
+extern void put_cmsg_scm_timestamping64(struct msghdr *msg, struct scm_timestamping_internal *tss);
+extern void put_cmsg_scm_timestamping(struct msghdr *msg, struct scm_timestamping_internal *tss);
+
+/* The __sys_...msg variants allow MSG_CMSG_COMPAT iff
+ * forbid_cmsg_compat==false
+ */
+extern long __sys_recvmsg(int fd, struct user_msghdr __user *msg,
+                         unsigned int flags, bool forbid_cmsg_compat);
+extern long __sys_sendmsg(int fd, struct user_msghdr __user *msg,
+                         unsigned int flags, bool forbid_cmsg_compat);
+extern int __sys_recvmmsg(int fd, struct mmsghdr __user *mmsg,
+                         unsigned int vlen, unsigned int flags,
+                         struct __kernel_timespec __user *timeout,
+                         struct old_timespec32 __user *timeout32);
+extern int __sys_sendmmsg(int fd, struct mmsghdr __user *mmsg,
+                         unsigned int vlen, unsigned int flags,
+                         bool forbid_cmsg_compat);
+extern long __sys_sendmsg_sock(struct socket *sock, struct msghdr *msg,
+                              unsigned int flags);
+extern long __sys_recvmsg_sock(struct socket *sock, struct msghdr *msg,
+                              struct user_msghdr __user *umsg,
+                              struct sockaddr __user *uaddr,
+                              unsigned int flags);
+extern int sendmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct iovec **iov);
+extern int recvmsg_copy_msghdr(struct msghdr *msg,
+                              struct user_msghdr __user *umsg, unsigned flags,
+                              struct sockaddr __user **uaddr,
+                              struct iovec **iov);
+extern int __copy_msghdr_from_user(struct msghdr *kmsg,
+                                  struct user_msghdr __user *umsg,
+                                  struct sockaddr __user **save_addr,
+                                  struct iovec __user **uiov, size_t *nsegs);
+
+/* helpers which do the actual work for syscalls */
+extern int __sys_recvfrom(int fd, void __user *ubuf, size_t size,
+                         unsigned int flags, struct sockaddr __user *addr,
+                         int __user *addr_len);
+extern int __sys_sendto(int fd, void __user *buff, size_t len,
+                       unsigned int flags, struct sockaddr __user *addr,
+                       int addr_len);
+extern int __sys_accept4_file(struct file *file, unsigned file_flags,
+                       struct sockaddr __user *upeer_sockaddr,
+                        int __user *upeer_addrlen, int flags,
+                        unsigned long nofile);
+extern int __sys_accept4(int fd, struct sockaddr __user *upeer_sockaddr,
+                        int __user *upeer_addrlen, int flags);
+extern int __sys_socket(int family, int type, int protocol);
+extern int __sys_bind(int fd, struct sockaddr __user *umyaddr, int addrlen);
+extern int __sys_connect_file(struct file *file, struct sockaddr_storage *addr,
+                             int addrlen, int file_flags);
+extern int __sys_connect(int fd, struct sockaddr __user *uservaddr,
+                        int addrlen);
+extern int __sys_listen(int fd, int backlog);
+extern int __sys_getsockname(int fd, struct sockaddr __user *usockaddr,
+                            int __user *usockaddr_len);
+extern int __sys_getpeername(int fd, struct sockaddr __user *usockaddr,
+                            int __user *usockaddr_len);
+extern int __sys_socketpair(int family, int type, int protocol,
+                           int __user *usockvec);
+extern int __sys_shutdown(int fd, int how);
+
+extern struct ns_common *get_net_ns(struct ns_common *ns);
+#endif /* _LINUX_SOCKET_H */
diff --git a/tools/perf/trace/beauty/socket.sh b/tools/perf/trace/beauty/socket.sh
new file mode 100755 (executable)
index 0000000..3820e5c
--- /dev/null
@@ -0,0 +1,24 @@
+#!/bin/sh
+# SPDX-License-Identifier: LGPL-2.1
+
+# This one uses a copy from the kernel sources headers that is in a
+# place used just for these tools/perf/beauty/ usage, we shouldn't not
+# put it in tools/include/linux otherwise they would be used in the
+# normal compiler building process and would drag needless stuff from the
+# kernel.
+
+# When what these scripts need is already in tools/include/ then use it,
+# otherwise grab and check the copy from the kernel sources just for these
+# string table building scripts.
+
+[ $# -eq 1 ] && header_dir=$1 || header_dir=tools/perf/trace/beauty/include/linux/
+
+printf "static const char *socket_families[] = {\n"
+# #define AF_LOCAL     1       /* POSIX name for AF_UNIX       */
+regex='^#define[[:space:]]+AF_(\w+)[[:space:]]+([[:digit:]]+).*'
+
+egrep $regex ${header_dir}/socket.h | \
+       sed -r "s/$regex/\2 \1/g"       | \
+       xargs printf "\t[%s] = \"%s\",\n" | \
+       egrep -v "\"(UNIX|MAX)\""
+printf "};\n"