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
hmp_trap(code,data,len)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