]>
git.ipfire.org Git - thirdparty/pciutils.git/blob - lib/names-net.c
2 * The PCI Library -- Resolving ID's via DNS
4 * Copyright (c) 2007--2008 Martin Mares <mj@ucw.cz>
6 * Can be freely distributed and used under the terms of the GNU GPL.
18 #include <netinet/in.h>
19 #include <arpa/nameser.h>
24 * Unfortunately, there are no portable functions for DNS RR parsing,
25 * so we will do the bit shuffling with our own bare hands.
28 #define GET16(x) do { if (p+2 > end) goto err; x = (p[0] << 8) | p[1]; p += 2; } while (0)
29 #define GET32(x) do { if (p+4 > end) goto err; x = (p[0] << 24) | (p[1] << 16) | (p[2] << 8) | p[3]; p += 4; } while (0)
40 u16 counts
[DNS_NUM_SECTIONS
];
41 byte
*sections
[DNS_NUM_SECTIONS
+1];
42 byte
*sec_ptr
, *sec_end
;
44 /* Result of dns_parse_rr(): */
53 dns_skip_name(byte
*p
, byte
*end
)
57 unsigned int x
= *p
++;
62 case 0: /* Uncompressed: x = length */
65 case 0xc0: /* Indirection: 1 byte more for offset */
67 return (p
< end
) ? p
: NULL
;
76 dns_parse_packet(struct dns_state
*s
, byte
*p
, unsigned int plen
)
79 unsigned int i
, j
, len
;
80 unsigned int UNUSED x
;
84 for (i
=0; i
<plen
; i
++)
86 if (!(i
%16)) printf("%04x:", i
);
87 printf(" %02x", p
[i
]);
88 if ((i
%16)==15 || i
==plen
-1) putchar('\n');
92 GET32(x
); /* ID and flags are ignored */
93 for (i
=0; i
<DNS_NUM_SECTIONS
; i
++)
95 for (i
=0; i
<DNS_NUM_SECTIONS
; i
++)
98 for (j
=0; j
< s
->counts
[i
]; j
++)
100 p
= dns_skip_name(p
, end
); /* Name */
103 GET32(x
); /* Type and class */
104 if (i
!= DNS_SEC_QUESTION
)
107 GET16(len
); /* Length of data */
122 dns_init_section(struct dns_state
*s
, int i
)
124 s
->sec_ptr
= s
->sections
[i
];
125 s
->sec_end
= s
->sections
[i
+1];
129 dns_parse_rr(struct dns_state
*s
)
131 byte
*p
= s
->sec_ptr
;
132 byte
*end
= s
->sec_end
;
136 p
= dns_skip_name(p
, end
);
144 s
->sec_ptr
= p
+ s
->rr_len
;
152 *pci_id_net_lookup(struct pci_access
*a
, int cat
, int id1
, int id2
, int id3
, int id4
)
154 static int resolver_inited
;
155 char name
[256], dnsname
[256], txt
[256], *domain
;
161 domain
= pci_get_param(a
, "net.domain");
162 if (!domain
|| !domain
[0])
168 sprintf(name
, "%04x", id1
);
171 sprintf(name
, "%04x.%04x", id2
, id1
);
174 sprintf(name
, "%04x.%04x.%04x.%04x", id4
, id3
, id2
, id1
);
176 case ID_GEN_SUBSYSTEM
:
177 sprintf(name
, "%04x.%04x.s", id2
, id1
);
180 sprintf(name
, "%02x.c", id1
);
183 sprintf(name
, "%02x.%02x.c", id2
, id1
);
186 sprintf(name
, "%02x.%02x.%02x.c", id3
, id2
, id1
);
191 sprintf(dnsname
, "%s.%s", name
, domain
);
193 a
->debug("Resolving %s\n", dnsname
);
194 if (!resolver_inited
)
199 res
= res_query(dnsname
, ns_c_in
, ns_t_txt
, answer
, sizeof(answer
));
202 a
->debug("\tfailed, h_errno=%d\n", h_errno
);
205 if (dns_parse_packet(&ds
, answer
, res
) < 0)
207 a
->debug("\tMalformed DNS packet received\n");
210 dns_init_section(&ds
, DNS_SEC_ANSWER
);
211 while (dns_parse_rr(&ds
) > 0)
213 if (ds
.rr_class
!= ns_c_in
|| ds
.rr_type
!= ns_t_txt
)
215 a
->debug("\tUnexpected RR in answer: class %d, type %d\n", ds
.rr_class
, ds
.rr_type
);
221 while (j
< dlen
&& j
+1+data
[j
] <= dlen
)
223 memcpy(txt
, &data
[j
+1], data
[j
]);
226 a
->debug("\t\"%s\"\n", txt
);
227 if (txt
[0] == 'i' && txt
[1] == '=')
228 return strdup(txt
+2);
237 char *pci_id_net_lookup(struct pci_access
*a UNUSED
, int cat UNUSED
, int id1 UNUSED
, int id2 UNUSED
, int id3 UNUSED
, int id4 UNUSED
)