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