1 /**************************************************************************/
2 /*                                                                        */
3 /*  code to support kernel generated traps -- user's can send their own   */
4 /*  thru normal channels.                                                 */
5 /*                                                                        */
6 /**************************************************************************/
7 
8 #if HMP && HMPTRAPS
9 
10 #include "../h/param.h"
11 #include "../h/dir.h"
12 #include "../h/user.h"
13 #include "../h/mbuf.h"
14 #include "../h/protosw.h"
15 #include "../h/socket.h"
16 #include "../h/socketvar.h"
17 #include "../h/errno.h"
18 
19 #include "../net/if.h"
20 #include "../net/route.h"
21 
22 #include "../bbnnet/in.h"
23 #include "../bbnnet/in_pcb.h"
24 #include "../bbnnet/in_var.h"
25 #include "../bbnnet/ip.h"
26 #include "../bbnnet/hmp.h"
27 #include "../bbnnet/hmp_var.h"
28 #include "../bbnnet/hmp_traps.h"
29 
30 /*
31  * list of monitoring hosts that want to get traps
32  * uses a sockaddr_hmp so you can specify address & port. doesn't use
33  * other fields but is the most common structure for saving port/host info.
34  */
35 
36 static struct sockaddr_hmp mon_hosts[MAX_MONHOSTS];
37 static int num_monhosts = 0;
38 
39 /*
40  * learn who gets traps
41  */
42 
43 getmonhosts(optval)
44 struct mbuf **optval;
45 {
46     struct mbuf *m;
47 
48     if ((m = m_getclr(M_WAIT,MT_DATA)) == 0)
49 	return(ENOBUFS);
50 
51     if (num_monhosts)
52     {
53 	m->m_len = num_monhosts * sizeof(struct sockaddr_hmp);
54 	bcopy((caddr_t)mon_hosts,mtod(m,caddr_t),(unsigned)m->m_len);
55     }
56     else
57     {
58 	/* would like to return nothing, but can't */
59 	m->m_len = sizeof(struct sockaddr_hmp);
60 	bzero(mtod(m,caddr_t),m->m_len);
61     }
62 
63     *optval = m;
64     return(0);
65 }
66 
67 /*
68  * changing who gets our traps
69  */
70 
71 setmonhosts(optval)
72 struct mbuf *optval;
73 {
74     register unsigned len;
75 
76     if (!suser())
77 	return(u.u_error);
78 
79     if (optval == 0)
80     {
81 	/* clearing table */
82 	num_monhosts = 0;
83 	return(0);
84     }
85 
86     len = (optval)->m_len;
87 
88     /* rational data ? */
89     if (((len/sizeof(struct sockaddr_hmp)) == 0) ||
90 	((len % sizeof(struct sockaddr_hmp)) != 0))
91 	return(EFAULT);
92 
93     if (len > sizeof(mon_hosts))
94 	return(ENOBUFS);	/* close enough to true error */
95 
96     bcopy(mtod(optval,caddr_t),(caddr_t)mon_hosts,len);
97 
98     num_monhosts = len / sizeof(struct sockaddr_hmp);
99 
100     return(0);
101 }
102 
103 /*
104  * what kernel calls to send stuff
105  */
106 
107 /* nobody does anything but copy this */
108 static struct hmpcb trappcb =
109 {
110     	0,		0,		HM_43HOST,	HM_43HOST,
111 	HM_TRAP,	HM_TRAP,	0,		0,
112 	0,		0,		0,
113 } ;
114 
115 hmp_trap(code, data, len)
116 int code;
117 caddr_t data;
118 unsigned len;
119 {
120     register int i;
121     struct mbuf *m;
122     struct inpcb inp;
123     struct hmpcb hp;
124     struct hmp_trap ht;
125 
126     if (num_monhosts == 0)
127 	return;
128 
129     if (len > (MLEN - sizeof(ht)))
130     {
131 	printf("hmp_trap: trap size too big\n");
132 	return;
133     }
134     bcopy((caddr_t)&trappcb,(caddr_t)&hp,sizeof(hp));
135     bzero((caddr_t)&inp,sizeof(inp));
136 
137     /* this may not be necessary but careful never hurts */
138     inp.inp_ppcb = &hp;
139     hp.hp_inpcb = &inp;
140 
141     /* fill in trap data leader */
142     ht.ht_time = iptime();
143     ht.ht_type = htonl((u_long)code);
144 
145 
146     for(i=0; i < num_monhosts; i++)
147     {
148 	/* get mbuf for packet */
149 	m = m_getclr(M_DONTWAIT,MT_DATA);
150 
151 	if (m == 0)
152 	    return;
153 
154 	bcopy((caddr_t)&ht,mtod(m,caddr_t),sizeof(ht));
155 	bcopy(data,mtod(m,caddr_t)+sizeof(ht),len);
156 
157 	m->m_len = len + sizeof(ht);
158 
159 	/* stuff remote address and port */
160 	inp.inp_faddr = mon_hosts[i].sin_addr;
161 	inp.inp_fport = mon_hosts[i].sin_port;
162 
163 	(void) hmp_output(&inp,m);
164     }
165 }
166 
167 #endif
168