Reputation: 3581
I'm writing some go code that will take the output of a sysctl and parse the output. I'm trying to do this in pure go, but with a struct definition generated by cgo.
inet_headers.go:
//go:build ignore
// +build ignore
package inet
// #include <netinet/in_pcb.h>
// #include <netinet/tcp_var.h>
import "C"
type Inpcb C.struct_inpcb
type _Inpcb_list_entry C.struct__inpcb_list_entry
type In_addr C.struct_in_addr
When I run go tool cgo -godefs inet_headers.go
I get mostly sensible output:
package inet
type Inpcb struct {
Inp_hash _Inpcb_list_entry
Reserved1 In_addr
Reserved2 In_addr
Inp_fport uint16
Inp_lport uint16
Inp_list _Inpcb_list_entry
Inp_ppcb uint32
Inp_pcbinfo uint32
Inp_socket uint32
Nat_owner uint8
Nat_cookie uint32
Inp_portlist _Inpcb_list_entry
Inp_phd uint32
Pad_cgo_0 [8]byte
Inp_flags int32
Inp_flow uint32
Inp_vflag uint8
Inp_ip_ttl uint8
Inp_ip_p uint8
Pad_cgo_1 [1]byte
Inp_dependfaddr [16]byte
Inp_dependladdr [16]byte
Inp_dependroute [32]byte
Inp_depend4 _Ctype_struct___3
Inp_depend6 _Ctype_struct___4
Hash_element int32
Inp_saved_ppcb uint32
Inp_sp uint32
Reserved [3]uint32
}
type _Inpcb_list_entry struct {
Next uint32
Prev uint32
}
type In_addr struct {
Addr uint32
}
However, the _Ctype_struct___3
is a problem because it is undefined. This is an anonymous struct embedded in struct inpcb
:
struct inpcb {
_INPCB_LIST_ENTRY(inpcb) inp_hash; /* hash list */
struct in_addr reserved1; /* reserved */
struct in_addr reserved2; /* reserved */
u_short inp_fport; /* foreign port */
u_short inp_lport; /* local port */
_INPCB_LIST_ENTRY(inpcb) inp_list; /* list for all peer PCBs */
_INPCB_PTR(caddr_t) inp_ppcb; /* per-protocol pcb */
_INPCB_PTR(struct inpcbinfo *) inp_pcbinfo; /* PCB list info */
_INPCB_PTR(void *) inp_socket; /* back pointer to socket */
u_char nat_owner; /* Used to NAT TCP/UDP traffic */
u_int32_t nat_cookie; /* Cookie stored and returned to NAT */
_INPCB_LIST_ENTRY(inpcb) inp_portlist; /* this PCB's local port list */
_INPCB_PTR(struct inpcbport *) inp_phd; /* head of this list */
inp_gen_t inp_gencnt; /* generation count of this instance */
int inp_flags; /* generic IP/datagram flags */
u_int32_t inp_flow;
u_char inp_vflag;
u_char inp_ip_ttl; /* time to live proto */
u_char inp_ip_p; /* protocol proto */
/* protocol dependent part */
union {
/* foreign host table entry */
struct in_addr_4in6 inp46_foreign;
struct in6_addr inp6_foreign;
} inp_dependfaddr;
union {
/* local host table entry */
struct in_addr_4in6 inp46_local;
struct in6_addr inp6_local;
} inp_dependladdr;
union {
/* placeholder for routing entry */
u_char inp4_route[20];
u_char inp6_route[32];
} inp_dependroute;
struct {
/* type of service proto */
u_char inp4_ip_tos;
/* IP options */
_INPCB_PTR(struct mbuf *) inp4_options;
/* IP multicast options */
_INPCB_PTR(struct ip_moptions *) inp4_moptions;
} inp_depend4;
struct {
/* IP options */
_INPCB_PTR(struct mbuf *) inp6_options;
u_int8_t inp6_hlim;
u_int8_t unused_uint8_1;
ushort unused_uint16_1;
/* IP6 options for outgoing packets */
_INPCB_PTR(struct ip6_pktopts *) inp6_outputopts;
/* IP multicast options */
_INPCB_PTR(struct ip6_moptions *) inp6_moptions;
/* ICMPv6 code type filter */
_INPCB_PTR(struct icmp6_filter *) inp6_icmp6filt;
/* IPV6_CHECKSUM setsockopt */
int inp6_cksum;
u_short inp6_ifindex;
short inp6_hops;
} inp_depend6;
int hash_element; /* Array index of pcb's hash list */
_INPCB_PTR(caddr_t) inp_saved_ppcb; /* pointer while cached */
_INPCB_PTR(struct inpcbpolicy *) inp_sp;
u_int32_t reserved[3]; /* reserved */
};
This works fine in straight cgo because the compiler will generate code for every struct. However, with cgo -godefs
, it seems that code is only generated for exported types that I have to list explicitly (e.g. type Inpcb C.struct_inpcb
).
Is there a way around this?
I can't explicitly export a type for _Ctype_struct___3
(and that's a bad idea anyway because there's no guarantee that type name will be generated next time). type StructInp_depend4 _Ctype_struct___3
results in identifier "_Ctype_struct___3" may conflict with identifiers generated by cgo
.
Or, is there a way to coerece cgo -godefs
to explicitly export certain types?
Edit: I am reading that this is a known issue.
Upvotes: 1
Views: 261