1/* ether.c - ethernet address lookup routines */
2/* $OpenLDAP$ */
3/* This work is part of OpenLDAP Software <http://www.openldap.org/>.
4 *
5 * Copyright 2008-2011 The OpenLDAP Foundation.
6 * Copyright 2008 by Howard Chu, Symas Corp.
7 * All rights reserved.
8 *
9 * Redistribution and use in source and binary forms, with or without
10 * modification, are permitted only as authorized by the OpenLDAP
11 * Public License.
12 *
13 * A copy of this license is available in the file LICENSE in the
14 * top-level directory of the distribution or, alternatively, at
15 * <http://www.OpenLDAP.org/license.html>.
16 */
17/* ACKNOWLEDGEMENTS:
18 * This code references portions of the nss-ldapd package
19 * written by Arthur de Jong. The nss-ldapd code was forked
20 * from the nss-ldap library written by Luke Howard.
21 */
22
23#include "nssov.h"
24
25struct ether_addr {
26  uint8_t ether_addr_octet[6];
27};
28
29/* ( nisSchema.2.11 NAME 'ieee802Device' SUP top AUXILIARY
30 *   DESC 'A device with a MAC address; device SHOULD be
31 *         used as a structural class'
32 *   MAY macAddress )
33 */
34
35/* the basic search filter for searches */
36static struct berval ether_filter = BER_BVC("(objectClass=ieee802Device)");
37
38/* the attributes to request with searches */
39static struct berval ether_keys[] = {
40	BER_BVC("cn"),
41	BER_BVC("macAddress"),
42	BER_BVNULL
43};
44
45NSSOV_INIT(ether)
46
47NSSOV_CBPRIV(ether,
48	char buf[256];
49	struct berval name;
50	struct berval addr;);
51
52#define WRITE_ETHER(fp,addr) \
53  {int ao[6]; \
54  sscanf(addr.bv_val,"%02x:%02x:%02x:%02x:%02x:%02x", \
55  	&ao[0], &ao[1], &ao[2], &ao[3], &ao[4], &ao[5] );\
56	tmpaddr.ether_addr_octet[0] = ao[0]; \
57	tmpaddr.ether_addr_octet[1] = ao[1]; \
58	tmpaddr.ether_addr_octet[2] = ao[2]; \
59	tmpaddr.ether_addr_octet[3] = ao[3]; \
60	tmpaddr.ether_addr_octet[4] = ao[4]; \
61	tmpaddr.ether_addr_octet[5] = ao[5]; } \
62  WRITE_TYPE(fp,tmpaddr,uint8_t[6]);
63
64static int write_ether(nssov_ether_cbp *cbp,Entry *entry)
65{
66	int32_t tmpint32;
67	struct ether_addr tmpaddr;
68	struct berval tmparr[2], empty;
69	struct berval *names,*ethers;
70	Attribute *a;
71	int i,j;
72
73	/* get the name of the ether entry */
74	if (BER_BVISNULL(&cbp->name))
75	{
76		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[0].an_desc);
77		if ( !a )
78		{
79			Debug(LDAP_DEBUG_ANY,"ether entry %s does not contain %s value\n",
80							entry->e_name.bv_val,cbp->mi->mi_attrs[0].an_desc->ad_cname.bv_val,0 );
81			return 0;
82		}
83		names = a->a_vals;
84	}
85	else
86	{
87		names=tmparr;
88		names[0]=cbp->name;
89		BER_BVZERO(&names[1]);
90	}
91	/* get the addresses */
92	if (BER_BVISNULL(&cbp->addr))
93	{
94		a = attr_find(entry->e_attrs, cbp->mi->mi_attrs[1].an_desc);
95		if ( !a )
96		{
97			Debug(LDAP_DEBUG_ANY,"ether entry %s does not contain %s value\n",
98							entry->e_name.bv_val,cbp->mi->mi_attrs[1].an_desc->ad_cname.bv_val,0 );
99			return 0;
100		}
101		ethers = a->a_vals;
102		/* TODO: move parsing of addresses up here */
103	}
104	else
105	{
106		ethers=tmparr;
107		ethers[0]=cbp->addr;
108		BER_BVZERO(&ethers[1]);
109	}
110	/* write entries for all names and addresses */
111	for (i=0;!BER_BVISNULL(&names[i]);i++)
112		for (j=0;!BER_BVISNULL(&ethers[j]);j++)
113		{
114			WRITE_INT32(cbp->fp,NSLCD_RESULT_BEGIN);
115			WRITE_BERVAL(cbp->fp,&names[i]);
116			WRITE_ETHER(cbp->fp,ethers[j]);
117		}
118	return 0;
119}
120
121NSSOV_CB(ether)
122
123NSSOV_HANDLE(
124	ether,byname,
125	char fbuf[1024];
126	struct berval filter = {sizeof(fbuf)};
127	filter.bv_val = fbuf;
128	BER_BVZERO(&cbp.addr);
129	READ_STRING(fp,cbp.buf);
130	cbp.name.bv_len = tmpint32;
131	cbp.name.bv_val = cbp.buf;,
132	Debug(LDAP_DEBUG_TRACE,"nssov_ether_byname(%s)\n",cbp.name.bv_val,0,0);,
133	NSLCD_ACTION_ETHER_BYNAME,
134	nssov_filter_byname(cbp.mi,0,&cbp.name,&filter)
135)
136
137NSSOV_HANDLE(
138	ether,byether,
139	struct ether_addr addr;
140	char fbuf[1024];
141	struct berval filter = {sizeof(fbuf)};
142	filter.bv_val = fbuf;
143	BER_BVZERO(&cbp.name);
144	READ_TYPE(fp,addr,uint8_t[6]);
145	cbp.addr.bv_len = snprintf(cbp.buf,sizeof(cbp.buf), "%x:%x:%x:%x:%x:%x",
146		addr.ether_addr_octet[0],
147		addr.ether_addr_octet[1],
148		addr.ether_addr_octet[2],
149		addr.ether_addr_octet[3],
150		addr.ether_addr_octet[4],
151		addr.ether_addr_octet[5]);
152	cbp.addr.bv_val = cbp.buf;,
153	Debug(LDAP_DEBUG_TRACE,"nssov_ether_byether(%s)\n",cbp.addr.bv_val,0,0);,
154	NSLCD_ACTION_ETHER_BYETHER,
155	nssov_filter_byid(cbp.mi,1,&cbp.addr,&filter)
156)
157
158NSSOV_HANDLE(
159	ether,all,
160	struct berval filter;
161	/* no parameters to read */
162	BER_BVZERO(&cbp.name);
163	BER_BVZERO(&cbp.addr);,
164	Debug(LDAP_DEBUG_TRACE,"nssov_ether_all()\n",0,0,0);,
165	NSLCD_ACTION_ETHER_ALL,
166	(filter=cbp.mi->mi_filter,0)
167)
168