github.com/inspektor-gadget/inspektor-gadget@v0.28.1/pkg/gadget-collection/gadgets/trace/tcpconnect/gadget.go (about) 1 // Copyright 2022 The Inspektor Gadget authors 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package tcpconnect 16 17 import ( 18 "encoding/json" 19 "fmt" 20 21 log "github.com/sirupsen/logrus" 22 23 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-collection/gadgets" 24 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadget-collection/gadgets/trace" 25 26 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/tcpconnect/tracer" 27 "github.com/inspektor-gadget/inspektor-gadget/pkg/gadgets/trace/tcpconnect/types" 28 29 gadgetv1alpha1 "github.com/inspektor-gadget/inspektor-gadget/pkg/apis/gadget/v1alpha1" 30 ) 31 32 type Trace struct { 33 helpers gadgets.GadgetHelpers 34 35 started bool 36 tracer trace.Tracer 37 } 38 39 type TraceFactory struct { 40 gadgets.BaseFactory 41 } 42 43 func NewFactory() gadgets.TraceFactory { 44 return &TraceFactory{ 45 BaseFactory: gadgets.BaseFactory{DeleteTrace: deleteTrace}, 46 } 47 } 48 49 func (f *TraceFactory) Description() string { 50 return `tcpconnect traces connect() system calls` 51 } 52 53 func (f *TraceFactory) OutputModesSupported() map[gadgetv1alpha1.TraceOutputMode]struct{} { 54 return map[gadgetv1alpha1.TraceOutputMode]struct{}{ 55 gadgetv1alpha1.TraceOutputModeStream: {}, 56 } 57 } 58 59 func deleteTrace(name string, t interface{}) { 60 trace := t.(*Trace) 61 if trace.tracer != nil { 62 trace.tracer.Stop() 63 } 64 } 65 66 func (f *TraceFactory) Operations() map[gadgetv1alpha1.Operation]gadgets.TraceOperation { 67 n := func() interface{} { 68 return &Trace{ 69 helpers: f.Helpers, 70 } 71 } 72 73 return map[gadgetv1alpha1.Operation]gadgets.TraceOperation{ 74 gadgetv1alpha1.OperationStart: { 75 Doc: "Start tcpconnect gadget", 76 Operation: func(name string, trace *gadgetv1alpha1.Trace) { 77 f.LookupOrCreate(name, n).(*Trace).Start(trace) 78 }, 79 }, 80 gadgetv1alpha1.OperationStop: { 81 Doc: "Stop tcpconnect gadget", 82 Operation: func(name string, trace *gadgetv1alpha1.Trace) { 83 f.LookupOrCreate(name, n).(*Trace).Stop(trace) 84 }, 85 }, 86 } 87 } 88 89 func (t *Trace) Start(trace *gadgetv1alpha1.Trace) { 90 if t.started { 91 trace.Status.State = gadgetv1alpha1.TraceStateStarted 92 return 93 } 94 95 traceName := gadgets.TraceName(trace.ObjectMeta.Namespace, trace.ObjectMeta.Name) 96 97 eventCallback := func(event *types.Event) { 98 r, err := json.Marshal(event) 99 if err != nil { 100 log.Warnf("Gadget %s: error marshaling event: %s", trace.Spec.Gadget, err) 101 return 102 } 103 t.helpers.PublishEvent(traceName, string(r)) 104 } 105 106 var err error 107 108 mountNsMap, err := t.helpers.TracerMountNsMap(traceName) 109 if err != nil { 110 trace.Status.OperationError = fmt.Sprintf("failed to find tracer's mount ns map: %s", err) 111 return 112 } 113 config := &tracer.Config{ 114 MountnsMap: mountNsMap, 115 } 116 t.tracer, err = tracer.NewTracer(config, t.helpers, eventCallback) 117 if err != nil { 118 trace.Status.OperationError = fmt.Sprintf("failed to create tracer: %s", err) 119 return 120 } 121 122 t.started = true 123 124 trace.Status.State = gadgetv1alpha1.TraceStateStarted 125 } 126 127 func (t *Trace) Stop(trace *gadgetv1alpha1.Trace) { 128 if !t.started { 129 trace.Status.OperationError = "Not started" 130 return 131 } 132 133 t.tracer.Stop() 134 t.tracer = nil 135 t.started = false 136 137 trace.Status.State = gadgetv1alpha1.TraceStateStopped 138 }